QSslSocket Client + Server
-
Hello,
I created a certificate + private key with OpenSSL:OpenSSL> req -x509 -newkey rsa:2048 -keyout server.key -nodes -days 365 -out ser ver.csr Loading 'screen' into random state - done Generating a 2048 bit RSA private key ......................................+++ .......................................................+++ writing new private key to 'server.key' ----- You are about to be asked to enter information that will be incorporated into your certificate request. What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank For some fields there will be a default value, If you enter '.', the field will be left blank. ----- Country Name (2 letter code) [AU]:CZ State or Province Name (full name) [Some-State]:?MyProvince Locality Name (eg, city) []:MyCity Organization Name (eg, company) [Internet Widgits Pty Ltd]:MyName Organizational Unit Name (eg, section) []:MyName Common Name (e.g. server FQDN or YOUR name) []:MyServer Email Address []:MyEmail@domain.com OpenSSL>
I use this method to connect to server:
bool SslClient::Connect(QString Address, int Port) { if (!QSslSocket::supportsSsl()) { qDebug() << "No SSL support!"; return false; } QHostAddress HostAddress; HostAddress.setAddress(Address); Socket = new QSslSocket(); connect(Socket, SIGNAL(sslErrors(QList<QSslError>)), this, SLOT(SslErrorsSlot(QList<QSslError>))); Socket->connectToHostEncrypted(Address, Port); if(!Socket->waitForEncrypted()) { delete Socket; return false; } connect(Socket, SIGNAL(readyRead()), this, SLOT(ReadSlot())); connect(Socket, SIGNAL(disconnected()), this, SLOT(DisconnectedSlot())); Connected = true; return true; }
When there is an incoming connection, SocketDescriptor of SslServer is set and SslServer::Start() is called:
void SslServer::Start( void) { if(Started) { return; } Started = true; Socket.setProtocol(QSsl::SslV3); QByteArray key; QByteArray cert; QFile fileKey("C:/SOURCE/Project/Qt/server.key"); if(fileKey.open(QIODevice ::ReadOnly)) { key = fileKey.readAll(); fileKey.close(); } else { qDebug() << fileKey.errorString(); } QFile fileCert("C:/SOURCE/Project/Qt/server.csr"); if(fileCert.open(QIODevice ::ReadOnly)) { cert = fileCert.readAll(); fileCert.close(); } else { qDebug() << fileCert.errorString(); } qDebug() << key + "\n" + cert; QSslKey sslKey(key, QSsl::Rsa); QSslCertificate sslCert(cert); Socket.setPrivateKey(sslKey); Socket.setLocalCertificate(sslCert); if (!Socket.setSocketDescriptor(SocketDescriptor)) { return; } Socket.startServerEncryption(); if(!Socket.waitForEncrypted()) { return; } connect(&Socket, SIGNAL(readyRead()), this, SLOT(ReadSlot())); connect(&Socket, SIGNAL(disconnected()), this, SLOT(DisconnectedSlot())); }
When making connection, server accepts connection (Socket.waitForEncrypted() returns true), but client doesn't connect (Socket->waitForEncrypted() returns false). When I catch SslErrors on client, I get:
- QSslError::HostNameMismatch
- QSslError::NoError
What does it mean and how to fix it?
-
I have resolved it, client missed CA certificate so:
@Socket->addCaCertificates("C:/SOURCE/Project/Qt/server.csr");@
added to client fixed my problem.