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

Merge pull request #126 from tomato42/npn

Add support for collecting supported NPN protocols
This commit is contained in:
Julien Vehent [:ulfr] 2016-09-17 08:11:03 -04:00 committed by GitHub
commit 197881da81
2 changed files with 47 additions and 13 deletions

View File

@ -377,6 +377,7 @@ parse_openssl_output() {
current_sigalg="None" current_sigalg="None"
current_renegotiation="False" current_renegotiation="False"
current_compression="" current_compression=""
current_npn="None"
certs_found=0 certs_found=0
current_raw_certificates=() current_raw_certificates=()
@ -399,6 +400,12 @@ parse_openssl_output() {
continue continue
fi fi
# get NPN protocols
if [[ $line =~ Protocols\ advertised\ by\ server:\ (.*) ]]; then
current_npn="${BASH_REMATCH[1]// /}"
continue
fi
# extract selected cipher # extract selected cipher
if [[ $line =~ New,\ ]]; then if [[ $line =~ New,\ ]]; then
local match=($line) local match=($line)
@ -620,6 +627,7 @@ test_cipher_on_target() {
trusted=$current_trusted trusted=$current_trusted
tickethint=$current_tickethint tickethint=$current_tickethint
ocspstaple=$current_ocspstaple ocspstaple=$current_ocspstaple
npn="$current_npn"
certificates="$current_certificates" certificates="$current_certificates"
# grab the cipher and PFS key size # grab the cipher and PFS key size
done done
@ -632,7 +640,7 @@ test_cipher_on_target() {
# if cipher contains NONE, the cipher wasn't accepted # if cipher contains NONE, the cipher wasn't accepted
elif [[ "$cipher" == '(NONE) ' ]]; then elif [[ "$cipher" == '(NONE) ' ]]; then
result="$cipher $protocols $pubkey $sigalg $trusted $tickethint $ocspstaple $pfs $current_curves $curves_ordering" result="$cipher $protocols $pubkey $sigalg $trusted $tickethint $ocspstaple $npn $pfs $current_curves $curves_ordering"
verbose "handshake failed, server returned ciphersuite '$result'" verbose "handshake failed, server returned ciphersuite '$result'"
return 1 return 1
@ -653,7 +661,7 @@ test_cipher_on_target() {
current_curves="$(get_curve_name "$(echo $pfs|cut -d ',' -f2)")" current_curves="$(get_curve_name "$(echo $pfs|cut -d ',' -f2)")"
fi fi
fi fi
result="$cipher $protocols $pubkey $sigalg $trusted $tickethint $ocspstaple $pfs $current_curves $curves_ordering" result="$cipher $protocols $pubkey $sigalg $trusted $tickethint $ocspstaple $npn $pfs $current_curves $curves_ordering"
verbose "handshake succeeded, server returned ciphersuite '$result'" verbose "handshake succeeded, server returned ciphersuite '$result'"
return 0 return 0
fi fi
@ -693,7 +701,7 @@ get_cipher_pref() {
sslcommand+=" -CAfile $CACERTS" sslcommand+=" -CAfile $CACERTS"
fi fi
sslcommand+=" -trusted_first -status $SCLIENTARGS -connect $TARGET" sslcommand+=" -trusted_first -status $SCLIENTARGS -connect $TARGET"
sslcommand+=" -cipher $ciphersuite" sslcommand+=" -cipher $ciphersuite -nextprotoneg http/1.1"
verbose "Connecting to '$TARGET' with ciphersuite '$ciphersuite'" verbose "Connecting to '$TARGET' with ciphersuite '$ciphersuite'"
# If the connection succeeded with the current cipher, benchmark and store # If the connection succeeded with the current cipher, benchmark and store
@ -728,6 +736,7 @@ display_results_in_terminal() {
local sigalg local sigalg
local trusted local trusted
local tickethint local tickethint
local npn
local ocspstaple local ocspstaple
local curvesordering local curvesordering
local different=False local different=False
@ -771,8 +780,9 @@ display_results_in_terminal() {
trusted="${cipher_data[4]}" trusted="${cipher_data[4]}"
tickethint="${cipher_data[5]}" tickethint="${cipher_data[5]}"
ocspstaple="${cipher_data[6]}" ocspstaple="${cipher_data[6]}"
if [[ $TEST_CURVES == "True" && -n ${cipher_data[9]} ]]; then npn="${cipher_data[7]}"
curvesordering="${cipher_data[9]}" if [[ $TEST_CURVES == "True" && -n ${cipher_data[10]} ]]; then
curvesordering="${cipher_data[10]}"
fi fi
else else
if [[ "$pubkey" != "${cipher_data[2]}" ]]; then if [[ "$pubkey" != "${cipher_data[2]}" ]]; then
@ -790,10 +800,14 @@ display_results_in_terminal() {
if [[ "$ocspstaple" != "${cipher_data[6]}" ]]; then if [[ "$ocspstaple" != "${cipher_data[6]}" ]]; then
different=True different=True
fi fi
if [[ -z $curvesordering && -n "${cipher_data[9]}" ]]; then if [[ "$npn" != "${cipher_data[7]}" ]]; then
curvesordering="${cipher_data[9]}" different=True
fi fi
if [[ -n $curvesordering && "$curvesordering" != "${cipher_data[9]}" ]]; then if [[ -z $curvesordering && -n "${cipher_data[10]}" ]]; then
curvesordering="${cipher_data[10]}"
fi
if [[ -n $curvesordering && "$curvesordering" != "${cipher_data[10]}" ]]; then
echo "CURVESORDERING"
different=True different=True
fi fi
fi fi
@ -803,7 +817,7 @@ display_results_in_terminal() {
header="prio ciphersuite protocols" header="prio ciphersuite protocols"
if [[ $different == "True" ]]; then if [[ $different == "True" ]]; then
header+=" pubkey_size signature_algoritm trusted ticket_hint ocsp_staple" header+=" pubkey_size signature_algoritm trusted ticket_hint ocsp_staple npn"
fi fi
header+=" pfs" header+=" pfs"
if [[ $has_curves == "True" ]]; then if [[ $has_curves == "True" ]]; then
@ -825,7 +839,7 @@ display_results_in_terminal() {
echo "$result"|grep -v '(NONE)' echo "$result"|grep -v '(NONE)'
else else
# prints priority, ciphersuite, protocols and pfs # prints priority, ciphersuite, protocols and pfs
awk '!/(NONE)/{print $1 " " $2 " " $3 " " $9 " " $10}' <<<"$result" awk '!/(NONE)/{print $1 " " $2 " " $3 " " $10 " " $11}' <<<"$result"
fi fi
done|column -t done|column -t
echo echo
@ -848,6 +862,7 @@ display_results_in_terminal() {
if [[ $different != "True" ]]; then if [[ $different != "True" ]]; then
echo -e "Certificate: $trusted, $pubkey bits, $sigalg signature" echo -e "Certificate: $trusted, $pubkey bits, $sigalg signature"
echo "TLS ticket lifetime hint: $tickethint" echo "TLS ticket lifetime hint: $tickethint"
echo "NPN protocols: $npn"
fi fi
if [[ $ocspstaple == "True" ]]; then if [[ $ocspstaple == "True" ]]; then
echo -e "OCSP stapling: ${c_green}supported${c_reset}" echo -e "OCSP stapling: ${c_green}supported${c_reset}"
@ -984,15 +999,16 @@ display_results_in_json() {
fi fi
echo -n "\"ticket_hint\":\"${cipher_arr[5]}\"," echo -n "\"ticket_hint\":\"${cipher_arr[5]}\","
echo -n "\"ocsp_stapling\":\"${cipher_arr[6]}\"," echo -n "\"ocsp_stapling\":\"${cipher_arr[6]}\","
pfs="${cipher_arr[7]}" echo -n "\"npn\":[\"${cipher_arr[7]//,/\",\"}\"],"
pfs="${cipher_arr[8]}"
[[ -z $pfs ]] && pfs="None" [[ -z $pfs ]] && pfs="None"
echo -n "\"pfs\":\"$pfs\"" echo -n "\"pfs\":\"$pfs\""
if [[ "${cipher_arr[0]}" =~ ECDH ]]; then if [[ "${cipher_arr[0]}" =~ ECDH ]]; then
echo -n "," echo -n ","
echo -n "\"curves\":[\"${cipher_arr[8]//,/\",\"}\"]" echo -n "\"curves\":[\"${cipher_arr[9]//,/\",\"}\"]"
if [[ $TEST_CURVES == "True" ]]; then if [[ $TEST_CURVES == "True" ]]; then
echo -n "," echo -n ","
echo -n "\"curves_ordering\":\"${cipher_arr[9]}\"" echo -n "\"curves_ordering\":\"${cipher_arr[10]}\""
fi fi
fi fi
echo -n "}" echo -n "}"

View File

@ -111,6 +111,7 @@ tickethint = defaultdict(int)
eccfallback = defaultdict(int) eccfallback = defaultdict(int)
eccordering = defaultdict(int) eccordering = defaultdict(int)
ecccurve = defaultdict(int) ecccurve = defaultdict(int)
npn = defaultdict(int)
ocspstaple = defaultdict(int) ocspstaple = defaultdict(int)
fallbacks = defaultdict(int) fallbacks = defaultdict(int)
# array with indexes of fallback names for the matrix report # array with indexes of fallback names for the matrix report
@ -174,6 +175,7 @@ for r,d,flist in os.walk(path):
tempeccfallback = "unknown" tempeccfallback = "unknown"
tempeccordering = "unknown" tempeccordering = "unknown"
tempecccurve = {} tempecccurve = {}
tempnpn = {}
tempfallbacks = {} tempfallbacks = {}
""" supported ciphers by the server under scan """ """ supported ciphers by the server under scan """
tempcipherstats = {} tempcipherstats = {}
@ -500,6 +502,13 @@ for r,d,flist in os.walk(path):
elif protocol == 'TLSv1.2': elif protocol == 'TLSv1.2':
TLS1_2 = True TLS1_2 = True
# save NPN protocols supported
if 'npn' in entry:
for proto in entry['npn']:
tempnpn[proto] = 1
if len(entry['npn']) == 1:
tempnpn[proto + ' Only'] = 1
""" save ECC curves stats """ """ save ECC curves stats """
if 'curves_ordering' in entry: if 'curves_ordering' in entry:
tempeccordering = entry['curves_ordering'] tempeccordering = entry['curves_ordering']
@ -593,6 +602,9 @@ for r,d,flist in os.walk(path):
for s in tempecccurve: for s in tempecccurve:
ecccurve[s] += 1 ecccurve[s] += 1
for s in tempnpn:
npn[s] += 1
if ocsp_stapling is None: if ocsp_stapling is None:
ocspstaple['Unknown'] += 1 ocspstaple['Unknown'] += 1
elif ocsp_stapling: elif ocsp_stapling:
@ -796,6 +808,12 @@ for stat in sorted(handshakestats):
percent = round(handshakestats[stat] / total * 100, 4) percent = round(handshakestats[stat] / total * 100, 4)
sys.stdout.write(stat.ljust(25) + " " + str(handshakestats[stat]).ljust(10) + str(percent).ljust(4) + "\n") sys.stdout.write(stat.ljust(25) + " " + str(handshakestats[stat]).ljust(10) + str(percent).ljust(4) + "\n")
print("\nSupported NPN protocols Count Percent ")
print("-------------------------+---------+--------")
for name, val in sorted(npn.items()):
percent = round(val / total * 100, 4)
sys.stdout.write(name.ljust(25) + " " + str(val).ljust(10) + str(percent).ljust(9) + "\n")
print("\nSupported PFS Count Percent PFS Percent") print("\nSupported PFS Count Percent PFS Percent")
print("-------------------------+---------+--------+-----------") print("-------------------------+---------+--------+-----------")
for stat in sorted(pfsstats): for stat in sorted(pfsstats):