[Development] Qt SSL Discussions at QtDevDays 2011

Richard Moore rich at kde.org
Sun Oct 30 16:18:38 CET 2011

These notes combine the results of the networking discussion at the
contributor meeting and also subsequent discussions that took place in the bar
(of course).

Issues with the current API

1) Currently ssl errors, and proxy authentication require a nested event loop
and stall the entire QNAM that triggers the request.

This issue causes problems with (for example) an authentication dialog in one
tab of a browser preventing loading of pages others.

2) There is currently no opportunity to perform additional validation of the
certificate chain beyond that performed during the initial handshake,
but /before/
any user data is transmitted.

This is an issue if you want to perform additional validation steps, examples of
these are notifications when a certificate has changed from the one
previously used
by a site (cached earlier) and implementing certificate pinning (such
as that implemented
by chrome) which allows you to embed information in the client about
which CA (or CAs) to
expect for particular sites. Another check that can be performed at
this point is
OCSP, which is needed for checking for revoked certificates.

3) It is currently easy for a developer to ignore SSL errors, often without even
determining which errors are occurring first.

Proposed Fixes for these Problems

*) Introduce an additional state to the process of connecting to an SSL server.

The idea is that client applications will be able to specify that once
the SSL handshake is completed that the QSslSocket should be paused.
While the socket is paused, no data will be transmitted to the server.
During this AwaitingConfirmation state, any additional checks can be
performed. In order to continue the connection, then they must
explicitly tell the socket to continue, they should also have the option
to abort the connection at this point with a guarantee that none of the
user's data will be transmitted to the server.

This single change allows use to resolve both the first and second
issue. The model for
connection would be something like this:

<handshake finishes, connection is now paused>
emit sslErrors()
emit handshakeComplete() (aka encrypted())

User calls either abort() or confirmConnection() when they have
completed the process.

*** How do we handle proxy auth?
*** Changes to ssl error handling to stop people blindly ignoring the errors.

- always pause on errors
- pause on no errors if previously requested (not default)
- user model is to accept a cert for a given domain, not to approve or
disaprove individual errors
- approving some but not all errors is essentially pointless
- still allow 'predefinition' of expected errors (eg. a particular
cert is expected by the app)
- ignoreSslErrors just calls continue (and is deprecated)

- In order to report these errors we need a way to add to QSslErrors
- Public method to add an error to the errorlist
- QSslErrors needs to gain a custom error value
- Add ocsp specific errors to qsslerror
- Add accessor for QSslOcspReply to QNetworkReply
- QNAM accessor to specify strict (require Good), relaxed (accept
unknown, no reply or no AIA ocsp), or None (don't check)

- Kill isValid()
  - kill completely
  - testConstraint( QFlags<ThingThatGoesWrong> constraint );
  - hasValidDate()
  - isBlacklisted()
  - enum ConstraintResult { Passed, Failed, Unknown }
  - ConstraintResult checkConstraint( QSslError )

- Provide a way to find which was the matching root certificate
- Can/do we provide access to the full chain?

More information about the Development mailing list