From 39990f5acec84e5fec69f6521435158ec83ca951 Mon Sep 17 00:00:00 2001 From: David Cooper Date: Tue, 6 Feb 2018 14:05:27 -0500 Subject: [PATCH 1/4] Fix #981 This commit fixes #981 by using a while loop instead of a for loop to check each DNS name in the SAN extension, copying the syntax used in certificate_info() to display all of the SANs. --- testssl.sh | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/testssl.sh b/testssl.sh index 9977f39..6fcff9e 100755 --- a/testssl.sh +++ b/testssl.sh @@ -6235,26 +6235,27 @@ compare_server_name_to_cert() # Check whether any of the DNS names in the certificate match the servername dns_sans="$(get_san_dns_from_cert "$cert")" - for san in $dns_sans; do - [[ $(toupper "$san") == "$servername" ]] && ret=1 && break - done + while read san; do + [[ -n "$san" ]] && [[ $(toupper "$san") == "$servername" ]] && ret=1 && break + done <<< "$dns_sans" if [[ $ret -eq 0 ]]; then # 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" | \ tr ',' '\n' | grep "IP Address:" | sed -e 's/IP Address://g' -e 's/ //g') - for san in $ip_sans; do - [[ "$san" == "$servername" ]] && ret=1 && break - done + while read san; do + [[ -n "$san" ]] && [[ "$san" == "$servername" ]] && ret=1 && break + done <<< "$ip_sans" fi # Check whether any of the DNS names in the certificate are wildcard names # that match the servername if [[ $ret -eq 0 ]]; then - for san in $dns_sans; do + while read san; do + [[ -n "$san" ]] || continue wildcard_match "$servername" "$san" [[ $? -eq 0 ]] && ret=2 && break - done + done <<< "$dns_sans" fi cn="$(get_cn_from_cert "$cert")" @@ -7250,9 +7251,9 @@ run_server_defaults() { if [[ "$sans_nosni" == "$sans_sni" ]]; then success[n]=0 else - for san in $sans_nosni; do - [[ " $sans_sni " =~ " $san " ]] && success[n]=0 && break - done + while read san; do + [[ -n "$san" ]] && [[ " $sans_sni " =~ " $san " ]] && success[n]=0 && break + done <<< "$sans_nosni" fi fi fi @@ -7457,7 +7458,7 @@ get_session_ticket_lifetime_from_serverhello() { get_san_dns_from_cert() { echo "$($OPENSSL x509 -in "$1" -noout -text 2>>$ERRFILE | \ 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')" } From 7bf070b0161dc7b89a1046576aa7d189bf295c6f Mon Sep 17 00:00:00 2001 From: Dirk Date: Thu, 8 Feb 2018 14:02:24 +0100 Subject: [PATCH 2/4] Changes in NPN+ALPN, internal improvements for all *_done_* calls In order to be more consistent with the other output functions having "svrty" in their name, *_done_best and *_done_good were changed to *_svrty_best and *_svrty_good. run_spdy/run_http2 were renamed to run_npn and run_alpn as this is what is actually being tested. Also the terminal and file output is now reflecting this. Also #980 was fixed in a sense that (only) for ALPN the protocol h2 will get a "good". There will be an additional CSV/JSON line for this. --- testssl.sh | 273 +++++++++++++++++++++++++++-------------------------- 1 file changed, 139 insertions(+), 134 deletions(-) diff --git a/testssl.sh b/testssl.sh index 6fcff9e..987522d 100755 --- a/testssl.sh +++ b/testssl.sh @@ -472,15 +472,15 @@ pr_grey() { tm_grey "$1"; [[ "$COLOR" -ne 0 ]] && html_out "$(html_reserved "$1")" || html_out "$(html_reserved "$1")" ) || html_out "$(html_reserved "$1")"; } -prln_done_good() { pr_done_good "$1"; outln; } +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_svrty_good() { tm_svrty_good "$1"; tmln_out; } +pr_svrty_good() { tm_svrty_good "$1"; [[ "$COLOR" -ge 2 ]] && ( "$COLORBLIND" && html_out "$(html_reserved "$1")" || html_out "$(html_reserved "$1")" ) || html_out "$(html_reserved "$1")"; } +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 -tmln_done_best() { tm_done_best "$1"; tmln_out; } -pr_done_best() { tm_done_best "$1"; [[ "$COLOR" -ge 2 ]] && ( "$COLORBLIND" && html_out "$(html_reserved "$1")" || html_out "$(html_reserved "$1")" ) || html_out "$(html_reserved "$1")"; } -prln_done_best() { pr_done_best "$1"; outln; } +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_svrty_best() { tm_svrty_best "$1"; tmln_out; } +pr_svrty_best() { tm_svrty_best "$1"; [[ "$COLOR" -ge 2 ]] && ( "$COLORBLIND" && html_out "$(html_reserved "$1")" || html_out "$(html_reserved "$1")" ) || html_out "$(html_reserved "$1")"; } +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 tmln_svrty_low() { tm_svrty_low "$1"; tmln_out; } @@ -1704,7 +1704,7 @@ detect_header() { includeSubDomains() { if grep -aiqw includeSubDomains "$1"; then - pr_done_good ", includeSubDomains" + pr_svrty_good ", includeSubDomains" return 0 else pr_litecyan ", just this domain" @@ -1714,7 +1714,7 @@ includeSubDomains() { preload() { if grep -aiqw preload "$1"; then - pr_done_good ", preload" + pr_svrty_good ", preload" return 0 else return 1 @@ -1748,7 +1748,7 @@ run_hsts() { pr_svrty_medium "HSTS max-age is set to 0. HSTS is disabled" fileout "HSTS_time" "MEDIUM" "0. HSTS is disabled" 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" else 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, " fileout "HPKP_SPKIs" "HIGH" "Only one key pinned" else - pr_done_good "$hpkp_nr_keys" + pr_svrty_good "$hpkp_nr_keys" out " keys, " fileout "HPKP_SPKIs" "OK" "$hpkp_nr_keys keys pinned in header" fi @@ -1842,7 +1842,7 @@ run_hpkp() { fi hpkp_age_days=$((hpkp_age_sec / 86400)) 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)" else out "$hpkp_age_sec s = " @@ -1910,7 +1910,7 @@ run_hpkp() { certificate_found=true # We have a match spki_match=true 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" fi debugme tm_out "\n $hpkp_spki | $hpkp_spki_hostcert" @@ -1923,7 +1923,7 @@ run_hpkp() { certificate_found=true spki_match=true 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" )" pr_italic " $ca_cn" 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" )" if [[ "$match_ca" == "$hpkp_ca" ]]; then # part of the chain out "\n$spaces_indented Root CA: " - pr_done_good "$hpkp_spki" + pr_svrty_good "$hpkp_spki" pr_italic " $ca_cn" 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 @@ -1977,7 +1977,7 @@ run_hpkp() { # for i=0 manually do the same as below as there's other indentation here if [[ -n "${backup_spki_str[0]}" ]]; then - pr_done_good "${backup_spki[0]}" + pr_svrty_good "${backup_spki[0]}" #out " Root CA: " prln_italic " ${backup_spki_str[0]}" else @@ -1987,7 +1987,7 @@ run_hpkp() { for ((i=1; i < ${#backup_spki[@]} ;i++ )); do if [[ -n "${backup_spki_str[i]}" ]]; then # 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: " prln_italic " ${backup_spki_str[i]}" else @@ -2309,7 +2309,7 @@ run_cookie_flags() { # ARG1: Path nr_secure=$(grep -iac secure $TMPFILE) case $nr_secure in 0) pr_svrty_medium "$negative_word" ;; - [123456789]) pr_done_good "$nr_secure/$nr_cookies";; + [123456789]) pr_svrty_good "$nr_secure/$nr_cookies";; esac out " secure, " if [[ $nr_cookies -eq $nr_secure ]]; then @@ -2320,7 +2320,7 @@ run_cookie_flags() { # ARG1: Path nr_httponly=$(grep -cai httponly $TMPFILE) case $nr_httponly in 0) pr_svrty_medium "$negative_word" ;; - [123456789]) pr_done_good "$nr_httponly/$nr_cookies";; + [123456789]) pr_svrty_good "$nr_httponly/$nr_cookies";; esac out " HttpOnly" if [[ $nr_cookies -eq $nr_httponly ]]; then @@ -2359,7 +2359,7 @@ run_more_flags() { else first=false fi - pr_done_good "$f2t" + pr_svrty_good "$f2t" outln " $(out_row_aligned_max_width "$HEADERVALUE" "$spaces" $TERM_WIDTH)" fileout "$f2t" "OK" "$HEADERVALUE" fi @@ -2549,7 +2549,7 @@ sub_cipherlists() { case $3 in 2) if [[ $sclient_success -eq 0 ]]; then # Strong is excellent to offer - pr_done_best "offered (OK)" + pr_svrty_best "offered (OK)" fileout "${jsonID}_$4" "OK" "offered" else pr_svrty_medium "not offered" @@ -2559,7 +2559,7 @@ sub_cipherlists() { 1) if [[ $sclient_success -eq 0 ]]; then # High is good to offer - pr_done_good "offered (OK)" + pr_svrty_good "offered (OK)" fileout "${jsonID}_$4" "OK" "offered" else # 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" else # 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" fi ;; @@ -2591,7 +2591,7 @@ sub_cipherlists() { pr_svrty_critical "offered (NOT ok)" fileout "${jsonID}_$4" "CRITICAL" "offered" else - pr_done_best "not offered (OK)" + pr_svrty_best "not offered (OK)" fileout "${jsonID}_$4" "OK" "not offered" fi ;; @@ -4248,7 +4248,7 @@ run_protocols() { local using_sockets=true 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 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 key_share_extn_nr="$KEY_SHARE_EXTN_NR" local lines nr_ciphers_detected @@ -4268,7 +4268,7 @@ run_protocols() { if [[ -n "$STARTTLS" ]]; then prln_underline "via sockets " else - prln_underline "via sockets except SPDY+HTTP2 " + prln_underline "via sockets except NPN+ALPN " fi fi outln @@ -4288,12 +4288,12 @@ run_protocols() { fileout "$jsonID" "WARN" "received a strange SSLv2 reply (rerun with DEBUG>=2)" ;; 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" add_tls_offered ssl2 no ;; 0) # reset - prln_done_best "not offered (OK)" + prln_svrty_best "not offered (OK)" fileout "$jsonID" "OK" "not offered" add_tls_offered ssl2 no ;; @@ -4326,7 +4326,7 @@ run_protocols() { fileout "$jsonID" "CRITICAL" "offered" add_tls_offered ssl2 yes ;; - 1) prln_done_best "not offered (OK)" + 1) prln_svrty_best "not offered (OK)" fileout "$jsonID" "OK" "not offered" add_tls_offered ssl2 no ;; @@ -4353,7 +4353,7 @@ run_protocols() { latest_supported_string="SSLv3" add_tls_offered ssl3 yes ;; - 1) prln_done_best "not offered (OK)" + 1) prln_svrty_best "not offered (OK)" fileout "$jsonID" "OK" "not offered" add_tls_offered ssl3 no ;; @@ -4535,7 +4535,7 @@ run_protocols() { ret=$? fi case $ret in - 0) prln_done_best "offered (OK)" + 0) prln_svrty_best "offered (OK)" fileout "$jsonID" "OK" "offered" latest_supported="0303" latest_supported_string="TLSv1.2" @@ -4663,7 +4663,7 @@ run_protocols() { fi KEY_SHARE_EXTN_NR="$key_share_extn_nr" 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" else pr_warning "Unexpected results"; outln "$debug_recomm" @@ -4809,7 +4809,7 @@ pr_dh_quality() { elif [[ "$bits" -le 1280 ]]; then pr_svrty_medium "$string" elif [[ "$bits" -ge 2048 ]]; then - pr_done_good "$string" + pr_svrty_good "$string" else out "$string" fi @@ -4830,7 +4830,7 @@ pr_ecdh_quality() { elif [[ "$bits" -le 224 ]]; then out "$string" elif [[ "$bits" -gt 224 ]]; then - pr_done_good "$string" + pr_svrty_good "$string" else out "$string" fi @@ -4879,7 +4879,7 @@ pr_ecdh_curve_quality() { # The return value is an indicator of the quality of the cipher in $1: # 0 = $1 is empty # 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 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) # RSA kx and e.g. GCM isn't certainly the best - pr_done_good "$text" + pr_svrty_good "$text" return 6 ;; *GCM*|*CCM*|*CHACHA20*) - pr_done_best "$text" + pr_svrty_best "$text" return 7 ;; #best ones ECDHE*AES*|DHE*AES*SHA*|*CAMELLIA*SHA) @@ -4942,13 +4942,13 @@ pr_cipher_quality() { pr_svrty_low "$text" return 4 else - pr_done_good "$text" + pr_svrty_good "$text" # RSA kx and e.g. GCM isn't certainly the best return 6 fi ;; *GCM*|*CCM*|*CHACHA20*) - pr_done_best "$text" + pr_svrty_best "$text" return 7 ;; *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)" fileout "$jsonID" "HIGH" "NOT cipher order configured" else - pr_done_best "yes (OK)" + pr_svrty_best "yes (OK)" has_cipher_order=true limitedsense="" fileout "$jsonID" "OK" "sets cipher order" @@ -5220,15 +5220,15 @@ run_server_preference() { [[ "$default_proto" == "TLSv1.0" ]] && default_proto="TLSv1" case "$default_proto" in *TLSv1.3) - prln_done_best $default_proto + prln_svrty_best $default_proto fileout "$jsonID" "OK" "Default protocol TLS1.3" ;; *TLSv1.2) - prln_done_best $default_proto + prln_svrty_best $default_proto fileout "$jsonID" "OK" "Default protocol TLS1.2" ;; *TLSv1.1) - prln_done_good $default_proto + prln_svrty_good $default_proto fileout "$jsonID" "OK" "Default protocol TLS1.1" ;; *TLSv1) @@ -5787,7 +5787,7 @@ determine_trust() { if [[ ${verify_retcode[i]} -eq 0 ]]; then trust[i]=true some_ok=true - debugme tm_done_good "Ok " + debugme tm_svrty_good "Ok " debugme tmln_out "${verify_retcode[i]}" else trust[i]=false @@ -5801,7 +5801,7 @@ determine_trust() { debugme tm_out " " if "$all_ok"; then # 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: fileout "${jsonID}${json_postfix}" "OK" "passed. $addtl_warning" else @@ -5842,7 +5842,7 @@ determine_trust() { outln # lf + green ones [[ "$DEBUG" -eq 0 ]] && tm_out "$spaces" - pr_done_good "OK: $ok_was" + pr_svrty_good "OK: $ok_was" fi fileout "${jsonID}${json_postfix}" "CRITICAL" "Some certificate trust checks failed -> $notok_was $addtl_warning, OK -> $ok_was" fi @@ -6314,7 +6314,7 @@ must_staple() { if "$supported"; then if "$provides_stapling"; then - prln_done_good "supported" + prln_svrty_good "supported" fileout "${jsonID}${json_postfix}" "OK" "supported" else prln_svrty_high "requires OCSP stapling (NOT ok)" @@ -6470,15 +6470,15 @@ certificate_info() { fileout "${jsonID}${json_postfix}" "INFO" "SHA224 with RSA" ;; sha256WithRSAEncryption) - prln_done_good "SHA256 with RSA" + prln_svrty_good "SHA256 with RSA" fileout "${jsonID}${json_postfix}" "OK" "SHA256 with RSA" ;; sha384WithRSAEncryption) - prln_done_good "SHA384 with RSA" + prln_svrty_good "SHA384 with RSA" fileout "${jsonID}${json_postfix}" "OK" "SHA384 with RSA" ;; sha512WithRSAEncryption) - prln_done_good "SHA512 with RSA" + prln_svrty_good "SHA512 with RSA" fileout "${jsonID}${json_postfix}" "OK" "SHA512 with RSA" ;; ecdsa-with-SHA1) @@ -6490,15 +6490,15 @@ certificate_info() { fileout "${jsonID}${json_postfix}" "INFO" "ECDSA with SHA224" ;; ecdsa-with-SHA256) - prln_done_good "ECDSA with SHA256" + prln_svrty_good "ECDSA with SHA256" fileout "${jsonID}${json_postfix}" "OK" "ECDSA with SHA256" ;; ecdsa-with-SHA384) - prln_done_good "ECDSA with SHA384" + prln_svrty_good "ECDSA with SHA384" fileout "${jsonID}${json_postfix}" "OK" "ECDSA with SHA384" ;; ecdsa-with-SHA512) - prln_done_good "ECDSA with SHA512" + prln_svrty_good "ECDSA with SHA512" fileout "${jsonID}${json_postfix}" "OK" "ECDSA with SHA512" ;; dsaWithSHA1) @@ -6510,7 +6510,7 @@ certificate_info() { fileout "${jsonID}${json_postfix}" "INFO" "DSA with SHA224" ;; dsa_with_SHA256) - prln_done_good "DSA with SHA256" + prln_svrty_good "DSA with SHA256" fileout "${jsonID}${json_postfix}" "OK" "DSA with SHA256" ;; rsassaPss) @@ -6525,15 +6525,15 @@ certificate_info() { fileout "${jsonID}${json_postfix}" "INFO" "RSASSA-PSS with SHA224" ;; sha256) - prln_done_good "RSASSA-PSS with SHA256" + prln_svrty_good "RSASSA-PSS with SHA256" fileout "${jsonID}${json_postfix}" "OK" "RSASSA-PSS with SHA256" ;; sha384) - prln_done_good "RSASSA-PSS with SHA384" + prln_svrty_good "RSASSA-PSS with SHA384" fileout "${jsonID}${json_postfix}" "OK" "RSASSA-PSS with SHA384" ;; sha512) - prln_done_good "RSASSA-PSS with SHA512" + prln_svrty_good "RSASSA-PSS with SHA512" fileout "${jsonID}${json_postfix}" "OK" "RSASSA-PSS with SHA512" ;; *) @@ -6595,7 +6595,7 @@ certificate_info() { out "$cert_keysize" fileout "${jsonID}${json_postfix}" "INFO" "$cert_keysize EC bits" 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" else out "keysize: $cert_keysize (not expected, FIXME)" @@ -6620,7 +6620,7 @@ certificate_info() { outln "$cert_keysize bits" fileout "${jsonID}${json_postfix}" "INFO" "$cert_keysize bits" elif [[ "$cert_keysize" -le 4096 ]]; then - pr_done_good "$cert_keysize" + pr_svrty_good "$cert_keysize" fileout "${jsonID}${json_postfix}" "OK" "$cert_keysize bits" outln " bits" else @@ -6877,7 +6877,7 @@ certificate_info() { ! "$has_dns_sans" && out " -- CN only match is deprecated" fi else - pr_done_good "$trustfinding" + pr_svrty_good "$trustfinding" trust_sni_finding="OK" fi @@ -7003,7 +7003,7 @@ certificate_info() { secs2warn=$((24 * 60 * 60 * days2warn1)) # high threshold expire=$($OPENSSL x509 -in $HOSTCERT -checkend $secs2warn 2>>$ERRFILE) if grep -qw not <<< "$expire"; then - pr_done_good "$days2expire >= $days2warn1 days" + pr_svrty_good "$days2expire >= $days2warn1 days" expfinding+="$days2expire >= $days2warn1 days" else pr_svrty_medium "expires < $days2warn1 days ($days2expire)" @@ -7075,7 +7075,7 @@ certificate_info() { fi else 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" provides_stapling=true else @@ -7106,7 +7106,7 @@ certificate_info() { caa_node=${caa_node#*.} done 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 out ": " else @@ -7132,7 +7132,7 @@ certificate_info() { out "$indent"; pr_bold " Certificate Transparency "; jsonID="certificate_transparency" if [[ "$ct" =~ extension ]]; then - pr_done_good "yes"; outln " ($ct)" + pr_svrty_good "yes"; outln " ($ct)" fileout "${jsonID}${json_postfix}" "OK" "yes ($ct)" else outln "$ct" @@ -7572,7 +7572,7 @@ run_pfs() { outln pfs_offered=true pfs_ciphers="" - pr_done_good " PFS is offered (OK)" + pr_svrty_good " PFS is offered (OK)" fileout "$jsonID" "OK" "offered" if "$WIDE"; then outln ", ciphers follow (client/browser support is important here) \n" @@ -7872,7 +7872,7 @@ run_pfs() { # good start to read: http://en.wikipedia.org/wiki/Transport_Layer_Security#Attacks_against_TLS.2FSSL -spdy_pre(){ +npn_pre(){ if [[ -n "$PROXY" ]]; then [[ -n "$1" ]] && pr_warning "$1" pr_warning "not tested as proxies do not support proxying it" @@ -7880,14 +7880,14 @@ spdy_pre(){ return 1 fi if ! "$HAS_SPDY"; then - pr_local_problem "$OPENSSL doesn't support SPDY/NPN"; - fileout "SPDY-NPN" "WARN" "not tested $OPENSSL doesn't support SPDY/NPN" + pr_local_problem "$OPENSSL doesn't support NPN/SPDY"; + fileout "NPN" "WARN" "not tested $OPENSSL doesn't support NPN/SPDY" return 7 fi return 0 } -http2_pre(){ +alpn_pre(){ if [[ -n "$PROXY" ]]; then [[ -n "$1" ]] && pr_warning " $1 " pr_warning "not tested as proxies do not support proxying it" @@ -7895,21 +7895,24 @@ http2_pre(){ return 1 fi if ! "$HAS_ALPN" && "$SSL_NATIVE"; then - prln_local_problem "$OPENSSL doesn't support HTTP2/ALPN"; - fileout "HTTP2-ALPN" "WARN" "HTTP/2 was not tested as $OPENSSL does not support it" + prln_local_problem "$OPENSSL doesn't support ALPN/HTTP2"; + fileout "ALPN" "WARN" "HTTP/2 was not tested as $OPENSSL does not support it" return 7 fi 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 -i ret=0 - local jsonID="SPDY-NPN" + local jsonID="NPN" [[ -n "$STARTTLS" ]] && return 0 - pr_bold " SPDY/NPN " - if ! spdy_pre; then + "$FAST" && return 0 + pr_bold " NPN/SPDY " + if ! npn_pre; then outln return 0 fi @@ -7932,7 +7935,6 @@ run_spdy() { ret=10 fi fi - #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 @@ -7940,16 +7942,16 @@ run_spdy() { } -run_http2() { +run_alpn() { local tmpstr alpn_extn len local -i ret=0 - local had_alpn_proto=false + local has_alpn_proto=false local alpn_finding="" - local jsonID="HTTP2-ALPN" + local jsonID="ALPN" [[ -n "$STARTTLS" ]] && return 0 - pr_bold " HTTP2/ALPN " - if ! http2_pre; then + pr_bold " ALPN/HTTP2 " + if ! alpn_pre; then outln return 0 fi @@ -7970,23 +7972,26 @@ run_http2() { echo "" > $TMPFILE 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) if [[ "$tmpstr" == *"$proto" ]]; then - if ! $had_alpn_proto; then - out "$proto" - alpn_finding+="$proto" - had_alpn_proto=true - else - out ", $proto" - alpn_finding+=", $proto" - fi + if ! $has_alpn_proto; then + has_alpn_proto=true + else + out ", " + fi + # only h2 is what browser need to use HTTP/2.0 and brings a security benefit + if [[ "$proto" == "h2" ]]; then + pr_svrty_good "$proto" + fileout "$jsonID" "OK" "$alpn_finding" + else + out "$proto" + alpn_finding+="$proto" + fi fi done - if $had_alpn_proto; then + if $has_alpn_proto; then outln " (offered)" - fileout "$jsonID" "INFO" "offered with protocols $alpn_finding" + fileout "$jsonID" "INFO" "$alpn_finding" ret=0 else outln "not offered" @@ -11532,7 +11537,7 @@ run_heartbleed(){ [[ -z "$TLS_EXTENSIONS" ]] && determine_tls_extensions if [[ ! "${TLS_EXTENSIONS}" =~ heartbeat ]]; then - pr_done_best "not vulnerable (OK)" + pr_svrty_best "not vulnerable (OK)" outln ", no heartbeat extension" fileout "$jsonID" "OK" "not vulnerable, no heartbeat extension" "$cve" "$cwe" return 0 @@ -11565,7 +11570,7 @@ run_heartbleed(){ sockread_serverhello 16384 $HEARTBLEED_MAX_WAITSOCK if [[ $? -eq 3 ]]; then 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" ret=0 else @@ -11590,7 +11595,7 @@ run_heartbleed(){ # check possibility of weird vsftpd reply, see #426, despite "1803" seems very unlikely... if grep -q '500 OOPS' "$SOCK_REPLY_FILE" ; then 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" ret=0 else @@ -11606,7 +11611,7 @@ run_heartbleed(){ ret=1 fi else - pr_done_best "not vulnerable (OK)" + pr_svrty_best "not vulnerable (OK)" fileout "$jsonID" "OK" "not vulnerable $cve" "$cwe" ret=0 fi @@ -11619,7 +11624,7 @@ run_heartbleed(){ # helper function ok_ids(){ - prln_done_best "\n ok -- something resetted our ccs packets" + prln_svrty_best "\n ok -- something resetted our ccs packets" return 0 } @@ -11741,7 +11746,7 @@ run_ccs_injection(){ # 28: Handshake failure if [[ -z "${tls_hello_ascii:0:12}" ]]; then # empty reply - pr_done_best "not vulnerable (OK)" + pr_svrty_best "not vulnerable (OK)" if [[ $retval -eq 3 ]]; then fileout "$jsonID" "OK" "not vulnerable (timed out)" "$cve" "$cwe" else @@ -11764,7 +11769,7 @@ run_ccs_injection(){ elif [[ $STARTTLS_PROTOCOL == "mysql" ]] && [[ "${tls_hello_ascii:14:12}" == "233038533031" ]]; then # MySQL community edition (yaSSL) returns a MySQL error instead of a TLS Alert # Error: #08S01 Bad handshake - pr_done_best "not vulnerable (OK)" + pr_svrty_best "not vulnerable (OK)" out ", looks like MySQL community edition (yaSSL)" 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 @@ -11830,7 +11835,7 @@ run_ticketbleed() { # highly unlikely that it is NOT supported. We may loose time here but it's more solid [[ -z "$TLS_EXTENSIONS" ]] && determine_tls_extensions if [[ ! "${TLS_EXTENSIONS}" =~ "session ticket" ]]; then - pr_done_best "not vulnerable (OK)" + pr_svrty_best "not vulnerable (OK)" outln ", no session ticket extension" fileout "$jsonID" "OK" "no session ticket extension" "$cve" "$cwe" return 0 @@ -11857,7 +11862,7 @@ run_ticketbleed() { session_tckt_tls="$(get_session_ticket_tls)" if [[ "$session_tckt_tls" == "," ]]; then - pr_done_best "not vulnerable (OK)" + pr_svrty_best "not vulnerable (OK)" outln ", no session tickets" fileout "$jsonID" "OK" "not vulnerable" "$cve" "$cwe" debugme echo " session ticket TLS \"$session_tckt_tls\"" @@ -11981,11 +11986,11 @@ run_ticketbleed() { 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}) -- " - pr_done_best "not vulnerable (OK)" + pr_svrty_best "not vulnerable (OK)" fileout "$jsonID" "OK" "not vulnerable" "$cve" "$cwe" break elif [[ -z "${tls_hello_ascii:0:2}" ]]; then - pr_done_best "not vulnerable (OK)" + pr_svrty_best "not vulnerable (OK)" out ", reply empty" fileout "$jsonID" "OK" "not vulnerable" "$cve" "$cwe" break @@ -12038,7 +12043,7 @@ run_ticketbleed() { pr_svrty_critical "VULNERABLE (NOT ok)" fileout "$jsonID" "CRITICAL" "VULNERABLE" "$cve" "$cwe" "$hint" else - pr_done_best "not vulnerable (OK)" + pr_svrty_best "not vulnerable (OK)" out ", memory fragments do not differ" fileout "$jsonID" "OK" "not vulnerable, session IDs were returned but memory fragments do not differ" "$cve" "$cwe" fi @@ -12084,7 +12089,7 @@ run_renego() { 0) prln_svrty_critical "VULNERABLE (NOT ok)" 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" ;; *) prln_warning "FIXME (bug): $sec_renego" @@ -12129,7 +12134,7 @@ run_renego() { 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 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" sec_client_renego=1 else @@ -12146,7 +12151,7 @@ run_renego() { fi ;; 1) - prln_done_good "not vulnerable (OK)" + prln_svrty_good "not vulnerable (OK)" fileout "$jsonID" "OK" "not vulnerable" "$cve" "$cwe" ;; *) @@ -12208,7 +12213,7 @@ run_crime() { fileout "CRIME_TLS" "WARN" "Check failed, couldn't connect" "$cve" "$cwe" ret=7 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 out " (not using HTTP anyway)" fileout "CRIME_TLS" "OK" "not vulnerable (not using HTTP anyway)" "$cve" "$cwe" @@ -12253,7 +12258,7 @@ run_crime() { # STR=$(grep Compression $TMPFILE ) # if echo $STR | grep -q NONE >/dev/null; then -# pr_done_best "not vulnerable (OK)" +# pr_svrty_best "not vulnerable (OK)" # ret=$((ret + 0)) # else # pr_svrty_critical "VULNERABLE (NOT ok)" @@ -12320,7 +12325,7 @@ run_breach() { prln_warning ") " ret=3 elif [[ -z $result ]]; then - pr_done_best "no HTTP compression (OK) " + pr_svrty_best "no HTTP compression (OK) " outln "$disclaimer" fileout "$jsonID" "OK" "no HTTP compression $disclaimer" "$cve" "$cwe" ret=0 @@ -12388,7 +12393,7 @@ run_sweet32() { pr_svrty_low "VULNERABLE"; out ", uses 64 bit block ciphers" fileout "SWEET32" "LOW" "uses 64 bit block ciphers" "$cve" "$cwe" "$hint" else - pr_done_best "not vulnerable (OK)"; + pr_svrty_best "not vulnerable (OK)"; if "$using_sockets"; then fileout "SWEET32" "OK" "not vulnerable" "$cve" "$cwe" else @@ -12447,7 +12452,7 @@ run_ssl_poodle() { fileout "$jsonID" "HIGH" "VULNERABLE, uses SSLv3+CBC" "$cve" "$cwe" "$hint" else POODLE=1 - pr_done_best "not vulnerable (OK)"; + pr_svrty_best "not vulnerable (OK)"; if "$using_sockets"; then fileout "$jsonID" "OK" "not vulnerable" "$cve" "$cwe" else @@ -12530,7 +12535,7 @@ run_tls_fallback_scsv() { fileout "$jsonID" "HIGH" "only SSLv3 supported" return 7 ;; - *) pr_done_good "No fallback possible, TLS 1.3 is the only protocol (OK)" + *) pr_svrty_good "No fallback possible, TLS 1.3 is the only protocol (OK)" fileout "$jsonID" "OK" "only TLS 1.3 supported" return 7 esac @@ -12552,7 +12557,7 @@ run_tls_fallback_scsv() { if [[ -z "$low_proto" ]]; then case "$high_proto" in "tls1_2") - pr_done_good "No fallback possible, no protocol below $high_proto_str offered (OK)" + pr_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)" ;; @@ -12589,11 +12594,11 @@ run_tls_fallback_scsv() { ret=1 fi 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" ret=0 elif grep -qa "alert handshake failure" "$TMPFILE"; then - pr_done_good "Probably OK. " + pr_svrty_good "Probably OK. " fileout "$jsonID" "OK" "Probably oK" # 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 @@ -12690,7 +12695,7 @@ run_freak() { pr_svrty_critical "VULNERABLE (NOT ok)"; out ", uses EXPORT RSA ciphers" fileout "$jsonID" "CRITICAL" "VULNERABLE, uses EXPORT RSA ciphers" "$cve" "$cwe" "$hint" 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" fi outln @@ -12909,17 +12914,17 @@ run_logjam() { out "${spaces}but no DH EXPORT ciphers${addtl_warning}" fileout "$jsonID" "OK" "not vulnerable, no DH EXPORT ciphers,$addtl_warning" "$cve" "$cwe" 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" out ", no DH key detected" fileout "$jsonID2" "OK" "no DH key detected" 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" out ", no common primes detected" fileout "$jsonID2" "OK" "no common primes detected" 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" fi fi @@ -12985,7 +12990,7 @@ run_drown() { fi 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" if [[ -n "$cert_fingerprint_sha2" ]]; then outln "$spaces make sure you don't use this certificate elsewhere with SSLv2 enabled services" @@ -13116,10 +13121,10 @@ run_beast(){ if [[ $sclient_success -ne 0 ]]; then # protocol supported? if "$continued"; then # second round: we hit TLS1 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" else - prln_done_good "no TLS1 (OK)" + prln_svrty_good "no TLS1 (OK)" fileout "$jsonID" "OK" "not vulnerable, no TLS1" "$cve" "$cwe" fi return 0 @@ -13247,12 +13252,12 @@ run_beast(){ first=false else [[ $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 fi else 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" fi fi @@ -13282,7 +13287,7 @@ run_beast(){ fileout "$jsonID" "MEDIUM" "VULNERABLE -- and no higher protocols as mitigation supported" "$cve" "$cwe" "$hint" 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" tmpfile_handle $FUNCNAME.txt @@ -13334,7 +13339,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) # 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 - pr_done_best "not vulnerable (OK)"; + pr_svrty_best "not vulnerable (OK)"; if "$using_sockets"; then fileout "$jsonID" "OK" "not vulnerable" "$cve" "$cwe" else @@ -13592,7 +13597,7 @@ run_rc4() { prln_local_problem "No RC4 Ciphers configured in $OPENSSL" fileout "$jsonID" "WARN" "RC4 ciphers not supported by local OpenSSL ($OPENSSL)" else - prln_done_good "no RC4 ciphers detected (OK)" + prln_svrty_good "no RC4 ciphers detected (OK)" fileout "$jsonID" "OK" "not vulnerable" "$cve" "$cwe" fi outln @@ -14028,7 +14033,7 @@ run_robot() { cipherlist="$(strip_inconsistent_ciphers "$tls_hexcode" ", $cipherlist")" cipherlist="${cipherlist:2}" 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" return 0 fi @@ -14214,7 +14219,7 @@ run_robot() { fileout "$jsonID" "CRITICAL" "VULNERABLE" fi else - prln_done_best "not vulnerable (OK)" + prln_svrty_best "not vulnerable (OK)" fileout "$jsonID" "OK" "not vulnerable" fi return 0 @@ -16740,8 +16745,8 @@ lets_roll() { fileout_section_header $section_number false && ((section_number++)) $do_protocols && { run_protocols; ret=$(($? + ret)); time_right_align run_protocols; - run_spdy; ret=$(($? + ret)); time_right_align run_spdy; - run_http2; ret=$(($? + ret)); time_right_align run_http2; + run_npn; ret=$(($? + ret)); time_right_align run_npn; + run_alpn; ret=$(($? + ret)); time_right_align run_alpn; } fileout_section_header $section_number true && ((section_number++)) "$do_grease" && { run_grease; ret=$(($? + ret)); time_right_align run_grease; } From 3084f241af9c43f1045f768225503789e769811b Mon Sep 17 00:00:00 2001 From: David Cooper Date: Thu, 8 Feb 2018 11:57:54 -0500 Subject: [PATCH 3/4] Fix #983 This commit fixes #983 by ensuring that the line printed just before calling "return" prints a newline character. It also fixes the problem that no output is sent to the JSON/CSV file in some cases in which no fallback is possible since the server does not support two different protocols below TLSv1.3. --- testssl.sh | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/testssl.sh b/testssl.sh index 987522d..c743a3f 100755 --- a/testssl.sh +++ b/testssl.sh @@ -12535,7 +12535,7 @@ run_tls_fallback_scsv() { fileout "$jsonID" "HIGH" "only SSLv3 supported" return 7 ;; - *) pr_svrty_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" return 7 esac @@ -12557,11 +12557,12 @@ run_tls_fallback_scsv() { if [[ -z "$low_proto" ]]; then case "$high_proto" in "tls1_2") - pr_svrty_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 + fileout "$jsonID" "OK" "no protocol below $high_proto_str offered" return 7 fi case "$low_proto" in From 8930fe7fb394c25063dfe1c83a9ba5d1d1d1b334 Mon Sep 17 00:00:00 2001 From: Dirk Date: Thu, 8 Feb 2018 18:20:24 +0100 Subject: [PATCH 4/4] add a imssing blank between Access-Control-Allow-Origin Upgrade X-Served-By Referrer-Policy X-UA-Compatible and their value --- testssl.sh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/testssl.sh b/testssl.sh index 987522d..e247895 100755 --- a/testssl.sh +++ b/testssl.sh @@ -2375,7 +2375,7 @@ run_more_flags() { first=false fi pr_litecyan "$f2t" - outln "$HEADERVALUE" # shouldn't be that long + outln " $HEADERVALUE" # shouldn't be that long fileout "$f2t" "INFO" "$f2t: $HEADERVALUE" fi done @@ -7903,7 +7903,8 @@ alpn_pre(){ } # 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 +# Thus we don't label any support for NPN as good. +# FAST mode skips this test run_npn() { local tmpstr local -i ret=0