Merge branch '2.9dev' of github.com:drwetter/testssl.sh into 2.9dev

This commit is contained in:
Dirk 2018-02-08 21:15:12 +01:00
commit 46fa94fa33
1 changed files with 156 additions and 148 deletions

View File

@ -472,15 +472,15 @@ pr_grey() { tm_grey "$1"; [[ "$COLOR" -ne 0 ]] && html_out "<span style=\"
tmln_grey() { tm_grey "$1"; tmln_out; } tmln_grey() { tm_grey "$1"; tmln_out; }
prln_grey() { pr_grey "$1"; outln; } prln_grey() { pr_grey "$1"; outln; }
tm_done_good() { [[ "$COLOR" -ge 2 ]] && ( "$COLORBLIND" && tm_out "\033[0;34m$1" || tm_out "\033[0;32m$1" ) || tm_out "$1"; tm_off; } # litegreen (liteblue), This is good tm_svrty_good() { [[ "$COLOR" -ge 2 ]] && ( "$COLORBLIND" && tm_out "\033[0;34m$1" || tm_out "\033[0;32m$1" ) || tm_out "$1"; tm_off; } # litegreen (liteblue), This is good
tmln_done_good() { tm_done_good "$1"; tmln_out; } tmln_svrty_good() { tm_svrty_good "$1"; tmln_out; }
pr_done_good() { tm_done_good "$1"; [[ "$COLOR" -ge 2 ]] && ( "$COLORBLIND" && html_out "<span style=\"color:#0000ee;\">$(html_reserved "$1")</span>" || html_out "<span style=\"color:#00cd00;\">$(html_reserved "$1")</span>" ) || html_out "$(html_reserved "$1")"; } pr_svrty_good() { tm_svrty_good "$1"; [[ "$COLOR" -ge 2 ]] && ( "$COLORBLIND" && html_out "<span style=\"color:#0000ee;\">$(html_reserved "$1")</span>" || html_out "<span style=\"color:#00cd00;\">$(html_reserved "$1")</span>" ) || html_out "$(html_reserved "$1")"; }
prln_done_good() { pr_done_good "$1"; outln; } prln_svrty_good() { pr_svrty_good "$1"; outln; }
tm_done_best() { [[ "$COLOR" -ge 2 ]] && ( "$COLORBLIND" && tm_out "\033[1;34m$1" || tm_out "\033[1;32m$1" ) || tm_out "$1"; tm_off; } # green (blue), This is the best tm_svrty_best() { [[ "$COLOR" -ge 2 ]] && ( "$COLORBLIND" && tm_out "\033[1;34m$1" || tm_out "\033[1;32m$1" ) || tm_out "$1"; tm_off; } # green (blue), This is the best
tmln_done_best() { tm_done_best "$1"; tmln_out; } tmln_svrty_best() { tm_svrty_best "$1"; tmln_out; }
pr_done_best() { tm_done_best "$1"; [[ "$COLOR" -ge 2 ]] && ( "$COLORBLIND" && html_out "<span style=\"color:#5c5cff;font-weight:bold;\">$(html_reserved "$1")</span>" || html_out "<span style=\"color:lime;font-weight:bold;\">$(html_reserved "$1")</span>" ) || html_out "$(html_reserved "$1")"; } pr_svrty_best() { tm_svrty_best "$1"; [[ "$COLOR" -ge 2 ]] && ( "$COLORBLIND" && html_out "<span style=\"color:#5c5cff;font-weight:bold;\">$(html_reserved "$1")</span>" || html_out "<span style=\"color:lime;font-weight:bold;\">$(html_reserved "$1")</span>" ) || html_out "$(html_reserved "$1")"; }
prln_done_best() { pr_done_best "$1"; outln; } prln_svrty_best() { pr_svrty_best "$1"; outln; }
tm_svrty_low() { [[ "$COLOR" -ge 2 ]] && tm_out "\033[1;33m$1" || tm_out "$1"; tm_off; } # yellow brown | academic or minor problem tm_svrty_low() { [[ "$COLOR" -ge 2 ]] && tm_out "\033[1;33m$1" || tm_out "$1"; tm_off; } # yellow brown | academic or minor problem
tmln_svrty_low() { tm_svrty_low "$1"; tmln_out; } tmln_svrty_low() { tm_svrty_low "$1"; tmln_out; }
@ -1704,7 +1704,7 @@ detect_header() {
includeSubDomains() { includeSubDomains() {
if grep -aiqw includeSubDomains "$1"; then if grep -aiqw includeSubDomains "$1"; then
pr_done_good ", includeSubDomains" pr_svrty_good ", includeSubDomains"
return 0 return 0
else else
pr_litecyan ", just this domain" pr_litecyan ", just this domain"
@ -1714,7 +1714,7 @@ includeSubDomains() {
preload() { preload() {
if grep -aiqw preload "$1"; then if grep -aiqw preload "$1"; then
pr_done_good ", preload" pr_svrty_good ", preload"
return 0 return 0
else else
return 1 return 1
@ -1748,7 +1748,7 @@ run_hsts() {
pr_svrty_medium "HSTS max-age is set to 0. HSTS is disabled" pr_svrty_medium "HSTS max-age is set to 0. HSTS is disabled"
fileout "HSTS_time" "MEDIUM" "0. HSTS is disabled" fileout "HSTS_time" "MEDIUM" "0. HSTS is disabled"
elif [[ $hsts_age_sec -gt $HSTS_MIN ]]; then elif [[ $hsts_age_sec -gt $HSTS_MIN ]]; then
pr_done_good "$hsts_age_days days" ; out "=$hsts_age_sec s" pr_svrty_good "$hsts_age_days days" ; out "=$hsts_age_sec s"
fileout "HSTS_time" "OK" "$hsts_age_days days (=$hsts_age_sec seconds) > $HSTS_MIN seconds" fileout "HSTS_time" "OK" "$hsts_age_days days (=$hsts_age_sec seconds) > $HSTS_MIN seconds"
else else
pr_svrty_medium "$hsts_age_sec s = $hsts_age_days days is too short ( >=$HSTS_MIN seconds recommended)" pr_svrty_medium "$hsts_age_sec s = $hsts_age_days days is too short ( >=$HSTS_MIN seconds recommended)"
@ -1829,7 +1829,7 @@ run_hpkp() {
pr_svrty_high "Only one key pinned (NOT ok), means the site may become unavailable in the future, " pr_svrty_high "Only one key pinned (NOT ok), means the site may become unavailable in the future, "
fileout "HPKP_SPKIs" "HIGH" "Only one key pinned" fileout "HPKP_SPKIs" "HIGH" "Only one key pinned"
else else
pr_done_good "$hpkp_nr_keys" pr_svrty_good "$hpkp_nr_keys"
out " keys, " out " keys, "
fileout "HPKP_SPKIs" "OK" "$hpkp_nr_keys keys pinned in header" fileout "HPKP_SPKIs" "OK" "$hpkp_nr_keys keys pinned in header"
fi fi
@ -1842,7 +1842,7 @@ run_hpkp() {
fi fi
hpkp_age_days=$((hpkp_age_sec / 86400)) hpkp_age_days=$((hpkp_age_sec / 86400))
if [[ $hpkp_age_sec -ge $HPKP_MIN ]]; then if [[ $hpkp_age_sec -ge $HPKP_MIN ]]; then
pr_done_good "$hpkp_age_days days" ; out "=$hpkp_age_sec s" pr_svrty_good "$hpkp_age_days days" ; out "=$hpkp_age_sec s"
fileout "HPKP_age" "OK" "HPKP age is set to $hpkp_age_days days ($hpkp_age_sec sec)" fileout "HPKP_age" "OK" "HPKP age is set to $hpkp_age_days days ($hpkp_age_sec sec)"
else else
out "$hpkp_age_sec s = " out "$hpkp_age_sec s = "
@ -1910,7 +1910,7 @@ run_hpkp() {
certificate_found=true # We have a match certificate_found=true # We have a match
spki_match=true spki_match=true
out "\n$spaces_indented Host cert: " out "\n$spaces_indented Host cert: "
pr_done_good "$hpkp_spki" pr_svrty_good "$hpkp_spki"
fileout "HPKP_$hpkp_spki" "OK" "SPKI $hpkp_spki matches the host certificate" fileout "HPKP_$hpkp_spki" "OK" "SPKI $hpkp_spki matches the host certificate"
fi fi
debugme tm_out "\n $hpkp_spki | $hpkp_spki_hostcert" debugme tm_out "\n $hpkp_spki | $hpkp_spki_hostcert"
@ -1923,7 +1923,7 @@ run_hpkp() {
certificate_found=true certificate_found=true
spki_match=true spki_match=true
out "\n$spaces_indented Sub CA: " out "\n$spaces_indented Sub CA: "
pr_done_good "$hpkp_spki" pr_svrty_good "$hpkp_spki"
ca_cn="$(sed "s/^[a-zA-Z0-9\+\/]*=* *//" <<< $"$hpkp_matches" )" ca_cn="$(sed "s/^[a-zA-Z0-9\+\/]*=* *//" <<< $"$hpkp_matches" )"
pr_italic " $ca_cn" pr_italic " $ca_cn"
fileout "HPKP_$hpkp_spki" "OK" "SPKI $hpkp_spki matches Intermediate CA \"$ca_cn\" pinned in the HPKP header" fileout "HPKP_$hpkp_spki" "OK" "SPKI $hpkp_spki matches Intermediate CA \"$ca_cn\" pinned in the HPKP header"
@ -1946,7 +1946,7 @@ run_hpkp() {
ca_cn="$(sed "s/^[a-zA-Z0-9\+\/]*=* *//" <<< $"$hpkp_matches" )" ca_cn="$(sed "s/^[a-zA-Z0-9\+\/]*=* *//" <<< $"$hpkp_matches" )"
if [[ "$match_ca" == "$hpkp_ca" ]]; then # part of the chain if [[ "$match_ca" == "$hpkp_ca" ]]; then # part of the chain
out "\n$spaces_indented Root CA: " out "\n$spaces_indented Root CA: "
pr_done_good "$hpkp_spki" pr_svrty_good "$hpkp_spki"
pr_italic " $ca_cn" pr_italic " $ca_cn"
fileout "HPKP_$hpkp_spki" "INFO" "SPKI $hpkp_spki matches Root CA \"$ca_cn\" pinned. (Root CA part of the chain)" fileout "HPKP_$hpkp_spki" "INFO" "SPKI $hpkp_spki matches Root CA \"$ca_cn\" pinned. (Root CA part of the chain)"
else # not part of chain else # not part of chain
@ -1977,7 +1977,7 @@ run_hpkp() {
# for i=0 manually do the same as below as there's other indentation here # for i=0 manually do the same as below as there's other indentation here
if [[ -n "${backup_spki_str[0]}" ]]; then if [[ -n "${backup_spki_str[0]}" ]]; then
pr_done_good "${backup_spki[0]}" pr_svrty_good "${backup_spki[0]}"
#out " Root CA: " #out " Root CA: "
prln_italic " ${backup_spki_str[0]}" prln_italic " ${backup_spki_str[0]}"
else else
@ -1987,7 +1987,7 @@ run_hpkp() {
for ((i=1; i < ${#backup_spki[@]} ;i++ )); do for ((i=1; i < ${#backup_spki[@]} ;i++ )); do
if [[ -n "${backup_spki_str[i]}" ]]; then if [[ -n "${backup_spki_str[i]}" ]]; then
# it's a Root CA outside the chain # it's a Root CA outside the chain
pr_done_good "$spaces_indented ${backup_spki[i]}" pr_svrty_good "$spaces_indented ${backup_spki[i]}"
#out " Root CA: " #out " Root CA: "
prln_italic " ${backup_spki_str[i]}" prln_italic " ${backup_spki_str[i]}"
else else
@ -2309,7 +2309,7 @@ run_cookie_flags() { # ARG1: Path
nr_secure=$(grep -iac secure $TMPFILE) nr_secure=$(grep -iac secure $TMPFILE)
case $nr_secure in case $nr_secure in
0) pr_svrty_medium "$negative_word" ;; 0) pr_svrty_medium "$negative_word" ;;
[123456789]) pr_done_good "$nr_secure/$nr_cookies";; [123456789]) pr_svrty_good "$nr_secure/$nr_cookies";;
esac esac
out " secure, " out " secure, "
if [[ $nr_cookies -eq $nr_secure ]]; then if [[ $nr_cookies -eq $nr_secure ]]; then
@ -2320,7 +2320,7 @@ run_cookie_flags() { # ARG1: Path
nr_httponly=$(grep -cai httponly $TMPFILE) nr_httponly=$(grep -cai httponly $TMPFILE)
case $nr_httponly in case $nr_httponly in
0) pr_svrty_medium "$negative_word" ;; 0) pr_svrty_medium "$negative_word" ;;
[123456789]) pr_done_good "$nr_httponly/$nr_cookies";; [123456789]) pr_svrty_good "$nr_httponly/$nr_cookies";;
esac esac
out " HttpOnly" out " HttpOnly"
if [[ $nr_cookies -eq $nr_httponly ]]; then if [[ $nr_cookies -eq $nr_httponly ]]; then
@ -2359,7 +2359,7 @@ run_more_flags() {
else else
first=false first=false
fi fi
pr_done_good "$f2t" pr_svrty_good "$f2t"
outln " $(out_row_aligned_max_width "$HEADERVALUE" "$spaces" $TERM_WIDTH)" outln " $(out_row_aligned_max_width "$HEADERVALUE" "$spaces" $TERM_WIDTH)"
fileout "$f2t" "OK" "$HEADERVALUE" fileout "$f2t" "OK" "$HEADERVALUE"
fi fi
@ -2375,7 +2375,7 @@ run_more_flags() {
first=false first=false
fi fi
pr_litecyan "$f2t" pr_litecyan "$f2t"
outln "$HEADERVALUE" # shouldn't be that long outln " $HEADERVALUE" # shouldn't be that long
fileout "$f2t" "INFO" "$f2t: $HEADERVALUE" fileout "$f2t" "INFO" "$f2t: $HEADERVALUE"
fi fi
done done
@ -2549,7 +2549,7 @@ sub_cipherlists() {
case $3 in case $3 in
2) if [[ $sclient_success -eq 0 ]]; then 2) if [[ $sclient_success -eq 0 ]]; then
# Strong is excellent to offer # Strong is excellent to offer
pr_done_best "offered (OK)" pr_svrty_best "offered (OK)"
fileout "${jsonID}_$4" "OK" "offered" fileout "${jsonID}_$4" "OK" "offered"
else else
pr_svrty_medium "not offered" pr_svrty_medium "not offered"
@ -2559,7 +2559,7 @@ sub_cipherlists() {
1) if [[ $sclient_success -eq 0 ]]; then 1) if [[ $sclient_success -eq 0 ]]; then
# High is good to offer # High is good to offer
pr_done_good "offered (OK)" pr_svrty_good "offered (OK)"
fileout "${jsonID}_$4" "OK" "offered" fileout "${jsonID}_$4" "OK" "offered"
else else
# FIXME: the rating could be readjusted if we knew the result of STRONG before # FIXME: the rating could be readjusted if we knew the result of STRONG before
@ -2582,7 +2582,7 @@ sub_cipherlists() {
fileout "${jsonID}_$4" "HIGH" "offered" fileout "${jsonID}_$4" "HIGH" "offered"
else else
# need a check for -eq 1 here # need a check for -eq 1 here
pr_done_good "not offered (OK)" pr_svrty_good "not offered (OK)"
fileout "${jsonID}_$4" "OK" "not offered" fileout "${jsonID}_$4" "OK" "not offered"
fi fi
;; ;;
@ -2591,7 +2591,7 @@ sub_cipherlists() {
pr_svrty_critical "offered (NOT ok)" pr_svrty_critical "offered (NOT ok)"
fileout "${jsonID}_$4" "CRITICAL" "offered" fileout "${jsonID}_$4" "CRITICAL" "offered"
else else
pr_done_best "not offered (OK)" pr_svrty_best "not offered (OK)"
fileout "${jsonID}_$4" "OK" "not offered" fileout "${jsonID}_$4" "OK" "not offered"
fi fi
;; ;;
@ -4248,7 +4248,7 @@ run_protocols() {
local using_sockets=true local using_sockets=true
local supported_no_ciph1="supported but couldn't detect a cipher (may need debugging)" local supported_no_ciph1="supported but couldn't detect a cipher (may need debugging)"
local supported_no_ciph2="supported but couldn't detect a cipher" local supported_no_ciph2="supported but couldn't detect a cipher"
local latest_supported="" # version.major and version.minor of highest version supported by the server. local latest_supported="" # version.major and version.minor of highest version supported by the server
local detected_version_string latest_supported_string local detected_version_string latest_supported_string
local key_share_extn_nr="$KEY_SHARE_EXTN_NR" local key_share_extn_nr="$KEY_SHARE_EXTN_NR"
local lines nr_ciphers_detected local lines nr_ciphers_detected
@ -4268,7 +4268,7 @@ run_protocols() {
if [[ -n "$STARTTLS" ]]; then if [[ -n "$STARTTLS" ]]; then
prln_underline "via sockets " prln_underline "via sockets "
else else
prln_underline "via sockets except SPDY+HTTP2 " prln_underline "via sockets except NPN+ALPN "
fi fi
fi fi
outln outln
@ -4288,12 +4288,12 @@ run_protocols() {
fileout "$jsonID" "WARN" "received a strange SSLv2 reply (rerun with DEBUG>=2)" fileout "$jsonID" "WARN" "received a strange SSLv2 reply (rerun with DEBUG>=2)"
;; ;;
1) # no sslv2 server hello returned, like in openlitespeed which returns HTTP! 1) # no sslv2 server hello returned, like in openlitespeed which returns HTTP!
prln_done_best "not offered (OK)" prln_svrty_best "not offered (OK)"
fileout "$jsonID" "OK" "not offered" fileout "$jsonID" "OK" "not offered"
add_tls_offered ssl2 no add_tls_offered ssl2 no
;; ;;
0) # reset 0) # reset
prln_done_best "not offered (OK)" prln_svrty_best "not offered (OK)"
fileout "$jsonID" "OK" "not offered" fileout "$jsonID" "OK" "not offered"
add_tls_offered ssl2 no add_tls_offered ssl2 no
;; ;;
@ -4326,7 +4326,7 @@ run_protocols() {
fileout "$jsonID" "CRITICAL" "offered" fileout "$jsonID" "CRITICAL" "offered"
add_tls_offered ssl2 yes add_tls_offered ssl2 yes
;; ;;
1) prln_done_best "not offered (OK)" 1) prln_svrty_best "not offered (OK)"
fileout "$jsonID" "OK" "not offered" fileout "$jsonID" "OK" "not offered"
add_tls_offered ssl2 no add_tls_offered ssl2 no
;; ;;
@ -4353,7 +4353,7 @@ run_protocols() {
latest_supported_string="SSLv3" latest_supported_string="SSLv3"
add_tls_offered ssl3 yes add_tls_offered ssl3 yes
;; ;;
1) prln_done_best "not offered (OK)" 1) prln_svrty_best "not offered (OK)"
fileout "$jsonID" "OK" "not offered" fileout "$jsonID" "OK" "not offered"
add_tls_offered ssl3 no add_tls_offered ssl3 no
;; ;;
@ -4535,7 +4535,7 @@ run_protocols() {
ret=$? ret=$?
fi fi
case $ret in case $ret in
0) prln_done_best "offered (OK)" 0) prln_svrty_best "offered (OK)"
fileout "$jsonID" "OK" "offered" fileout "$jsonID" "OK" "offered"
latest_supported="0303" latest_supported="0303"
latest_supported_string="TLSv1.2" latest_supported_string="TLSv1.2"
@ -4663,7 +4663,7 @@ run_protocols() {
fi fi
KEY_SHARE_EXTN_NR="$key_share_extn_nr" KEY_SHARE_EXTN_NR="$key_share_extn_nr"
if [[ -n "$drafts_offered" ]]; then if [[ -n "$drafts_offered" ]]; then
pr_done_best "offered (OK)"; outln ": $drafts_offered" pr_svrty_best "offered (OK)"; outln ": $drafts_offered"
fileout "$jsonID" "OK" "offered with $drafts_offered" fileout "$jsonID" "OK" "offered with $drafts_offered"
else else
pr_warning "Unexpected results"; outln "$debug_recomm" pr_warning "Unexpected results"; outln "$debug_recomm"
@ -4809,7 +4809,7 @@ pr_dh_quality() {
elif [[ "$bits" -le 1280 ]]; then elif [[ "$bits" -le 1280 ]]; then
pr_svrty_medium "$string" pr_svrty_medium "$string"
elif [[ "$bits" -ge 2048 ]]; then elif [[ "$bits" -ge 2048 ]]; then
pr_done_good "$string" pr_svrty_good "$string"
else else
out "$string" out "$string"
fi fi
@ -4830,7 +4830,7 @@ pr_ecdh_quality() {
elif [[ "$bits" -le 224 ]]; then elif [[ "$bits" -le 224 ]]; then
out "$string" out "$string"
elif [[ "$bits" -gt 224 ]]; then elif [[ "$bits" -gt 224 ]]; then
pr_done_good "$string" pr_svrty_good "$string"
else else
out "$string" out "$string"
fi fi
@ -4879,7 +4879,7 @@ pr_ecdh_curve_quality() {
# The return value is an indicator of the quality of the cipher in $1: # The return value is an indicator of the quality of the cipher in $1:
# 0 = $1 is empty # 0 = $1 is empty
# 1 = pr_svrty_critical, 2 = pr_svrty_high, 3 = pr_svrty_medium, 4 = pr_svrty_low # 1 = pr_svrty_critical, 2 = pr_svrty_high, 3 = pr_svrty_medium, 4 = pr_svrty_low
# 5 = neither good nor bad, 6 = pr_done_good, 7 = pr_done_best # 5 = neither good nor bad, 6 = pr_svrty_good, 7 = pr_svrty_best
# #
# Please note this section isn't particular spot on. It needs to be reconsidered/redone # Please note this section isn't particular spot on. It needs to be reconsidered/redone
pr_cipher_quality() { pr_cipher_quality() {
@ -4904,11 +4904,11 @@ pr_cipher_quality() {
;; ;;
AES256-GCM-SHA384|AES128-GCM-SHA256|AES256-CCM|AES128-CCM|ARIA256-GCM-SHA384|ARIA128-GCM-SHA256) AES256-GCM-SHA384|AES128-GCM-SHA256|AES256-CCM|AES128-CCM|ARIA256-GCM-SHA384|ARIA128-GCM-SHA256)
# RSA kx and e.g. GCM isn't certainly the best # RSA kx and e.g. GCM isn't certainly the best
pr_done_good "$text" pr_svrty_good "$text"
return 6 return 6
;; ;;
*GCM*|*CCM*|*CHACHA20*) *GCM*|*CCM*|*CHACHA20*)
pr_done_best "$text" pr_svrty_best "$text"
return 7 return 7
;; #best ones ;; #best ones
ECDHE*AES*|DHE*AES*SHA*|*CAMELLIA*SHA) ECDHE*AES*|DHE*AES*SHA*|*CAMELLIA*SHA)
@ -4942,13 +4942,13 @@ pr_cipher_quality() {
pr_svrty_low "$text" pr_svrty_low "$text"
return 4 return 4
else else
pr_done_good "$text" pr_svrty_good "$text"
# RSA kx and e.g. GCM isn't certainly the best # RSA kx and e.g. GCM isn't certainly the best
return 6 return 6
fi fi
;; ;;
*GCM*|*CCM*|*CHACHA20*) *GCM*|*CCM*|*CHACHA20*)
pr_done_best "$text" pr_svrty_best "$text"
return 7 return 7
;; ;;
*ECDHE*AES*CBC*|*DHE*AES*SHA*|*RSA*AES*SHA*|*CAMELLIA*SHA*) *ECDHE*AES*CBC*|*DHE*AES*SHA*|*RSA*AES*SHA*|*CAMELLIA*SHA*)
@ -5185,7 +5185,7 @@ run_server_preference() {
limitedsense=" (limited sense as client will pick)" limitedsense=" (limited sense as client will pick)"
fileout "$jsonID" "HIGH" "NOT cipher order configured" fileout "$jsonID" "HIGH" "NOT cipher order configured"
else else
pr_done_best "yes (OK)" pr_svrty_best "yes (OK)"
has_cipher_order=true has_cipher_order=true
limitedsense="" limitedsense=""
fileout "$jsonID" "OK" "sets cipher order" fileout "$jsonID" "OK" "sets cipher order"
@ -5220,15 +5220,15 @@ run_server_preference() {
[[ "$default_proto" == "TLSv1.0" ]] && default_proto="TLSv1" [[ "$default_proto" == "TLSv1.0" ]] && default_proto="TLSv1"
case "$default_proto" in case "$default_proto" in
*TLSv1.3) *TLSv1.3)
prln_done_best $default_proto prln_svrty_best $default_proto
fileout "$jsonID" "OK" "Default protocol TLS1.3" fileout "$jsonID" "OK" "Default protocol TLS1.3"
;; ;;
*TLSv1.2) *TLSv1.2)
prln_done_best $default_proto prln_svrty_best $default_proto
fileout "$jsonID" "OK" "Default protocol TLS1.2" fileout "$jsonID" "OK" "Default protocol TLS1.2"
;; ;;
*TLSv1.1) *TLSv1.1)
prln_done_good $default_proto prln_svrty_good $default_proto
fileout "$jsonID" "OK" "Default protocol TLS1.1" fileout "$jsonID" "OK" "Default protocol TLS1.1"
;; ;;
*TLSv1) *TLSv1)
@ -5787,7 +5787,7 @@ determine_trust() {
if [[ ${verify_retcode[i]} -eq 0 ]]; then if [[ ${verify_retcode[i]} -eq 0 ]]; then
trust[i]=true trust[i]=true
some_ok=true some_ok=true
debugme tm_done_good "Ok " debugme tm_svrty_good "Ok "
debugme tmln_out "${verify_retcode[i]}" debugme tmln_out "${verify_retcode[i]}"
else else
trust[i]=false trust[i]=false
@ -5801,7 +5801,7 @@ determine_trust() {
debugme tm_out " " debugme tm_out " "
if "$all_ok"; then if "$all_ok"; then
# all stores ok # all stores ok
pr_done_good "Ok "; pr_warning "$addtl_warning" pr_svrty_good "Ok "; pr_warning "$addtl_warning"
# we did to stdout the warning above already, so we could stay here with OK: # we did to stdout the warning above already, so we could stay here with OK:
fileout "${jsonID}${json_postfix}" "OK" "passed. $addtl_warning" fileout "${jsonID}${json_postfix}" "OK" "passed. $addtl_warning"
else else
@ -5842,7 +5842,7 @@ determine_trust() {
outln outln
# lf + green ones # lf + green ones
[[ "$DEBUG" -eq 0 ]] && tm_out "$spaces" [[ "$DEBUG" -eq 0 ]] && tm_out "$spaces"
pr_done_good "OK: $ok_was" pr_svrty_good "OK: $ok_was"
fi fi
fileout "${jsonID}${json_postfix}" "CRITICAL" "Some certificate trust checks failed -> $notok_was $addtl_warning, OK -> $ok_was" fileout "${jsonID}${json_postfix}" "CRITICAL" "Some certificate trust checks failed -> $notok_was $addtl_warning, OK -> $ok_was"
fi fi
@ -6235,26 +6235,27 @@ compare_server_name_to_cert()
# Check whether any of the DNS names in the certificate match the servername # Check whether any of the DNS names in the certificate match the servername
dns_sans="$(get_san_dns_from_cert "$cert")" dns_sans="$(get_san_dns_from_cert "$cert")"
for san in $dns_sans; do while read san; do
[[ $(toupper "$san") == "$servername" ]] && ret=1 && break [[ -n "$san" ]] && [[ $(toupper "$san") == "$servername" ]] && ret=1 && break
done done <<< "$dns_sans"
if [[ $ret -eq 0 ]]; then if [[ $ret -eq 0 ]]; then
# Check whether any of the IP addresses in the certificate match the servername # Check whether any of the IP addresses in the certificate match the servername
ip_sans=$($OPENSSL x509 -in "$cert" -noout -text 2>>$ERRFILE | grep -A2 "Subject Alternative Name" | \ ip_sans=$($OPENSSL x509 -in "$cert" -noout -text 2>>$ERRFILE | grep -A2 "Subject Alternative Name" | \
tr ',' '\n' | grep "IP Address:" | sed -e 's/IP Address://g' -e 's/ //g') tr ',' '\n' | grep "IP Address:" | sed -e 's/IP Address://g' -e 's/ //g')
for san in $ip_sans; do while read san; do
[[ "$san" == "$servername" ]] && ret=1 && break [[ -n "$san" ]] && [[ "$san" == "$servername" ]] && ret=1 && break
done done <<< "$ip_sans"
fi fi
# Check whether any of the DNS names in the certificate are wildcard names # Check whether any of the DNS names in the certificate are wildcard names
# that match the servername # that match the servername
if [[ $ret -eq 0 ]]; then if [[ $ret -eq 0 ]]; then
for san in $dns_sans; do while read san; do
[[ -n "$san" ]] || continue
wildcard_match "$servername" "$san" wildcard_match "$servername" "$san"
[[ $? -eq 0 ]] && ret=2 && break [[ $? -eq 0 ]] && ret=2 && break
done done <<< "$dns_sans"
fi fi
cn="$(get_cn_from_cert "$cert")" cn="$(get_cn_from_cert "$cert")"
@ -6313,7 +6314,7 @@ must_staple() {
if "$supported"; then if "$supported"; then
if "$provides_stapling"; then if "$provides_stapling"; then
prln_done_good "supported" prln_svrty_good "supported"
fileout "${jsonID}${json_postfix}" "OK" "supported" fileout "${jsonID}${json_postfix}" "OK" "supported"
else else
prln_svrty_high "requires OCSP stapling (NOT ok)" prln_svrty_high "requires OCSP stapling (NOT ok)"
@ -6469,15 +6470,15 @@ certificate_info() {
fileout "${jsonID}${json_postfix}" "INFO" "SHA224 with RSA" fileout "${jsonID}${json_postfix}" "INFO" "SHA224 with RSA"
;; ;;
sha256WithRSAEncryption) sha256WithRSAEncryption)
prln_done_good "SHA256 with RSA" prln_svrty_good "SHA256 with RSA"
fileout "${jsonID}${json_postfix}" "OK" "SHA256 with RSA" fileout "${jsonID}${json_postfix}" "OK" "SHA256 with RSA"
;; ;;
sha384WithRSAEncryption) sha384WithRSAEncryption)
prln_done_good "SHA384 with RSA" prln_svrty_good "SHA384 with RSA"
fileout "${jsonID}${json_postfix}" "OK" "SHA384 with RSA" fileout "${jsonID}${json_postfix}" "OK" "SHA384 with RSA"
;; ;;
sha512WithRSAEncryption) sha512WithRSAEncryption)
prln_done_good "SHA512 with RSA" prln_svrty_good "SHA512 with RSA"
fileout "${jsonID}${json_postfix}" "OK" "SHA512 with RSA" fileout "${jsonID}${json_postfix}" "OK" "SHA512 with RSA"
;; ;;
ecdsa-with-SHA1) ecdsa-with-SHA1)
@ -6489,15 +6490,15 @@ certificate_info() {
fileout "${jsonID}${json_postfix}" "INFO" "ECDSA with SHA224" fileout "${jsonID}${json_postfix}" "INFO" "ECDSA with SHA224"
;; ;;
ecdsa-with-SHA256) ecdsa-with-SHA256)
prln_done_good "ECDSA with SHA256" prln_svrty_good "ECDSA with SHA256"
fileout "${jsonID}${json_postfix}" "OK" "ECDSA with SHA256" fileout "${jsonID}${json_postfix}" "OK" "ECDSA with SHA256"
;; ;;
ecdsa-with-SHA384) ecdsa-with-SHA384)
prln_done_good "ECDSA with SHA384" prln_svrty_good "ECDSA with SHA384"
fileout "${jsonID}${json_postfix}" "OK" "ECDSA with SHA384" fileout "${jsonID}${json_postfix}" "OK" "ECDSA with SHA384"
;; ;;
ecdsa-with-SHA512) ecdsa-with-SHA512)
prln_done_good "ECDSA with SHA512" prln_svrty_good "ECDSA with SHA512"
fileout "${jsonID}${json_postfix}" "OK" "ECDSA with SHA512" fileout "${jsonID}${json_postfix}" "OK" "ECDSA with SHA512"
;; ;;
dsaWithSHA1) dsaWithSHA1)
@ -6509,7 +6510,7 @@ certificate_info() {
fileout "${jsonID}${json_postfix}" "INFO" "DSA with SHA224" fileout "${jsonID}${json_postfix}" "INFO" "DSA with SHA224"
;; ;;
dsa_with_SHA256) dsa_with_SHA256)
prln_done_good "DSA with SHA256" prln_svrty_good "DSA with SHA256"
fileout "${jsonID}${json_postfix}" "OK" "DSA with SHA256" fileout "${jsonID}${json_postfix}" "OK" "DSA with SHA256"
;; ;;
rsassaPss) rsassaPss)
@ -6524,15 +6525,15 @@ certificate_info() {
fileout "${jsonID}${json_postfix}" "INFO" "RSASSA-PSS with SHA224" fileout "${jsonID}${json_postfix}" "INFO" "RSASSA-PSS with SHA224"
;; ;;
sha256) sha256)
prln_done_good "RSASSA-PSS with SHA256" prln_svrty_good "RSASSA-PSS with SHA256"
fileout "${jsonID}${json_postfix}" "OK" "RSASSA-PSS with SHA256" fileout "${jsonID}${json_postfix}" "OK" "RSASSA-PSS with SHA256"
;; ;;
sha384) sha384)
prln_done_good "RSASSA-PSS with SHA384" prln_svrty_good "RSASSA-PSS with SHA384"
fileout "${jsonID}${json_postfix}" "OK" "RSASSA-PSS with SHA384" fileout "${jsonID}${json_postfix}" "OK" "RSASSA-PSS with SHA384"
;; ;;
sha512) sha512)
prln_done_good "RSASSA-PSS with SHA512" prln_svrty_good "RSASSA-PSS with SHA512"
fileout "${jsonID}${json_postfix}" "OK" "RSASSA-PSS with SHA512" fileout "${jsonID}${json_postfix}" "OK" "RSASSA-PSS with SHA512"
;; ;;
*) *)
@ -6594,7 +6595,7 @@ certificate_info() {
out "$cert_keysize" out "$cert_keysize"
fileout "${jsonID}${json_postfix}" "INFO" "$cert_keysize EC bits" fileout "${jsonID}${json_postfix}" "INFO" "$cert_keysize EC bits"
elif [[ "$cert_keysize" -le 533 ]]; then elif [[ "$cert_keysize" -le 533 ]]; then
pr_done_good "$cert_keysize" pr_svrty_good "$cert_keysize"
fileout "${jsonID}${json_postfix}" "OK" "$cert_keysize EC bits" fileout "${jsonID}${json_postfix}" "OK" "$cert_keysize EC bits"
else else
out "keysize: $cert_keysize (not expected, FIXME)" out "keysize: $cert_keysize (not expected, FIXME)"
@ -6619,7 +6620,7 @@ certificate_info() {
outln "$cert_keysize bits" outln "$cert_keysize bits"
fileout "${jsonID}${json_postfix}" "INFO" "$cert_keysize bits" fileout "${jsonID}${json_postfix}" "INFO" "$cert_keysize bits"
elif [[ "$cert_keysize" -le 4096 ]]; then elif [[ "$cert_keysize" -le 4096 ]]; then
pr_done_good "$cert_keysize" pr_svrty_good "$cert_keysize"
fileout "${jsonID}${json_postfix}" "OK" "$cert_keysize bits" fileout "${jsonID}${json_postfix}" "OK" "$cert_keysize bits"
outln " bits" outln " bits"
else else
@ -6876,7 +6877,7 @@ certificate_info() {
! "$has_dns_sans" && out " -- CN only match is deprecated" ! "$has_dns_sans" && out " -- CN only match is deprecated"
fi fi
else else
pr_done_good "$trustfinding" pr_svrty_good "$trustfinding"
trust_sni_finding="OK" trust_sni_finding="OK"
fi fi
@ -7002,7 +7003,7 @@ certificate_info() {
secs2warn=$((24 * 60 * 60 * days2warn1)) # high threshold secs2warn=$((24 * 60 * 60 * days2warn1)) # high threshold
expire=$($OPENSSL x509 -in $HOSTCERT -checkend $secs2warn 2>>$ERRFILE) expire=$($OPENSSL x509 -in $HOSTCERT -checkend $secs2warn 2>>$ERRFILE)
if grep -qw not <<< "$expire"; then if grep -qw not <<< "$expire"; then
pr_done_good "$days2expire >= $days2warn1 days" pr_svrty_good "$days2expire >= $days2warn1 days"
expfinding+="$days2expire >= $days2warn1 days" expfinding+="$days2expire >= $days2warn1 days"
else else
pr_svrty_medium "expires < $days2warn1 days ($days2expire)" pr_svrty_medium "expires < $days2warn1 days ($days2expire)"
@ -7074,7 +7075,7 @@ certificate_info() {
fi fi
else else
if grep -a "OCSP Response Status" <<<"$ocsp_response_status" | grep -q successful; then if grep -a "OCSP Response Status" <<<"$ocsp_response_status" | grep -q successful; then
pr_done_good "offered" pr_svrty_good "offered"
fileout "${jsonID}${json_postfix}" "OK" "offered" fileout "${jsonID}${json_postfix}" "OK" "offered"
provides_stapling=true provides_stapling=true
else else
@ -7105,7 +7106,7 @@ certificate_info() {
caa_node=${caa_node#*.} caa_node=${caa_node#*.}
done done
if [[ -n "$caa" ]]; then if [[ -n "$caa" ]]; then
pr_done_good "available"; out " - please check for match with \"Issuer\" above" pr_svrty_good "available"; out " - please check for match with \"Issuer\" above"
if [[ $(count_lines "$caa") -eq 1 ]]; then if [[ $(count_lines "$caa") -eq 1 ]]; then
out ": " out ": "
else else
@ -7131,7 +7132,7 @@ certificate_info() {
out "$indent"; pr_bold " Certificate Transparency "; out "$indent"; pr_bold " Certificate Transparency ";
jsonID="certificate_transparency" jsonID="certificate_transparency"
if [[ "$ct" =~ extension ]]; then if [[ "$ct" =~ extension ]]; then
pr_done_good "yes"; outln " ($ct)" pr_svrty_good "yes"; outln " ($ct)"
fileout "${jsonID}${json_postfix}" "OK" "yes ($ct)" fileout "${jsonID}${json_postfix}" "OK" "yes ($ct)"
else else
outln "$ct" outln "$ct"
@ -7250,9 +7251,9 @@ run_server_defaults() {
if [[ "$sans_nosni" == "$sans_sni" ]]; then if [[ "$sans_nosni" == "$sans_sni" ]]; then
success[n]=0 success[n]=0
else else
for san in $sans_nosni; do while read san; do
[[ " $sans_sni " =~ " $san " ]] && success[n]=0 && break [[ -n "$san" ]] && [[ " $sans_sni " =~ " $san " ]] && success[n]=0 && break
done done <<< "$sans_nosni"
fi fi
fi fi
fi fi
@ -7457,7 +7458,7 @@ get_session_ticket_lifetime_from_serverhello() {
get_san_dns_from_cert() { get_san_dns_from_cert() {
echo "$($OPENSSL x509 -in "$1" -noout -text 2>>$ERRFILE | \ echo "$($OPENSSL x509 -in "$1" -noout -text 2>>$ERRFILE | \
grep -A2 "Subject Alternative Name" | tr ',' '\n' | grep "DNS:" | \ grep -A2 "Subject Alternative Name" | tr ',' '\n' | grep "DNS:" | \
sed -e 's/DNS://g' -e 's/ //g' | tr '\n' ' ')" sed -e 's/DNS://g' -e 's/ //g')"
} }
@ -7571,7 +7572,7 @@ run_pfs() {
outln outln
pfs_offered=true pfs_offered=true
pfs_ciphers="" pfs_ciphers=""
pr_done_good " PFS is offered (OK)" pr_svrty_good " PFS is offered (OK)"
fileout "$jsonID" "OK" "offered" fileout "$jsonID" "OK" "offered"
if "$WIDE"; then if "$WIDE"; then
outln ", ciphers follow (client/browser support is important here) \n" outln ", ciphers follow (client/browser support is important here) \n"
@ -7871,7 +7872,7 @@ run_pfs() {
# good start to read: http://en.wikipedia.org/wiki/Transport_Layer_Security#Attacks_against_TLS.2FSSL # good start to read: http://en.wikipedia.org/wiki/Transport_Layer_Security#Attacks_against_TLS.2FSSL
spdy_pre(){ npn_pre(){
if [[ -n "$PROXY" ]]; then if [[ -n "$PROXY" ]]; then
[[ -n "$1" ]] && pr_warning "$1" [[ -n "$1" ]] && pr_warning "$1"
pr_warning "not tested as proxies do not support proxying it" pr_warning "not tested as proxies do not support proxying it"
@ -7879,14 +7880,14 @@ spdy_pre(){
return 1 return 1
fi fi
if ! "$HAS_SPDY"; then if ! "$HAS_SPDY"; then
pr_local_problem "$OPENSSL doesn't support SPDY/NPN"; pr_local_problem "$OPENSSL doesn't support NPN/SPDY";
fileout "SPDY-NPN" "WARN" "not tested $OPENSSL doesn't support SPDY/NPN" fileout "NPN" "WARN" "not tested $OPENSSL doesn't support NPN/SPDY"
return 7 return 7
fi fi
return 0 return 0
} }
http2_pre(){ alpn_pre(){
if [[ -n "$PROXY" ]]; then if [[ -n "$PROXY" ]]; then
[[ -n "$1" ]] && pr_warning " $1 " [[ -n "$1" ]] && pr_warning " $1 "
pr_warning "not tested as proxies do not support proxying it" pr_warning "not tested as proxies do not support proxying it"
@ -7894,21 +7895,25 @@ http2_pre(){
return 1 return 1
fi fi
if ! "$HAS_ALPN" && "$SSL_NATIVE"; then if ! "$HAS_ALPN" && "$SSL_NATIVE"; then
prln_local_problem "$OPENSSL doesn't support HTTP2/ALPN"; prln_local_problem "$OPENSSL doesn't support ALPN/HTTP2";
fileout "HTTP2-ALPN" "WARN" "HTTP/2 was not tested as $OPENSSL does not support it" fileout "ALPN" "WARN" "HTTP/2 was not tested as $OPENSSL does not support it"
return 7 return 7
fi fi
return 0 return 0
} }
run_spdy() { # modern browsers do not support it anymore but we shoud still test it at least for fingerprinting the server side
# Thus we don't label any support for NPN as good.
# FAST mode skips this test
run_npn() {
local tmpstr local tmpstr
local -i ret=0 local -i ret=0
local jsonID="SPDY-NPN" local jsonID="NPN"
[[ -n "$STARTTLS" ]] && return 0 [[ -n "$STARTTLS" ]] && return 0
pr_bold " SPDY/NPN " "$FAST" && return 0
if ! spdy_pre; then pr_bold " NPN/SPDY "
if ! npn_pre; then
outln outln
return 0 return 0
fi fi
@ -7931,7 +7936,6 @@ run_spdy() {
ret=10 ret=10
fi fi
fi fi
#outln
# btw: nmap can do that too http://nmap.org/nsedoc/scripts/tls-nextprotoneg.html # 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 # nmap --script=tls-nextprotoneg #NODE -p $PORT is your friend if your openssl doesn't want to test this
tmpfile_handle $FUNCNAME.txt tmpfile_handle $FUNCNAME.txt
@ -7939,16 +7943,16 @@ run_spdy() {
} }
run_http2() { run_alpn() {
local tmpstr alpn_extn len local tmpstr alpn_extn len
local -i ret=0 local -i ret=0
local had_alpn_proto=false local has_alpn_proto=false
local alpn_finding="" local alpn_finding=""
local jsonID="HTTP2-ALPN" local jsonID="ALPN"
[[ -n "$STARTTLS" ]] && return 0 [[ -n "$STARTTLS" ]] && return 0
pr_bold " HTTP2/ALPN " pr_bold " ALPN/HTTP2 "
if ! http2_pre; then if ! alpn_pre; then
outln outln
return 0 return 0
fi fi
@ -7969,23 +7973,26 @@ run_http2() {
echo "" > $TMPFILE echo "" > $TMPFILE
fi fi
fi fi
#tmpstr=$(grep -a '^ALPN protocol' $TMPFILE | sed 's/ALPN protocol.*: //')
#tmpstr=$(awk '/^ALPN protocol*:/ { print $2 }' $TMPFILE)
tmpstr=$(awk -F':' '/^ALPN protocol*:/ { print $2 }' $TMPFILE) tmpstr=$(awk -F':' '/^ALPN protocol*:/ { print $2 }' $TMPFILE)
if [[ "$tmpstr" == *"$proto" ]]; then if [[ "$tmpstr" == *"$proto" ]]; then
if ! $had_alpn_proto; then if ! $has_alpn_proto; then
out "$proto" has_alpn_proto=true
alpn_finding+="$proto" else
had_alpn_proto=true out ", "
else fi
out ", $proto" # only h2 is what browser need to use HTTP/2.0 and brings a security benefit
alpn_finding+=", $proto" if [[ "$proto" == "h2" ]]; then
fi pr_svrty_good "$proto"
fileout "$jsonID" "OK" "$alpn_finding"
else
out "$proto"
alpn_finding+="$proto"
fi
fi fi
done done
if $had_alpn_proto; then if $has_alpn_proto; then
outln " (offered)" outln " (offered)"
fileout "$jsonID" "INFO" "offered with protocols $alpn_finding" fileout "$jsonID" "INFO" "$alpn_finding"
ret=0 ret=0
else else
outln "not offered" outln "not offered"
@ -11531,7 +11538,7 @@ run_heartbleed(){
[[ -z "$TLS_EXTENSIONS" ]] && determine_tls_extensions [[ -z "$TLS_EXTENSIONS" ]] && determine_tls_extensions
if [[ ! "${TLS_EXTENSIONS}" =~ heartbeat ]]; then if [[ ! "${TLS_EXTENSIONS}" =~ heartbeat ]]; then
pr_done_best "not vulnerable (OK)" pr_svrty_best "not vulnerable (OK)"
outln ", no heartbeat extension" outln ", no heartbeat extension"
fileout "$jsonID" "OK" "not vulnerable, no heartbeat extension" "$cve" "$cwe" fileout "$jsonID" "OK" "not vulnerable, no heartbeat extension" "$cve" "$cwe"
return 0 return 0
@ -11564,7 +11571,7 @@ run_heartbleed(){
sockread_serverhello 16384 $HEARTBLEED_MAX_WAITSOCK sockread_serverhello 16384 $HEARTBLEED_MAX_WAITSOCK
if [[ $? -eq 3 ]]; then if [[ $? -eq 3 ]]; then
append=", timed out" append=", timed out"
pr_done_best "not vulnerable (OK)"; out "$append" pr_svrty_best "not vulnerable (OK)"; out "$append"
fileout "$jsonID" "OK" "not vulnerable $append" "$cve" "$cwe" fileout "$jsonID" "OK" "not vulnerable $append" "$cve" "$cwe"
ret=0 ret=0
else else
@ -11589,7 +11596,7 @@ run_heartbleed(){
# check possibility of weird vsftpd reply, see #426, despite "1803" seems very unlikely... # check possibility of weird vsftpd reply, see #426, despite "1803" seems very unlikely...
if grep -q '500 OOPS' "$SOCK_REPLY_FILE" ; then if grep -q '500 OOPS' "$SOCK_REPLY_FILE" ; then
append=", successful weeded out vsftpd false positive" append=", successful weeded out vsftpd false positive"
pr_done_best "not vulnerable (OK)"; out "$append" pr_svrty_best "not vulnerable (OK)"; out "$append"
fileout "$jsonID" "OK" "not vulnerable $append" "$cve" "$cwe" fileout "$jsonID" "OK" "not vulnerable $append" "$cve" "$cwe"
ret=0 ret=0
else else
@ -11605,7 +11612,7 @@ run_heartbleed(){
ret=1 ret=1
fi fi
else else
pr_done_best "not vulnerable (OK)" pr_svrty_best "not vulnerable (OK)"
fileout "$jsonID" "OK" "not vulnerable $cve" "$cwe" fileout "$jsonID" "OK" "not vulnerable $cve" "$cwe"
ret=0 ret=0
fi fi
@ -11618,7 +11625,7 @@ run_heartbleed(){
# helper function # helper function
ok_ids(){ ok_ids(){
prln_done_best "\n ok -- something resetted our ccs packets" prln_svrty_best "\n ok -- something resetted our ccs packets"
return 0 return 0
} }
@ -11740,7 +11747,7 @@ run_ccs_injection(){
# 28: Handshake failure # 28: Handshake failure
if [[ -z "${tls_hello_ascii:0:12}" ]]; then if [[ -z "${tls_hello_ascii:0:12}" ]]; then
# empty reply # empty reply
pr_done_best "not vulnerable (OK)" pr_svrty_best "not vulnerable (OK)"
if [[ $retval -eq 3 ]]; then if [[ $retval -eq 3 ]]; then
fileout "$jsonID" "OK" "not vulnerable (timed out)" "$cve" "$cwe" fileout "$jsonID" "OK" "not vulnerable (timed out)" "$cve" "$cwe"
else else
@ -11763,7 +11770,7 @@ run_ccs_injection(){
elif [[ $STARTTLS_PROTOCOL == "mysql" ]] && [[ "${tls_hello_ascii:14:12}" == "233038533031" ]]; then elif [[ $STARTTLS_PROTOCOL == "mysql" ]] && [[ "${tls_hello_ascii:14:12}" == "233038533031" ]]; then
# MySQL community edition (yaSSL) returns a MySQL error instead of a TLS Alert # MySQL community edition (yaSSL) returns a MySQL error instead of a TLS Alert
# Error: #08S01 Bad handshake # Error: #08S01 Bad handshake
pr_done_best "not vulnerable (OK)" pr_svrty_best "not vulnerable (OK)"
out ", looks like MySQL community edition (yaSSL)" out ", looks like MySQL community edition (yaSSL)"
fileout "$jsonID" "OK" "not vulnerable (MySQL community edition (yaSSL) detected)" "$cve" "$cwe" fileout "$jsonID" "OK" "not vulnerable (MySQL community edition (yaSSL) detected)" "$cve" "$cwe"
elif [[ "$byte6" == [0-9a-f][0-9a-f] ]] && [[ "${tls_hello_ascii:2:2}" != "03" ]]; then elif [[ "$byte6" == [0-9a-f][0-9a-f] ]] && [[ "${tls_hello_ascii:2:2}" != "03" ]]; then
@ -11829,7 +11836,7 @@ run_ticketbleed() {
# highly unlikely that it is NOT supported. We may loose time here but it's more solid # highly unlikely that it is NOT supported. We may loose time here but it's more solid
[[ -z "$TLS_EXTENSIONS" ]] && determine_tls_extensions [[ -z "$TLS_EXTENSIONS" ]] && determine_tls_extensions
if [[ ! "${TLS_EXTENSIONS}" =~ "session ticket" ]]; then if [[ ! "${TLS_EXTENSIONS}" =~ "session ticket" ]]; then
pr_done_best "not vulnerable (OK)" pr_svrty_best "not vulnerable (OK)"
outln ", no session ticket extension" outln ", no session ticket extension"
fileout "$jsonID" "OK" "no session ticket extension" "$cve" "$cwe" fileout "$jsonID" "OK" "no session ticket extension" "$cve" "$cwe"
return 0 return 0
@ -11856,7 +11863,7 @@ run_ticketbleed() {
session_tckt_tls="$(get_session_ticket_tls)" session_tckt_tls="$(get_session_ticket_tls)"
if [[ "$session_tckt_tls" == "," ]]; then if [[ "$session_tckt_tls" == "," ]]; then
pr_done_best "not vulnerable (OK)" pr_svrty_best "not vulnerable (OK)"
outln ", no session tickets" outln ", no session tickets"
fileout "$jsonID" "OK" "not vulnerable" "$cve" "$cwe" fileout "$jsonID" "OK" "not vulnerable" "$cve" "$cwe"
debugme echo " session ticket TLS \"$session_tckt_tls\"" debugme echo " session ticket TLS \"$session_tckt_tls\""
@ -11980,11 +11987,11 @@ run_ticketbleed() {
if [[ "${tls_hello_ascii:0:2}" == "15" ]]; then if [[ "${tls_hello_ascii:0:2}" == "15" ]]; then
debugme echo -n "TLS Alert ${tls_hello_ascii:10:4} (TLS version: ${tls_hello_ascii:2:4}) -- " debugme echo -n "TLS Alert ${tls_hello_ascii:10:4} (TLS version: ${tls_hello_ascii:2:4}) -- "
pr_done_best "not vulnerable (OK)" pr_svrty_best "not vulnerable (OK)"
fileout "$jsonID" "OK" "not vulnerable" "$cve" "$cwe" fileout "$jsonID" "OK" "not vulnerable" "$cve" "$cwe"
break break
elif [[ -z "${tls_hello_ascii:0:2}" ]]; then elif [[ -z "${tls_hello_ascii:0:2}" ]]; then
pr_done_best "not vulnerable (OK)" pr_svrty_best "not vulnerable (OK)"
out ", reply empty" out ", reply empty"
fileout "$jsonID" "OK" "not vulnerable" "$cve" "$cwe" fileout "$jsonID" "OK" "not vulnerable" "$cve" "$cwe"
break break
@ -12037,7 +12044,7 @@ run_ticketbleed() {
pr_svrty_critical "VULNERABLE (NOT ok)" pr_svrty_critical "VULNERABLE (NOT ok)"
fileout "$jsonID" "CRITICAL" "VULNERABLE" "$cve" "$cwe" "$hint" fileout "$jsonID" "CRITICAL" "VULNERABLE" "$cve" "$cwe" "$hint"
else else
pr_done_best "not vulnerable (OK)" pr_svrty_best "not vulnerable (OK)"
out ", memory fragments do not differ" out ", memory fragments do not differ"
fileout "$jsonID" "OK" "not vulnerable, session IDs were returned but memory fragments do not differ" "$cve" "$cwe" fileout "$jsonID" "OK" "not vulnerable, session IDs were returned but memory fragments do not differ" "$cve" "$cwe"
fi fi
@ -12083,7 +12090,7 @@ run_renego() {
0) prln_svrty_critical "VULNERABLE (NOT ok)" 0) prln_svrty_critical "VULNERABLE (NOT ok)"
fileout "$jsonID" "CRITICAL" "VULNERABLE" "$cve" "$cwe" "$hint" fileout "$jsonID" "CRITICAL" "VULNERABLE" "$cve" "$cwe" "$hint"
;; ;;
1) prln_done_best "not vulnerable (OK)" 1) prln_svrty_best "not vulnerable (OK)"
fileout "$jsonID" "OK" "not vulnerable" "$cve" "$cwe" fileout "$jsonID" "OK" "not vulnerable" "$cve" "$cwe"
;; ;;
*) prln_warning "FIXME (bug): $sec_renego" *) prln_warning "FIXME (bug): $sec_renego"
@ -12128,7 +12135,7 @@ run_renego() {
echo R | $OPENSSL s_client $(s_client_options "$proto $BUGS $legacycmd $STARTTLS -msg -connect $NODEIP:$PORT $SNI $PROXY") >$TMPFILE 2>>$ERRFILE & echo R | $OPENSSL s_client $(s_client_options "$proto $BUGS $legacycmd $STARTTLS -msg -connect $NODEIP:$PORT $SNI $PROXY") >$TMPFILE 2>>$ERRFILE &
wait_kill $! $HEADER_MAXSLEEP wait_kill $! $HEADER_MAXSLEEP
if [[ $? -eq 3 ]]; then if [[ $? -eq 3 ]]; then
pr_done_good "likely not vulnerable (OK)"; outln ", timed out" # it hung pr_svrty_good "likely not vulnerable (OK)"; outln ", timed out" # it hung
fileout "$jsonID" "OK" "likely not vulnerable (timed out)" "$cve" "$cwe" fileout "$jsonID" "OK" "likely not vulnerable (timed out)" "$cve" "$cwe"
sec_client_renego=1 sec_client_renego=1
else else
@ -12145,7 +12152,7 @@ run_renego() {
fi fi
;; ;;
1) 1)
prln_done_good "not vulnerable (OK)" prln_svrty_good "not vulnerable (OK)"
fileout "$jsonID" "OK" "not vulnerable" "$cve" "$cwe" fileout "$jsonID" "OK" "not vulnerable" "$cve" "$cwe"
;; ;;
*) *)
@ -12207,7 +12214,7 @@ run_crime() {
fileout "CRIME_TLS" "WARN" "Check failed, couldn't connect" "$cve" "$cwe" fileout "CRIME_TLS" "WARN" "Check failed, couldn't connect" "$cve" "$cwe"
ret=7 ret=7
elif grep -a Compression $TMPFILE | grep -aq NONE >/dev/null; then elif grep -a Compression $TMPFILE | grep -aq NONE >/dev/null; then
pr_done_good "not vulnerable (OK)" pr_svrty_good "not vulnerable (OK)"
if [[ $SERVICE != "HTTP" ]] && ! "$CLIENT_AUTH"; then if [[ $SERVICE != "HTTP" ]] && ! "$CLIENT_AUTH"; then
out " (not using HTTP anyway)" out " (not using HTTP anyway)"
fileout "CRIME_TLS" "OK" "not vulnerable (not using HTTP anyway)" "$cve" "$cwe" fileout "CRIME_TLS" "OK" "not vulnerable (not using HTTP anyway)" "$cve" "$cwe"
@ -12252,7 +12259,7 @@ run_crime() {
# STR=$(grep Compression $TMPFILE ) # STR=$(grep Compression $TMPFILE )
# if echo $STR | grep -q NONE >/dev/null; then # if echo $STR | grep -q NONE >/dev/null; then
# pr_done_best "not vulnerable (OK)" # pr_svrty_best "not vulnerable (OK)"
# ret=$((ret + 0)) # ret=$((ret + 0))
# else # else
# pr_svrty_critical "VULNERABLE (NOT ok)" # pr_svrty_critical "VULNERABLE (NOT ok)"
@ -12319,7 +12326,7 @@ run_breach() {
prln_warning ") " prln_warning ") "
ret=3 ret=3
elif [[ -z $result ]]; then elif [[ -z $result ]]; then
pr_done_best "no HTTP compression (OK) " pr_svrty_best "no HTTP compression (OK) "
outln "$disclaimer" outln "$disclaimer"
fileout "$jsonID" "OK" "no HTTP compression $disclaimer" "$cve" "$cwe" fileout "$jsonID" "OK" "no HTTP compression $disclaimer" "$cve" "$cwe"
ret=0 ret=0
@ -12387,7 +12394,7 @@ run_sweet32() {
pr_svrty_low "VULNERABLE"; out ", uses 64 bit block ciphers" pr_svrty_low "VULNERABLE"; out ", uses 64 bit block ciphers"
fileout "SWEET32" "LOW" "uses 64 bit block ciphers" "$cve" "$cwe" "$hint" fileout "SWEET32" "LOW" "uses 64 bit block ciphers" "$cve" "$cwe" "$hint"
else else
pr_done_best "not vulnerable (OK)"; pr_svrty_best "not vulnerable (OK)";
if "$using_sockets"; then if "$using_sockets"; then
fileout "SWEET32" "OK" "not vulnerable" "$cve" "$cwe" fileout "SWEET32" "OK" "not vulnerable" "$cve" "$cwe"
else else
@ -12446,7 +12453,7 @@ run_ssl_poodle() {
fileout "$jsonID" "HIGH" "VULNERABLE, uses SSLv3+CBC" "$cve" "$cwe" "$hint" fileout "$jsonID" "HIGH" "VULNERABLE, uses SSLv3+CBC" "$cve" "$cwe" "$hint"
else else
POODLE=1 POODLE=1
pr_done_best "not vulnerable (OK)"; pr_svrty_best "not vulnerable (OK)";
if "$using_sockets"; then if "$using_sockets"; then
fileout "$jsonID" "OK" "not vulnerable" "$cve" "$cwe" fileout "$jsonID" "OK" "not vulnerable" "$cve" "$cwe"
else else
@ -12529,7 +12536,7 @@ run_tls_fallback_scsv() {
fileout "$jsonID" "HIGH" "only SSLv3 supported" fileout "$jsonID" "HIGH" "only SSLv3 supported"
return 7 return 7
;; ;;
*) pr_done_good "No fallback possible, TLS 1.3 is the only protocol (OK)" *) prln_svrty_good "No fallback possible, TLS 1.3 is the only protocol (OK)"
fileout "$jsonID" "OK" "only TLS 1.3 supported" fileout "$jsonID" "OK" "only TLS 1.3 supported"
return 7 return 7
esac esac
@ -12551,11 +12558,12 @@ run_tls_fallback_scsv() {
if [[ -z "$low_proto" ]]; then if [[ -z "$low_proto" ]]; then
case "$high_proto" in case "$high_proto" in
"tls1_2") "tls1_2")
pr_done_good "No fallback possible, no protocol below $high_proto_str offered (OK)" prln_svrty_good "No fallback possible, no protocol below $high_proto_str offered (OK)"
;; ;;
*) out "No fallback possible, no protocol below $high_proto_str offered (OK)" *) outln "No fallback possible, no protocol below $high_proto_str offered (OK)"
;; ;;
esac esac
fileout "$jsonID" "OK" "no protocol below $high_proto_str offered"
return 7 return 7
fi fi
case "$low_proto" in case "$low_proto" in
@ -12588,11 +12596,11 @@ run_tls_fallback_scsv() {
ret=1 ret=1
fi fi
elif grep -qa "alert inappropriate fallback" "$TMPFILE"; then elif grep -qa "alert inappropriate fallback" "$TMPFILE"; then
pr_done_good "Downgrade attack prevention supported (OK)" pr_svrty_good "Downgrade attack prevention supported (OK)"
fileout "$jsonID" "OK" "supported" fileout "$jsonID" "OK" "supported"
ret=0 ret=0
elif grep -qa "alert handshake failure" "$TMPFILE"; then elif grep -qa "alert handshake failure" "$TMPFILE"; then
pr_done_good "Probably OK. " pr_svrty_good "Probably OK. "
fileout "$jsonID" "OK" "Probably oK" fileout "$jsonID" "OK" "Probably oK"
# see RFC 7507, https://github.com/drwetter/testssl.sh/issues/121 # see RFC 7507, https://github.com/drwetter/testssl.sh/issues/121
# other case reported by Nicolas was F5 and at costumer of mine: the same # other case reported by Nicolas was F5 and at costumer of mine: the same
@ -12689,7 +12697,7 @@ run_freak() {
pr_svrty_critical "VULNERABLE (NOT ok)"; out ", uses EXPORT RSA ciphers" pr_svrty_critical "VULNERABLE (NOT ok)"; out ", uses EXPORT RSA ciphers"
fileout "$jsonID" "CRITICAL" "VULNERABLE, uses EXPORT RSA ciphers" "$cve" "$cwe" "$hint" fileout "$jsonID" "CRITICAL" "VULNERABLE, uses EXPORT RSA ciphers" "$cve" "$cwe" "$hint"
else else
pr_done_best "not vulnerable (OK)"; out "$addtl_warning" pr_svrty_best "not vulnerable (OK)"; out "$addtl_warning"
fileout "$jsonID" "OK" "not vulnerable $addtl_warning" "$cve" "$cwe" fileout "$jsonID" "OK" "not vulnerable $addtl_warning" "$cve" "$cwe"
fi fi
outln outln
@ -12908,17 +12916,17 @@ run_logjam() {
out "${spaces}but no DH EXPORT ciphers${addtl_warning}" out "${spaces}but no DH EXPORT ciphers${addtl_warning}"
fileout "$jsonID" "OK" "not vulnerable, no DH EXPORT ciphers,$addtl_warning" "$cve" "$cwe" fileout "$jsonID" "OK" "not vulnerable, no DH EXPORT ciphers,$addtl_warning" "$cve" "$cwe"
elif [[ $ret -eq 3 ]]; then elif [[ $ret -eq 3 ]]; then
pr_done_good "not vulnerable (OK):"; out " no DH EXPORT ciphers${addtl_warning}" pr_svrty_good "not vulnerable (OK):"; out " no DH EXPORT ciphers${addtl_warning}"
fileout "$jsonID" "OK" "not vulnerable, no DH EXPORT ciphers,$addtl_warning" "$cve" "$cwe" fileout "$jsonID" "OK" "not vulnerable, no DH EXPORT ciphers,$addtl_warning" "$cve" "$cwe"
out ", no DH key detected" out ", no DH key detected"
fileout "$jsonID2" "OK" "no DH key detected" fileout "$jsonID2" "OK" "no DH key detected"
elif [[ $ret -eq 0 ]]; then elif [[ $ret -eq 0 ]]; then
pr_done_good "not vulnerable (OK):"; out " no DH EXPORT ciphers${addtl_warning}" pr_svrty_good "not vulnerable (OK):"; out " no DH EXPORT ciphers${addtl_warning}"
fileout "$jsonID" "OK" "not vulnerable, no DH EXPORT ciphers,$addtl_warning" "$cve" "$cwe" fileout "$jsonID" "OK" "not vulnerable, no DH EXPORT ciphers,$addtl_warning" "$cve" "$cwe"
out ", no common primes detected" out ", no common primes detected"
fileout "$jsonID2" "OK" "no common primes detected" fileout "$jsonID2" "OK" "no common primes detected"
elif [[ $ret -eq 7 ]]; then elif [[ $ret -eq 7 ]]; then
pr_done_good "partly not vulnerable:"; out " no DH EXPORT ciphers${addtl_warning}" pr_svrty_good "partly not vulnerable:"; out " no DH EXPORT ciphers${addtl_warning}"
fileout "$jsonID" "OK" "not vulnerable, no DH EXPORT ciphers,$addtl_warning" "$cve" "$cwe" fileout "$jsonID" "OK" "not vulnerable, no DH EXPORT ciphers,$addtl_warning" "$cve" "$cwe"
fi fi
fi fi
@ -12984,7 +12992,7 @@ run_drown() {
fi fi
ret=1 ret=1
;; ;;
*) prln_done_best "not vulnerable on this host and port (OK)" *) prln_svrty_best "not vulnerable on this host and port (OK)"
fileout "DROWN" "OK" "not vulnerable to DROWN on this host and port" "$cve" "$cwe" fileout "DROWN" "OK" "not vulnerable to DROWN on this host and port" "$cve" "$cwe"
if [[ -n "$cert_fingerprint_sha2" ]]; then if [[ -n "$cert_fingerprint_sha2" ]]; then
outln "$spaces make sure you don't use this certificate elsewhere with SSLv2 enabled services" outln "$spaces make sure you don't use this certificate elsewhere with SSLv2 enabled services"
@ -13115,10 +13123,10 @@ run_beast(){
if [[ $sclient_success -ne 0 ]]; then # protocol supported? if [[ $sclient_success -ne 0 ]]; then # protocol supported?
if "$continued"; then # second round: we hit TLS1 if "$continued"; then # second round: we hit TLS1
if "$HAS_SSL3" || "$using_sockets"; then if "$HAS_SSL3" || "$using_sockets"; then
prln_done_good "no SSL3 or TLS1 (OK)" prln_svrty_good "no SSL3 or TLS1 (OK)"
fileout "$jsonID" "OK" "not vulnerable, no SSL3 or TLS1" "$cve" "$cwe" fileout "$jsonID" "OK" "not vulnerable, no SSL3 or TLS1" "$cve" "$cwe"
else else
prln_done_good "no TLS1 (OK)" prln_svrty_good "no TLS1 (OK)"
fileout "$jsonID" "OK" "not vulnerable, no TLS1" "$cve" "$cwe" fileout "$jsonID" "OK" "not vulnerable, no TLS1" "$cve" "$cwe"
fi fi
return 0 return 0
@ -13246,12 +13254,12 @@ run_beast(){
first=false first=false
else else
[[ $proto == "tls1" ]] && ! $first && echo -n "$spaces " [[ $proto == "tls1" ]] && ! $first && echo -n "$spaces "
prln_done_good "no CBC ciphers for $(toupper $proto) (OK)" prln_svrty_good "no CBC ciphers for $(toupper $proto) (OK)"
first=false first=false
fi fi
else else
if ! "$vuln_beast" ; then if ! "$vuln_beast" ; then
prln_done_good "no CBC ciphers for $(toupper $proto) (OK)" prln_svrty_good "no CBC ciphers for $(toupper $proto) (OK)"
fileout "${jsonID}_CBC_$(toupper $proto)" "OK" "No CBC ciphers for $(toupper $proto)" "$cve" "$cwe" fileout "${jsonID}_CBC_$(toupper $proto)" "OK" "No CBC ciphers for $(toupper $proto)" "$cve" "$cwe"
fi fi
fi fi
@ -13281,7 +13289,7 @@ run_beast(){
fileout "$jsonID" "MEDIUM" "VULNERABLE -- and no higher protocols as mitigation supported" "$cve" "$cwe" "$hint" fileout "$jsonID" "MEDIUM" "VULNERABLE -- and no higher protocols as mitigation supported" "$cve" "$cwe" "$hint"
fi fi
fi fi
"$first" && ! "$vuln_beast" && prln_done_good "no CBC ciphers found for any protocol (OK)" "$first" && ! "$vuln_beast" && prln_svrty_good "no CBC ciphers found for any protocol (OK)"
"$using_sockets" && HAS_DH_BITS="$has_dh_bits" "$using_sockets" && HAS_DH_BITS="$has_dh_bits"
tmpfile_handle $FUNCNAME.txt tmpfile_handle $FUNCNAME.txt
@ -13333,7 +13341,7 @@ run_lucky13() {
# the CBC padding which led to timing differences during MAC processing has been solved in openssl (https://www.openssl.org/news/secadv/20130205.txt) # the CBC padding which led to timing differences during MAC processing has been solved in openssl (https://www.openssl.org/news/secadv/20130205.txt)
# and other software. However we can't tell with reasonable effort from the outside. Thus we still issue a warning and label it experimental # and other software. However we can't tell with reasonable effort from the outside. Thus we still issue a warning and label it experimental
else else
pr_done_best "not vulnerable (OK)"; pr_svrty_best "not vulnerable (OK)";
if "$using_sockets"; then if "$using_sockets"; then
fileout "$jsonID" "OK" "not vulnerable" "$cve" "$cwe" fileout "$jsonID" "OK" "not vulnerable" "$cve" "$cwe"
else else
@ -13591,7 +13599,7 @@ run_rc4() {
prln_local_problem "No RC4 Ciphers configured in $OPENSSL" prln_local_problem "No RC4 Ciphers configured in $OPENSSL"
fileout "$jsonID" "WARN" "RC4 ciphers not supported by local OpenSSL ($OPENSSL)" fileout "$jsonID" "WARN" "RC4 ciphers not supported by local OpenSSL ($OPENSSL)"
else else
prln_done_good "no RC4 ciphers detected (OK)" prln_svrty_good "no RC4 ciphers detected (OK)"
fileout "$jsonID" "OK" "not vulnerable" "$cve" "$cwe" fileout "$jsonID" "OK" "not vulnerable" "$cve" "$cwe"
fi fi
outln outln
@ -14027,7 +14035,7 @@ run_robot() {
cipherlist="$(strip_inconsistent_ciphers "$tls_hexcode" ", $cipherlist")" cipherlist="$(strip_inconsistent_ciphers "$tls_hexcode" ", $cipherlist")"
cipherlist="${cipherlist:2}" cipherlist="${cipherlist:2}"
elif [[ $ret -ne 0 ]]; then elif [[ $ret -ne 0 ]]; then
prln_done_best "Server does not support any cipher suites that use RSA key transport" prln_svrty_best "Server does not support any cipher suites that use RSA key transport"
fileout "$jsonID" "OK" "not vulnerable, no RSA key transport cipher" fileout "$jsonID" "OK" "not vulnerable, no RSA key transport cipher"
return 0 return 0
fi fi
@ -14213,7 +14221,7 @@ run_robot() {
fileout "$jsonID" "CRITICAL" "VULNERABLE" fileout "$jsonID" "CRITICAL" "VULNERABLE"
fi fi
else else
prln_done_best "not vulnerable (OK)" prln_svrty_best "not vulnerable (OK)"
fileout "$jsonID" "OK" "not vulnerable" fileout "$jsonID" "OK" "not vulnerable"
fi fi
return 0 return 0
@ -16739,8 +16747,8 @@ lets_roll() {
fileout_section_header $section_number false && ((section_number++)) fileout_section_header $section_number false && ((section_number++))
$do_protocols && { $do_protocols && {
run_protocols; ret=$(($? + ret)); time_right_align run_protocols; run_protocols; ret=$(($? + ret)); time_right_align run_protocols;
run_spdy; ret=$(($? + ret)); time_right_align run_spdy; run_npn; ret=$(($? + ret)); time_right_align run_npn;
run_http2; ret=$(($? + ret)); time_right_align run_http2; run_alpn; ret=$(($? + ret)); time_right_align run_alpn;
} }
fileout_section_header $section_number true && ((section_number++)) fileout_section_header $section_number true && ((section_number++))
"$do_grease" && { run_grease; ret=$(($? + ret)); time_right_align run_grease; } "$do_grease" && { run_grease; ret=$(($? + ret)); time_right_align run_grease; }