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 ACCEPT Received Record Header: Version = TLS 1.2 (0x303) Content Type = Handshake (22) Length = 312 ClientHello, Length=308 client_version=0x303 (TLS 1.2) <snip> Sent Record Header: 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. Matt