diff --git a/.gitignore b/.gitignore index adad0cf..cf8dc88 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,7 @@ .DS_Store tmp.json *.bak + +*.xml + +*.iml diff --git a/t/01_badssl.com.t b/t/01_badssl.com.t index dc6c362..8c91e07 100755 --- a/t/01_badssl.com.t +++ b/t/01_badssl.com.t @@ -28,7 +28,7 @@ foreach my $f ( @$json ) { if ( $f->{id} eq "expiration" ) { $found = 1; like($f->{finding},qr/^Certificate Expiration.*expired\!/,"Finding reads expired."); $tests++; - is($f->{severity}, "NOT ok", "Severity should be NOT ok"); $tests++; + is($f->{severity}, "CRITICAL", "Severity should be CRITICAL"); $tests++; last; } } @@ -56,7 +56,7 @@ foreach my $f ( @$json ) { if ( $f->{id} eq "chain_of_trust" ) { $found = 1; like($f->{finding},qr/^All certificate trust checks failed/,"Finding says certificate cannot be trusted."); $tests++; - is($f->{severity}, "NOT ok", "Severity should be NOT ok"); $tests++; + is($f->{severity}, "CRITICAL", "Severity should be CRITICAL"); $tests++; last; } } @@ -100,7 +100,7 @@ foreach my $f ( @$json ) { if ( $f->{id} eq "chain_of_trust" ) { $found = 1; like($f->{finding},qr/^All certificate trust checks failed.*incomplete/,"Finding says certificate cannot be trusted."); $tests++; - is($f->{severity}, "NOT ok", "Severity should be NOT ok"); $tests++; + is($f->{severity}, "CRITICAL", "Severity should be CRITICAL"); $tests++; last; } } @@ -118,7 +118,7 @@ is($found,1,"We had a finding for this in the JSON output"); $tests++; # if ( $f->{id} eq "chain_of_trust" ) { # $found = 1; # like($f->{finding},qr/^All certificate trust checks failed.*incomplete/,"Finding says certificate cannot be trusted."); $tests++; -# is($f->{severity}, "NOT ok", "Severity should be NOT ok"); $tests++; +# is($f->{severity}, "CRITICAL", "Severity should be CRITICAL"); $tests++; # last; # } #} @@ -132,4 +132,4 @@ sub json($) { $file = `cat $file`; unlink $file; return from_json($file); -} +} \ No newline at end of file diff --git a/testssl.sh b/testssl.sh index 70c3d74..5fce1fe 100755 --- a/testssl.sh +++ b/testssl.sh @@ -91,7 +91,7 @@ egrep -q "dev|rc" <<< "$VERSION" && \ readonly PROG_NAME=$(basename "$0") readonly RUN_DIR=$(dirname "$0") -TESTSSL_INSTALL_DIR="${TESTSSL_INSTALL_DIR:-""}" # if you run testssl.sh from a different path you can set either TESTSSL_INSTALL_DIR +TESTSSL_INSTALL_DIR="${TESTSSL_INSTALL_DIR:-""}" # if you run testssl.sh from a different path you can set either TESTSSL_INSTALL_DIR CA_BUNDLES_PATH="${CA_BUNDLES_PATH:-""}" # or CA_BUNDLES_PATH to find the CA BUNDLES. TESTSSL_INSTALL_DIR helps you to find the RFC mapping also MAPPING_FILE_RFC="" OPENSSL_LOCATION="" @@ -255,6 +255,8 @@ GET_REQ11="" readonly UA_STD="TLS tester from $SWURL" readonly UA_SNEAKY="Mozilla/5.0 (X11; Linux x86_64; rv:41.0) Gecko/20100101 Firefox/41.0" FIRST_FINDING=true # Is this the first finding we are outputting to file? +START_TIME=0 +END_TIME=0 # Devel stuff, see -q below TLS_LOW_BYTE="" @@ -264,6 +266,45 @@ HEX_CIPHER="" HEXDUMP=(hexdump -ve '16/1 "%02x " " \n"') # This is used to analyze the reply HEXDUMPPLAIN=(hexdump -ve '1/1 "%.2x"') # Replaces both xxd -p and tr -cd '[:print:]' +#################### SEVERITY #################### +INFO=0 +OK=0 +LOW=1 +MEDIUM=2 +HIGH=3 +CRITICAL=4 + +SEVERITY_LEVEL=0 + +set_severity_level() { + local severity=$1 + + if [[ "$severity" == "LOW" ]]; then + SEVERITY_LEVEL=$LOW + elif [[ "$severity" == "MEDIUM" ]]; then + SEVERITY_LEVEL=$MEDIUM + elif [[ "$severity" == "HIGH" ]]; then + SEVERITY_LEVEL=$HIGH + elif [[ "$severity" == "CRITICAL" ]]; then + SEVERITY_LEVEL=$CRITICAL + else + echo "Supported severity levels are LOW, MEDIUM, HIGH, CRITICAL!" + help + fi +} + +show_finding() { + local severity=$1 + + ([[ "$severity" == "DEBUG" ]]) || + ([[ "$severity" == "WARN" ]]) || + ([[ "$severity" == "INFO" ]] && [[ $SEVERITY_LEVEL -le $INFO ]]) || + ([[ "$severity" == "OK" ]] && [[ $SEVERITY_LEVEL -le $OK ]]) || + ([[ "$severity" == "LOW" ]] && [[ $SEVERITY_LEVEL -le $LOW ]]) || + ([[ "$severity" == "MEDIUM" ]] && [[ $SEVERITY_LEVEL -le $MEDIUM ]]) || + ([[ "$severity" == "HIGH" ]] && [[ $SEVERITY_LEVEL -le $HIGH ]]) || + ([[ "$severity" == "CRITICAL" ]] && [[ $SEVERITY_LEVEL -le $CRITICAL ]]) +} ###### some hexbytes for bash network sockets follow ###### @@ -452,20 +493,125 @@ set_color_functions() { } strip_quote() { - # remove color codes (see http://www.commandlinefu.com/commands/view/3584/remove-color-codes-special-characters-with-sed) + # remove color codes (see http://www.commandlinefu.com/commands/view/3584/remove-color-codes-special-characters-with-sed) # \', leading and all trailing spaces sed -e "s,\x1B\[[0-9;]*[a-zA-Z],,g" \ -e "s/\"/\\'/g" \ -e 's/^ *//g' \ - -e 's/ *$//g' <<< "$1" + -e 's/ *$//g' <<< "$1" } +#################### JSON FILE FORMATING #################### +fileout_pretty_json_header() { + START_TIME=$(date +%s) + + echo -e " \"host\" : \"$NODE\", + \"port\" : \"$PORT\", + \"startTime\" : \"$START_TIME\", + \"version\" : \"$VERSION\", + \"scanResult\" : { + " +} + +fileout_pretty_json_footer() { + local scan_time=$((END_TIME - START_TIME)) + echo -e " }, + \"ip\" : \"$NODEIP\", + \"scanTime\" : \"$scan_time\"\n}" +} + +fileout_json_header() { + "$do_json" && printf "[\n" > "$JSONFILE" + "$do_pretty_json" && (printf "{\n%s" "$(fileout_pretty_json_header)") > "$JSONFILE" +} + +fileout_json_footer() { + "$do_json" && printf "]\n" >> "$JSONFILE" + "$do_pretty_json" && (printf "\n%s" "$(fileout_pretty_json_footer)") >> "$JSONFILE" +} + +fileout_json_section() { + case $1 in + 1) + echo -e " \"service\" : [" + ;; + 2) + echo -e ",\n \"protocols\" : [" + ;; + 3) + echo -e ",\n \"ciphers\" : [" + ;; + 4) + echo -e ",\n \"pfs\" : [" + ;; + 5) + echo -e ",\n \"serverPreferences\" : [" + ;; + 6) + echo -e ",\n \"serverDefaults\" : [" + ;; + 7) + echo -e ",\n \"headerResponse\" : [" + ;; + 8) + echo -e ",\n \"vulnerabilities\" : [" + ;; + 9) + echo -e ",\n \"cipherTests\" : [" + ;; + 10) + echo -e ",\n \"browserSimulations\": [" + ;; + *) + echo "invalid section" + ;; + esac +} + +fileout_section_header(){ + local str="" + $2 && str="$(fileout_section_footer)" + "$do_pretty_json" && FIRST_FINDING=true && (printf "%s%s\n" "$str" "$(fileout_json_section "$1")") >> "$JSONFILE" +} + +fileout_section_footer() { + "$do_pretty_json" && printf "\n ]" >> "$JSONFILE" +} + +fileout_json_finding() { + if "$do_json"; then + "$FIRST_FINDING" || echo -n "," >> "$JSONFILE" + echo -e " { + \"id\" : \"$1\", + \"ip\" : \"$NODE/$NODEIP\", + \"port\" : \"$PORT\", + \"severity\" : \"$2\", + \"finding\" : \"$finding\" + }" >> "$JSONFILE" + fi + if "$do_pretty_json"; then + ("$FIRST_FINDING" && echo -n " {" >> "$JSONFILE") || echo -n ",{" >> "$JSONFILE" + echo -e -n " + \"id\" : \"$1\", + \"severity\" : \"$2\", + \"finding\" : \"$finding\" + }" >> "$JSONFILE" + fi +} + +is_json_format() { + ([[ -f "$JSONFILE" ]] && ("$do_json" || "$do_pretty_json")) +} + +################# JSON FILE FORMATING END #################### + +##################### FILE FORMATING ######################### fileout_header() { if "$APPEND"; then if [[ -f "$JSONFILE" ]]; then FIRST_FINDING=false # We need to insert a comma, because there is file content already else - "$do_json" && printf "[\n" > "$JSONFILE" + fileout_json_header fi if "$do_csv"; then if [[ -f "$CSVFILE" ]]; then @@ -477,34 +623,31 @@ fileout_header() { fi fi else - "$do_json" && printf "[\n" > "$JSONFILE" + fileout_json_header "$do_csv" && echo "\"id\",\"fqdn/ip\",\"port\",\"severity\",\"finding\"" > "$CSVFILE" fi } fileout_footer() { - "$do_json" && [[ -f "$JSONFILE" ]] && printf "]\n" >> "$JSONFILE" + is_json_format && fileout_json_footer } fileout() { # ID, SEVERITY, FINDING - local finding=$(strip_lf "$(newline_to_spaces "$(strip_quote "$3")")") + local severity="$2" - if "$do_json"; then - "$FIRST_FINDING" || echo -n "," >> $JSONFILE - echo " { - \"id\" : \"$1\", - \"ip\" : \"$NODE/$NODEIP\", - \"port\" : \"$PORT\", - \"severity\" : \"$2\", - \"finding\" : \"$finding\" - }" >> $JSONFILE + if show_finding "$severity"; then + local finding=$(strip_lf "$(newline_to_spaces "$(strip_quote "$3")")") + + is_json_format && (fileout_json_finding "$1" "$severity" "$finding") + + # does the following do any sanitization? + if "$do_csv"; then + echo -e \""$1\"",\"$NODE/$NODEIP\",\"$PORT"\",\""$severity"\",\""$finding"\"" >> "$CSVFILE" + fi + "$FIRST_FINDING" && FIRST_FINDING=false fi - # does the following do any sanitization? - if "$do_csv"; then - echo -e \""$1\"",\"$NODE/$NODEIP\",\"$PORT"\",\""$2"\",\""$finding"\"" >>$CSVFILE - fi - "$FIRST_FINDING" && FIRST_FINDING=false } +################### FILE FORMATING END ######################### ###### helper function definitions ###### @@ -786,7 +929,7 @@ run_http_header() { # populate vars for HTTP time debugme echo "$NOW_TIME: $HTTP_TIME" - + # delete from pattern til the end. We ignore any leading spaces (e.g. www.amazon.de) sed -e '//,$d' -e '//,$d' -e '/$HEADERFILE.2 @@ -809,7 +952,7 @@ run_http_header() { out ", redirecting to \"$redirect\"" if [[ $redirect == "http://"* ]]; then pr_svrty_high " -- Redirect to insecure URL (NOT ok)" - fileout "HTTP_STATUS_CODE" "NOT ok" \, "Redirect to insecure URL (NOT ok). Url: \"$redirect\"" + fileout "HTTP_STATUS_CODE" "HIGH" \, "Redirect to insecure URL (NOT ok). Url: \"$redirect\"" fi fileout "HTTP_STATUS_CODE" "INFO" \ "Testing HTTP header response @ \"$URL_PATH\", $HTTP_STATUS_CODE$msg_thereafter, redirecting to \"$redirect\"" @@ -893,7 +1036,7 @@ detect_ipv4() { fi pr_svrty_high "$result" outln "\n$spaces$your_ip_msg" - fileout "ip_in_header_$count" "NOT ok" "IPv4 address in header $result $your_ip_msg" + fileout "ip_in_header_$count" "HIGH" "IPv4 address in header $result $your_ip_msg" fi count=$count+1 done < $HEADERFILE @@ -950,7 +1093,7 @@ detect_header() { elif [[ $nr -eq 1 ]]; then HEADERVALUE=$(grep -Faiw "$key:" $HEADERFILE | sed 's/^.*://') return 1 - else + else pr_svrty_medium "misconfiguration: " pr_italic "$key" pr_svrty_medium " ${nr}x" @@ -1027,13 +1170,13 @@ run_hsts() { fileout "hsts_preload" "OK" "HSTS domain is marked for preloading" else fileout "hsts_preload" "INFO" "HSTS domain is NOT marked for preloading" - #FIXME: To be checked against preloading lists, + #FIXME: To be checked against preloading lists, # e.g. https://dxr.mozilla.org/mozilla-central/source/security/manager/boot/src/nsSTSPreloadList.inc # https://chromium.googlesource.com/chromium/src/+/master/net/http/transport_security_state_static.json fi else out "--" - fileout "hsts" "NOT ok" "No support for HTTP Strict Transport Security" + fileout "hsts" "HIGH" "No support for HTTP Strict Transport Security" fi outln @@ -1141,7 +1284,7 @@ run_hpkp() { # certificates that were provided in $TEMPDIR/intermediatecerts.pem # http://backreference.org/2010/05/09/ocsp-verification-with-openssl/ awk -v n=-1 "/Certificate chain/ {start=1} - /-----BEGIN CERTIFICATE-----/{ if (start) {inc=1; n++} } + /-----BEGIN CERTIFICATE-----/{ if (start) {inc=1; n++} } inc { print > (\"$TEMPDIR/level\" n \".crt\") } /---END CERTIFICATE-----/{ inc=0 }" $TMPFILE nrsaved=$(count_words "$(echo $TEMPDIR/level?.crt 2>/dev/null)") @@ -1154,7 +1297,7 @@ run_hpkp() { $OPENSSL dgst -sha256 -binary | $OPENSSL enc -base64)" hpkp_name="$(get_cn_from_cert $cert_fname)" hpkp_ca="$($OPENSSL x509 -in $cert_fname -issuer -noout|sed 's/^.*CN=//' | sed 's/\/.*$//')" - [[ -n $hpkp_name ]] || hpkp_name=$($OPENSSL x509 -in "$cert_fname" -subject -noout | sed 's/^subject= //') + [[ -n $hpkp_name ]] || hpkp_name=$($OPENSSL x509 -in "$cert_fname" -subject -noout | sed 's/^subject= //') echo "$hpkp_spki_ca $hpkp_name" >> "$TEMPDIR/intermediate.hashes" done fi @@ -1192,12 +1335,12 @@ run_hpkp() { # we compare now against a precompiled list of SPKIs against the ROOT CAs we have in $ca_hashes if ! "$certificate_found"; then - hpkp_matches=$(grep -h "$hpkp_spki" $ca_hashes | sort -u) + hpkp_matches=$(grep -h "$hpkp_spki" $ca_hashes 2>/dev/null | sort -u) if [[ -n $hpkp_matches ]]; then certificate_found=true # root CA found spki_match=true if [[ $(count_lines "$hpkp_matches") -eq 1 ]]; then - # replace by awk + # replace by awk match_ca=$(sed "s/[a-zA-Z0-9\+\/]*=* *//" <<< "$hpkp_matches") else match_ca="" @@ -1225,12 +1368,12 @@ run_hpkp() { # Most likely a backup SPKI, unfortunately we can't tell for what it is: host, intermediates has_backup_spki=true backup_spki[i]="$(strip_lf "$hpkp_spki")" # save it for later - backup_spki_str[i]="" # no root ca + backup_spki_str[i]="" # no root ca i=$((i + 1)) fileout "hpkp_$hpkp_spki" "INFO" "SPKI $hpkp_spki doesn't match anything. This is ok for a backup for any certificate" # CSV/JSON output here for the sake of simplicity, rest we do en bloc below fi - done + done # now print every backup spki out we saved before out "\n$spaces_indented Backups: " @@ -1254,6 +1397,11 @@ run_hpkp() { outln "$spaces_indented ${backup_spki[i]}" fi done + if [[ ! -f "$ca_hashes" ]] && "$spki_match"; then + out "$spaces " + pr_warningln "Attribution of further hashes couldn't be done as $ca_hashes could not be found" + fileout "hpkp_spkimatch" "WARN" "Attribution of further hashes couldn't be done as $ca_hashes could not be found" + fi # If all else fails... if ! "$spki_match"; then @@ -1265,7 +1413,7 @@ run_hpkp() { if ! "$has_backup_spki"; then pr_svrty_highln " No backup keys found. Loss/compromise of the currently pinned key(s) will lead to bricked site. " fileout "hpkp_backup" "HIGH" "No backup keys found. Loss/compromise of the currently pinned key(s) will lead to bricked site." - fi + fi else outln "--" fileout "hpkp" "INFO" "No support for HTTP Public Key Pinning" @@ -1510,7 +1658,7 @@ run_more_flags() { pr_litecyan "$f2t"; outln "$HEADERVALUE" fileout "$f2t" "WARN" "$f2t: $HEADERVALUE" fi - done + done #TODO: I am not testing for the correctness or anything stupid yet, e.g. "X-Frame-Options: allowall" or Access-Control-Allow-Origin: * if "$first"; then @@ -1637,7 +1785,7 @@ std_cipherlists() { 1) # the ugly ones if [[ $sclient_success -eq 0 ]]; then pr_svrty_critical "offered (NOT ok)" - fileout "std_$4" "NOT ok" "$2 offered (NOT ok) - ugly" + fileout "std_$4" "CRITICAL" "$2 offered (NOT ok) - ugly" else pr_done_best "not offered (OK)" fileout "std_$4" "OK" "$2 not offered (OK)" @@ -1646,7 +1794,7 @@ std_cipherlists() { 2) # bad but not worst if [[ $sclient_success -eq 0 ]]; then pr_svrty_high "offered (NOT ok)" - fileout "std_$4" "NOT ok" "$2 offered (NOT ok) - bad" + fileout "std_$4" "HIGH" "$2 offered (NOT ok) - bad" else pr_done_good "not offered (OK)" fileout "std_$4" "OK" "$2 not offered (OK)" @@ -1662,7 +1810,7 @@ std_cipherlists() { fi ;; *) # we shouldn't reach this - pr_warning "?: $3 (please report this)" + pr_warning "?: $3 (please report this)" fileout "std_$4" "WARN" "return condition $3 unclear" ;; esac @@ -1994,7 +2142,7 @@ run_cipher_per_proto() { locally_supported "$proto" "$proto_text" || continue outln has_server_protocol "${proto:1}" || continue - + # The OpenSSL ciphers function, prior to version 1.1.0, could only understand -ssl2, -ssl3, and -tls1. if [[ "$proto" == "-ssl2" ]] || [[ "$proto" == "-ssl3" ]] || \ [[ $OSSL_VER_MAJOR.$OSSL_VER_MINOR == "1.1.0"* ]] || [[ $OSSL_VER_MAJOR.$OSSL_VER_MINOR == "1.1.1"* ]]; then @@ -2136,7 +2284,7 @@ create_client_simulation_tls_clienthello() { len=2*$(hex2dec "${tls_handshake_ascii:$offset:2}")+2 tls_compression_methods="${tls_handshake_ascii:$offset:$len}" offset=$offset+$len - + if [[ $offset -ge $tls_handshake_ascii_len ]]; then # No extensions out "$tls_handshake_ascii" @@ -3202,11 +3350,11 @@ run_protocols() { add_tls_offered "ssl2" if [[ 0 -eq "$nr_ciphers_detected" ]]; then pr_svrty_highln "supported but couldn't detect a cipher and vulnerable to CVE-2015-3197 "; - fileout "sslv2" "NOT ok" "SSLv2 offered (NOT ok), vulnerable to CVE-2015-3197" + fileout "sslv2" "HIGH" "SSLv2 offered (NOT ok), vulnerable to CVE-2015-3197" else pr_svrty_critical "offered (NOT ok), also VULNERABLE to DROWN attack"; outln " -- $nr_ciphers_detected ciphers" - fileout "sslv2" "NOT ok" "SSLv2 offered (NOT ok), vulnerable to DROWN attack. Detected ciphers: $nr_ciphers_detected" + fileout "sslv2" "CRITICAL" "SSLv2 offered (NOT ok), vulnerable to DROWN attack. Detected ciphers: $nr_ciphers_detected" fi fi ;; esac @@ -3216,7 +3364,7 @@ run_protocols() { case $? in 0) pr_svrty_criticalln "offered (NOT ok)" - fileout "sslv2" "NOT ok" "SSLv2 is offered (NOT ok)" + fileout "sslv2" "CRITICAL" "SSLv2 is offered (NOT ok)" add_tls_offered "ssl2" ;; 1) @@ -3225,7 +3373,7 @@ run_protocols() { ;; 5) pr_svrty_high "CVE-2015-3197: $supported_no_ciph2"; - fileout "sslv2" "WARN" "CVE-2015-3197: SSLv2 is $supported_no_ciph2" + fileout "sslv2" "HIGH" "CVE-2015-3197: SSLv2 is $supported_no_ciph2" add_tls_offered "ssl2" ;; 7) @@ -3243,7 +3391,7 @@ run_protocols() { case $? in 0) pr_svrty_highln "offered (NOT ok)" - fileout "sslv3" "NOT ok" "SSLv3 is offered (NOT ok)" + fileout "sslv3" "HIGH" "SSLv3 is offered (NOT ok)" latest_supported="0300" latest_supported_string="SSLv3" add_tls_offered "ssl3" @@ -3256,18 +3404,18 @@ run_protocols() { if [[ "$DETECTED_TLS_VERSION" == 03* ]]; then detected_version_string="TLSv1.$((0x$DETECTED_TLS_VERSION-0x0301))" pr_svrty_criticalln "server responded with higher version number ($detected_version_string) than requested by client (NOT ok)" - fileout "sslv3" "NOT ok" "SSLv3: server responded with higher version number ($detected_version_string) than requested by client (NOT ok)" + fileout "sslv3" "CRITICAL" "SSLv3: server responded with higher version number ($detected_version_string) than requested by client (NOT ok)" else pr_svrty_criticalln "server responded with version number ${DETECTED_TLS_VERSION:0:2}.${DETECTED_TLS_VERSION:2:2} (NOT ok)" - fileout "sslv3" "NOT ok" "SSLv3: server responded with version number ${DETECTED_TLS_VERSION:0:2}.${DETECTED_TLS_VERSION:2:2} (NOT ok)" + fileout "sslv3" "CRITICAL" "SSLv3: server responded with version number ${DETECTED_TLS_VERSION:0:2}.${DETECTED_TLS_VERSION:2:2} (NOT ok)" fi ;; 5) - fileout "sslv3" "WARN" "SSLv3 is $supported_no_ciph1" pr_svrty_high "$supported_no_ciph2" + fileout "sslv3" "HIGH" "SSLv3 is $supported_no_ciph1" outln "(may need debugging)" add_tls_offered "ssl3" - ;; + ;; 7) fileout "sslv3" "INFO" "SSLv3 is not tested due to lack of local support" ;; # no local support @@ -3294,7 +3442,7 @@ run_protocols() { fileout "tls1" "INFO" "TLSv1.0 is not offered" # neither good or bad else pr_svrty_criticalln " -- connection failed rather than downgrading to $latest_supported_string (NOT ok)" - fileout "tls1" "NOT ok" "TLSv1.0: connection failed rather than downgrading to $latest_supported_string (NOT ok)" + fileout "tls1" "CRITICAL" "TLSv1.0: connection failed rather than downgrading to $latest_supported_string (NOT ok)" fi ;; 2) @@ -3306,10 +3454,10 @@ run_protocols() { elif [[ "$DETECTED_TLS_VERSION" == 03* ]]; then detected_version_string="TLSv1.$((0x$DETECTED_TLS_VERSION-0x0301))" pr_svrty_criticalln " -- server responded with higher version number ($detected_version_string) than requested by client" - fileout "tls1" "NOT ok" "TLSv1.0: server responded with higher version number ($detected_version_string) than requested by client (NOT ok)" + fileout "tls1" "CRITICAL" "TLSv1.0: server responded with higher version number ($detected_version_string) than requested by client (NOT ok)" else pr_svrty_criticalln " -- server responded with version number ${DETECTED_TLS_VERSION:0:2}.${DETECTED_TLS_VERSION:2:2}" - fileout "tls1" "NOT ok" "TLSv1.0: server responded with version number ${DETECTED_TLS_VERSION:0:2}.${DETECTED_TLS_VERSION:2:2} (NOT ok)" + fileout "tls1" "CRITICAL" "TLSv1.0: server responded with version number ${DETECTED_TLS_VERSION:0:2}.${DETECTED_TLS_VERSION:2:2} (NOT ok)" fi ;; 5) @@ -3343,7 +3491,7 @@ run_protocols() { fileout "tls1_1" "INFO" "TLSv1.1 is not offered" # neither good or bad else pr_svrty_criticalln " -- connection failed rather than downgrading to $latest_supported_string" - fileout "tls1_1" "NOT ok" "TLSv1.1: connection failed rather than downgrading to $latest_supported_string (NOT ok)" + fileout "tls1_1" "CRITICAL" "TLSv1.1: connection failed rather than downgrading to $latest_supported_string (NOT ok)" fi ;; 2) @@ -3351,17 +3499,17 @@ run_protocols() { if [[ "$DETECTED_TLS_VERSION" == "$latest_supported" ]]; then [[ $DEBUG -eq 1 ]] && out " -- downgraded" outln - fileout "tls1_1" "NOT ok" "TLSv1.1 is not offered, and downgraded to a weaker protocol (NOT ok)" + fileout "tls1_1" "CRITICAL" "TLSv1.1 is not offered, and downgraded to a weaker protocol (NOT ok)" elif [[ "$DETECTED_TLS_VERSION" == "0300" ]] && [[ "$latest_supported" == "0301" ]]; then pr_svrty_criticalln " -- server supports TLSv1.0, but downgraded to SSLv3 (NOT ok)" - fileout "tls1_1" "NOT ok" "TLSv1.1 is not offered, and downgraded to SSLv3 rather than TLSv1.0 (NOT ok)" + fileout "tls1_1" "CRITICAL" "TLSv1.1 is not offered, and downgraded to SSLv3 rather than TLSv1.0 (NOT ok)" elif [[ "$DETECTED_TLS_VERSION" == 03* ]] && [[ 0x$DETECTED_TLS_VERSION -gt 0x0302 ]]; then detected_version_string="TLSv1.$((0x$DETECTED_TLS_VERSION-0x0301))" pr_svrty_criticalln " -- server responded with higher version number ($detected_version_string) than requested by client (NOT ok)" - fileout "tls1_1" "NOT ok" "TLSv1.1 is not offered, server responded with higher version number ($detected_version_string) than requested by client (NOT ok)" + fileout "tls1_1" "CRITICAL" "TLSv1.1 is not offered, server responded with higher version number ($detected_version_string) than requested by client (NOT ok)" else pr_svrty_criticalln " -- server responded with version number ${DETECTED_TLS_VERSION:0:2}.${DETECTED_TLS_VERSION:2:2} (NOT ok)" - fileout "tls1" "NOT ok" "TLSv1.1: server responded with version number ${DETECTED_TLS_VERSION:0:2}.${DETECTED_TLS_VERSION:2:2} (NOT ok)" + fileout "tls1" "CRITICAL" "TLSv1.1: server responded with version number ${DETECTED_TLS_VERSION:0:2}.${DETECTED_TLS_VERSION:2:2} (NOT ok)" fi ;; 5) @@ -3394,7 +3542,7 @@ run_protocols() { fileout "tls1_2" "MEDIUM" "TLSv1.2 is not offered" # no GCM, penalty else pr_svrty_criticalln " -- connection failed rather than downgrading to $latest_supported_string" - fileout "tls1_1" "NOT ok" "TLSv1.2: connection failed rather than downgrading to $latest_supported_string" + fileout "tls1_1" "CRITICAL" "TLSv1.2: connection failed rather than downgrading to $latest_supported_string" fi ;; 2) @@ -3410,13 +3558,13 @@ run_protocols() { fileout "tls1_2" "MEDIUM" "TLSv1.2 is not offered and downgraded to a weaker protocol" elif [[ "$DETECTED_TLS_VERSION" == 03* ]] && [[ 0x$DETECTED_TLS_VERSION -lt 0x$latest_supported ]]; then pr_svrty_criticalln " -- server supports $latest_supported_string, but downgraded to $detected_version_string" - fileout "tls1_2" "NOT ok" "TLSv1.2 is not offered, and downgraded to $detected_version_string rather than $latest_supported_string (NOT ok)" + fileout "tls1_2" "CRITICAL" "TLSv1.2 is not offered, and downgraded to $detected_version_string rather than $latest_supported_string (NOT ok)" elif [[ "$DETECTED_TLS_VERSION" == 03* ]] && [[ 0x$DETECTED_TLS_VERSION -gt 0x0303 ]]; then pr_svrty_criticalln " -- server responded with higher version number ($detected_version_string) than requested by client" - fileout "tls1_2" "NOT ok" "TLSv1.2 is not offered, server responded with higher version number ($detected_version_string) than requested by client (NOT ok)" + fileout "tls1_2" "CRITICAL" "TLSv1.2 is not offered, server responded with higher version number ($detected_version_string) than requested by client (NOT ok)" else pr_svrty_criticalln " -- server responded with version number ${DETECTED_TLS_VERSION:0:2}.${DETECTED_TLS_VERSION:2:2}" - fileout "tls1" "NOT ok" "TLSv1.2: server responded with version number ${DETECTED_TLS_VERSION:0:2}.${DETECTED_TLS_VERSION:2:2} (NOT ok)" + fileout "tls1" "CRITICAL" "TLSv1.2: server responded with version number ${DETECTED_TLS_VERSION:0:2}.${DETECTED_TLS_VERSION:2:2} (NOT ok)" fi ;; 5) @@ -3503,7 +3651,7 @@ read_dhbits_from_file() { elif [[ "$bits" -le 193 ]]; then # hmm, according to https://wiki.openssl.org/index.php/Elliptic_Curve_Cryptography it should ok pr_svrty_minor "$bits $add" # but openssl removed it https://github.com/drwetter/testssl.sh/issues/299#issuecomment-220905416 elif [[ "$bits" -le 224 ]]; then - out "$bits $add" + out "$bits $add" elif [[ "$bits" -gt 224 ]]; then pr_done_good "$bits $add" else @@ -3533,8 +3681,8 @@ run_server_preference() { outln pr_bold " Has server cipher order? " - [[ "$OPTIMAL_PROTO" == "-ssl2" ]] && addcmd="$OPTIMAL_PROTO" - if [[ ! "$OPTIMAL_PROTO" =~ ssl ]]; then + [[ "$OPTIMAL_PROTO" == "-ssl2" ]] && addcmd="$OPTIMAL_PROTO" + if [[ ! "$OPTIMAL_PROTO" =~ ssl ]]; then addcmd="$SNI" sni="$SNI" if "$HAS_NO_SSL2" && [[ -z "$SNI" ]]; then @@ -3586,7 +3734,7 @@ run_server_preference() { if [[ "$cipher1" != "$cipher2" ]]; then pr_svrty_high "nope (NOT ok)" remark4default_cipher=" (limited sense as client will pick)" - fileout "order" "NOT ok" "Server does NOT set a cipher order (NOT ok)" + fileout "order" "HIGH" "Server does NOT set a cipher order (NOT ok)" else pr_done_best "yes (OK)" remark4default_cipher="" @@ -3618,11 +3766,11 @@ run_server_preference() { ;; *SSLv2) pr_svrty_criticalln $default_proto - fileout "order_proto" "NOT ok" "Default protocol SSLv2" + fileout "order_proto" "CRITICAL" "Default protocol SSLv2" ;; *SSLv3) pr_svrty_criticalln $default_proto - fileout "order_proto" "NOT ok" "Default protocol SSLv3" + fileout "order_proto" "CRITICAL" "Default protocol SSLv3" ;; "") pr_warning "default proto empty" @@ -3644,11 +3792,11 @@ run_server_preference() { case "$default_cipher" in *NULL*|*EXP*) pr_svrty_critical "$default_cipher" - fileout "order_cipher" "NOT ok" "Default cipher: $default_cipher$(read_dhbits_from_file "$TMPFILE") (NOT ok) $remark4default_cipher" + fileout "order_cipher" "CRITICAL" "Default cipher: $default_cipher$(read_dhbits_from_file "$TMPFILE") (NOT ok) $remark4default_cipher" ;; *RC4*) pr_svrty_high "$default_cipher" - fileout "order_cipher" "NOT ok" "Default cipher: $default_cipher$(read_dhbits_from_file "$TMPFILE") (NOT ok) remark4default_cipher" + fileout "order_cipher" "HIGH" "Default cipher: $default_cipher$(read_dhbits_from_file "$TMPFILE") (NOT ok) remark4default_cipher" ;; *CBC*) pr_svrty_medium "$default_cipher" @@ -3660,7 +3808,7 @@ run_server_preference() { ;; # best ones ECDHE*AES*) pr_svrty_minor "$default_cipher" - fileout "order_cipher" "WARN" "Default cipher: $default_cipher$(read_dhbits_from_file "$TMPFILE") (cbc) $remark4default_cipher" + fileout "order_cipher" "LOW" "Default cipher: $default_cipher$(read_dhbits_from_file "$TMPFILE") (cbc) $remark4default_cipher" ;; # it's CBC. --> lucky13 "") pr_warning "default cipher empty" ; @@ -3859,7 +4007,7 @@ cipher_pref_check() { if [[ $p == tls1_2 ]]; then # for some servers the ClientHello is limited to 128 ciphers or the ClientHello itself has a length restriction. # So far, this was only observed in TLS 1.2, affected are e.g. old Cisco LBs or ASAs, see issue #189 - # To check whether a workaround is needed we send a laaarge list of ciphers/big client hello. If connect fails, + # To check whether a workaround is needed we send a laaarge list of ciphers/big client hello. If connect fails, # we hit the bug and automagically do the workround. Cost: this is for all servers only 1x more connect $OPENSSL s_client $STARTTLS -tls1_2 $BUGS -cipher "$overflow_probe_cipherlist" -connect $NODEIP:$PORT $PROXY $SNI >$ERRFILE >$TMPFILE if ! sclient_connect_successful $? $TMPFILE; then @@ -3970,8 +4118,8 @@ determine_trust() { local spaces=" " local -i certificates_provided=1+$(grep -c "\-\-\-\-\-BEGIN CERTIFICATE\-\-\-\-\-" $TEMPDIR/intermediatecerts.pem) local addtl_warning - - # If $json_prefix is not empty, then there is more than one certificate + + # If $json_prefix is not empty, then there is more than one certificate # and the output should should be indented by two more spaces. [[ -n $json_prefix ]] && spaces=" " @@ -4032,7 +4180,7 @@ determine_trust() { # all failed (we assume with the same issue), we're displaying the reason out " " verify_retcode_helper "${verify_retcode[1]}" - fileout "${json_prefix}chain_of_trust" "NOT ok" "All certificate trust checks failed: $(verify_retcode_helper "${verify_retcode[1]}"). $addtl_warning" + fileout "${json_prefix}chain_of_trust" "CRITICAL" "All certificate trust checks failed: $(verify_retcode_helper "${verify_retcode[1]}"). $addtl_warning" else # is one ok and the others not ==> display the culprit store if $some_ok ; then @@ -4055,7 +4203,7 @@ determine_trust() { [[ "$DEBUG" -eq 0 ]] && out "$spaces" pr_done_good "OK: $ok_was" fi - fileout "${json_prefix}chain_of_trust" "NOT ok" "Some certificate trust checks failed : OK : $ok_was NOT ok: $notok_was $addtl_warning" + fileout "${json_prefix}chain_of_trust" "CRITICAL" "Some certificate trust checks failed : OK : $ok_was NOT ok: $notok_was $addtl_warning" fi [[ -n "$addtl_warning" ]] && out "\n$spaces" && pr_warning "$addtl_warning" fi @@ -4135,7 +4283,7 @@ determine_tls_extensions() { savedir=$(pwd); cd $TEMPDIR # http://backreference.org/2010/05/09/ocsp-verification-with-openssl/ awk -v n=-1 '/Server certificate/ {start=1} - /-----BEGIN CERTIFICATE-----/{ if (start) {inc=1; n++} } + /-----BEGIN CERTIFICATE-----/{ if (start) {inc=1; n++} } inc { print > ("level" n ".crt") } /---END CERTIFICATE-----/{ inc=0 }' $TMPFILE nrsaved=$(count_words "$(echo level?.crt 2>/dev/null)") @@ -4164,12 +4312,12 @@ determine_tls_extensions() { $OPENSSL s_client $STARTTLS $BUGS $1 -showcerts -connect $NODEIP:$PORT $PROXY $addcmd -$proto -tlsextdebug $alpn_params -status $ERRFILE >$TMPFILE if sclient_connect_successful $? $TMPFILE; then success=0 - grep -a 'TLS server extension' $TMPFILE >$TEMPDIR/tlsext-alpn.txt + grep -a 'TLS server extension' $TMPFILE >$TEMPDIR/tlsext-alpn.txt fi $OPENSSL s_client $STARTTLS $BUGS $1 -showcerts -connect $NODEIP:$PORT $PROXY $addcmd -$proto -tlsextdebug $npn_params -status $ERRFILE >$TMPFILE if sclient_connect_successful $? $TMPFILE ; then - success=0 - grep -a 'TLS server extension' $TMPFILE >$TEMPDIR/tlsext-npn.txt + success=0 + grep -a 'TLS server extension' $TMPFILE >$TEMPDIR/tlsext-npn.txt break fi done # this loop is needed for IIS6 and others which have a handshake size limitations @@ -4199,7 +4347,7 @@ determine_tls_extensions() { savedir=$(pwd); cd $TEMPDIR # http://backreference.org/2010/05/09/ocsp-verification-with-openssl/ awk -v n=-1 '/Certificate chain/ {start=1} - /-----BEGIN CERTIFICATE-----/{ if (start) {inc=1; n++} } + /-----BEGIN CERTIFICATE-----/{ if (start) {inc=1; n++} } inc { print > ("level" n ".crt") } /---END CERTIFICATE-----/{ inc=0 }' $TMPFILE nrsaved=$(count_words "$(echo level?.crt 2>/dev/null)") @@ -4227,7 +4375,7 @@ get_cn_from_cert() { local subject # attention! openssl 1.0.2 doesn't properly handle online output from certifcates from trustwave.com/github.com - #FIXME: use -nameopt oid for robustness + #FIXME: use -nameopt oid for robustness # for e.g. russian sites -esc_msb,utf8 works in an UTF8 terminal -- any way to check platform indepedent? # see x509(1ssl): @@ -4289,7 +4437,7 @@ wildcard_match() basename_offset=$len_servername-$len_basename # Check that initial part of $servername matches initial part of $certname - # and that final part of $servername matches final part of $certname. + # and that final part of $servername matches final part of $certname. [[ "${servername:0:len_part1}" != "${certname:0:len_part1}" ]] && return 1 [[ "${servername:basename_offset:len_basename}" != "$basename" ]] && return 1 @@ -4397,7 +4545,7 @@ certificate_info() { else spaces=" " fi - + cert_sig_algo=$($OPENSSL x509 -in $HOSTCERT -noout -text 2>>$ERRFILE | grep "Signature Algorithm" | sed 's/^.*Signature Algorithm: //' | sort -u ) cert_key_algo=$($OPENSSL x509 -in $HOSTCERT -noout -text 2>>$ERRFILE | awk -F':' '/Public Key Algorithm:/ { print $2 }' | sort -u ) @@ -4490,15 +4638,15 @@ certificate_info() { ;; md2*) pr_svrty_criticalln "MD2" - fileout "${json_prefix}algorithm" "NOT ok" "Signature Algorithm: MD2 (NOT ok)" + fileout "${json_prefix}algorithm" "CRITICAL" "Signature Algorithm: MD2 (NOT ok)" ;; md4*) pr_svrty_criticalln "MD4" - fileout "${json_prefix}algorithm" "NOT ok" "Signature Algorithm: MD4 (NOT ok)" + fileout "${json_prefix}algorithm" "CRITICAL" "Signature Algorithm: MD4 (NOT ok)" ;; md5*) pr_svrty_criticalln "MD5" - fileout "${json_prefix}algorithm" "NOT ok" "Signature Algorithm: MD5 (NOT ok)" + fileout "${json_prefix}algorithm" "CRITICAL" "Signature Algorithm: MD5 (NOT ok)" ;; *) out "$cert_sig_algo (" @@ -4527,12 +4675,12 @@ certificate_info() { # see http://csrc.nist.gov/publications/nistpubs/800-57/sp800-57_part1_rev3_general.pdf # Table 2 @ chapter 5.6.1 (~ p64) if [[ $cert_key_algo =~ ecdsa ]] || [[ $cert_key_algo =~ ecPublicKey ]]; then - if [[ "$cert_keysize" -le 110 ]]; then # a guess + if [[ "$cert_keysize" -le 110 ]]; then # a guess pr_svrty_critical "$cert_keysize" - fileout "${json_prefix}key_size" "NOT ok" "Server keys $cert_keysize EC bits (NOT ok)" + fileout "${json_prefix}key_size" "CRITICAL" "Server keys $cert_keysize EC bits (NOT ok)" elif [[ "$cert_keysize" -le 123 ]]; then # a guess pr_svrty_high "$cert_keysize" - fileout "${json_prefix}key_size" "NOT ok" "Server keys $cert_keysize EC bits (NOT ok)" + fileout "${json_prefix}key_size" "HIGH" "Server keys $cert_keysize EC bits (NOT ok)" elif [[ "$cert_keysize" -le 163 ]]; then pr_svrty_medium "$cert_keysize" fileout "${json_prefix}key_size" "MEDIUM" "Server keys $cert_keysize EC bits" @@ -4552,11 +4700,11 @@ certificate_info() { if [[ "$cert_keysize" -le 512 ]]; then pr_svrty_critical "$cert_keysize" outln " bits" - fileout "${json_prefix}key_size" "NOT ok" "Server keys $cert_keysize bits (NOT ok)" + fileout "${json_prefix}key_size" "CRITICAL" "Server keys $cert_keysize bits (NOT ok)" elif [[ "$cert_keysize" -le 768 ]]; then pr_svrty_high "$cert_keysize" outln " bits" - fileout "${json_prefix}key_size" "NOT ok" "Server keys $cert_keysize bits (NOT ok)" + fileout "${json_prefix}key_size" "HIGH" "Server keys $cert_keysize bits (NOT ok)" elif [[ "$cert_keysize" -le 1024 ]]; then pr_svrty_medium "$cert_keysize" outln " bits" @@ -4588,7 +4736,7 @@ certificate_info() { outln "$spaces$cert_fingerprint_sha2" fileout "${json_prefix}fingerprint" "INFO" "Fingerprints / Serial: $cert_fingerprint_sha1 / $cert_fingerprint_serial, $cert_fingerprint_sha2" [[ -z $CERT_FINGERPRINT_SHA2 ]] && \ - CERT_FINGERPRINT_SHA2="$cert_fingerprint_sha2" || + CERT_FINGERPRINT_SHA2="$cert_fingerprint_sha2" || CERT_FINGERPRINT_SHA2="$cert_fingerprint_sha2 $CERT_FINGERPRINT_SHA2" out "$indent"; pr_bold " Common Name (CN) " @@ -4666,7 +4814,7 @@ certificate_info() { if [[ "$issuer_O" == "issuer=" ]] || [[ "$issuer_O" == "issuer= " ]] || [[ "$issuer_CN" == "$cn" ]]; then pr_svrty_criticalln "self-signed (NOT ok)" - fileout "${json_prefix}issuer" "NOT ok" "Issuer: selfsigned (NOT ok)" + fileout "${json_prefix}issuer" "CRITICAL" "Issuer: selfsigned (NOT ok)" else issuerfinding="$(pr_dquoted "$issuer_CN")" if [[ -z "$issuer_O" ]] && [[ -n "$issuer_DC" ]]; then @@ -4820,7 +4968,7 @@ certificate_info() { if ! echo $expire | grep -qw not; then pr_svrty_critical "expired!" expfinding="expired!" - expok="NOT ok" + expok="CRITICAL" else secs2warn=$((24 * 60 * 60 * days2warn2)) # low threshold first expire=$($OPENSSL x509 -in $HOSTCERT -checkend $secs2warn 2>>$ERRFILE) @@ -4833,12 +4981,12 @@ certificate_info() { else pr_svrty_medium "expires < $days2warn1 days ($days2expire)" expfinding+="expires < $days2warn1 days ($days2expire)" - expok="WARN" + expok="MEDIUM" fi else pr_svrty_high "expires < $days2warn2 days ($days2expire) !" expfinding+="expires < $days2warn2 days ($days2expire) !" - expok="NOT ok" + expok="HIGH" fi fi outln " ($startdate --> $enddate)" @@ -4852,7 +5000,7 @@ certificate_info() { crl="$($OPENSSL x509 -in $HOSTCERT -noout -text 2>>$ERRFILE | grep -A 4 "CRL Distribution" | grep URI | sed 's/^.*URI://')" if [[ -z "$crl" ]]; then pr_svrty_highln "--" - fileout "${json_prefix}crl" "NOT ok" "No CRL provided (NOT ok)" + fileout "${json_prefix}crl" "HIGH" "No CRL provided (NOT ok)" elif grep -q http <<< "$crl"; then if [[ $(count_lines "$crl") -eq 1 ]]; then outln "$crl" @@ -4870,7 +5018,7 @@ certificate_info() { ocsp_uri=$($OPENSSL x509 -in $HOSTCERT -noout -ocsp_uri 2>>$ERRFILE) if [[ -z "$ocsp_uri" ]]; then pr_svrty_highln "--" - fileout "${json_prefix}ocsp_uri" "NOT ok" "OCSP URI : -- (NOT ok)" + fileout "${json_prefix}ocsp_uri" "HIGH" "OCSP URI : -- (NOT ok)" else outln "$ocsp_uri" fileout "${json_prefix}ocsp_uri" "INFO" "OCSP URI : $ocsp_uri" @@ -4879,7 +5027,7 @@ certificate_info() { out "$indent"; pr_bold " OCSP stapling " if grep -a "OCSP response" <<<"$ocsp_response" | grep -q "no response sent" ; then pr_svrty_minor "--" - fileout "${json_prefix}ocsp_stapling" "INFO" "OCSP stapling : not offered" + fileout "${json_prefix}ocsp_stapling" "LOW" "OCSP stapling : not offered" else if grep -a "OCSP Response Status" <<<"$ocsp_response_status" | grep -q successful; then pr_done_good "offered" @@ -4973,7 +5121,7 @@ run_server_defaults() { all_tls_extensions="${all_tls_extensions} \"${line}\"" fi done <<<$TLS_EXTENSIONS - + cp "$TEMPDIR/$NODEIP.determine_tls_extensions.txt" $TMPFILE >$ERRFILE if [[ -z "$sessticket_str" ]]; then @@ -5042,7 +5190,7 @@ run_server_defaults() { fi fi done - + if [[ $certs_found -eq 0 ]]; then [[ -z "$TLS_EXTENSIONS" ]] && determine_tls_extensions [[ -n "$TLS_EXTENSIONS" ]] && all_tls_extensions=" $TLS_EXTENSIONS" @@ -5077,9 +5225,9 @@ run_server_defaults() { unit=$(echo $sessticket_str | grep -a lifetime | sed -e 's/^.*'"$lifetime"'//' -e 's/[ ()]//g') out "$lifetime $unit " pr_svrty_minorln "(PFS requires session ticket keys to be rotated <= daily)" - fileout "session_ticket" "INFO" "TLS session tickes RFC 5077 valid for $lifetime $unit (PFS requires session ticket keys to be rotated at least daily)" + fileout "session_ticket" "LOW" "TLS session tickes RFC 5077 valid for $lifetime $unit (PFS requires session ticket keys to be rotated at least daily)" fi - + pr_bold " SSL Session ID support " if "$NO_SSL_SESSIONID"; then outln "no" @@ -5088,9 +5236,9 @@ run_server_defaults() { outln "yes" fileout "session_id" "INFO" "SSL session ID support: yes" fi - + tls_time - + i=1 while [[ $i -le $certs_found ]]; do echo "${previous_hostcert[i]}" > $HOSTCERT @@ -5189,7 +5337,7 @@ run_pfs() { if ! "$pfs_offered"; then pr_svrty_medium "WARN: no PFS ciphers found" - fileout "pfs_ciphers" "NOT ok" "(Perfect) Forward Secrecy Ciphers: no PFS ciphers found (NOT ok)" + fileout "pfs_ciphers" "MEDIUM" "(Perfect) Forward Secrecy Ciphers: no PFS ciphers found (NOT ok)" else fileout "pfs_ciphers" "INFO" "(Perfect) Forward Secrecy Ciphers: $pfs_ciphers" fi @@ -5738,7 +5886,7 @@ parse_sslv2_serverhello() { echo "SSLv2 cipher spec length: 0x$v2_hello_cipherspec_length" fi fi - + certificate_len=2*$(hex2dec "$v2_hello_cert_length") [[ -e $HOSTCERT ]] && rm $HOSTCERT [[ -e $TEMPDIR/intermediatecerts.pem ]] && rm $TEMPDIR/intermediatecerts.pem @@ -5760,7 +5908,7 @@ parse_sslv2_serverhello() { let offset=$offset+6 done echo "======================================" >> $TMPFILE - + tmpfile_handle $FUNCNAME.txt fi return $ret @@ -5864,13 +6012,17 @@ parse_tls_serverhello() { local tls_handshake_ascii="" tls_alert_ascii="" local -i tls_hello_ascii_len tls_handshake_ascii_len tls_alert_ascii_len msg_len local tls_serverhello_ascii="" + local tls_serverkeyexchange_ascii="" local -i tls_serverhello_ascii_len=0 + local -i tls_serverkeyexchange_ascii_len=0 local tls_alert_descrip tls_sid_len_hex local -i tls_sid_len offset extns_offset local tls_msg_type tls_content_type tls_protocol tls_protocol2 tls_hello_time - local tls_err_level tls_err_descr tls_cipher_suite tls_compression_method - local tls_extensions="" extension_type + local tls_err_level tls_err_descr tls_cipher_suite rfc_cipher_suite tls_compression_method + local tls_extensions="" extension_type named_curve_str="" local -i i j extension_len tls_extensions_len + local -i curve_type named_curve + local -i dh_bits=0 msb mask TLS_TIME="" DETECTED_TLS_VERSION="" @@ -6028,7 +6180,7 @@ parse_tls_serverhello() { done fi - # Now extract just the server hello handshake message. + # Now extract just the server hello and server key exchange handshake messages. tls_handshake_ascii_len=${#tls_handshake_ascii} if [[ $DEBUG -ge 2 ]] && [[ $tls_handshake_ascii_len -gt 0 ]]; then echo "TLS handshake messages:" @@ -6095,6 +6247,13 @@ parse_tls_serverhello() { fi tls_serverhello_ascii="${tls_handshake_ascii:i:msg_len}" tls_serverhello_ascii_len=$msg_len + elif ( [[ "$process_full" == "all" ]] || [[ "$process_full" == "ephemeralkey" ]] ) && [[ "$tls_msg_type" == "0C" ]]; then + if [[ -n "$tls_serverkeyexchange_ascii" ]]; then + debugme pr_warningln "Response contained more than one ServerKeyExchange handshake message." + return 1 + fi + tls_serverkeyexchange_ascii="${tls_handshake_ascii:i:msg_len}" + tls_serverkeyexchange_ascii_len=$msg_len fi done @@ -6224,10 +6383,11 @@ parse_tls_serverhello() { fi echo "===============================================================================" >> $TMPFILE if [[ "${tls_cipher_suite:0:2}" == "00" ]]; then - echo "Cipher : $(show_rfc_style "x${tls_cipher_suite:2:2}")" >> $TMPFILE + rfc_cipher_suite="$(show_rfc_style "x${tls_cipher_suite:2:2}")" else - echo "Cipher : $(show_rfc_style "x${tls_cipher_suite:0:4}")" >> $TMPFILE + rfc_cipher_suite="$(show_rfc_style "x${tls_cipher_suite:0:4}")" fi + echo "Cipher : $rfc_cipher_suite" >> $TMPFILE if [[ "0x${tls_protocol2:2:2}" -le "0x03" ]]; then case $tls_compression_method in 00) echo "Compression: NONE" >> $TMPFILE ;; @@ -6263,6 +6423,92 @@ parse_tls_serverhello() { fi outln fi + + # Now parse the server key exchange message + if [[ $tls_serverkeyexchange_ascii_len -ne 0 ]]; then + if [[ $rfc_cipher_suite =~ "TLS_ECDHE_" ]] || [[ $rfc_cipher_suite =~ "TLS_ECDH_anon" ]]; then + if [[ $tls_serverkeyexchange_ascii_len -lt 6 ]]; then + debugme echo "Malformed ServerKeyExchange Handshake message in ServerHello." + tmpfile_handle $FUNCNAME.txt + return 1 + fi + curve_type=$(hex2dec "${tls_serverkeyexchange_ascii:0:2}") + if [[ $curve_type -eq 3 ]]; then + # named_curve - the curve is identified by a 2-byte number + named_curve=$(hex2dec "${tls_serverkeyexchange_ascii:2:4}") + # http://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-8 + case $named_curve in + 1) dh_bits=163 ; named_curve_str="K-163" ;; + 2) dh_bits=163 ; named_curve_str="sect163r1" ;; + 3) dh_bits=163 ; named_curve_str="B-163" ;; + 4) dh_bits=193 ; named_curve_str="sect193r1" ;; + 5) dh_bits=193 ; named_curve_str="sect193r2" ;; + 6) dh_bits=233 ; named_curve_str="K-233" ;; + 7) dh_bits=233 ; named_curve_str="B-233" ;; + 8) dh_bits=239 ; named_curve_str="sect239k1" ;; + 9) dh_bits=283 ; named_curve_str="K-283" ;; + 10) dh_bits=283 ; named_curve_str="B-283" ;; + 11) dh_bits=409 ; named_curve_str="K-409" ;; + 12) dh_bits=409 ; named_curve_str="B-409" ;; + 13) dh_bits=571 ; named_curve_str="K-571" ;; + 14) dh_bits=571 ; named_curve_str="B-571" ;; + 15) dh_bits=160 ; named_curve_str="secp160k1" ;; + 16) dh_bits=160 ; named_curve_str="secp160r1" ;; + 17) dh_bits=160 ; named_curve_str="secp160r2" ;; + 18) dh_bits=192 ; named_curve_str="secp192k1" ;; + 19) dh_bits=192 ; named_curve_str="P-192" ;; + 20) dh_bits=224 ; named_curve_str="secp224k1" ;; + 21) dh_bits=224 ; named_curve_str="P-224" ;; + 22) dh_bits=256 ; named_curve_str="secp256k1" ;; + 23) dh_bits=256 ; named_curve_str="P-256" ;; + 24) dh_bits=384 ; named_curve_str="P-384" ;; + 25) dh_bits=521 ; named_curve_str="P-521" ;; + 26) dh_bits=256 ; named_curve_str="brainpoolP256r1" ;; + 27) dh_bits=384 ; named_curve_str="brainpoolP384r1" ;; + 28) dh_bits=512 ; named_curve_str="brainpoolP512r1" ;; + 29) dh_bits=256 ; named_curve_str="X25519" ;; + 30) dh_bits=448 ; named_curve_str="X448" ;; + esac + fi + [[ $DEBUG -ge 2 ]] && [[ $dh_bits -ne 0 ]] && echo "dh_bits: ECDH, $named_curve_str, $dh_bits bits" + [[ $dh_bits -ne 0 ]] && echo "Server Temp Key: ECDH, $named_curve_str, $dh_bits bits" >> $TMPFILE + elif [[ $rfc_cipher_suite =~ "TLS_DHE_" ]] || [[ $rfc_cipher_suite =~ "TLS_DH_anon" ]]; then + # For DH ephemeral keys the first field is p, and the length of + # p is the same as the length of the public key. + if [[ $tls_serverkeyexchange_ascii_len -lt 4 ]]; then + debugme echo "Malformed ServerKeyExchange Handshake message in ServerHello." + tmpfile_handle $FUNCNAME.txt + return 1 + fi + dh_bits=$(hex2dec "${tls_serverkeyexchange_ascii:0:4}") + offset=4+2*$dh_bits + if [[ $tls_serverkeyexchange_ascii_len -lt $offset ]]; then + debugme echo "Malformed ServerKeyExchange Handshake message in ServerHello." + tmpfile_handle $FUNCNAME.txt + return 1 + fi + + # Subtract any leading 0 bits + for (( i=4; i < offset; i=i+2 )); do + [[ "${tls_serverkeyexchange_ascii:i:2}" != "00" ]] && break + dh_bits=$dh_bits-1 + done + if [[ $i -ge $offset ]]; then + debugme echo "Malformed ServerKeyExchange Handshake message in ServerHello." + tmpfile_handle $FUNCNAME.txt + return 1 + fi + + dh_bits=8*$dh_bits + msb=$(hex2dec "${tls_serverkeyexchange_ascii:i:2}") + for (( mask=128; msb < mask; mask/=2 )); do + dh_bits=$dh_bits-1 + done + + [[ $DEBUG -ge 2 ]] && [[ $dh_bits -ne 0 ]] && echo "dh_bits: DH,$named_curve_str $dh_bits bits" + [[ $dh_bits -ne 0 ]] && echo "Server Temp Key: DH,$named_curve_str $dh_bits bits" >> $TMPFILE + fi + fi tmpfile_handle $FUNCNAME.txt return 0 } @@ -6530,7 +6776,7 @@ socksend_tls_clienthello() { all_extensions=" ,$LEN_STR # first the len of all extentions. ,$all_extensions" - + fi # RFC 3546 doesn't specify SSLv3 to have SNI, openssl just ignores the switch if supplied @@ -6618,7 +6864,7 @@ tls_sockets() { if [[ $ret -eq 0 ]]; then sockread_serverhello 32768 TLS_NOW=$(LC_ALL=C date "+%s") - + tls_hello_ascii=$(hexdump -v -e '16/1 "%02X"' "$SOCK_REPLY_FILE") tls_hello_ascii="${tls_hello_ascii%%[!0-9A-F]*}" @@ -6716,7 +6962,7 @@ tls_sockets() { # mainly adapted from https://gist.github.com/takeshixx/10107280 run_heartbleed(){ local tls_proto_offered tls_hexcode - local heartbleed_payload client_hello + local heartbleed_payload client_hello local -i n ret lines_returned local -i hb_rounds=3 local append="" @@ -6837,7 +7083,7 @@ run_heartbleed(){ else rm "$SOCK_REPLY_FILE" pr_svrty_critical "VULNERABLE (NOT ok)" - fileout "heartbleed" "NOT ok" "Heartbleed (CVE-2014-0160): VULNERABLE (NOT ok)$append" + fileout "heartbleed" "CRITICAL" "Heartbleed (CVE-2014-0160): VULNERABLE (NOT ok)$append" ret=1 break fi @@ -6863,7 +7109,7 @@ run_heartbleed(){ out "likely " pr_svrty_critical "VULNERABLE (NOT ok)" [[ $DEBUG -ge 1 ]] && out " use debug >=2 to confirm" - fileout "heartbleed" "NOT ok" "Heartbleed (CVE-2014-0160): likely VULNERABLE (NOT ok)$append" + fileout "heartbleed" "CRITICAL" "Heartbleed (CVE-2014-0160): likely VULNERABLE (NOT ok)$append" fi else # for the repeated tries we did that already @@ -6998,9 +7244,9 @@ run_ccs_injection(){ else pr_svrty_critical "VULNERABLE (NOT ok)" if [[ $retval -eq 3 ]]; then - fileout "ccs" "NOT ok" "CCS (CVE-2014-0224): VULNERABLE (NOT ok) (timed out)" + fileout "ccs" "CRITICAL" "CCS (CVE-2014-0224): VULNERABLE (NOT ok) (timed out)" else - fileout "ccs" "NOT ok" "CCS (CVE-2014-0224): VULNERABLE (NOT ok)" + fileout "ccs" "CRITICAL" "CCS (CVE-2014-0224): VULNERABLE (NOT ok)" fi ret=1 fi @@ -7031,7 +7277,7 @@ run_renego() { case $sec_renego in 0) pr_svrty_criticalln "VULNERABLE (NOT ok)" - fileout "secure_renego" "NOT ok" "Secure Renegotiation (CVE-2009-3555) : VULNERABLE (NOT ok)" + fileout "secure_renego" "CRITICAL" "Secure Renegotiation (CVE-2009-3555) : VULNERABLE (NOT ok)" ;; 1) pr_done_bestln "not vulnerable (OK)" @@ -7148,7 +7394,7 @@ run_crime() { else if [[ $SERVICE == "HTTP" ]]; then pr_svrty_high "VULNERABLE (NOT ok)" - fileout "crime" "NOT ok" "CRIME, TLS (CVE-2012-4929) : VULNERABLE (NOT ok)" + fileout "crime" "HIGH" "CRIME, TLS (CVE-2012-4929) : VULNERABLE (NOT ok)" else pr_svrty_medium "VULNERABLE but not using HTTP: probably no exploit known" fileout "crime" "MEDIUM" "CRIME, TLS (CVE-2012-4929) : VULNERABLE (WARN), but not using HTTP: probably no exploit known" @@ -7249,7 +7495,7 @@ run_breach() { pr_svrty_high "potentially NOT ok, uses $result HTTP compression." outln "$disclaimer" outln "$spaces$when_makesense" - fileout "breach" "NOT ok" "BREACH (CVE-2013-3587) : potentially VULNERABLE, uses $result HTTP compression. $disclaimer ($when_makesense)" + fileout "breach" "HIGH" "BREACH (CVE-2013-3587) : potentially VULNERABLE, uses $result HTTP compression. $disclaimer ($when_makesense)" ret=1 fi # Any URL can be vulnerable. I am testing now only the given URL! @@ -7275,7 +7521,7 @@ run_ssl_poodle() { [[ "$DEBUG" -eq 2 ]] && egrep -q "error|failure" $ERRFILE | egrep -av "unable to get local|verify error" if [[ $sclient_success -eq 0 ]]; then pr_svrty_high "VULNERABLE (NOT ok)"; out ", uses SSLv3+CBC (check TLS_FALLBACK_SCSV mitigation below)" - fileout "poodle_ssl" "NOT ok" "POODLE, SSL (CVE-2014-3566) : VULNERABLE (NOT ok), uses SSLv3+CBC (check if TLS_FALLBACK_SCSV mitigation is used)" + fileout "poodle_ssl" "HIGH" "POODLE, SSL (CVE-2014-3566) : VULNERABLE (NOT ok), uses SSLv3+CBC (check if TLS_FALLBACK_SCSV mitigation is used)" else pr_done_best "not vulnerable (OK)" fileout "poodle_ssl" "OK" "POODLE, SSL (CVE-2014-3566) : not vulnerable (OK)" @@ -7396,7 +7642,7 @@ run_freak() { [[ $DEBUG -eq 2 ]] && egrep -a "error|failure" $ERRFILE | egrep -av "unable to get local|verify error" if [[ $sclient_success -eq 0 ]]; then pr_svrty_critical "VULNERABLE (NOT ok)"; out ", uses EXPORT RSA ciphers" - fileout "freak" "NOT ok" "FREAK (CVE-2015-0204) : VULNERABLE (NOT ok), uses EXPORT RSA ciphers" + fileout "freak" "CRITICAL" "FREAK (CVE-2015-0204) : VULNERABLE (NOT ok), uses EXPORT RSA ciphers" else pr_done_best "not vulnerable (OK)"; out "$addtl_warning" fileout "freak" "OK" "FREAK (CVE-2015-0204) : not vulnerable (OK) $addtl_warning" @@ -7448,7 +7694,7 @@ run_logjam() { if [[ $sclient_success -eq 0 ]]; then pr_svrty_critical "VULNERABLE (NOT ok)"; out ", uses DHE EXPORT ciphers, common primes not checked." - fileout "logjam" "NOT ok" "LOGJAM (CVE-2015-4000) : VULNERABLE (NOT ok), uses DHE EXPORT ciphers, common primes not checked." + fileout "logjam" "CRITICAL" "LOGJAM (CVE-2015-4000) : VULNERABLE (NOT ok), uses DHE EXPORT ciphers, common primes not checked." else pr_done_best "not vulnerable (OK)"; out "$addtl_warning" fileout "logjam" "OK" "LOGJAM (CVE-2015-4000) : not vulnerable (OK) $addtl_warning" @@ -7485,7 +7731,7 @@ run_drown() { outln " (rerun with DEBUG >=2)" [[ $DEBUG -ge 3 ]] && hexdump -C "$TEMPDIR/$NODEIP.sslv2_sockets.dd" | head -1 ret=7 - fileout "drown" "MINOR_ERROR" "SSLv2: received a strange SSLv2 reply (rerun with DEBUG>=2)" + fileout "drown" "WARN" "SSLv2: received a strange SSLv2 reply (rerun with DEBUG>=2)" ;; 3) # vulnerable lines=$(count_lines "$(hexdump -C "$TEMPDIR/$NODEIP.sslv2_sockets.dd" 2>/dev/null)") @@ -7494,10 +7740,10 @@ run_drown() { nr_ciphers_detected=$((V2_HELLO_CIPHERSPEC_LENGTH / 3)) if [[ 0 -eq "$nr_ciphers_detected" ]]; then pr_svrty_highln "CVE-2015-3197: SSLv2 supported but couldn't detect a cipher (NOT ok)"; - fileout "drown" "NOT ok" "SSLv2 offered (NOT ok), CVE-2015-3197: but could not detect a cipher" + fileout "drown" "HIGH" "SSLv2 offered (NOT ok), CVE-2015-3197: but could not detect a cipher" else pr_svrty_criticalln "VULNERABLE (NOT ok), SSLv2 offered with $nr_ciphers_detected ciphers"; - fileout "drown" "NOT ok" "VULNERABLE (NOT ok), SSLv2 offered with $nr_ciphers_detected ciphers" + fileout "drown" "CRITICAL" "VULNERABLE (NOT ok), SSLv2 offered with $nr_ciphers_detected ciphers" fi fi ret=1 @@ -7603,7 +7849,7 @@ run_beast(){ sclient_connect_successful $? $TMPFILE sclient_success=$? if [[ $sclient_success -eq 0 ]]; then - vuln_beast=true + vuln_beast=true "$WIDE" && first=false fi if "$WIDE"; then @@ -7613,7 +7859,7 @@ run_beast(){ neat_list "$HEXC" "$cbc_cipher" "$kx" "$enc" #why this is needed? if [[ $sclient_success -eq 0 ]]; then if [[ -n "$higher_proto_supported" ]]; then - pr_svrty_minorln "available" + pr_svrty_minorln "available" else pr_svrty_mediumln "available" fi @@ -7675,7 +7921,7 @@ run_beast(){ pr_svrty_minor "VULNERABLE" outln " -- but also supports higher protocols (possible mitigation):$higher_proto_supported" fi - fileout "beast" "MINOR" "BEAST (CVE-2011-3389) : VULNERABLE -- but also supports higher protocols (possible mitigation):$higher_proto_supported" + fileout "beast" "LOW" "BEAST (CVE-2011-3389) : VULNERABLE -- but also supports higher protocols (possible mitigation):$higher_proto_supported" else if "$WIDE"; then outln @@ -7771,7 +8017,7 @@ run_rc4() { done < <($OPENSSL ciphers -V $rc4_ciphers_list:@STRENGTH) outln "$WIDE" && pr_svrty_high "VULNERABLE (NOT ok)" - fileout "rc4" "NOT ok" "RC4 (CVE-2013-2566, CVE-2015-2808) : VULNERABLE (NOT ok) Detected ciphers: $rc4_detected" + fileout "rc4" "HIGH" "RC4 (CVE-2013-2566, CVE-2015-2808) : VULNERABLE (NOT ok) Detected ciphers: $rc4_detected" else pr_done_goodln "no RC4 ciphers detected (OK)" fileout "rc4" "OK" "RC4 (CVE-2013-2566, CVE-2015-2808) : not vulnerable (OK)" @@ -7802,13 +8048,13 @@ run_tls_truncation() { old_fart() { outln "Get precompiled bins or compile https://github.com/PeterMosmans/openssl ." - fileout "old_fart" "ERROR" "Your $OPENSSL $OSSL_VER version is an old fart... . It doesn\'t make much sense to proceed. Get precompiled bins or compile https://github.com/PeterMosmans/openssl ." + fileout "old_fart" "WARN" "Your $OPENSSL $OSSL_VER version is an old fart... . It doesn\'t make much sense to proceed. Get precompiled bins or compile https://github.com/PeterMosmans/openssl ." fatal "Your $OPENSSL $OSSL_VER version is an old fart... . It doesn\'t make much sense to proceed." -5 } # try very hard to determine the install path to get ahold of the mapping file and the CA bundles # TESTSSL_INSTALL_DIR can be supplied via environment so that the RFC mapping and CA bundles can be found -# (mapping file provides "keycode/ RFC style name", see RFCs, cipher(1), +# (mapping file provides "keycode/ RFC style name", see RFCs, cipher(1), # www.carbonwind.net/TLS_Cipher_Suites_Project/tls_ssl_cipher_suites_simple_table_all.htm get_install_dir() { [[ -z "$TESTSSL_INSTALL_DIR" ]] && TESTSSL_INSTALL_DIR="$(dirname ${BASH_SOURCE[0]})" @@ -7988,7 +8234,7 @@ check4openssl_oldfarts() { # FreeBSD needs to have /dev/fd mounted. This is a friendly hint, see #258 check_bsd_mount() { - if [[ "$(uname)" == FreeBSD ]]; then + if [[ "$(uname)" == FreeBSD ]]; then if ! mount | grep -q "^devfs"; then outln "you seem to run $PROG_NAME= in a jail. Hopefully you're did \"mount -t fdescfs fdesc /dev/fd\"" elif mount | grep '/dev/fd' | grep -q fdescfs; then @@ -8054,7 +8300,7 @@ special invocations: partly mandatory parameters: URI host|host:port|URL|URL:port (port 443 is assumed unless otherwise specified) pattern an ignore case word pattern of cipher hexcode or any other string in the name, kx or bits - protocol is one of the STARTTLS protocols ftp,smtp,pop3,imap,xmpp,telnet,ldap + protocol is one of the STARTTLS protocols ftp,smtp,pop3,imap,xmpp,telnet,ldap (for the latter two you need e.g. the supplied openssl) tuning options (can also be preset via environment variables): @@ -8082,9 +8328,12 @@ file output options (can also be preset via environment variables): --logfile logs stdout to if file is a dir or to specified log file --json additional output of findings to JSON file in cwd --jsonfile additional output to JSON and output JSON to the specified file + --json-pretty additional pretty structed output of findings to JSON file in cwd + --jsonfile-pretty additional pretty structed output to JSON and output JSON to the specified file --csv additional output of findings to CSV file in cwd --csvfile set output to CSV and output CSV to the specified file --append if or exists rather append then overwrite + --severity severities with lower level will be filtered All options requiring a value can also be called with '=' e.g. testssl.sh -t=smtp --wide --openssl=/usr/bin/openssl . @@ -8752,7 +9001,7 @@ prepare_logging() { #exec 2> >(tee -a ${LOGFILE} >&2) fi - if "$do_json"; then + if "$do_json" || "$do_pretty_json"; then if [[ -z "$JSONFILE" ]]; then JSONFILE=$fname_prefix-$(date +"%Y%m%d-%H%M".json) elif [[ -d "$JSONFILE" ]]; then @@ -8773,7 +9022,7 @@ prepare_logging() { return 0 } - + # args: string containing ip addresses filter_ip6_address() { local a @@ -9282,7 +9531,7 @@ run_mass_testing_parallel() { fi pr_reverse "====== Running in parallel file batch mode with file=\"$FNAME\" ======"; outln outln "(output is in ....\n)" -#FIXME: once this function is being called we need a handler which does the right thing +#FIXME: once this function is being called we need a handler which does the right thing # ==> not overwrite while read cmdline; do cmdline=$(filter_input "$cmdline") @@ -9343,6 +9592,7 @@ initialize_globals() { do_mass_testing=false do_logging=false do_json=false + do_pretty_json=false do_csv=false do_pfs=false do_protocols=false @@ -9686,6 +9936,18 @@ parse_cmd_line() { [[ $? -eq 0 ]] && shift do_json=true ;; + --json-pretty) + do_pretty_json=true + ;; + --jsonfile-pretty|--jsonfile-pretty=*) + JSONFILE=$(parse_opt_equal_sign "$1" "$2") + [[ $? -eq 0 ]] && shift + do_pretty_json=true + ;; + --severity|--severity=*) + set_severity_level "$(parse_opt_equal_sign "$1" "$2")" + [[ $? -eq 0 ]] && shift + ;; --csv) do_csv=true ;; # DEFINITION of CSVFILE is not arg specified: automagically in parse_hn_port() @@ -9780,11 +10042,16 @@ reset_hostdepended_vars() { lets_roll() { local ret + local section_number=1 [[ -z "$NODEIP" ]] && fatal "$NODE doesn't resolve to an IP address" 2 nodeip_to_proper_ip6 reset_hostdepended_vars determine_rdns + + START_TIME=$(date +%s) + + fileout_section_header $section_number false && ((section_number++)) determine_service "$1" # any starttls service goes here $do_tls_sockets && [[ $TLS_LOW_BYTE -eq 22 ]] && { sslv2_sockets "" "true"; echo "$?" ; exit 0; } @@ -9792,16 +10059,26 @@ lets_roll() { $do_test_just_one && test_just_one ${single_cipher} # all top level functions now following have the prefix "run_" + fileout_section_header $section_number true && ((section_number++)) $do_protocols && { run_protocols; ret=$(($? + ret)); } $do_spdy && { run_spdy; ret=$(($? + ret)); } $do_http2 && { run_http2; ret=$(($? + ret)); } + + fileout_section_header $section_number true && ((section_number++)) $do_std_cipherlists && { run_std_cipherlists; ret=$(($? + ret)); } + + fileout_section_header $section_number true && ((section_number++)) $do_pfs && { run_pfs; ret=$(($? + ret)); } + + fileout_section_header $section_number true && ((section_number++)) $do_server_preference && { run_server_preference; ret=$(($? + ret)); } + + fileout_section_header $section_number true && ((section_number++)) $do_server_defaults && { run_server_defaults; ret=$(($? + ret)); } if $do_header; then #TODO: refactor this into functions + fileout_section_header $section_number true && ((section_number++)) if [[ $SERVICE == "HTTP" ]]; then run_http_header "$URL_PATH" run_http_date "$URL_PATH" @@ -9813,6 +10090,8 @@ lets_roll() { run_more_flags "$URL_PATH" run_rp_banner "$URL_PATH" fi + else + ((section_number++)) fi # vulnerabilities @@ -9820,6 +10099,8 @@ lets_roll() { outln; pr_headlineln " Testing vulnerabilities " outln fi + + fileout_section_header $section_number true && ((section_number++)) $do_heartbleed && { run_heartbleed; ret=$(($? + ret)); } $do_ccs_injection && { run_ccs_injection; ret=$(($? + ret)); } $do_renego && { run_renego; ret=$(($? + ret)); } @@ -9833,11 +10114,17 @@ lets_roll() { $do_beast && { run_beast; ret=$(($? + ret)); } $do_rc4 && { run_rc4; ret=$(($? + ret)); } + fileout_section_header $section_number true && ((section_number++)) $do_allciphers && { run_allciphers; ret=$(($? + ret)); } $do_cipher_per_proto && { run_cipher_per_proto; ret=$(($? + ret)); } + + fileout_section_header $section_number true && ((section_number++)) $do_client_simulation && { run_client_simulation; ret=$(($? + ret)); } + fileout_section_footer + outln + END_TIME=$(date +%s) datebanner " Done" return $ret