Openssl: SSL_set_SSL_CTX is a bad idea

Created on 27 Apr 2018  路  4Comments  路  Source: openssl/openssl

The whole concept behind SSL_set_SSL_CTX() is just a bad idea. I think we should deprecate it and replace it with an alternative API.

In #1652 @vdukhovni said:

As soon as possible it would be good to have a sensible replacement for this in support for alternative chains for SNI. It should not be necessary to have a whole new context just to vend a different certificate chain. A much lighter-weight mechanism should I think be available.

If users want to do more, and also customize groups,..., perhaps use a separate session cache based on SNI, then a per-SNI context comes into play, but if so, it should likely be more fully-featured. This might mean delaying initialization of settings in the SSL handle until they are needed, and then picking them up from the extant context (if not explicitly set in the SSL handle itself).

And @t-j-h said:

Changing the SSL_CTX after a certain point shouldn't be possible - in fact the whole concept of altering your "factory" really is problematic - and this API was added explicitly to "support extensions" in commit ed3883d - there should be a different way to do this - and I would be in favour of removing this API at the earliest opportunity.

This can't be done in the 1.1.1 timeframe, so setting this with a post-1.1.1 milestone.

documentation feature

All 4 comments

From the perspective of a library user, I have two comments about SSL_set_SSL_CTX:

First, I am using this function in the SWI-Prolog OpenSSL bindings, to implement server-side SNI. In Prolog, SNI works via a user-extensible predicate that yields an SSL context depending on the hostname. For example, such a user-defined predicate may look as follows:

sni(C0, Hostname, C) :- ...

where C0 is the default SSL context, and the predicate uses the given Hostname to compute a new context C which is then dynamically plugged in via SSL_set_SSL_CTX to further negotiate the connection.

For the particular use case of Prolog-based OpenSSL bindings, I consider it essential that no destructive modifications be required to carry out all desired operations. Currently, this is the case! For example, to implement server-side SNI, I can currently create a new SSL context and plug it in via SSL_set_SSL_CTX, without having to modify any existing context. This property ensures thread-safety of the whole library, and I would greatly appreciate if this consideration could be taken into account when devising a new API. This issue is hence related to #2165.

Second, I agree that the way SSL_set_SSL_CTX currently works can yield counter-intuitive results and is thus not ideal. For example, to mention just one particular case I noticed: This API cannot be used to negotiate different minimal or maximal protocol versions depending on the hostname. This may be due to limitations of the protocol itself, or also due to incomplete exchange of context properties as mentioned in https://github.com/openssl/openssl/issues/1652#issuecomment-384742127.

Second, I agree that the way SSL_set_SSL_CTX currently works can yield counter-intuitive results and is thus not ideal. For example, to mention just one particular case I noticed: This API cannot be used to negotiate different minimal or maximal protocol versions depending on the hostname. This may be due to limitations of the protocol itself, or also due to incomplete exchange of context properties as mentioned in #1652 (comment).

I think this is more because up until recently, there was not an opportunity for user code (e.g., servername callback) to run before version negotiation had occurred. Starting with 1.1.1 there is a "client hello callback" that runs extremely early in the handshake processing, and is able to alter the supported versions based on the hostname.

I found myself using SSL_set_SSL_CTX today from the ALPN callback (to pick a different cert and various parameters based on selected ALPN).
The fact that it doesn't copy all parameters caused a bit of confusion.

Some time has passed, and we're still in the same boat. SSL_set_SSL_CTX remains undocumented (except in passing).
It is I think important (since it has not been replaced in 3.0.0 as yet, and likely insufficient time remains to do so) to at least partly document it.

  • Which context is used for session management, ticket callbacks, session modes, ...
  • Which context is used for min/max protocol version bounds and the option bits?
  • Which context is used for the candidate cipher lists, the supported curves, ...?
  • Of course the SNI context is used for selecting the server certificate...
    ...
    In other words which settings does the new context override, and which continue to be used from the initial context?
Was this page helpful?
0 / 5 - 0 ratings