Search code examples
c++qtsslopensslssl-certificate

Peer certificate of Client in QSslServer is always Null in Qt C++


I have a Simple SSL Client/Server program, Retrieving the server certificate on the client side works but retrieving the client certificate on the server side returns null,

Server

#include <QCoreApplication>
#include <QtNetwork>
#include <QSslSocket>
#include <QSslKey>
#include <QSslCertificate>
#include <iostream>
#include <QFile>

int main(int argc, char **argv) {
    QCoreApplication app(argc, argv);

    // please update your own certificate and key files
    QFile key("C:/Users/dharu/Documents/server/key.pem"), cert("C:\\Users\\dharu\\Documents\\server\\cert.pem");

    key.open(QIODevice::ReadOnly);
    cert.open(QIODevice::ReadOnly);

    // Load server's SSL certificate and private key
    QSslKey privateKey(key.readAll(), QSsl::Rsa);
    QSslCertificate serverCert(cert.readAll());

    // Set up SSL configuration
    QSslConfiguration sslConfig;
    sslConfig.setPrivateKey(privateKey);
    sslConfig.setLocalCertificate(serverCert);

    // Set up the server
    QSslServer server;

    server.setSslConfiguration(sslConfig);
    server.listen(QHostAddress::Any, 5000);

    QObject::connect(&server, &QSslServer::startedEncryptionHandshake, [&](auto sock) {
        qDebug() << "Client connected";
        if (sock->peerCertificate().isNull()) {
            qDebug() << "Cannot retrieve Client Certificate";
        } else{
            qDebug()<<"Client Certificate is Obtained !";
        }
    });

    std::cout<<"Started server at 5000!"<<std::endl;


    return app.exec();
}

Output

Started server at 5000!
Client connected
Cannot retrieve Client Certificate

Client

#include <QCoreApplication>
#include <QtNetwork>
#include <QSslSocket>
#include <QSslKey>
#include <QSslCertificate>
#include <iostream>

int main(int argc, char **argv) {
    QCoreApplication app(argc, argv);

    // please update your own certificate and key files
    QFile key("C:/Users/dharu/Documents/server/key.pem"), cert("C:\\Users\\dharu\\Documents\\server\\cert.pem");

    key.open(QIODevice::ReadOnly);
    cert.open(QIODevice::ReadOnly);

    // Load server's SSL certificate and private key
    QSslKey privateKey(key.readAll(), QSsl::Rsa);
    QSslCertificate clientCert(cert.readAll());

    // Set up SSL configuration
    QSslConfiguration sslConfig;
    sslConfig.setPrivateKey(privateKey);
    sslConfig.setLocalCertificate(clientCert);

    // Set up the client
    QSslSocket socket;
     std::cout<<"setting Configuration .... "<<std::endl;
    socket.setSslConfiguration(sslConfig);

    socket.setPeerVerifyMode(QSslSocket::VerifyNone);
    std::cout<<"Connecting..."<<std::endl;
    socket.connectToHostEncrypted("127.0.0.1", 5000);

    QObject::connect(&socket, &QSslSocket::encrypted, [&](){
        qDebug() <<"Connected to server securely."<< socket.isEncrypted();
        qDebug() << "Connected to server securely.";

        if(socket.peerCertificate().isNull())
            qDebug( )<<"Server Certificate is null";

        else
            qDebug( )<<"Server Certificate is Obtained";


        QByteArray requestData = socket.readAll();
        qDebug() << "Received from server:" << requestData;
    });

    return app.exec();
}

Output

setting Configuration .... 
Connecting...
Connected to server securely. true
Connected to server securely.
Server Certificate is Obtained
Received from server: ""

how to fix it, Thanks in advance!

Edit:

I also tried to set the peer verify mode to verifyPeer in SSL configuration before starting listening the server no improvement :(


Solution

  • Seems like you're trying to retrive in onStartedencryption , Try to retrieve the certificate on pendingConnectionAvailable signal