Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Minimal working example of QWebEngine with client certificates?



  • I am trying to get client certificates working with the Qt web engine (version 5.15), but I can't seem to get it done!

    I have a local server set up to use SSL, to expect client certificates and check them against a locally created root CA certificate. The client on the other hand, has a client certificate, signed by this local root CA.

    This is as far as I can whittle it down ... which might be too far, causing the problems!

    #include <QApplication>
    #include <QtWebEngine>
    #include <QWebEngineProfile>
    #include <QWebEngineView>
    
    class MyWebPage : public QWebEnginePage
    {
    public:
        MyWebPage(QObject * Parent) :
            QWebEnginePage{Parent}
        {
            QObject::connect(this, &QWebEnginePage::selectClientCertificate, this, &MyWebPage::SelectClientCertificate);
        }
    protected:
        auto certificateError(QWebEngineCertificateError const & CertificateError) -> bool override
        {
            return true;
        }
        
        auto SelectClientCertificate(QWebEngineClientCertificateSelection ClientCertificateSelection) -> void
        {
            ClientCertificateSelection.select(ClientCertificateSelection.certificates().front());
        }
    };
    
    auto main(int argc, char *argv[]) -> int
    {
        QtWebEngine::initialize();
        
        auto Application = QApplication{argc, argv};
        auto WebView = QWebEngineView{};
        
        WebView.resize(1024, 750);
        WebView.show();
        
        auto ClientCertificateFile = QFile{"client.pem"};
        ClientCertificateFile.open(QIODevice::ReadOnly);
        auto ClientCertificate = QSslCertificate{&ClientCertificateFile};
        ClientCertificateFile.close();
        
        auto PrivateKeyFile = QFile{"client.key"};
        PrivateKeyFile.open(QIODevice::ReadOnly);
        auto PrivateKey = QSslKey{&PrivateKeyFile, QSsl::Rsa, QSsl::Pem, QSsl::PrivateKey};
        PrivateKeyFile.close();
        
        auto WebPage = MyWebPage{&WebView};
        
        WebPage.profile()->clientCertificateStore()->add(ClientCertificate, PrivateKey);
        WebPage.setUrl(QUrl{"https://localhost/"});
        WebView.setPage(&WebPage);
    
        return Application.exec();
    }
    

    What I get is an error message in the browser window with "ERR_SSL_CLIENT_AUTH_NO_COMMON_ALGORITHMS" - so apparently browser and server don't know how to talk to each other.

    I've tried curl and it works fine with either

    curl --tlsv1.2 --tls-max 1.2 --insecure https://localhost/ --cert client.certificate.pem --key client.private_key.key

    or

    curl --tlsv1.3 --tls-max 1.3 --insecure https://localhost/ --cert client.certificate.pem --key client.private_key.key

    I've tried deactivating client certificates on the server side and it works fine.

    Are there any problems with my example? Did I miss some initialization steps or something?

    Maybe my example WOULD be working - if only the client and server knew how to talk to each other, so that, consequently, the error really is in the cipher suites?! Is there any way I can check the exchanged and possible algorithms? Ultimately, I find that very unlikely, as we're talking about a Chrome backend on the client side talking to an Apache server, both of which are hugely popular ...

    Any hints?

    Thank you for any help you can offer and best regards!


Log in to reply