basysKom Application Development Services

Qt WebEngine Custom Server Certificates
Essential Summary
In this blog post, we’re having a look at how we added support for custom server certificates to Qt WebEngine. This way an application can talk to a server using a self-signed TLS certificate without adding it to the system-wide certificate store.
One of our clients is building an application with a web-based front-end. In order to provide a clean, controlled environment where no browser extensions or user settings interfere, it is viewed in a dedicated browser built with Qt WebEngine.
The corresponding web server uses a self-signed TLS certificate. That’s fair for the environment where the application is deployed in. However, this also means that the certificate and its issuing CA must be added to the system’s trust store. Adding a new Root CA rightfully needs administrative privileges, but is also not really what we want: the certificate is only relevant for our application and we want it to run without such pre-configuration.

Since Qt 5.13, Qt WebEngine has had an in-memory client certificate store where you can add additional certificates without affecting the system’s certificate store. However, there has been no API to add server certificates. Luckily, Chromium 122, which coincidentally is the base for Qt 6.8 LTS, refactored certificate handling: the creation parameters for its “cert verifier” now accept a list of initial_additional_certificates that are considered irrespective of the platform’s trust store. Therefore, we intended to add a new API to QWebEngineProfile so an application can provide a QList<QSslCertificate> of additional certificates.

Unfortunately, since this is only designed to be used during the creation of the cert verifier, our new QWebEngineProfile::setAdditionalTrustedCertificates method would take effect only once, before the website is loaded for the first time and subsequent calls effectively did nothing. That’s not a very predictable API design. Luckily again, Qt 6.9 introduced the QWebEngineProfileBuilder specifically intended for this kind of “write-once” API.

We moved the method there, added some unit tests, and the just released Qt 6.10 now supports setting additional trusted server certificates: QWebEngineProfileBuilder::setAdditionalTrustedCertificates.

auto rootCa = QSslCertificate::fromPath(u"...pem"_s); // QSslCertificate::fromPath also new in Qt 6.10.

QWebEngineProfileBuilder builder;
builder.setAdditionalTrustedCertificates({rootCa});

m_profile.reset(builder.createProfile(profileName)); 

Amusingly, when the changes were merged, some security monitoring system (through Qt’s GitHub mirror) sent an email advising us that we might have leaked a private key on a git repository. Yes, thanks for the heads-up but that key is just used by our unit test

Picture of Kai Uwe Broulik

Kai Uwe Broulik

Kai Uwe Broulik is Software Architect at basysKom where he designs embedded HMI applications based on Qt with C++ and QML. He also trains customers on how to use Qt efficiently. With his more than ten years of experience in Qt he has successfully deployed Qt applications to a variety of platforms, such as mobile phones, desktop environments, as well as automotive and other embedded devices.

Leave a Reply

Your email address will not be published. Required fields are marked *

More Blogarticles

basysKom Newsletter

We collect only the data you enter in this form (no IP address or information that can be derived from it). The collected data is only used in order to send you our regular newsletters, from which you can unsubscribe at any point using the link at the bottom of each newsletter. We will retain this information until you ask us to delete it permanently. For more information about our privacy policy, read Privacy Policy