2
0
mirror of https://github.com/mozilla/cipherscan.git synced 2024-11-22 22:33:40 +01:00

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 committed by Hubert Kario
parent 4ffa061977
commit 8bcc9d3cf6

View File

@ -21,9 +21,38 @@ def natural_sort(l):
alphanum_key = lambda key: [ convert(c) for c in re.split('([0-9]+)', key) ] alphanum_key = lambda key: [ convert(c) for c in re.split('([0-9]+)', key) ]
return sorted(l, key = alphanum_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 report_untrused=False
cipherstats = defaultdict(int) cipherstats = defaultdict(int)
FF_RC4_Only_cipherstats = defaultdict(int)
FF_RC4_preferred_cipherstats = defaultdict(int)
FF_incompatible_cipherstats = defaultdict(int)
pfsstats = defaultdict(int) pfsstats = defaultdict(int)
protocolstats = defaultdict(int) protocolstats = defaultdict(int)
handshakestats = defaultdict(int) handshakestats = defaultdict(int)
@ -52,6 +81,11 @@ for r,d,flist in os.walk(path):
DES3 = False DES3 = False
CAMELLIA = False CAMELLIA = False
RC4 = 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 ADH = False
DHE = False DHE = False
AECDH = False AECDH = False
@ -91,6 +125,20 @@ for r,d,flist in os.walk(path):
if 'False' in entry['trusted'] and report_untrused == False: if 'False' in entry['trusted'] and report_untrused == False:
continue 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 """ """ store the ciphers supported """
if 'ADH' in entry['cipher'] or 'AECDH' in entry['cipher']: if 'ADH' in entry['cipher'] or 'AECDH' in entry['cipher']:
ciphertypes += 1 ciphertypes += 1
@ -262,6 +310,20 @@ for r,d,flist in os.walk(path):
cipherstats['RC4 forced in TLS1.1+'] += 1 cipherstats['RC4 forced in TLS1.1+'] += 1
cipherstats['RC4 Preferred'] += 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: for cipher in tempcipherstats:
cipherstats[cipher] += 1 cipherstats[cipher] += 1
@ -315,6 +377,13 @@ for r,d,flist in os.walk(path):
#if total % 1999 == 0: #if total % 1999 == 0:
# break # 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) print("SSL/TLS survey of %i websites from Alexa's top 1 million" % total)
if report_untrused == False: if report_untrused == False:
print("Stats only from connections that did provide valid certificates") print("Stats only from connections that did provide valid certificates")
@ -327,6 +396,24 @@ for stat in sorted(cipherstats):
percent = round(cipherstats[stat] / total * 100, 4) percent = round(cipherstats[stat] / total * 100, 4)
sys.stdout.write(stat.ljust(25) + " " + str(cipherstats[stat]).ljust(10) + str(percent).ljust(4) + "\n") 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("\nSupported Handshakes Count Percent")
print("-------------------------+---------+-------") print("-------------------------+---------+-------")
for stat in sorted(handshakestats): for stat in sorted(handshakestats):