QsslSocket: Cannot access peer (client) certificate on other peer (server) - qt

This is the follow-up to my original problem: Qt Server+Client App: encryption fails (updated with code)
Also posted this to Qt Forums: http://qt-project.org/forums/viewthread/41293/
Hi,
my goal is establishing two-ways authentication for Server+Client apps. I am having a strange problem however. Using certificates generated by XCA and OpenSSL for testing purposes in my Server+Client apps using Qt 5.2.0.
Note: I do not use QSslSocket::ignoreSslErrors() to get past the errors.
2 scenarios:
1)
Client has valid clientCA, valid local certificate (signed by serverCA, client template) and valid private key set.
Server has valid serverCA, valid local certificate (signed by clientCA, server template) and valid private key set.
2)
Client has valid clientCA.
Server has valid local certificate (signed by clientCA, server template) and valid private key set.
———————-
ad 1)
I can establish secure connection fine but only if I set QSslSocket::peerVerifyMode to VerifyNone on server side (automatically VerifyPeer on the client).
If I do NOT do that I get assigned automatically VerifyPeer mode even though the socket is correctly evaluated as server side (checked SslMode for this). That is apparently contrary to the documentation as it says it should be automatically QueryPeer if the socket is server side. However even setting the socket to QueryPeer manually does not help and the handshake fails the same as with VerifyPeer.
Now the error I get is:
QSslError::CertificateSignatureFailed (4) “The signature of the certificate is invalid”
Inspecting the peer certificate on SSL error (and/or encrypted) on the server reveals that no certificate was presented by the peer (the peerCertificate() yields null certificate) so it is no wonder it fails with this error. I cannot get the peer certificate on client side either in this case.
BUT even if VerifyNone is set on server and encryption succeeds I still get the above mentioned error due to peer (client) not presenting its certificate despite the fact that it should NOT be requested in the first place. On client I can get peer (server) certificate in this case.
———————-
ad 2)
This is documentation style scenario, that should be capable of one way authentication only (client authenticating the server). In this case the peerVerifyMode is again selected as VerifyPeer on server by default.
However peerVerifyMode does NOT have any effect on the handshake on server side! Even when set to VerifyPeer it succeeds despite the fact that client has not presented any certificates.
No matter the setting of peerVerifyMode the error occurs the same as in #1 plus two new errors, therefore I get on server:
QSslError::CertificateSignatureFailed (4) “The signature of the certificate is invalid”
QSslError::UnableToGetLocalIssuerCertificate (11) “The issuer certificate of a locally looked up certificate could not be found”
QSslError::UnableToVerifyFirstCertificate (12) “No certificates could be verified”
Despite these the SSL handshake succeeds regardless of peerVerifyMode on the server side. I get no errors on the client. This once again is contrary to the documentation that clearly states that in case of ANY SSL error the connection is dropped unless they are ignored.
———————————————
I do not understand this behaviour nor how to fix it since I am fairly sure the certificates are ok (the test handshake using the openssl.exe succeeds with verify return code 0 (Ok)). It seems to me that the settings of peerVerifyMode is often ignored though and that in some cases errors are automatically ignored as well. Since they are related to unsent (or not received) peer (client) certificate on the server side I can understand it but not if the peerVerifyMode is set to VerifyPeer.
Can anybody help? Thank you!

I have been able to solve this issue in unusual way. It was caused by bug in Qt, I think this one https://bugreports.qt-project.org/browse/QTBUG-7200 since it matched the symptoms of my latest attempts (same error in Qt while openssl succeeded in verifying the certificates etc.).
Update from 5.2.0 to 5.3.0-beta solved it (bug was apparently solved in 5.2.2).

Related

Use ruby grpc client with self signed certificate

Trying to use ruby GRPC client to connect to a go GRPC server. The server uses TLS credentials with self signed certificates. I have trusted the certificate on my system (ubuntu 20.04) but still getting Handshake failed with fatal error SSL_ERROR_SSL: error:1000007d:SSL routines:OPENSSL_internal:CERTIFICATE_VERIFY_FAILED
Only way this is working is by manually setting GRPC::Core::ChannelCredentials.new(File.read(cert_path)) when initializing the client. Another workaround is setting :this_channel_is_insecure, but this only works if I remove TLS credentials in the server altogether (which I do not want).
Is there any way to get the GRPC client to work with the system certs?
I assume the gem is using roots.pem and trying to override that using GRPC::Core::ChannelCredentials.set_default_roots_pem results in Could not load any root certificate.
Also, I have not found any parameter that would let me skip certificate verification.
The default root location can be overridden using the GRPC_DEFAULT_SSL_ROOTS_FILE_PATH environment variable pointing to a file on the file system containing the roots. Setting GRPC::Core::ChannelCredentials.new(File.read(cert_path)) also seems fine to me.
In Ruby, most likely the feature to skip cert verification in TLS is not supported. We have the corresponding feature supported in underlying core, but it might not be plumbed to Ruby yet(at least not that I am aware of). If you need that, feel free to open a feature request to in gRPC Github page.
Thank you!

API request and Error in curl::curl_fetch_memory(url, handle = handle) : SSL certificate problem: certificate has expired

I was running the code for months without any issues, and couple days before.
GET(url="myurl", query)
Today I've got an error
Error in curl::curl_fetch_memory(url, handle = handle) :
SSL certificate problem: certificate has expired
The SSL cert on the site is active and ends in a year.
Also the same GET request is working via browser....
What is the issue? 🤷‍♂️
Try testing your server with this tool: https://www.ionos.com/tools/ssl-checker and see if it says that it is "not installed correctly".
If you find that it has been working historically but recently stopped, you likely have an invalid chain of trust. Recently, a common root CA certificate expired. Your server may be using this and sending it as part of it's chain of certificates it sends to clients. If that is the case, and it is this recently-expired root CA, your fix will most likely look like removing that root certificate from your bundle. So you'd include the intermediate certificates still, but exclude the root. You can then use these tools to revalidate if things are setup correctly.
You can also see the chain and some of the validity information using this tool: https://www.sslshopper.com/ssl-checker.html

how to solve "ssl certificate problem: unable to get local issuer certificate" in ubuntu 16.04

I'm using rvest to scrape a website. I'm totally OK with other websites but this one is using another type of certificate I think. I've seen similar questions here and in github but no one could help me.
Any help is appreciated.
My script is as follows:
url <- "https://search.codal.ir/api/search/v1/q?PageNumber=1&Symbol=%D9%81%D8%B3%D8%A7&Subject=%20&CompanyState=0&LetterType=6&TracingNo=-1&LetterCode=%20&FromDate=1395/01/01&ToDate=%DB%B1%DB%B3%DB%B9%DB%B8/%DB%B0%DB%B3/%DB%B1%DB%B6&AuditorRef=-1&YearEndToDate=&Publisher=false&Mains=true&Childs=false&Audited=false&NotAudited=true&Length=-1&Consolidatable=true&NotConsolidatable=true&CompanyType=1&Category=1"
data <- fromJSON(url)[[3]]
and the error is:
"Error in open.connection(con, "rb") :
SSL certificate problem: unable to get local issuer certificate"
This is a wrongly configured server (search.codal.ir). A friendly email to their admins could probably be considered.
The problem here is that this TLS server doesn't send a complete cert chain in the handshake, which it should according to standards. More specifically, it doesn't send the intermediate certificate. This is visible by posting "search.codal.ir" into SSL Labs test page and the results are clear.
Intermediate certificates are certs that are sort of "in between" the root certificate (that exists in the CA store) and the server's own certificate.
This sometimes work better in browsers than with curl because
browsers typically cache the intermediate certs (which can be used by multiple hosts)
some browsers (like Chrome) supports features like AIA (Authority Information Access) which makes it able to download intermediate certificates on-demand. RFC 5280 has the details.
The curl error message unable to get local issuer certificate almost always means this is what happened.
Fixing it
The real and proper fix should be done by the server admins. This is a server setup problem.
Working around it
You can download the intermediate cert manually and put it in your CA store, the PEM file you tell curl (or other client) to use when verifying the peer.
The SSL Labs page says the following about the missing intermediate cert:
Certum Organization Validation CA SHA2
Fingerprint SHA256: fd02362244f31266caff005818d1004ec4eb08fb239aafaaafff47497d6005d6
Pin SHA256: 51GveKNrpJjtGpXY5QDx03s3YTQwaQic6dWBqo3zX6s=
RSA 2048 bits (e 65537) / SHA256withRSA
(I couldn't find where to download it from)
Don't do this
You can disable certificate verification completely which then will allow your program to continue. But you've then given up on all security and there are just sadness and tears going down that road. Only do that for experiments, never for production.
You can try :
library(httr)
set_config(config(ssl_verifypeer = 0L))

Import Fiddler certicicate

Im trying to get Odata service in Power Bi and i always get this error
OData: Request failed: The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure channel.
But when I do run the Fiddler and I add its certificate ,everything works perfect.
and when I close the Fiddler I get the same old error. How should I solve it, should I add this certificate to the IIS in case yes how!.
I added the Fiddler and the service link to the Trusted Root. But it did not work.
always after closing Fiddler the connection is gone.

Need advice on Self-Signed SSL and Java

Issues have been asked many times about how to handle self-signed certificates with Java and implementations are often provided. However, I'm not sure that these implementations will give me the security/trust I am looking for.
My circumstance is as follows: I have a client program connecting to our server application. Both of these we have complete control over. Our client post's a stream using https to a URL at our server, and the server responds. Currently (and this is what I'm trying to fix) the server has a self signed certificate. Java doesn't like this and FOR TESTING ONLY, we are pretty much ignoring the certificate altogether by trusting any certificate.
I have little knowledge of SSL. My boss says we can use our self-signed certificate and it will be secure as long we don't make our crypt. key public. This sounds correct to me, but a lot of posts say self-signed cert's are automatically vulnerable to man-in-the-middle attacks. Does this mean SSL sends the crypt. key along with the certificate?
Since we have control over both ends, should we just encrypt our data ourselves with a secret key, and decrypt it at the end using our key? Or is there reason to use SSL?
Instead of trusting any certificate blindly (which would make the connection vulnerable to MITM attacks), configure your Java client to trust that particular certificate. Self-signed certificates do not inherently make SSL/TLS connections vulnerable to MITM attacks, they just make their distribution and the evaluation of trust more specific to this particular deployment (i.e. you have to configure it manually).
You can do this in at least 3 ways (pick the easiest one for you, I'd suggest bullet point #2):
Import the server certificate into your client's global trust store (lib/security/cacerts in your JRE directory). This will make all applications run with this JRE trust this certificate.
Import the server certificate into another truststore (possibly a local copy of lib/security/cacerts) and make this particular application use this truststore. This can be done using the javax.net.ssl.trustStore system properties.
Make your client application use an SSLContext initialised with an X509TrustManager configured to trust that certificate: either something written manually or a trust manager coming from TrustManagerFactory initialised by loading a local keystore that contains that particular certificate (as in the previous method).
You'll find more details about all this in the JSSE Reference Guide.
(This answer to a similar question should give you the details for doing all this properly, in particular keytool -import ....)
The arguments against self signed certificates mainly apply to web-applications. Since with the current infrastructure a browser won't be able to validate your self-signed certificate.
Since you have control over the client, you can simply hardcode the certificate you expect into the client. For example you might calculate the sha1 hash of the certificate, and check if that matches the expected value. That way you don't even need to trust hundreds of CAs.
To achieve secure communication you need to first ensure your talking to the right computer. When the client first attempts to establish a secure connection, it pings the server and the server responds with its cert. At this point you MUST validate the servers cert before continuing. The cert includes a public key and signature that can be used to ensure the cert is valid. For example, in web browsers this means checking to see it's been signed by an authority listed as trusted in your browser settings, if that check fails you'll see red warnings in your browser. In your case this will mean you have manually (or in code) added the servers cert into a trust store so that it is trusted.

Resources