Thursday, September 11, 2014

OpenSSL cipher cargo culting

From the new version of my dovecot conf that dpkg installed in the trusty upgrade:

ssl_cipher_list = ALL:!LOW:!SSLv2:ALL:!aNULL:!ADH:!eNULL:!EXP:RC4+RSA:+HIGH:+MEDIUM

oh God my eyes, why so much bleeding!?

ALL is listed twice, after some bans, which prevent the second instance from having any effect.

ADH is a subset of aNULL, therefore banning aNULL has already banned ADH and the latter is a no-op.

The +HIGH:+MEDIUM bit is tricky because it looks like a no-op (it can’t add anything over ALL or any of the banned modes), but actually specifies that the server prefers HIGH over MEDIUM.  The real effect of this in the current library version is to lower the priority of SEED ciphers, down below Camellia and some of the AES modes.

Checking openssl ciphers HIGH on the command-line indicates this is a library that thinks 3DES is “high security.”  (Although taking it out is technically non-compliant, as TLS up to and including v1.1 mandates support for it.)  And this configuration will add anything it considers MEDIUM in?  That includes not only RC4-SHA, but SEED-SHA and RC4-MD5, both of which are presumably unintentional.

It even turns out that ‘SSLv2’ is not recognized by this version of OpenSSL.  openssl ciphers SSLv2 is an error, and there is no difference between ALL and ALL:!SSLv2.  It’s not even special-cased, since ALL:!SPAM is also not an error.

OpenSSL considers DSS to be perfectly fine as well, even though using it with SHA-1 (which all the MEDIUM DSS ciphers are) means only 1024 bits of strength.

RC4-MD5 is also included in RC4+RSA, by the way.

Finally, ALL and HIGH include some key-exchange mechanisms that are basically irrelevant to the regular Internet, like SRP, PSK, and non-ephemeral ECDH.  It’s just a waste of bandwidth to include them if the client is never going to choose them.

All that said, a reasonable default cipher list (for wide compatibility and spec compliance) would aim to start with the best parts, then strip away the ones that aren’t so “best” anymore, unless mandated.  Something like:

ssl_cipher_list = RC4-SHA:+HIGH:!DSS+SHA:!MD5:!aNULL:!eNULL

Technically the !eNULL is unnecessary, but by now, I refuse to trust that it is actually “disabled unless explicitly enabled.”  Because OpenSSL.

Bonus facts:
  1. I cannot find evidence that AES was ever added to Windows XP SChannel, though it’s part of Windows Server 2003 and up.
  2. Windows Vista SChannel supports only up to TLS v1.0.  Windows 7 added v1.1 and v1.2.
  3. In terms of web browsers, the above points are relevant only to Internet Explorer, as others include their own cross-platform SSL library instead of using SChannel.
  4. Windows Server 2003 had AES added in KB 948963 because at one point, HIGH did not include any ciphers supported by SChannel at the time.

No comments: