Merge pull request #248 from lainegholson/master

Add HTTP2/ALPN support
This commit is contained in:
Dirk Wetter 2015-12-22 12:05:53 +01:00
commit f65fa69c3c

View File

@ -133,7 +133,7 @@ DEBUG=${DEBUG:-0} # 1.: the temp files won't be erased.
# 3: slight hexdumps + other info,
# 4: display bytes sent via sockets, 5: display bytes received via sockets, 6: whole 9 yards
WIDE=${WIDE:-false} # whether to display for some options the cipher or the table with hexcode/KX,Enc,strength etc.
LOGFILE=${LOGILE-""} # logfile if used
LOGFILE=${LOGFILE:-""} # logfile if used
HAS_IPv6=${HAS_IPv6:-false} # if you have OPENSSL with IPv6 support AND IPv6 networking set it to yes and testssl.sh works!
# tuning vars, can not be set by a cmd line switch
@ -160,6 +160,8 @@ IKNOW_FNAME=false
# further global vars just declared here
readonly NPN_PROTOs="spdy/4a2,spdy/3,spdy/3.1,spdy/2,spdy/1,http/1.1"
# alpn_protos needs to be space-separated, not comma-seperated
readonly ALPN_PROTOs="h2 h2-17 h2-16 h2-15 h2-14 spdy/3.1 http/1.1"
TEMPDIR=""
TMPFILE=""
ERRFILE=""
@ -218,7 +220,7 @@ readonly UA_SNEAKY="Mozilla/5.0 (X11; Linux x86_64; rv:41.0) Gecko/20100101 Fire
TLS_LOW_BYTE=""
HEX_CIPHER=""
# The various hexdump commands we need to replace xxd (BSD compatibility))
# The various hexdump commands we need to replace xxd (BSD compatibility)
HEXDUMPVIEW=(hexdump -C) # This is used in verbose mode to see what's going on
HEXDUMP=(hexdump -ve '16/1 "%02x " " \n"') # This is used to analyze the reply
HEXDUMPPLAIN=(hexdump -ve '1/1 "%.2x"') # Replaces both xxd -p and tr -cd '[:print:]'
@ -1750,7 +1752,7 @@ run_server_preference() {
[[ -n "$PROXY" ]] && arg=" SPDY/NPN is"
[[ -n "$STARTTLS" ]] && arg=" "
if spdy_pre " $arg" ; then # is NPN/SPDY supported and is this no STARTTLS? / no PROXY
$OPENSSL s_client -host $NODE -port $PORT $BUGS -nextprotoneg "$NPN_PROTOs" </dev/null 2>>$ERRFILE >$TMPFILE
$OPENSSL s_client -connect $NODEIP:$PORT $BUGS -nextprotoneg "$NPN_PROTOs" </dev/null 2>>$ERRFILE >$TMPFILE
if sclient_connect_successful $? $TMPFILE; then
proto[i]=$(grep -aw "Next protocol" $TMPFILE | sed -e 's/^Next protocol://' -e 's/(.)//' -e 's/ //g')
if [[ -z "${proto[i]}" ]]; then
@ -2436,23 +2438,41 @@ spdy_pre(){
return 0
}
http2_pre(){
if [[ -n "$STARTTLS" ]]; then
[[ -n "$1" ]] && out "$1"
out "(HTTP/2 is a HTTP protocol and thus not tested here)"
return 1
fi
if [[ -n "$PROXY" ]]; then
[[ -n "$1" ]] && pr_litemagenta " $1 "
pr_litemagenta "not tested as proxies do not support proxying it"
return 1
fi
if ! $HAS_ALPN; then
local_problem "$OPENSSL doesn't support HTTP2/ALPN";
return 7
fi
return 0
}
run_spdy() {
local tmpstr
local -i ret=0
pr_bold " SPDY/NPN "
if ! spdy_pre ; then
outln "\n"
outln
return 0
fi
$OPENSSL s_client -host $NODE -port $PORT $BUGS -nextprotoneg $NPN_PROTOs </dev/null 2>$ERRFILE >$TMPFILE
$OPENSSL s_client -connect $NODEIP:$PORT $BUGS $SNI -nextprotoneg $NPN_PROTOs </dev/null 2>$ERRFILE >$TMPFILE
tmpstr=$(grep -a '^Protocols' $TMPFILE | sed 's/Protocols.*: //')
if [[ -z "$tmpstr" ]] || [[ "$tmpstr" == " " ]]; then
outln "not offered"
ret=1
else
# now comes a strange thing: "Protocols advertised by server:" is empty but connection succeeded
if echo $tmpstr | egrep -aq "spdy|http" ; then
if echo $tmpstr | egrep -aq "h2|spdy|http" ; then
out "$tmpstr"
outln " (advertised)"
ret=0
@ -2461,7 +2481,7 @@ run_spdy() {
ret=10
fi
fi
outln
#outln
# btw: nmap can do that too http://nmap.org/nsedoc/scripts/tls-nextprotoneg.html
# nmap --script=tls-nextprotoneg #NODE -p $PORT is your friend if your openssl doesn't want to test this
tmpfile_handle $FUNCNAME.txt
@ -2469,6 +2489,40 @@ run_spdy() {
}
run_http2() {
local tmpstr
local -i ret=0
local had_alpn_proto
pr_bold " HTTP2/ALPN "
if ! http2_pre ; then
outln
return 0
fi
for proto in $ALPN_PROTOs; do
# for some reason OpenSSL doesn't list the advertised protocols, so instead try common protocols
$OPENSSL s_client -connect $NODEIP:$PORT $BUGS $SNI -alpn $proto </dev/null 2>$ERRFILE >$TMPFILE
tmpstr=$(grep -a '^ALPN protocol' $TMPFILE | sed 's/ALPN protocol.*: //')
if [[ "$tmpstr" = "$proto" ]]; then
if [[ -z "$had_alpn_proto" ]]; then
out "$proto"
had_alpn_proto=1
else
out ", $proto"
fi
fi
done
if [ "$had_alpn_proto" ]; then
outln " (offered)"
ret=0
else
outln "not offered"
ret=1
fi
tmpfile_handle $FUNCNAME.txt
return $ret
}
# arg1: string to send
# arg2: possible success strings a egrep pattern, needed!
starttls_line() {
@ -4069,6 +4123,7 @@ $PROG_NAME <options> URI ("$PROG_NAME URI" does everything except -E)
-S, --server_defaults displays the servers default picks and certificate info
-P, --preference displays the servers picks: protocol+cipher
-y, --spdy, --npn checks for SPDY/NPN
-Y, --http2, --alpn checks for HTTP2/ALPN
-x, --single-cipher <pattern> tests matched <pattern> of ciphers
(if <pattern> not a number: word match)
-U, --vulnerable tests all vulnerabilities
@ -4932,6 +4987,7 @@ initialize_globals() {
do_server_defaults=false
do_server_preference=false
do_spdy=false
do_http2=false
do_ssl_poodle=false
do_tls_fallback_scsv=false
do_test_just_one=false
@ -4959,6 +5015,7 @@ set_scanning_defaults() {
do_server_defaults=true
do_server_preference=true
do_spdy=true
do_http2=true
do_ssl_poodle=true
do_tls_fallback_scsv=true
VULN_COUNT=10
@ -4970,7 +5027,7 @@ query_globals() {
for gbl in do_allciphers do_vulnerabilities do_beast do_breach do_ccs_injection do_cipher_per_proto do_crime \
do_freak do_logjam do_header do_heartbleed do_mx_all_ips do_pfs do_protocols do_rc4 do_renego \
do_std_cipherlists do_server_defaults do_server_preference do_spdy do_ssl_poodle do_tls_fallback_scsv \
do_std_cipherlists do_server_defaults do_server_preference do_spdy do_http2 do_ssl_poodle do_tls_fallback_scsv \
do_test_just_one do_tls_sockets do_mass_testing; do
[[ "${!gbl}" == "true" ]] && let true_nr++
done
@ -4983,7 +5040,7 @@ debug_globals() {
for gbl in do_allciphers do_vulnerabilities do_beast do_breach do_ccs_injection do_cipher_per_proto do_crime \
do_freak do_logjam do_header do_heartbleed do_rc4 do_mx_all_ips do_pfs do_protocols do_rc4 do_renego \
do_std_cipherlists do_server_defaults do_server_preference do_spdy do_ssl_poodle do_tls_fallback_scsv \
do_std_cipherlists do_server_defaults do_server_preference do_spdy do_http2 do_ssl_poodle do_tls_fallback_scsv \
do_test_just_one do_tls_sockets do_mass_testing; do
printf "%-22s = %s\n" $gbl "${!gbl}"
done
@ -5071,10 +5128,14 @@ parse_cmd_line() {
-p|--protocols)
do_protocols=true
do_spdy=true
do_http2=true
;;
-y|--spdy|--npn)
do_spdy=true
;;
-Y|--http2|--alpn)
do_http2=true
;;
-f|--ciphers)
do_std_cipherlists=true
;;
@ -5309,6 +5370,7 @@ lets_roll() {
# all top level functions now following have the prefix "run_"
$do_protocols && { run_protocols; ret=$(($? + ret)); }
$do_spdy && { run_spdy; ret=$(($? + ret)); }
$do_http2 && { run_http2; ret=$(($? + ret)); }
$do_std_cipherlists && { run_std_cipherlists; ret=$(($? + ret)); }
$do_pfs && { run_pfs; ret=$(($? + ret)); }
$do_server_preference && { run_server_preference; ret=$(($? + ret)); }