Improving Qt's SSL Support
Qt has pretty good support for SSL that is sufficient for a lot of common uses, but the SSL support is missing a number of features that exist in applications such as Firefox, Internet Explorer or Opera. In addition, whilst Qt uses OpenSSL for the underlying implementation of SSL, it only provides an API for using a small subset of the available facilities.
I've been doing some work to enhance the SSL support in Qt, and have been asked to put together this page which is a cross between a TODO list, a set of links to existing solutions, and a pie-in-the-sky wishlist.
Areas for Improvement
There are a number of missing facilities in Qt's SSL support right now; here's a rough list cross-referenced with the QT-BUG tracking number:
- Improved certificate handling
- No support for creating certificates, QTBUG-20279 See gitorious.org/qt-certificate-addon for an addon that offers this.
- No support of EV (extended validation) certificates, QTBUG-12815
- Improved TLS handshake support
- Provide a generic mechanism for setting and retrieving TLS extensions in the client hello and server hello provided during the handshake process
- Add the ability to retrieve and set the supplemental data handshake message
- Add the ability to propagate errors encountered during the handshake to applications
- OCSP and related issues
- No support for OCSP (online certificate status protocol), QTBUG-12812
- No support for TLS certificate status extension AKA OCSP stapling (asking the server to check OCSP himself and send us the response (sic)), QTBUG-17158
- General API limitations
- No DNS pinning (though there is a DNS cache minimising this issue), QTBUG-12814
- No API for the SSL context, QTBUG-14983
- No support for TLS Renegotiation Information (securing TLS renegotiation), QTBUG-18305
- Additional protocols
- No support for HSTS (HTTP strict transport security, means the server tells a client to connect to the https version directly rather than to the http version), QTBUG-18030
- Internal cleanups
- typedef for STACK vs STACK_
- Specify supported openssl versions
- Consider changing the way QSslConfiguration works as the deep copy stuff is unexpected
- Centralise the code for setting up a CA store (used for both connecting and verify)
It should be noted that most of these issues only affect a tiny minority of possible uses. That said, wouldn't it be nice if we had support for them in Qt with a nice API?
Areas for performance improvement
- support the "abbreviated handshake" (as used by Google) to reduce round trip time, QTBUG-15452
- do not use a tcp socket internally to send ssl data, QTBUG-14160
- Once the extra layer (above) is removed check if ensuring we always disable the Nagle algorithm helps our performance.
Work Underway
This would be a depressing page if it wasn't for the fact that these issues are being addressed. So, let's look at the areas where progress is already being made:
(OCSP) Online Certificate Status Protocol Support
I've implemented the basic facilities required for OCSP support in Qt, specifically accessors for the AIA field of the certificate, and classes to generate and validate OCSP requests/responses. Still remaining is the integration of this code into the QNetworkAccessManager and QSslSocket classes, and a cache of the results. As of Nov 2011 after a hiatus while I worked on some other areas, I have got this building against Qt 5.
The code is currently in my personal clone at https://qt.gitorious.org/~rich/qt/richs-qtbase/commits/ocsp-support
Notification when the Certificate for a Site Changes
I wrote a proof of concept for this that showed up some API limitations that prevent a production quality implementation. This looks like something that can be addressed in a future release without major issues. I've written up the details of the implementation and the its limitations at http://www.kdedevelopers.org/node/4434
Support for TLS extensions and supplemental data
Work is being tracked in the issue tracker and a Wiki is being used to work through implementation and API design issues: Improving_TLS_handshake_support
Solved Issues
This section is for areas that have been put to bed:
- enable SSL session sharing, QTBUG-14983 [resolved]
- limit SSL message size to fit into one TCP packet, QTBUG-16716 / QTBUG-28764 [invalid]
- Qt uses shell globs for wildcards rather than the newer more restrictive policies. QTBUG-4455 [resolved]
- No support for SNI (server name indication) extension, QTBUG-1352 [resolved] This has been implemented by Daniel Black and David Faure and is now merged into Qt master.
- [performance] on Linux, load root certs on demand, and not all on startup (if supported by the system via openssl's c_rehash script), QTBUG-14016 [resolved]
- No simple API for only enabling SSL3 and TLS1 while disabling SSL2, QTBUG-12338 and QTBUG-15220 [resolved]
- The way the subject and issuer info is extracted from the x509 cert is buggy and slow. This function should be replaced with something using the openssl functions to get the elements of the subject using the tag name directly. This was addressed by the following merge MR 922. There are some remaining API issues, that are covered above.
- QSslCertificate does not provide an API to dump a certificate as text. Now merged in master, see https://qt.gitorious.org/qt/qtbase/merge_requests/2
- API provides no access to duplicate fields in certificate issuer and subject. [ Qt5 MR 5 https://qt.gitorious.org/qt/qtbase/merge_requests/5 ] [resolved]
- No accessor for unusual (but legal) fields in certificate issuer and subject. See MR https://qt.gitorious.org/qt/qtbase/merge_requests/18 [resolved]
- No way to check that a certificate chain is valid unless you're connecting to a site using it. [ see https://qt.gitorious.org/qt/qtbase/merge_requests/11 ] [resolved]
- API doesn't allow to use opaque keys as QSslKey (needed by PKCS#11 and HSM) [ Qt5 MR 48 https://qt.gitorious.org/qt/qtbase/merge_requests/48 ]
- No API for enabling or disabling compression which is required to connect to some buggy servers (eg. the on KDE bug 275524 ) there are probably other servers as broken as this one around. Only newish openssl's support this which means that we'll probably hit an increasing number of such problems. See [ Qt5 MR 68 MR https://qt.gitorious.org/qt/qtbase/merge_requests/68 ] [resolved] [backported to 4.8]
- QSslCertificate does not provide access to the extensions a certificate contains. Resolved through gerrit change I5c5d9513: SSL certificates: add functionality to read extensions
- Consider removing symbian support code [removed]
- No support for intermediate certificates when acting as a server socket, QTBUG-13281 [resolved]
- SSL Context API There appears to be active work from Nokia on this issue, as can be seen from the task tracker in QTBUG-14983. This will also allow sharing of the SSL context between requests removing the need for round trips and SSL negotiation each time. [resolved] Note that the API is internal.
OpenSSL on OS X
OS X has the oldest versions of OpenSSL in use on any platform, so it's setting the lower limit on what we can rely on:
OS X version | OpenSSL version | OpenSSL build date |
---|---|---|
10.10.3 | 0.9.8zd | 8 Jan 2015 |
10.9.2 | 0.9.8y | 5 Feb 2013 |
10.8.4 | 0.9.8x | 10 May 2012 |
10.8.3 | 0.9.8r | 8 Feb 2011 |
10.8.2 | 0.9.8r | 8 Feb 2011 |
10.7.4 | 0.9.8r | 8 Feb 2011 |
10.6.8 v1.1 | 0.9.8x | 10 May 2012 |
10.6.0 | 0.9.8k | 25 Mar 2009 |
10.5.8 | 0.9.7l | 28 Sep 2006 |
To Do Lists
Rich Moore:
- Certificate change notifier
- EV certificates
- OCSP
Peter: