简体   繁体   中英

QNetworkAccessManager ssl handshake fails

I'm using QNAM and QNetworkRequest to make a post request to our server. On most machines it works fine, but on some it fails. All machines are running windows and connecting to the same Ubuntu server. Between two windows 7 machines, one works and one fails. Both machines should have the same ssleay32.dll and libeay32.dll (I include them in my installation package). After installing chrome on to the "broken" machine, it can now properly perform the SSL handshake. If I remove all certificates (intermediate and trusted) relating to our CA (Thawte) the SSL handshake fails again.

manager = new QNetworkAccessManager( this );

connect( manager, SIGNAL( finished( QNetworkReply* ) ),
         this, SLOT( licenseServerReply( QNetworkReply* ) ) );

connect( manager, SIGNAL(sslErrors(QNetworkReply*,QList<QSslError>)),
         this, SLOT( sslErrorOccured(QNetworkReply*,QList<QSslError>))
         );
request.setUrl( "https://www.myURL.com/postFromMachine/");

postData.append( "computer-name=" );
postData.append( hostInfo.hostName() );
postData.append( "&" );

manager->post( request, postData );

I've connected a slot to the sslErrors() signal of the QNetworkRequest object and I get the following when the SSL handshake fails: Debug: "The issuer certificate of a locally looked up certificate could not be found" Debug: "The root CA certificate is not trusted for this purpose"

In an attempt to fix the missing cert I added all certificates (intermediate and trusted) on the working machine concerning our Root Authority "Thawte" and related certificates "Thawte consulting" etc... to an QSSLSocket object and passed that object to the QNAM via QSSLCOnfiguration. There were 9 of them total and it didn't seem to fix the issue. I added the following code before manager->post().

QSslSocket *socket = new QSslSocket( this );
socket->addCaCertificates( ":/Certs/thawte1.cer" );
socket->addCaCertificates( ":/Certs/thawte2.cer" );
// Several more certs ...
socket->addCaCertificates( ":/Certs/thawte9.cer" );

QSslConfiguration conf;
conf.setCaCertificates( socket->caCertificates() );
request.setSslConfiguration( conf );

After discussion on an IRC chat I was pointed to the following command on the server to ensure it has the proper certificate chain:

openssl s_client -verify 5 -CApath /etc/ssl/certs -connect www.myurl.com:443 -showcerts

It replied with [ok] and no errors. The issuer is always the subject of the next cert in the chain, and the chain goes all the way to the root CA. Unless there is more to check with that command, it seems good to me.

I also checked the chain of certificates on the following site, and it seems like everything was good (expect possibly a weak certificate for path #2) https://www.ssllabs.com/ssltest/analyze.html

Am at a loss of what to do, how can I prove that the server has the right certificate chain? If it does have the right certificate chain, why don't all machines perform the handshake properly (ie what certificates or settings do I need to add/change in my application to get them to work)? I don't want to simply ignore the SSLErrors as I want to be 100% sure that I have an encrypted connection to the proper host.

Thanks in advance for all the help!

I modified the socket->addCaCertificate to addDefaultCaCertificate and switched them from .cer to .pem ( I got the .pem files directly from our server ). Now everything works great. Note, don't copy your private key from your server, ensure it is the CA public keys.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM