[Qt-interest] Problems with CAFile using QSslSocket

Tony Rietwyk tony.rietwyk at rightsoft.com.au
Sat Jul 24 04:24:27 CEST 2010


Eduardo wrote: 

> Hello everyone!
> 
> I'm trying to stablish a secure connection between a server and a
> client. I'm using QSslSocket, QTcpServer etc. I've created my own
> certificate, then my own CA Authority and signed the certificate with
> it, following the steps shown in [1] and [2]. I've verified that the
> signed PEM certificate is valid with openssl:
> 
> 
> edulix at edulix-laptop .../sslsockets_example/certs/server_cert $
> openssl verify -CaFile ca-cert.pem localhost.pem
> usage: verify [-verbose] [-CApath path] [-CAfile file] [-purpose
> purpose] [-crl_check] [-engine e] cert1 cert2 ...
> recognized usages:
>         sslclient       SSL client
>         sslserver       SSL server
>         nssslserver     Netscape SSL server
>         smimesign       S/MIME signing
>         smimeencrypt    S/MIME encryption
>         crlsign         CRL signing
>         any             Any Purpose
>         ocsphelper      OCSP helper
>         timestampsign   Time Stamp signing
> 
> 
> I execute the  sslsockets_example_server and sslsockets_example_client
> binaries in that directory too (sslsockets_example/certs/server_cert).
> This is the output I get:
> 
> $ sslsockets_example_server
> Listening on port  1025
> SslServerConnection::SslServerConnection 8
> caCertificates.first().subjectInfo(QSslCertificate::CommonName)
> "Baltimore CyberTrust Mobile Root"
> privateKey.isNull():  false
> certificate.isNull():  false
> SslServerConnection::stateChanged()
> mode:  0
> state:  QAbstractSocket::ConnectedState
> Calling startServerEncryption()
> SslServerConnection::sslModeChanged() 2
> SslServerConnection::sslErrors()
> error: "The issuer certificate of a locally looked up certificate
> could not be found"
> error: "No certificates could be verified"
> SslServerConnection::encrypted()
> SslServerConnection::readyRead()
> Read from socket: "hello"
> 
> 
> $ sslsockets_example_client
> caCertificates.first().subjectInfo(QSslCertificate::LocalityName) ""
> SecureClient::start(); called to m_socket->connectToHostEncrypted
> SecureClient::hostFound()
> SecureClient::connected()
> SecureClient::errorOccured()
> SecureClient::connectionEstablished()
> 
> 
> As you can notice I'm ignoring SSL errors otherwise it wouldn't work.
> The problem as you can see is that even though the ca-cert.pem file is
> being correctly put into a QSslCertificate object, there are problems
> when using it in the QSslSocket; see the server complaining: "The
> issuer certificate of a locally looked up certificate could not be
> found".
> 
> I attach the whole code and the very certs I'm using so that you can
> test it too..
> 
> Thanks in advance,
>    Eduardo Robles Elvira.
> 
> PD: First post in this list yay!
> --
> [1] http://sial.org/howto/openssl/ca/
> [2] http://sial.org/howto/openssl/csr/


Welcome to the list! 

Qt gets a predefined list of root certificates from somewhere.  That list
may not include your certificate's referrer - sorry I'm not sure what the
correct terminology is.  Here is the code I used to work around the problem
by adding the referrer, and debug the default list: 

	// Load up root certificate for our web certificate.... it's not
included in Qt default list
	QFile certFile( ":/misc/AddTrustExternalCARoot.crt" );
	if (certFile.open( QIODevice::ReadOnly ))
		rootCertificate = new QSslCertificate( &certFile, QSsl::Pem
);

	certFile.close();

	QSslConfiguration *sslConfig = new QSslConfiguration(
		QSslConfiguration::defaultConfiguration() );

	QList<QSslCertificate> *caCerts = new QList<QSslCertificate>(
		sslConfig->caCertificates() );

	if (rootCertificate->isValid())
	{
		caCerts->append( *rootCertificate );
		sslConfig->setCaCertificates( *caCerts );
		QSslConfiguration::setDefaultConfiguration( *sslConfig );
	}

#ifndef QT_NO_DEBUG
	int x_end = caCerts->count();
	qDebug() << "caCerts.count" << x_end;
	for( int x = 0;  x < x_end;  ++x )
		qDebug() << "caCert" << x 
			<< ": Org" <<
caCerts->at(x).issuerInfo(QSslCertificate::Organization)
			<< "ComNam:"  <<
caCerts->at(x).issuerInfo(QSslCertificate::CommonName)
			<< "Country: " <<
caCerts->at(x).issuerInfo(QSslCertificate::CountryName);
#endif

Hope that helps, 

Tony.




More information about the Qt-interest-old mailing list