report ciphers causing incompatibility for Firefox

It turns out that the situation is even more bleak for Firefox
with regards to RC4, add it to report
This commit is contained in:
Hubert Kario 2014-06-30 10:42:53 +02:00
parent 142726c4fd
commit 1b4dcc4393
1 changed files with 87 additions and 0 deletions

View File

@ -21,9 +21,38 @@ def natural_sort(l):
alphanum_key = lambda key: [ convert(c) for c in re.split('([0-9]+)', key) ]
return sorted(l, key = alphanum_key)
""" list of ciphers offerred by Firefox 29 by default """
firefox_ciphers=[
'ECDHE-ECDSA-AES128-GCM-SHA256',
'ECDHE-RSA-AES128-GCM-SHA256',
'ECDHE-ECDSA-AES256-SHA',
'ECDHE-ECDSA-AES128-SHA',
'ECDHE-RSA-AES128-SHA',
'ECDHE-RSA-AES256-SHA',
'ECDHE-RSA-DES-CBC3-SHA',
'ECDHE-ECDSA-RC4-SHA',
'ECDHE-RSA-RC4-SHA',
'DHE-RSA-AES128-SHA',
'DHE-DSS-AES128-SHA',
'DHE-RSA-CAMELLIA128-SHA',
'DHE-RSA-AES256-SHA',
'DHE-DSS-AES256-SHA',
'DHE-RSA-CAMELLIA256-SHA',
'EDH-RSA-DES-CBC3-SHA',
'AES128-SHA',
'CAMELLIA128-SHA',
'AES256-SHA',
'CAMELLIA256-SHA',
'DES-CBC3-SHA',
'RC4-SHA',
'RC4-MD5']
report_untrused=False
cipherstats = defaultdict(int)
FF_RC4_Only_cipherstats = defaultdict(int)
FF_RC4_preferred_cipherstats = defaultdict(int)
FF_incompatible_cipherstats = defaultdict(int)
pfsstats = defaultdict(int)
protocolstats = defaultdict(int)
handshakestats = defaultdict(int)
@ -53,6 +82,11 @@ for r,d,flist in os.walk(path):
DES3 = False
CAMELLIA = False
RC4 = False
""" the following depends on FF_compat, so by default it can be True """
RC4_Only_FF = True
FF_compat = False
temp_FF_incompat = {}
FF_RC4_Pref = None
ADH = False
DHE = False
AECDH = False
@ -92,6 +126,20 @@ for r,d,flist in os.walk(path):
if 'False' in entry['trusted'] and report_untrused == False:
continue
# check if the advertised ciphers are not effectively RC4 Only
# for firefox or incompatible with firefox
if entry['cipher'] in firefox_ciphers:
# if this is first cipher and we already are getting RC4
# then it means that RC4 is preferred
if not FF_compat:
if 'RC4' in entry['cipher']:
FF_RC4_Pref = True
FF_compat = True
if not 'RC4' in entry['cipher']:
RC4_Only_FF = False
else:
temp_FF_incompat[entry['cipher']] = 1
""" store the ciphers supported """
if 'ADH' in entry['cipher'] or 'AECDH' in entry['cipher']:
ciphertypes += 1
@ -269,6 +317,20 @@ for r,d,flist in os.walk(path):
cipherstats['RC4 forced in TLS1.1+'] += 1
cipherstats['RC4 Preferred'] += 1
if FF_compat:
if RC4_Only_FF and ciphertypes != 1:
cipherstats['x:FF 29 RC4 Only'] += 1
for cipher in temp_FF_incompat:
FF_RC4_Only_cipherstats[cipher] += 1
if FF_RC4_Pref and not 'RC4' in results['ciphersuite'][0]['cipher']:
cipherstats['x:FF 29 RC4 Preferred'] += 1
for cipher in temp_FF_incompat:
FF_RC4_preferred_cipherstats[cipher] += 1
else:
cipherstats['x:FF 29 incompatible'] += 1
for cipher in temp_FF_incompat:
FF_incompatible_cipherstats[cipher] += 1
for cipher in tempcipherstats:
cipherstats[cipher] += 1
@ -322,6 +384,13 @@ for r,d,flist in os.walk(path):
#if total % 1999 == 0:
# break
""" The 'x:FF 29 RC4 Preferred' counts only sites that effectively prefer
RC4 when using FF, to make reporting more readable, sum it with sites
that do that for all ciphers"""
if "x:FF 29 RC4 Preferred" in cipherstats and "RC4 Preferred" in cipherstats:
cipherstats['x:FF 29 RC4 Preferred'] += cipherstats['RC4 Preferred']
print("SSL/TLS survey of %i websites from Alexa's top 1 million" % total)
if report_untrused == False:
print("Stats only from connections that did provide valid certificates")
@ -334,6 +403,24 @@ for stat in sorted(cipherstats):
percent = round(cipherstats[stat] / total * 100, 4)
sys.stdout.write(stat.ljust(25) + " " + str(cipherstats[stat]).ljust(10) + str(percent).ljust(4) + "\n")
print("\nFF 29 RC4 Only other ciphers Count Percent")
print("-----------------------------+---------+------")
for stat in sorted(FF_RC4_Only_cipherstats):
percent = round(FF_RC4_Only_cipherstats[stat] / total * 100, 4)
sys.stdout.write(stat.ljust(30) + " " + str(FF_RC4_Only_cipherstats[stat]).ljust(10) + str(percent).ljust(4) + "\n")
print("\nFF 29 RC4 pref other ciphers Count Percent")
print("-----------------------------+---------+------")
for stat in sorted(FF_RC4_preferred_cipherstats):
percent = round(FF_RC4_preferred_cipherstats[stat] / total * 100, 4)
sys.stdout.write(stat.ljust(30) + " " + str(FF_RC4_preferred_cipherstats[stat]).ljust(10) + str(percent).ljust(4) + "\n")
print("\nFF 29 incompatible ciphers Count Percent")
print("-----------------------------+---------+------")
for stat in sorted(FF_incompatible_cipherstats):
percent = round(FF_incompatible_cipherstats[stat] / total * 100, 4)
sys.stdout.write(stat.ljust(30) + " " + str(FF_incompatible_cipherstats[stat]).ljust(10) + str(percent).ljust(4) + "\n")
print("\nSupported Handshakes Count Percent")
print("-------------------------+---------+-------")
for stat in sorted(handshakestats):