[openssl-users] Does openssl server always choose highest TLS version offered?

Matt Caswell matt at openssl.org
Fri Nov 6 23:58:44 UTC 2015

On 06/11/15 21:32, Viktor Dukhovni wrote:
> On Fri, Nov 06, 2015 at 08:59:58PM +0000, Nounou Dadoun wrote:
>> Quick question, modifying context options on an openssl server (disabling
>> SSLv2 and SSLv3, enabling TLSv1 (for compatibility for now), TLSv1.1 and
>> TLSv1.2) and I had a question about which version is chosen in practice
>> in a TLS connection.
> On the server side, if at all possible, the selected protocol will
> be the highest one not disabled.

On the server side the selected protocol will *always* be the highest
one not disabled.

>> I've read that in general the client proposes the highest version it
>> supports and the server chooses a compatible version or rejects if there
>> isn't one.  
> The client proposes a range from lowest to highest.

OpenSSL only considers the version provided by the client in the
ClientHello itself. The server will select the highest protocol version
that it supports and is not disabled. The selected version could be
lower than the one set by the client in the record layer, i.e. from
OpenSSL's point of view the client provides an upper bound only not a range.

Consider this (OpenSSL version 1.0.2 config'd with enable-ssl-trace):

$ openssl s_server -no_tls1_2 -trace
Using default temp DH parameters
Received Record
  Version = TLS 1.2 (0x303)
  Content Type = Handshake (22)
  Length = 312
    ClientHello, Length=308
      client_version=0x303 (TLS 1.2)

Sent Record
  Version = TLS 1.1 (0x302)
  Content Type = Handshake (22)
  Length = 66
    ServerHello, Length=62
      server_version=0x302 (TLS 1.1)

In the above I used a hacked OpenSSL client to advertise TLSv1.2 in the
ClientHello *and* to use TLSv1.2 in the record layer. OpenSSL server has
had TLSv1.2 disabled so it selected TLSv1.1.

>> Rfc5246 basically says that the server will choose the highest
>> version but I wanted to confirm that that's what openssl does (just to be
>> certain).
> OpenSSL may be unable to choose the highest version if none of the
> enabled ciphersuites are compatible with that version.  That should
> be rare, so in practice the server will choose the highest version
> proposed by the client and supported by the server.

OpenSSL selects the version it is going to use regardless of the
available ciphersuites. Only after selecting its version will the server
select the ciphersuite to use. If there aren't any compatible with the
selected version then it will fail with a "no shared cipher" error.

For example consider the following:
$ openssl version
OpenSSL 1.0.2e-dev xx XXX xxxx

$ openssl s_server -cipher DES-CBC-MD5

$ openssl s_client -cipher DES-CBC-MD5

The above fails with a "no shared cipher" error even though both client
and server do have a shared cipher. The reason is that both client and
server support TLSv1.2 so that is the version that is selected. Only
then does the server try to select a ciphersuite. At that point it will
disregard DES-CBC-MD5 because that is an SSLv2 ciphersuite that is
incompatible with TLSv1.2. It now has no ciphersuites left to use and fails.

In practice this doesn't ever happen.

>> e.g.  if the client proposes TLSv1.2 and the server supports TLSv1.2, will
>> the server *ever* select TLSv1.1? thanks.
> It could, if none of the shared ciphersuites were compatible with
> TLS 1.2.  However, TLS 1.2 essentially supports a superset of the
> ciphersuites of TLS 1.0 and TLS 1.1 so this condition is unlikely.

No. It will always select TLSv1.2. However, with the exception of the
SSLv2 ciphersuites, *all* ciphersuites are upwardly compatible.

> The exception is EXPORT ciphersuites which were removed from TLS
> 1.2, but until quite recently was still willing to negotiate them
> even with TLS 1.2.  So if a client offers some EXPORT ciphers and
> the server is configured to use only EXPORT ciphers, I'm not sure
> whether these versions of OpenSSL will abort the handshake, or will
> choose a lower protocol version.
All released versions of OpenSSL will still negotiate EXPORT
ciphersuites in TLSv1.2 if it has been configured to enable those
ciphersuites. All recent versions of OpenSSL have no EXPORT ciphersuites
in the DEFAULT cipher string so you would have to explicitly enable them
for this to occur. This is quite a recent change though.


More information about the openssl-users mailing list