New sort order for server choice of ciphersuites.
Back in 175b2678, we allowed servers to recognize clients who are
telling them the truth about their ciphersuites, and select the best
cipher from on that list. This implemented the server side of proposal
198.
In bugs 11492, 11498, and 11499, cypherpunks found a bunch of mistakes
and omissions and typos in the UNRESTRICTED_SERVER_CIPHER_LIST we had.
In #11513, I found a couple more.
Rather than try to hand-edit this list, I wrote a short python script
to generate our ciphersuite preferences from the openssl headers.
The new rules are:
* Require forward secrecy.
* Require RSA (since our servers only configure RSA keys)
* Require AES or 3DES. (This means, reject RC4, DES, SEED, CAMELLIA,
and NULL.)
* No export ciphersuites.
Then:
* Prefer AES to 3DES.
* If both suites have the same cipher, prefer ECDHE to DHE.
* If both suites have the same DHE group type, prefer GCM to CBC.
* If both suites have the same cipher mode, prefer SHA384 to SHA256
to SHA1.
* If both suites have the same digest, prefer AES256 to AES128.
2014-04-14 20:10:05 +02:00
|
|
|
#!/usr/bin/python
|
2015-01-02 20:27:39 +01:00
|
|
|
# Copyright 2014-2015, The Tor Project, Inc
|
New sort order for server choice of ciphersuites.
Back in 175b2678, we allowed servers to recognize clients who are
telling them the truth about their ciphersuites, and select the best
cipher from on that list. This implemented the server side of proposal
198.
In bugs 11492, 11498, and 11499, cypherpunks found a bunch of mistakes
and omissions and typos in the UNRESTRICTED_SERVER_CIPHER_LIST we had.
In #11513, I found a couple more.
Rather than try to hand-edit this list, I wrote a short python script
to generate our ciphersuite preferences from the openssl headers.
The new rules are:
* Require forward secrecy.
* Require RSA (since our servers only configure RSA keys)
* Require AES or 3DES. (This means, reject RC4, DES, SEED, CAMELLIA,
and NULL.)
* No export ciphersuites.
Then:
* Prefer AES to 3DES.
* If both suites have the same cipher, prefer ECDHE to DHE.
* If both suites have the same DHE group type, prefer GCM to CBC.
* If both suites have the same cipher mode, prefer SHA384 to SHA256
to SHA1.
* If both suites have the same digest, prefer AES256 to AES128.
2014-04-14 20:10:05 +02:00
|
|
|
# See LICENSE for licensing information
|
|
|
|
|
|
|
|
# This script parses openssl headers to find ciphersuite names, determines
|
|
|
|
# which ones we should be willing to use as a server, and sorts them according
|
|
|
|
# to preference rules.
|
|
|
|
#
|
|
|
|
# Run it on all the files in your openssl include directory.
|
|
|
|
|
|
|
|
import re
|
|
|
|
import sys
|
|
|
|
|
|
|
|
EPHEMERAL_INDICATORS = [ "_EDH_", "_DHE_", "_ECDHE_" ]
|
|
|
|
BAD_STUFF = [ "_DES_40_", "MD5", "_RC4_", "_DES_64_",
|
2017-01-24 21:29:26 +01:00
|
|
|
"_SEED_", "_CAMELLIA_", "_NULL",
|
|
|
|
"_CCM_8", "_DES_", ]
|
New sort order for server choice of ciphersuites.
Back in 175b2678, we allowed servers to recognize clients who are
telling them the truth about their ciphersuites, and select the best
cipher from on that list. This implemented the server side of proposal
198.
In bugs 11492, 11498, and 11499, cypherpunks found a bunch of mistakes
and omissions and typos in the UNRESTRICTED_SERVER_CIPHER_LIST we had.
In #11513, I found a couple more.
Rather than try to hand-edit this list, I wrote a short python script
to generate our ciphersuite preferences from the openssl headers.
The new rules are:
* Require forward secrecy.
* Require RSA (since our servers only configure RSA keys)
* Require AES or 3DES. (This means, reject RC4, DES, SEED, CAMELLIA,
and NULL.)
* No export ciphersuites.
Then:
* Prefer AES to 3DES.
* If both suites have the same cipher, prefer ECDHE to DHE.
* If both suites have the same DHE group type, prefer GCM to CBC.
* If both suites have the same cipher mode, prefer SHA384 to SHA256
to SHA1.
* If both suites have the same digest, prefer AES256 to AES128.
2014-04-14 20:10:05 +02:00
|
|
|
|
|
|
|
# these never get #ifdeffed.
|
|
|
|
MANDATORY = [
|
|
|
|
"TLS1_TXT_DHE_RSA_WITH_AES_256_SHA",
|
|
|
|
"TLS1_TXT_DHE_RSA_WITH_AES_128_SHA",
|
|
|
|
]
|
|
|
|
|
|
|
|
def find_ciphers(filename):
|
|
|
|
with open(filename) as f:
|
|
|
|
for line in f:
|
|
|
|
m = re.search(r'(?:SSL3|TLS1)_TXT_\w+', line)
|
|
|
|
if m:
|
|
|
|
yield m.group(0)
|
|
|
|
|
|
|
|
def usable_cipher(ciph):
|
|
|
|
ephemeral = False
|
|
|
|
for e in EPHEMERAL_INDICATORS:
|
|
|
|
if e in ciph:
|
|
|
|
ephemeral = True
|
|
|
|
if not ephemeral:
|
|
|
|
return False
|
|
|
|
|
|
|
|
if "_RSA_" not in ciph:
|
|
|
|
return False
|
|
|
|
|
|
|
|
for b in BAD_STUFF:
|
|
|
|
if b in ciph:
|
|
|
|
return False
|
|
|
|
return True
|
|
|
|
|
|
|
|
# All fields we sort on, in order of priority.
|
|
|
|
FIELDS = [ 'cipher', 'fwsec', 'mode', 'digest', 'bitlength' ]
|
|
|
|
# Map from sorted fields to recognized value in descending order of goodness
|
2017-01-24 21:29:26 +01:00
|
|
|
FIELD_VALS = { 'cipher' : [ 'AES', 'CHACHA20' ],
|
New sort order for server choice of ciphersuites.
Back in 175b2678, we allowed servers to recognize clients who are
telling them the truth about their ciphersuites, and select the best
cipher from on that list. This implemented the server side of proposal
198.
In bugs 11492, 11498, and 11499, cypherpunks found a bunch of mistakes
and omissions and typos in the UNRESTRICTED_SERVER_CIPHER_LIST we had.
In #11513, I found a couple more.
Rather than try to hand-edit this list, I wrote a short python script
to generate our ciphersuite preferences from the openssl headers.
The new rules are:
* Require forward secrecy.
* Require RSA (since our servers only configure RSA keys)
* Require AES or 3DES. (This means, reject RC4, DES, SEED, CAMELLIA,
and NULL.)
* No export ciphersuites.
Then:
* Prefer AES to 3DES.
* If both suites have the same cipher, prefer ECDHE to DHE.
* If both suites have the same DHE group type, prefer GCM to CBC.
* If both suites have the same cipher mode, prefer SHA384 to SHA256
to SHA1.
* If both suites have the same digest, prefer AES256 to AES128.
2014-04-14 20:10:05 +02:00
|
|
|
'fwsec' : [ 'ECDHE', 'DHE' ],
|
2017-01-24 21:29:26 +01:00
|
|
|
'mode' : [ 'POLY1305', 'GCM', 'CCM', 'CBC', ],
|
|
|
|
'digest' : [ 'n/a', 'SHA384', 'SHA256', 'SHA', ],
|
New sort order for server choice of ciphersuites.
Back in 175b2678, we allowed servers to recognize clients who are
telling them the truth about their ciphersuites, and select the best
cipher from on that list. This implemented the server side of proposal
198.
In bugs 11492, 11498, and 11499, cypherpunks found a bunch of mistakes
and omissions and typos in the UNRESTRICTED_SERVER_CIPHER_LIST we had.
In #11513, I found a couple more.
Rather than try to hand-edit this list, I wrote a short python script
to generate our ciphersuite preferences from the openssl headers.
The new rules are:
* Require forward secrecy.
* Require RSA (since our servers only configure RSA keys)
* Require AES or 3DES. (This means, reject RC4, DES, SEED, CAMELLIA,
and NULL.)
* No export ciphersuites.
Then:
* Prefer AES to 3DES.
* If both suites have the same cipher, prefer ECDHE to DHE.
* If both suites have the same DHE group type, prefer GCM to CBC.
* If both suites have the same cipher mode, prefer SHA384 to SHA256
to SHA1.
* If both suites have the same digest, prefer AES256 to AES128.
2014-04-14 20:10:05 +02:00
|
|
|
'bitlength' : [ '256', '128', '192' ],
|
|
|
|
}
|
|
|
|
|
|
|
|
class Ciphersuite(object):
|
|
|
|
def __init__(self, name, fwsec, cipher, bitlength, mode, digest):
|
2017-01-24 21:29:26 +01:00
|
|
|
if fwsec == 'EDH':
|
|
|
|
fwsec = 'DHE'
|
|
|
|
|
|
|
|
if mode in [ '_CBC3', '_CBC', '' ]:
|
|
|
|
mode = 'CBC'
|
|
|
|
elif mode == '_GCM':
|
|
|
|
mode = 'GCM'
|
|
|
|
|
New sort order for server choice of ciphersuites.
Back in 175b2678, we allowed servers to recognize clients who are
telling them the truth about their ciphersuites, and select the best
cipher from on that list. This implemented the server side of proposal
198.
In bugs 11492, 11498, and 11499, cypherpunks found a bunch of mistakes
and omissions and typos in the UNRESTRICTED_SERVER_CIPHER_LIST we had.
In #11513, I found a couple more.
Rather than try to hand-edit this list, I wrote a short python script
to generate our ciphersuite preferences from the openssl headers.
The new rules are:
* Require forward secrecy.
* Require RSA (since our servers only configure RSA keys)
* Require AES or 3DES. (This means, reject RC4, DES, SEED, CAMELLIA,
and NULL.)
* No export ciphersuites.
Then:
* Prefer AES to 3DES.
* If both suites have the same cipher, prefer ECDHE to DHE.
* If both suites have the same DHE group type, prefer GCM to CBC.
* If both suites have the same cipher mode, prefer SHA384 to SHA256
to SHA1.
* If both suites have the same digest, prefer AES256 to AES128.
2014-04-14 20:10:05 +02:00
|
|
|
self.name = name
|
|
|
|
self.fwsec = fwsec
|
|
|
|
self.cipher = cipher
|
|
|
|
self.bitlength = bitlength
|
|
|
|
self.mode = mode
|
|
|
|
self.digest = digest
|
|
|
|
|
|
|
|
for f in FIELDS:
|
|
|
|
assert(getattr(self, f) in FIELD_VALS[f])
|
|
|
|
|
|
|
|
def sort_key(self):
|
|
|
|
return tuple(FIELD_VALS[f].index(getattr(self,f)) for f in FIELDS)
|
|
|
|
|
|
|
|
|
|
|
|
def parse_cipher(ciph):
|
|
|
|
m = re.match('(?:TLS1|SSL3)_TXT_(EDH|DHE|ECDHE)_RSA(?:_WITH)?_(AES|DES)_(256|128|192)(|_CBC|_CBC3|_GCM)_(SHA|SHA256|SHA384)$', ciph)
|
|
|
|
|
2017-01-24 21:29:26 +01:00
|
|
|
if m:
|
|
|
|
fwsec, cipher, bits, mode, digest = m.groups()
|
|
|
|
return Ciphersuite(ciph, fwsec, cipher, bits, mode, digest)
|
|
|
|
|
|
|
|
m = re.match('(?:TLS1|SSL3)_TXT_(EDH|DHE|ECDHE)_RSA(?:_WITH)?_(AES|DES)_(256|128|192)_CCM', ciph)
|
|
|
|
if m:
|
|
|
|
fwsec, cipher, bits = m.groups()
|
|
|
|
return Ciphersuite(ciph, fwsec, cipher, bits, "CCM", "n/a")
|
New sort order for server choice of ciphersuites.
Back in 175b2678, we allowed servers to recognize clients who are
telling them the truth about their ciphersuites, and select the best
cipher from on that list. This implemented the server side of proposal
198.
In bugs 11492, 11498, and 11499, cypherpunks found a bunch of mistakes
and omissions and typos in the UNRESTRICTED_SERVER_CIPHER_LIST we had.
In #11513, I found a couple more.
Rather than try to hand-edit this list, I wrote a short python script
to generate our ciphersuite preferences from the openssl headers.
The new rules are:
* Require forward secrecy.
* Require RSA (since our servers only configure RSA keys)
* Require AES or 3DES. (This means, reject RC4, DES, SEED, CAMELLIA,
and NULL.)
* No export ciphersuites.
Then:
* Prefer AES to 3DES.
* If both suites have the same cipher, prefer ECDHE to DHE.
* If both suites have the same DHE group type, prefer GCM to CBC.
* If both suites have the same cipher mode, prefer SHA384 to SHA256
to SHA1.
* If both suites have the same digest, prefer AES256 to AES128.
2014-04-14 20:10:05 +02:00
|
|
|
|
2017-01-24 21:29:26 +01:00
|
|
|
m = re.match('(?:TLS1|SSL3)_TXT_(EDH|DHE|ECDHE)_RSA(?:_WITH)?_CHACHA20_POLY1305', ciph)
|
|
|
|
if m:
|
|
|
|
fwsec, = m.groups()
|
|
|
|
return Ciphersuite(ciph, fwsec, "CHACHA20", "256", "POLY1305", "n/a")
|
New sort order for server choice of ciphersuites.
Back in 175b2678, we allowed servers to recognize clients who are
telling them the truth about their ciphersuites, and select the best
cipher from on that list. This implemented the server side of proposal
198.
In bugs 11492, 11498, and 11499, cypherpunks found a bunch of mistakes
and omissions and typos in the UNRESTRICTED_SERVER_CIPHER_LIST we had.
In #11513, I found a couple more.
Rather than try to hand-edit this list, I wrote a short python script
to generate our ciphersuite preferences from the openssl headers.
The new rules are:
* Require forward secrecy.
* Require RSA (since our servers only configure RSA keys)
* Require AES or 3DES. (This means, reject RC4, DES, SEED, CAMELLIA,
and NULL.)
* No export ciphersuites.
Then:
* Prefer AES to 3DES.
* If both suites have the same cipher, prefer ECDHE to DHE.
* If both suites have the same DHE group type, prefer GCM to CBC.
* If both suites have the same cipher mode, prefer SHA384 to SHA256
to SHA1.
* If both suites have the same digest, prefer AES256 to AES128.
2014-04-14 20:10:05 +02:00
|
|
|
|
2017-01-24 21:29:26 +01:00
|
|
|
print "/* Couldn't parse %s ! */"%ciph
|
|
|
|
return None
|
New sort order for server choice of ciphersuites.
Back in 175b2678, we allowed servers to recognize clients who are
telling them the truth about their ciphersuites, and select the best
cipher from on that list. This implemented the server side of proposal
198.
In bugs 11492, 11498, and 11499, cypherpunks found a bunch of mistakes
and omissions and typos in the UNRESTRICTED_SERVER_CIPHER_LIST we had.
In #11513, I found a couple more.
Rather than try to hand-edit this list, I wrote a short python script
to generate our ciphersuite preferences from the openssl headers.
The new rules are:
* Require forward secrecy.
* Require RSA (since our servers only configure RSA keys)
* Require AES or 3DES. (This means, reject RC4, DES, SEED, CAMELLIA,
and NULL.)
* No export ciphersuites.
Then:
* Prefer AES to 3DES.
* If both suites have the same cipher, prefer ECDHE to DHE.
* If both suites have the same DHE group type, prefer GCM to CBC.
* If both suites have the same cipher mode, prefer SHA384 to SHA256
to SHA1.
* If both suites have the same digest, prefer AES256 to AES128.
2014-04-14 20:10:05 +02:00
|
|
|
|
|
|
|
|
|
|
|
ALL_CIPHERS = []
|
|
|
|
|
|
|
|
for fname in sys.argv[1:]:
|
2017-01-24 21:29:26 +01:00
|
|
|
for c in find_ciphers(fname):
|
|
|
|
if usable_cipher(c):
|
|
|
|
parsed = parse_cipher(c)
|
|
|
|
if parsed != None:
|
|
|
|
ALL_CIPHERS.append(parsed)
|
New sort order for server choice of ciphersuites.
Back in 175b2678, we allowed servers to recognize clients who are
telling them the truth about their ciphersuites, and select the best
cipher from on that list. This implemented the server side of proposal
198.
In bugs 11492, 11498, and 11499, cypherpunks found a bunch of mistakes
and omissions and typos in the UNRESTRICTED_SERVER_CIPHER_LIST we had.
In #11513, I found a couple more.
Rather than try to hand-edit this list, I wrote a short python script
to generate our ciphersuite preferences from the openssl headers.
The new rules are:
* Require forward secrecy.
* Require RSA (since our servers only configure RSA keys)
* Require AES or 3DES. (This means, reject RC4, DES, SEED, CAMELLIA,
and NULL.)
* No export ciphersuites.
Then:
* Prefer AES to 3DES.
* If both suites have the same cipher, prefer ECDHE to DHE.
* If both suites have the same DHE group type, prefer GCM to CBC.
* If both suites have the same cipher mode, prefer SHA384 to SHA256
to SHA1.
* If both suites have the same digest, prefer AES256 to AES128.
2014-04-14 20:10:05 +02:00
|
|
|
|
|
|
|
ALL_CIPHERS.sort(key=Ciphersuite.sort_key)
|
|
|
|
|
2017-01-27 22:15:26 +01:00
|
|
|
indent = " "*7
|
|
|
|
|
New sort order for server choice of ciphersuites.
Back in 175b2678, we allowed servers to recognize clients who are
telling them the truth about their ciphersuites, and select the best
cipher from on that list. This implemented the server side of proposal
198.
In bugs 11492, 11498, and 11499, cypherpunks found a bunch of mistakes
and omissions and typos in the UNRESTRICTED_SERVER_CIPHER_LIST we had.
In #11513, I found a couple more.
Rather than try to hand-edit this list, I wrote a short python script
to generate our ciphersuite preferences from the openssl headers.
The new rules are:
* Require forward secrecy.
* Require RSA (since our servers only configure RSA keys)
* Require AES or 3DES. (This means, reject RC4, DES, SEED, CAMELLIA,
and NULL.)
* No export ciphersuites.
Then:
* Prefer AES to 3DES.
* If both suites have the same cipher, prefer ECDHE to DHE.
* If both suites have the same DHE group type, prefer GCM to CBC.
* If both suites have the same cipher mode, prefer SHA384 to SHA256
to SHA1.
* If both suites have the same digest, prefer AES256 to AES128.
2014-04-14 20:10:05 +02:00
|
|
|
for c in ALL_CIPHERS:
|
|
|
|
if c is ALL_CIPHERS[-1]:
|
2017-01-27 22:15:26 +01:00
|
|
|
colon = ''
|
New sort order for server choice of ciphersuites.
Back in 175b2678, we allowed servers to recognize clients who are
telling them the truth about their ciphersuites, and select the best
cipher from on that list. This implemented the server side of proposal
198.
In bugs 11492, 11498, and 11499, cypherpunks found a bunch of mistakes
and omissions and typos in the UNRESTRICTED_SERVER_CIPHER_LIST we had.
In #11513, I found a couple more.
Rather than try to hand-edit this list, I wrote a short python script
to generate our ciphersuite preferences from the openssl headers.
The new rules are:
* Require forward secrecy.
* Require RSA (since our servers only configure RSA keys)
* Require AES or 3DES. (This means, reject RC4, DES, SEED, CAMELLIA,
and NULL.)
* No export ciphersuites.
Then:
* Prefer AES to 3DES.
* If both suites have the same cipher, prefer ECDHE to DHE.
* If both suites have the same DHE group type, prefer GCM to CBC.
* If both suites have the same cipher mode, prefer SHA384 to SHA256
to SHA1.
* If both suites have the same digest, prefer AES256 to AES128.
2014-04-14 20:10:05 +02:00
|
|
|
else:
|
|
|
|
colon = ' ":"'
|
|
|
|
|
|
|
|
if c.name in MANDATORY:
|
2017-01-27 22:15:26 +01:00
|
|
|
print "%s/* Required */"%indent
|
|
|
|
print '%s%s%s'%(indent,c.name,colon)
|
New sort order for server choice of ciphersuites.
Back in 175b2678, we allowed servers to recognize clients who are
telling them the truth about their ciphersuites, and select the best
cipher from on that list. This implemented the server side of proposal
198.
In bugs 11492, 11498, and 11499, cypherpunks found a bunch of mistakes
and omissions and typos in the UNRESTRICTED_SERVER_CIPHER_LIST we had.
In #11513, I found a couple more.
Rather than try to hand-edit this list, I wrote a short python script
to generate our ciphersuite preferences from the openssl headers.
The new rules are:
* Require forward secrecy.
* Require RSA (since our servers only configure RSA keys)
* Require AES or 3DES. (This means, reject RC4, DES, SEED, CAMELLIA,
and NULL.)
* No export ciphersuites.
Then:
* Prefer AES to 3DES.
* If both suites have the same cipher, prefer ECDHE to DHE.
* If both suites have the same DHE group type, prefer GCM to CBC.
* If both suites have the same cipher mode, prefer SHA384 to SHA256
to SHA1.
* If both suites have the same digest, prefer AES256 to AES128.
2014-04-14 20:10:05 +02:00
|
|
|
else:
|
|
|
|
print "#ifdef %s"%c.name
|
2017-01-27 22:15:26 +01:00
|
|
|
print '%s%s%s'%(indent,c.name,colon)
|
New sort order for server choice of ciphersuites.
Back in 175b2678, we allowed servers to recognize clients who are
telling them the truth about their ciphersuites, and select the best
cipher from on that list. This implemented the server side of proposal
198.
In bugs 11492, 11498, and 11499, cypherpunks found a bunch of mistakes
and omissions and typos in the UNRESTRICTED_SERVER_CIPHER_LIST we had.
In #11513, I found a couple more.
Rather than try to hand-edit this list, I wrote a short python script
to generate our ciphersuite preferences from the openssl headers.
The new rules are:
* Require forward secrecy.
* Require RSA (since our servers only configure RSA keys)
* Require AES or 3DES. (This means, reject RC4, DES, SEED, CAMELLIA,
and NULL.)
* No export ciphersuites.
Then:
* Prefer AES to 3DES.
* If both suites have the same cipher, prefer ECDHE to DHE.
* If both suites have the same DHE group type, prefer GCM to CBC.
* If both suites have the same cipher mode, prefer SHA384 to SHA256
to SHA1.
* If both suites have the same digest, prefer AES256 to AES128.
2014-04-14 20:10:05 +02:00
|
|
|
print "#endif"
|
|
|
|
|
2017-01-27 22:15:26 +01:00
|
|
|
print '%s;'%indent
|
New sort order for server choice of ciphersuites.
Back in 175b2678, we allowed servers to recognize clients who are
telling them the truth about their ciphersuites, and select the best
cipher from on that list. This implemented the server side of proposal
198.
In bugs 11492, 11498, and 11499, cypherpunks found a bunch of mistakes
and omissions and typos in the UNRESTRICTED_SERVER_CIPHER_LIST we had.
In #11513, I found a couple more.
Rather than try to hand-edit this list, I wrote a short python script
to generate our ciphersuite preferences from the openssl headers.
The new rules are:
* Require forward secrecy.
* Require RSA (since our servers only configure RSA keys)
* Require AES or 3DES. (This means, reject RC4, DES, SEED, CAMELLIA,
and NULL.)
* No export ciphersuites.
Then:
* Prefer AES to 3DES.
* If both suites have the same cipher, prefer ECDHE to DHE.
* If both suites have the same DHE group type, prefer GCM to CBC.
* If both suites have the same cipher mode, prefer SHA384 to SHA256
to SHA1.
* If both suites have the same digest, prefer AES256 to AES128.
2014-04-14 20:10:05 +02:00
|
|
|
|