Qt5 client certificate authentication



  • I have Qt 5.4.0 on Windows 8.1 and Qt 5.4.2 on ArchLinux latest and get exactly the same result.

    I have web-site which requires client SSL certificate. Server seems to be configured properly since execution of

    openssl s_client -connect myserver:443 -cert client.crt -key client.key
    

    prints

    Verify return code: 0 (ok)
    

    Also,

     curl --cert client.pem https://myserver/
    

    works just fine.

    Server certificate is valid, browsers accept it, etc. Client certificate is self signed. Just in case, server is nginx and here is relevant config fragment

    listen                         *:443 ssl;
    
    server_name                    myserver;
    
    ssl                            on;
    ssl_certificate                /etc/nginx/ssl/myserver.crt;
    ssl_certificate_key            /etc/nginx/ssl/myserver.key;
    ssl_dhparam                    /etc/nginx/ssl/myserver.dh;
    ssl_protocols                  TLSv1.1 TLSv1.2;
    ssl_ciphers                    "ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:DES-CBC3-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4";
    ssl_prefer_server_ciphers      on;
    ssl_client_certificate         /etc/nginx/ssl/ca.crt;
    ssl_verify_client              on;
    

    But the following simplest Qt5 application

    #include <qcoreapplication.h>
    #include <qfile.h>
    #include <qnetworkaccessmanager.h>
    #include <qnetworkconfiguration.h>
    #include <qnetworkproxy.h>
    #include <qnetworkreply.h>
    #include <qnetworkrequest.h>
    #include <qsslcertificate.h>
    #include <qsslconfiguration.h>
    #include <qsslkey.h>
    
    int main(int argc, char *argv[])
    {
        QCoreApplication a(argc, argv);
    
        QNetworkProxyFactory::setUseSystemConfiguration(true);
    
        QSslConfiguration sslConfiguration;
    
        QFile privateKeyFile("client.key");
        privateKeyFile.open(QIODevice::ReadOnly);
    
        QFile certificateFile("client.crt");
        certificateFile.open(QIODevice::ReadOnly);
    
        QSslKey privateKey(&privateKeyFile, QSsl::Opaque);
        QSslCertificate certificate(&certificateFile);
    
        qWarning() << QSslSocket::supportsSsl();
        qWarning() << certificate.serialNumber();
        qWarning() << certificate.subjectInfo(QSslCertificate::CommonName);
        qWarning() << certificate.expiryDate();
    
        sslConfiguration.setPrivateKey(privateKey);
        sslConfiguration.setLocalCertificate(certificate);
    
        QNetworkRequest networkRequest(QUrl("https://server/"));
    
        networkRequest.setSslConfiguration(sslConfiguration);
    
        QNetworkAccessManager networkAccessManager;
    
        QNetworkReply* networkReply = networkAccessManager.get(networkRequest);
    
        QEventLoop loop;
    
        QObject::connect(&networkAccessManager, &QNetworkAccessManager::finished, &loop, &QEventLoop::quit);
    
        loop.exec();
    
        qWarning() << networkReply->error();
        qWarning() << networkReply->errorString();
    
        delete networkReply;
    
        return a.exec();
    }
    

    fails with the following console output on Windows

    QSslSocket: cannot resolve TLSv1_1_client_method
    QSslSocket: cannot resolve TLSv1_2_client_method
    QSslSocket: cannot resolve TLSv1_1_server_method
    QSslSocket: cannot resolve TLSv1_2_server_method
    QSslSocket: cannot resolve SSL_select_next_proto
    QSslSocket: cannot resolve SSL_CTX_set_next_proto_select_cb
    QSslSocket: cannot resolve SSL_get0_next_proto_negotiated
    true
    "01"
    ("AA-00-00-00")
    QDateTime("2035-06-21 21:41:13.000 UTC Qt::UTC")
    99
    "Unable to init SSL Context: "
    

    and the following console output on Linux

    true
    "01"
    ("AA-00-00-00")
    QDateTime("2035-06-21 21:41:13.000 UTC Qt::UTC")
    99
    "Unable to init SSL Context: "
    

    If I remove "networkRequest.setSslConfiguration(sslConfiguration);" I just get 400 error from server stating I need to send client certificate.

    Adding "sslConfiguration.setPeerVerifyMode(QSslSocket::VerifyNone);" changes nothing.

    I will be happy to get any advice what can be cause of Qt5 code failure.


  • Lifetime Qt Champion

    Hi and welcome to devnet,

    Just to rule out the obvious: do you have client.key and client.crt in the same folder as your application ?



  • Yes,

    I'm printing subject and serial to console to make sure valid and proper certificate was used.


  • Lifetime Qt Champion

    You should also check the sslErrors signal


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.