From af84d9b22052b40ac4176cc82fbd70dc18e420c9 Mon Sep 17 00:00:00 2001 From: David Cooper Date: Tue, 29 Nov 2016 11:16:01 -0500 Subject: [PATCH 01/61] run_cipher_per_proto() speedup + sockets This PR implements `run_cipher_per_proto()` in a manner similar to `run_allciphers()`. --- testssl.sh | 366 ++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 265 insertions(+), 101 deletions(-) diff --git a/testssl.sh b/testssl.sh index 884c143..b03af2c 100755 --- a/testssl.sh +++ b/testssl.sh @@ -2475,124 +2475,288 @@ run_allciphers() { # test for all ciphers per protocol locally configured (w/o distinguishing whether they are good or bad) run_cipher_per_proto() { - local proto proto_text ossl_ciphers_proto - local -i nr_ciphers - local n sslvers auth mac export - local -a hexcode ciph kx enc export2 - local -i i j parent child end_of_bundle round_num bundle_size num_bundles mod_check - local -a ciphers_found - local dhlen + local proto proto_hex proto_text ossl_ciphers_proto + local -i nr_ciphers nr_ossl_ciphers nr_nonossl_ciphers success + local n sslvers auth mac export hexc sslv2_ciphers="" cipher + local -a hexcode normalized_hexcode ciph rfc_ciph kx enc export2 + local -a hexcode2 ciph2 rfc_ciph2 + local -i i bundle end_of_bundle bundle_size num_bundles mod_check + local -a ciphers_found ciphers_found2 sigalg ossl_supported index + local dhlen supported_sslv2_ciphers ciphers_to_test addcmd sni temp local available local id + local has_dh_bits="$HAS_DH_BITS" + local using_sockets=true - pr_headlineln " Testing all locally available ciphers per protocol against the server, ordered by encryption strength " - ! "$HAS_DH_BITS" && pr_warningln " (Your $OPENSSL cannot show DH/ECDH bits)" + "$SSL_NATIVE" && using_sockets=false + "$FAST" && using_sockets=false + [[ $TLS_NR_CIPHERS == 0 ]] && using_sockets=false + + if "$using_sockets"; then + pr_headlineln " Testing per protocol via OpenSSL and sockets against the server, ordered by encryption strength " + else + pr_headlineln " Testing all locally available ciphers per protocol against the server, ordered by encryption strength " + outln + [[ $TLS_NR_CIPHERS == 0 ]] && ! "$SSL_NATIVE" && ! "$FAST" && pr_warning " Cipher mapping not available, doing a fallback to openssl" + if ! "$HAS_DH_BITS"; then + [[ $TLS_NR_CIPHERS == 0 ]] && ! "$SSL_NATIVE" && ! "$FAST" && out "." + pr_warningln " (Your $OPENSSL cannot show DH/ECDH bits)" + fi + fi outln neat_header - outln " -ssl2 SSLv2\n -ssl3 SSLv3\n -tls1 TLS 1\n -tls1_1 TLS 1.1\n -tls1_2 TLS 1.2"| while read proto proto_text; do - locally_supported "$proto" "$proto_text" || continue + outln " -ssl2 22 SSLv2\n -ssl3 00 SSLv3\n -tls1 01 TLS 1\n -tls1_1 02 TLS 1.1\n -tls1_2 03 TLS 1.2"| while read proto proto_hex proto_text; do + "$using_sockets" || locally_supported "$proto" "$proto_text" || continue + "$using_sockets" && out "$proto_text " 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 - ossl_ciphers_proto="$proto" - else - ossl_ciphers_proto="-tls1" - fi - # get a list of all the cipher suites to test (only need the hexcode, ciph, kx, enc, and export values) + # get a list of all the cipher suites to test nr_ciphers=0 - while read hexcode[nr_ciphers] n ciph[nr_ciphers] sslvers kx[nr_ciphers] auth enc[nr_ciphers] mac export2[nr_ciphers]; do - nr_ciphers=$nr_ciphers+1 - done < <($OPENSSL ciphers $ossl_ciphers_proto -V 'ALL:COMPLEMENTOFALL:@STRENGTH' 2>$ERRFILE) - - # Split ciphers into bundles of size 4**n, starting with the smallest - # "n" that leaves the ciphers in one bundle, and then reducing "n" by - # one in each round. Only test a bundle of 4**n ciphers against the - # server if it was part of a bundle of 4**(n+1) ciphers that included - # a cipher supported by the server. Continue until n=0. - - # Determine the smallest bundle size that will result in their being one bundle. - for(( bundle_size=1; bundle_size < nr_ciphers; bundle_size*=4 )); do - : - done - - # set ciphers_found[1] so that the complete bundle will be tested in round 0. - ciphers_found[1]=true - # Some servers can't handle a handshake with >= 128 ciphers. - for (( round_num=0; bundle_size>=128; bundle_size/=4 )); do - round_num=$round_num+1 - for (( i=4**$round_num; i<2*4**$round_num; i++ )); do - ciphers_found[i]=true + if "$using_sockets" || [[ $OSSL_VER_MAJOR -lt 1 ]]; then + for (( i=0; i < TLS_NR_CIPHERS; i++ )); do + hexc="$(tolower "${TLS_CIPHER_HEXCODE[i]}")" + ciph[nr_ciphers]="${TLS_CIPHER_OSSL_NAME[i]}" + rfc_ciph[nr_ciphers]="${TLS_CIPHER_RFC_NAME[i]}" + kx[nr_ciphers]="${TLS_CIPHER_KX[i]}" + enc[nr_ciphers]="${TLS_CIPHER_ENC[i]}" + export2[nr_ciphers]="${TLS_CIPHER_EXPORT[i]}" + ciphers_found[nr_ciphers]=false + sigalg[nr_ciphers]="" + ossl_supported[nr_ciphers]=${TLS_CIPHER_OSSL_SUPPORTED[i]} + if "$using_sockets" && ! "$has_dh_bits" && ( [[ ${kx[i]} == "Kx=ECDH" ]] || [[ ${kx[i]} == "Kx=DH" ]] || [[ ${kx[i]} == "Kx=EDH" ]] ); then + ossl_supported[nr_ciphers]=false + fi + if [[ ${#hexc} -eq 9 ]]; then + hexcode[nr_ciphers]="${hexc:2:2},${hexc:7:2}" + if [[ "${hexc:2:2}" == "00" ]]; then + normalized_hexcode[nr_ciphers]="x${hexc:7:2}" + else + normalized_hexcode[nr_ciphers]="x${hexc:2:2}${hexc:7:2}" + fi + else + hexcode[nr_ciphers]="${hexc:2:2},${hexc:7:2},${hexc:12:2}" + normalized_hexcode[nr_ciphers]="x${hexc:2:2}${hexc:7:2}${hexc:12:2}" + fi + if ( "$using_sockets" || "${TLS_CIPHER_OSSL_SUPPORTED[i]}" ); then + if [[ ${#hexc} -eq 9 ]] && [[ "$proto_text" != "SSLv2" ]]; then + if [[ "$proto_text" == "TLS 1.3" ]]; then + [[ "${hexc:2:2}" == "13" ]] && nr_ciphers+=1 + elif [[ "$proto_text" == "TLS 1.2" ]]; then + [[ "${hexc:2:2}" != "13" ]] && nr_ciphers+=1 + elif [[ ! "${TLS_CIPHER_RFC_NAME[i]}" =~ "SHA256" ]] && [[ ! "${TLS_CIPHER_RFC_NAME[i]}" =~ "SHA384" ]] && \ + [[ "${TLS_CIPHER_RFC_NAME[i]}" != *"_CCM" ]] && [[ "${TLS_CIPHER_RFC_NAME[i]}" != *"_CCM_8" ]]; then + nr_ciphers+=1 + fi + elif [[ ${#hexc} -eq 14 ]] && [[ "$proto_text" == "SSLv2" ]]; then + sslv2_ciphers+=", ${hexcode[nr_ciphers]}" + nr_ciphers+=1 + fi + fi done - done - for (( 1; bundle_size>=1; bundle_size/=4 )); do - # Note that since the number of ciphers isn't a power of 4, the number - # of bundles may be may be less than 4**(round_num+1), and the final - # bundle may have fewer than bundle_size ciphers. - num_bundles=$nr_ciphers/$bundle_size - mod_check=$nr_ciphers%$bundle_size - [[ $mod_check -ne 0 ]] && num_bundles=$num_bundles+1 - for (( i=0; i$TMPFILE 2>$ERRFILE $TMPFILE 2>$ERRFILE >$ERRFILE) + fi - # If this is a "leaf" of the test tree, then print out the results. - if [[ $bundle_size -eq 1 ]] && ( ${ciphers_found[child]} || "$SHOW_EACH_C"); then - export=${export2[i]} - normalize_ciphercode "${hexcode[i]}" - if [[ ${kx[i]} == "Kx=ECDH" ]] || [[ ${kx[i]} == "Kx=DH" ]] || [[ ${kx[i]} == "Kx=EDH" ]]; then - if ${ciphers_found[child]}; then - dhlen=$(read_dhbits_from_file "$TMPFILE" quiet) - kx[i]="${kx[i]} $dhlen" - fi - fi - neat_list "$HEXC" "${ciph[i]}" "${kx[i]}" "${enc[i]}" - if "$SHOW_EACH_C"; then - if ${ciphers_found[child]}; then + if [[ "$proto" == "-ssl2" ]] && "$using_sockets"; then + sslv2_sockets "${sslv2_ciphers:2}" "true" + if [[ $? -eq 3 ]] && [[ "$V2_HELLO_CIPHERSPEC_LENGTH" -ne 0 ]]; then + supported_sslv2_ciphers="$(grep "Supported cipher: " "$TEMPDIR/$NODEIP.parse_sslv2_serverhello.txt")" + "$SHOW_SIGALGO" && s="$($OPENSSL x509 -noout -text -in "$HOSTCERT" | awk -F':' '/Signature Algorithm/ { print $2 }' | head -1)" + for (( i=0 ; i$TMPFILE 2>$ERRFILE = 128 ciphers. So, + # test cipher suites in bundles of 128 or less. + num_bundles=$nr_ossl_ciphers/128 + mod_check=$nr_ossl_ciphers%128 + [[ $mod_check -ne 0 ]] && num_bundles=$num_bundles+1 + + bundle_size=$nr_ossl_ciphers/$num_bundles + mod_check=$nr_ossl_ciphers%$num_bundles + [[ $mod_check -ne 0 ]] && bundle_size+=1 + fi + + sni="" + [[ ! "$proto" =~ ssl ]] && sni="$SNI" + for (( bundle=0; bundle < num_bundles; bundle++ )); do + end_of_bundle=$bundle*$bundle_size+$bundle_size + [[ $end_of_bundle -gt $nr_ossl_ciphers ]] && end_of_bundle=$nr_ossl_ciphers + for (( success=0; success==0 ; 1 )); do + ciphers_to_test="" + for (( i=bundle*bundle_size; i < end_of_bundle; i++ )); do + ! "${ciphers_found2[i]}" && ciphers_to_test+=":${ciph2[i]}" + done + success=1 + if [[ -n "$ciphers_to_test" ]]; then + $OPENSSL s_client -cipher "${ciphers_to_test:1}" $proto $STARTTLS $BUGS -connect $NODEIP:$PORT $PROXY $sni >$TMPFILE 2>$ERRFILE = 128 ciphers. So, + # test cipher suites in bundles of 128 or less. + num_bundles=$nr_nonossl_ciphers/128 + mod_check=$nr_nonossl_ciphers%128 + [[ $mod_check -ne 0 ]] && num_bundles=$num_bundles+1 + + bundle_size=$nr_nonossl_ciphers/$num_bundles + mod_check=$nr_nonossl_ciphers%$num_bundles + [[ $mod_check -ne 0 ]] && bundle_size+=1 + fi + + for (( bundle=0; bundle < num_bundles; bundle++ )); do + end_of_bundle=$bundle*$bundle_size+$bundle_size + [[ $end_of_bundle -gt $nr_nonossl_ciphers ]] && end_of_bundle=$nr_nonossl_ciphers + for (( success=0; success==0 ; 1 )); do + ciphers_to_test="" + for (( i=bundle*bundle_size; i < end_of_bundle; i++ )); do + ! "${ciphers_found2[i]}" && ciphers_to_test+=", ${hexcode2[i]}" + done + success=1 + if [[ -n "$ciphers_to_test" ]]; then + if "$SHOW_SIGALGO"; then + tls_sockets "$proto_hex" "${ciphers_to_test:2}, 00,ff" "all" + else + tls_sockets "$proto_hex" "${ciphers_to_test:2}, 00,ff" "ephemeralkey" + fi + if [[ $? -eq 0 ]]; then + success=0 + cipher=$(awk '/Cipher *:/ { print $3 }' "$TEMPDIR/$NODEIP.parse_tls_serverhello.txt") + for (( i=bundle*bundle_size; i < end_of_bundle; i++ )); do + [[ "$cipher" == "${rfc_ciph2[i]}" ]] && ciphers_found2[i]=true && break + done + i=${index[i]} + ciphers_found[i]=true + if [[ "$proto_text" == "TLS 1.3" ]]; then + temp=$(awk -F': ' '/^Server Temp Key/ { print $2 }' "$TEMPDIR/$NODEIP.parse_tls_serverhello.txt") # extract line + kx[i]="Kx=$(awk -F',' '{ print $1 }' <<< $temp)" + fi + if [[ ${kx[i]} == "Kx=ECDH" ]] || [[ ${kx[i]} == "Kx=DH" ]] || [[ ${kx[i]} == "Kx=EDH" ]]; then + dhlen=$(read_dhbits_from_file "$TEMPDIR/$NODEIP.parse_tls_serverhello.txt" quiet) + kx[i]="${kx[i]} $dhlen" + fi + "$SHOW_SIGALGO" && [[ -r "$HOSTCERT" ]] && \ + sigalg[i]="$($OPENSSL x509 -noout -text -in "$HOSTCERT" | awk -F':' '/Signature Algorithm/ { print $2 }' | head -1)" + fi + fi + done + done + fi + + for (( i=0 ; i Date: Wed, 30 Nov 2016 13:40:28 -0500 Subject: [PATCH 02/61] Limit calls to tolower() It turns out that calling `tolower()` once for each cipher to test is very expensive. So, this commit tries to call `tolower()` only when necessary. --- testssl.sh | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/testssl.sh b/testssl.sh index abbc213..cd2ebd2 100755 --- a/testssl.sh +++ b/testssl.sh @@ -2515,7 +2515,7 @@ run_cipher_per_proto() { nr_ciphers=0 if "$using_sockets" || [[ $OSSL_VER_MAJOR -lt 1 ]]; then for (( i=0; i < TLS_NR_CIPHERS; i++ )); do - hexc="$(tolower "${TLS_CIPHER_HEXCODE[i]}")" + hexc="${TLS_CIPHER_HEXCODE[i]}" ciph[nr_ciphers]="${TLS_CIPHER_OSSL_NAME[i]}" rfc_ciph[nr_ciphers]="${TLS_CIPHER_RFC_NAME[i]}" kx[nr_ciphers]="${TLS_CIPHER_KX[i]}" @@ -2535,6 +2535,7 @@ run_cipher_per_proto() { normalized_hexcode[nr_ciphers]="x${hexc:2:2}${hexc:7:2}" fi else + hexc="$(tolower "$hexc")" hexcode[nr_ciphers]="${hexc:2:2},${hexc:7:2},${hexc:12:2}" normalized_hexcode[nr_ciphers]="x${hexc:2:2}${hexc:7:2}${hexc:12:2}" fi @@ -2570,9 +2571,9 @@ run_cipher_per_proto() { ciphers_found[nr_ciphers]=false if [[ ${#hexc} -eq 9 ]]; then if [[ "${hexc:2:2}" == "00" ]]; then - normalized_hexcode[nr_ciphers]="$(tolower "x${hexc:7:2}")" + normalized_hexcode[nr_ciphers]="x${hexc:7:2}" else - normalized_hexcode[nr_ciphers]="$(tolower "x${hexc:2:2}${hexc:7:2}")" + normalized_hexcode[nr_ciphers]="x${hexc:2:2}${hexc:7:2}" fi else normalized_hexcode[nr_ciphers]="$(tolower "x${hexc:2:2}${hexc:7:2}${hexc:12:2}")" @@ -2738,6 +2739,7 @@ run_cipher_per_proto() { for (( i=0 ; i Date: Thu, 1 Dec 2016 16:51:38 -0500 Subject: [PATCH 03/61] Use sockets to determine cipher order This PR modifies `cipher_pref_check()` to use `tls_sockets()`. As with similar PRs for `run_allciphers()`, `run_cipher_per_proto()`, and `run_rc4()`, it also makes use of `$OPENSSL s_client`, since `$OPENSSL s_client` is faster than `tls_sockets()`. With this PR, `cipher_pref_check()` first uses `$OPENSSL s_client` to obtain an ordered list of ciphers. It then makes one call to `tls_sockets()` (or a few calls if proto is TLSv1.2 and `$SERVER_SIZE_LIMIT_BUG` is `true`) to find if the server supports any ciphers that are not detected by `$OPENSSL s_client`. If not, then it is done. If it finds one, then it throws out the previous results and starts over with `tls_sockets()`. [If proto is TLSv1.2 and `$SERVER_SIZE_LIMIT_BUG` is `true`, then it doesn't throw out the `$OPENSSL s_client` results. Instead, it continues with `tls_sockets()` to get the full list of supported ciphers, and then uses `tls_sockets()` to order that list.] The result is that this PR works almost as fast as the current `cipher_pref_check()` if `$OPENSSL s_client` finds all of the supported ciphers, at the cost of a performance penalty when testing servers that support ciphers that would have otherwise been missed using just OpenSSL. Note that in this PR I removed SSLv2 from the list of protocols tested. This is because https://community.qualys.com/thread/16255 states that "in SSLv2 the client selects the suite to use." It seems that in SSLv2, the client sends a list of ciphers that it supports, the server responds with a list of ciphers that the client and server have in common, and then "the client selects the suite to use." So, showing a cipher order for SSLv2 is a bit misleading. As noted in #543, this PR does not modify the second part of `cipher_pref_check()`, which deals with NPN protocols. --- testssl.sh | 232 ++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 177 insertions(+), 55 deletions(-) diff --git a/testssl.sh b/testssl.sh index 538e4b8..d735471 100755 --- a/testssl.sh +++ b/testssl.sh @@ -4342,15 +4342,18 @@ run_server_preference() { check_tls12_pref() { local batchremoved="-CAMELLIA:-IDEA:-KRB5:-PSK:-SRP:-aNULL:-eNULL" local batchremoved_success=false - local tested_cipher="-$1" - local order="$1" + local tested_cipher="" + local order="" + local -i nr_ciphers_found_r1=0 nr_ciphers_found_r2=0 while true; do - $OPENSSL s_client $STARTTLS -tls1_2 $BUGS -cipher "ALL:$tested_cipher:$batchremoved" -connect $NODEIP:$PORT $PROXY $SNI >$ERRFILE >$TMPFILE + $OPENSSL s_client $STARTTLS -tls1_2 $BUGS -cipher "ALL$tested_cipher:$batchremoved" -connect $NODEIP:$PORT $PROXY $SNI >$ERRFILE >$TMPFILE if sclient_connect_successful $? $TMPFILE ; then cipher=$(awk '/Cipher.*:/ { print $3 }' $TMPFILE) order+=" $cipher" tested_cipher="$tested_cipher:-$cipher" + nr_ciphers_found_r1+=1 + "$FAST" && break else debugme outln "A: $tested_cipher" break @@ -4358,7 +4361,7 @@ check_tls12_pref() { done batchremoved="${batchremoved//-/}" while true; do - # no ciphers from "ALL:$tested_cipher:$batchremoved" left + # no ciphers from "ALL$tested_cipher:$batchremoved" left # now we check $batchremoved, and remove the minus signs first: $OPENSSL s_client $STARTTLS -tls1_2 $BUGS -cipher "$batchremoved" -connect $NODEIP:$PORT $PROXY $SNI >$ERRFILE >$TMPFILE if sclient_connect_successful $? $TMPFILE ; then @@ -4366,7 +4369,9 @@ check_tls12_pref() { cipher=$(awk '/Cipher.*:/ { print $3 }' $TMPFILE) order+=" $cipher" batchremoved="$batchremoved:-$cipher" + nr_ciphers_found_r1+=1 debugme outln "B1: $batchremoved" + "$FAST" && break else debugme outln "B2: $batchremoved" break @@ -4376,34 +4381,31 @@ check_tls12_pref() { if "$batchremoved_success"; then # now we combine the two cipher sets from both while loops + [[ "${order:0:1}" == " " ]] && order="${order:1}" combined_ciphers="${order// /:}" - $OPENSSL s_client $STARTTLS -tls1_2 $BUGS -cipher "$combined_ciphers" -connect $NODEIP:$PORT $PROXY $SNI >$ERRFILE >$TMPFILE - if sclient_connect_successful $? $TMPFILE ; then - # first cipher - cipher=$(awk '/Cipher.*:/ { print $3 }' $TMPFILE) - order="$cipher" - tested_cipher="-$cipher" - else - fixmeln "something weird happened around line $((LINENO - 6))" - return 1 - fi + order="" ; tested_cipher="" while true; do - $OPENSSL s_client $STARTTLS -tls1_2 $BUGS -cipher "$combined_ciphers:$tested_cipher" -connect $NODEIP:$PORT $PROXY $SNI >$ERRFILE >$TMPFILE + $OPENSSL s_client $STARTTLS -tls1_2 $BUGS -cipher "$combined_ciphers$tested_cipher" -connect $NODEIP:$PORT $PROXY $SNI >$ERRFILE >$TMPFILE if sclient_connect_successful $? $TMPFILE ; then cipher=$(awk '/Cipher.*:/ { print $3 }' $TMPFILE) order+=" $cipher" tested_cipher="$tested_cipher:-$cipher" + nr_ciphers_found_r2+=1 + "$FAST" && break else # nothing left, we're done - out " $order" break fi done - - else - # second cipher set didn't succeed: we can just output everything - out " $order" + if "$FAST" && [[ $nr_ciphers_found_r2 -ne 1 ]]; then + fixmeln "something weird happened around line $((LINENO - 14))" + return 1 + elif ! "$FAST" && [[ $nr_ciphers_found_r2 -ne $nr_ciphers_found_r1 ]]; then + fixmeln "something weird happened around line $((LINENO - 16))" + return 1 + fi fi + out "$order" tmpfile_handle $FUNCNAME.txt return 0 @@ -4411,35 +4413,34 @@ check_tls12_pref() { cipher_pref_check() { - local p proto protos npn_protos sni + local p proto proto_hex npn_protos sni local tested_cipher cipher order local overflow_probe_cipherlist="ALL:-ECDHE-RSA-AES256-GCM-SHA384:-AES128-SHA:-DES-CBC3-SHA" + local -i i nr_ciphers nr_nonossl_ciphers num_bundles mod_check bundle_size bundle end_of_bundle success + local hexc ciphers_to_test + local -a rfc_ciph hexcode ciphers_found ciphers_found2 + local -a -i index + local using_sockets=true ciphers_found_with_sockets + + "$SSL_NATIVE" && using_sockets=false + "$FAST" && using_sockets=false + [[ $TLS_NR_CIPHERS == 0 ]] && using_sockets=false pr_bold " Cipher order" - for p in ssl2 ssl3 tls1 tls1_1 tls1_2; do - order="" - if [[ $p == ssl2 ]] && ! "$HAS_SSL2"; then - out "\n SSLv2: "; local_problem "$OPENSSL doesn't support \"s_client -ssl2\""; - continue - fi - if [[ $p == ssl3 ]] && ! "$HAS_SSL3"; then + outln " ssl3 00 SSLv3\n tls1 01 TLSv1\n tls1_1 02 TLSv1.1\n tls1_2 03 TLSv1.2"| while read p proto_hex proto; do + order=""; ciphers_found_with_sockets=false + if [[ $p == ssl3 ]] && ! "$HAS_SSL3" && ! "$using_sockets"; then out "\n SSLv3: "; local_problem "$OPENSSL doesn't support \"s_client -ssl3\""; continue fi - # with the supplied binaries SNI works also for SSLv2 (+ SSLv3) - [[ "$p" =~ ssl ]] && sni="" || sni=$SNI - $OPENSSL s_client $STARTTLS -"$p" $BUGS -connect $NODEIP:$PORT $PROXY $sni $ERRFILE >$TMPFILE - if sclient_connect_successful $? $TMPFILE; then - tested_cipher="" - proto=$(awk '/Protocol/ { print $3 }' $TMPFILE) - cipher=$(awk '/Cipher *:/ { print $3 }' $TMPFILE) - [[ -z "$proto" ]] && continue # for early openssl versions sometimes needed - outln - printf " %-10s" "$proto: " - tested_cipher="-"$cipher - order="$cipher" - if [[ $p == tls1_2 ]]; then + has_server_protocol "$p" || continue + + if [[ $p != ssl3 ]] || "$HAS_SSL3"; then + # with the supplied binaries SNI works also for SSLv3 + [[ "$p" =~ ssl ]] && sni="" || sni=$SNI + + if [[ $p == tls1_2 ]] && ! "$SERVER_SIZE_LIMIT_BUG"; 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, @@ -4451,23 +4452,144 @@ cipher_pref_check() { fi fi if [[ $p == tls1_2 ]] && "$SERVER_SIZE_LIMIT_BUG"; then - order=$(check_tls12_pref "$cipher") - out "$order" + order="$(check_tls12_pref)" else - out " $cipher" # this is the first cipher for protocol - if ! "$FAST"; then - while true; do - $OPENSSL s_client $STARTTLS -"$p" $BUGS -cipher "ALL:$tested_cipher" -connect $NODEIP:$PORT $PROXY $sni >$ERRFILE >$TMPFILE - sclient_connect_successful $? $TMPFILE || break - cipher=$(awk '/Cipher *:/ { print $3 }' $TMPFILE) - out " $cipher" - order+=" $cipher" - tested_cipher="$tested_cipher:-$cipher" - done - fi + tested_cipher="" + while true; do + $OPENSSL s_client $STARTTLS -"$p" $BUGS -cipher "ALL:COMPLEMENTOFALL$tested_cipher" -connect $NODEIP:$PORT $PROXY $sni >$ERRFILE >$TMPFILE + sclient_connect_successful $? $TMPFILE || break + cipher=$(awk '/Cipher *:/ { print $3 }' $TMPFILE) + [[ -z "$cipher" ]] && break + order+=" $cipher" + tested_cipher+=":-"$cipher + "$FAST" && break + done fi fi - [[ -z "$order" ]] || fileout "order_$p" "INFO" "Default cipher order for protocol $p: $order" + + nr_nonossl_ciphers=0 + if "$using_sockets"; then + for (( i=0; i < TLS_NR_CIPHERS; i++ )); do + ciphers_found[i]=false + hexc="${TLS_CIPHER_HEXCODE[i]}" + if [[ ${#hexc} -eq 9 ]]; then + if [[ " $order " =~ " ${TLS_CIPHER_OSSL_NAME[i]} " ]]; then + ciphers_found[i]=true + else + ciphers_found2[nr_nonossl_ciphers]=false + hexcode[nr_nonossl_ciphers]="${hexc:2:2},${hexc:7:2}" + rfc_ciph[nr_nonossl_ciphers]="${TLS_CIPHER_RFC_NAME[i]}" + index[nr_nonossl_ciphers]=$i + # Only test ciphers that are relevant to the protocol. + if [[ "$p" == "tls1_3" ]]; then + [[ "${hexc:2:2}" == "13" ]] && nr_nonossl_ciphers+=1 + elif [[ "$p" == "tls1_2" ]]; then + [[ "${hexc:2:2}" != "13" ]] && nr_nonossl_ciphers+=1 + elif [[ ! "${TLS_CIPHER_RFC_NAME[i]}" =~ "SHA256" ]] && \ + [[ ! "${TLS_CIPHER_RFC_NAME[i]}" =~ "SHA384" ]] && \ + [[ "${TLS_CIPHER_RFC_NAME[i]}" != *"_CCM" ]] && \ + [[ "${TLS_CIPHER_RFC_NAME[i]}" != *"_CCM_8" ]]; then + nr_nonossl_ciphers+=1 + fi + fi + fi + done + fi + + if [[ $nr_nonossl_ciphers -eq 0 ]]; then + num_bundles=0 + elif [[ $p != tls1_2 ]] || ! "$SERVER_SIZE_LIMIT_BUG"; then + num_bundles=1 + bundle_size=$nr_nonossl_ciphers + else + num_bundles=$nr_nonossl_ciphers/128 + mod_check=$nr_nonossl_ciphers%128 + [[ $mod_check -ne 0 ]] && num_bundles=$num_bundles+1 + + bundle_size=$nr_nonossl_ciphers/$num_bundles + mod_check=$nr_nonossl_ciphers%$num_bundles + [[ $mod_check -ne 0 ]] && bundle_size+=1 + fi + + for (( bundle=0; bundle < num_bundles; bundle++ )); do + end_of_bundle=$bundle*$bundle_size+$bundle_size + [[ $end_of_bundle -gt $nr_nonossl_ciphers ]] && end_of_bundle=$nr_nonossl_ciphers + while true; do + ciphers_to_test="" + for (( i=bundle*bundle_size; i < end_of_bundle; i++ )); do + ! "${ciphers_found2[i]}" && ciphers_to_test+=", ${hexcode[i]}" + done + [[ -z "$ciphers_to_test" ]] && break + tls_sockets "$proto_hex" "${ciphers_to_test:2}, 00,ff" "ephemeralkey" + [[ $? -ne 0 ]] && break + cipher=$(awk '/Cipher *:/ { print $3 }' "$TEMPDIR/$NODEIP.parse_tls_serverhello.txt") + for (( i=bundle*bundle_size; i < end_of_bundle; i++ )); do + [[ "$cipher" == "${rfc_ciph[i]}" ]] && ciphers_found2[i]=true && break + done + i=${index[i]} + ciphers_found[i]=true + ciphers_found_with_sockets=true + if [[ $p != tls1_2 ]] || ! "$SERVER_SIZE_LIMIT_BUG"; then + # Throw out the results found so far and start over using just sockets + bundle=$num_bundles + for (( i=0; i < TLS_NR_CIPHERS; i++ )); do + ciphers_found[i]=true + done + break + fi + done + done + + # If additional ciphers were found using sockets and there is no + # SERVER_SIZE_LIMIT_BUG, then just use sockets to find the cipher order. + # If there is a SERVER_SIZE_LIMIT_BUG, then use sockets to find the cipher + # order, but starting with the list of ciphers supported by the server. + if "$ciphers_found_with_sockets"; then + order="" + nr_ciphers=0 + for (( i=0; i < TLS_NR_CIPHERS; i++ )); do + hexc="${TLS_CIPHER_HEXCODE[i]}" + if "${ciphers_found[i]}" && [[ ${#hexc} -eq 9 ]]; then + ciphers_found2[nr_ciphers]=false + hexcode[nr_ciphers]="${hexc:2:2},${hexc:7:2}" + rfc_ciph[nr_ciphers]="${TLS_CIPHER_RFC_NAME[i]}" + if [[ "$p" == "tls1_3" ]]; then + [[ "${hexc:2:2}" == "13" ]] && nr_ciphers+=1 + elif [[ "$p" == "tls1_2" ]]; then + [[ "${hexc:2:2}" != "13" ]] && nr_ciphers+=1 + elif [[ ! "${TLS_CIPHER_RFC_NAME[i]}" =~ "SHA256" ]] && \ + [[ ! "${TLS_CIPHER_RFC_NAME[i]}" =~ "SHA384" ]] && \ + [[ "${TLS_CIPHER_RFC_NAME[i]}" != *"_CCM" ]] && \ + [[ "${TLS_CIPHER_RFC_NAME[i]}" != *"_CCM_8" ]]; then + nr_ciphers+=1 + fi + fi + done + while true; do + ciphers_to_test="" + for (( i=0; i < nr_ciphers; i++ )); do + ! "${ciphers_found2[i]}" && ciphers_to_test+=", ${hexcode[i]}" + done + [[ -z "$ciphers_to_test" ]] && break + tls_sockets "$proto_hex" "${ciphers_to_test:2}, 00,ff" "ephemeralkey" + [[ $? -ne 0 ]] && break + cipher=$(awk '/Cipher *:/ { print $3 }' "$TEMPDIR/$NODEIP.parse_tls_serverhello.txt") + for (( i=0; i < nr_ciphers; i++ )); do + [[ "$cipher" == "${rfc_ciph[i]}" ]] && ciphers_found2[i]=true && break + done + cipher="$(rfc2openssl "$cipher")" + # If there is no OpenSSL name for the cipher, then use the RFC name + [[ -z "$cipher" ]] && cipher=$(awk '/Cipher *:/ { print $3 }' "$TEMPDIR/$NODEIP.parse_tls_serverhello.txt") + order+=" $cipher" + done + fi + + if [[ -n "$order" ]]; then + outln + printf " %-10s" "$proto: " + out "$order" + fileout "order_$p" "INFO" "Default cipher order for protocol $p: $order" + fi done outln From dd04a10b2f15c2221853e8a00b12bdb5dbbf61f5 Mon Sep 17 00:00:00 2001 From: David Cooper Date: Tue, 6 Dec 2016 11:37:41 -0500 Subject: [PATCH 04/61] run_beast() speedup + sockets This PR implements `run_beast()` in a manner similar to `run_allciphers()`. --- testssl.sh | 208 +++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 153 insertions(+), 55 deletions(-) diff --git a/testssl.sh b/testssl.sh index 883c267..c5e191f 100755 --- a/testssl.sh +++ b/testssl.sh @@ -8805,22 +8805,29 @@ run_drown() { # Browser Exploit Against SSL/TLS: don't use CBC Ciphers in SSLv3 TLSv1.0 run_beast(){ - local hexcode dash cbc_cipher sslvers kx auth enc mac export addcmd - local detected_proto - local -i sclient_success=0 - local detected_cbc_ciphers="" + local hexc dash cbc_cipher sslvers auth mac export sni + local -a ciph hexcode normalized_hexcode kx enc export2 + local proto proto_hex + local -i i nr_ciphers=0 sclient_success=0 + local detected_cbc_ciphers="" ciphers_to_test local higher_proto_supported="" - local -i sclient_success=0 local vuln_beast=false local spaces=" " local cr=$'\n' local first=true local continued=false - local cbc_cipher_list="EXP-RC2-CBC-MD5:IDEA-CBC-SHA:EXP-DES-CBC-SHA:DES-CBC-SHA:DES-CBC3-SHA:EXP-DH-DSS-DES-CBC-SHA:DH-DSS-DES-CBC-SHA:DH-DSS-DES-CBC3-SHA:EXP-DH-RSA-DES-CBC-SHA:DH-RSA-DES-CBC-SHA:DH-RSA-DES-CBC3-SHA:EXP-EDH-DSS-DES-CBC-SHA:EDH-DSS-DES-CBC-SHA:EDH-DSS-DES-CBC3-SHA:EXP-EDH-RSA-DES-CBC-SHA:EDH-RSA-DES-CBC-SHA:EDH-RSA-DES-CBC3-SHA:EXP-ADH-DES-CBC-SHA:ADH-DES-CBC-SHA:ADH-DES-CBC3-SHA:KRB5-DES-CBC-SHA:KRB5-DES-CBC3-SHA:KRB5-IDEA-CBC-SHA:KRB5-DES-CBC-MD5:KRB5-DES-CBC3-MD5:KRB5-IDEA-CBC-MD5:EXP-KRB5-DES-CBC-SHA:EXP-KRB5-RC2-CBC-SHA:EXP-KRB5-DES-CBC-MD5:EXP-KRB5-RC2-CBC-MD5:AES128-SHA:DH-DSS-AES128-SHA:DH-RSA-AES128-SHA:DHE-DSS-AES128-SHA:DHE-RSA-AES128-SHA:ADH-AES128-SHA:AES256-SHA:DH-DSS-AES256-SHA:DH-RSA-AES256-SHA:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:ADH-AES256-SHA:AES128-SHA256:AES256-SHA256:DH-DSS-AES128-SHA256:DH-RSA-AES128-SHA256:DHE-DSS-AES128-SHA256:CAMELLIA128-SHA:DH-DSS-CAMELLIA128-SHA:DH-RSA-CAMELLIA128-SHA:DHE-DSS-CAMELLIA128-SHA:DHE-RSA-CAMELLIA128-SHA:ADH-CAMELLIA128-SHA:EXP1024-DES-CBC-SHA:EXP1024-DHE-DSS-DES-CBC-SHA:DHE-RSA-AES128-SHA256:DH-DSS-AES256-SHA256:DH-RSA-AES256-SHA256:DHE-DSS-AES256-SHA256:DHE-RSA-AES256-SHA256:ADH-AES128-SHA256:ADH-AES256-SHA256:CAMELLIA256-SHA:DH-DSS-CAMELLIA256-SHA:DH-RSA-CAMELLIA256-SHA:DHE-DSS-CAMELLIA256-SHA:DHE-RSA-CAMELLIA256-SHA:ADH-CAMELLIA256-SHA:PSK-3DES-EDE-CBC-SHA:PSK-AES128-CBC-SHA:PSK-AES256-CBC-SHA:SEED-SHA:DH-DSS-SEED-SHA:DH-RSA-SEED-SHA:DHE-DSS-SEED-SHA:DHE-RSA-SEED-SHA:ADH-SEED-SHA:ECDH-ECDSA-DES-CBC3-SHA:ECDH-ECDSA-AES128-SHA:ECDH-ECDSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA:ECDH-RSA-DES-CBC3-SHA:ECDH-RSA-AES128-SHA:ECDH-RSA-AES256-SHA:ECDHE-RSA-DES-CBC3-SHA:ECDHE-RSA-AES128-SHA:ECDHE-RSA-AES256-SHA:AECDH-DES-CBC3-SHA:AECDH-AES128-SHA:AECDH-AES256-SHA:SRP-3DES-EDE-CBC-SHA:SRP-RSA-3DES-EDE-CBC-SHA:SRP-DSS-3DES-EDE-CBC-SHA:SRP-AES-128-CBC-SHA:SRP-RSA-AES-128-CBC-SHA:SRP-DSS-AES-128-CBC-SHA:SRP-AES-256-CBC-SHA:SRP-RSA-AES-256-CBC-SHA:SRP-DSS-AES-256-CBC-SHA:ECDHE-ECDSA-AES128-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDH-ECDSA-AES128-SHA256:ECDH-ECDSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA384:ECDH-RSA-AES128-SHA256:ECDH-RSA-AES256-SHA384:RC2-CBC-MD5:EXP-RC2-CBC-MD5:IDEA-CBC-MD5:DES-CBC-MD5:DES-CBC3-MD5" + local cbc_cipher_list="ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:SRP-DSS-AES-256-CBC-SHA:SRP-RSA-AES-256-CBC-SHA:SRP-AES-256-CBC-SHA:DHE-PSK-AES256-CBC-SHA:DHE-RSA-AES256-SHA:DHE-DSS-AES256-SHA:DH-RSA-AES256-SHA:DH-DSS-AES256-SHA:DHE-RSA-CAMELLIA256-SHA:DHE-DSS-CAMELLIA256-SHA:DH-RSA-CAMELLIA256-SHA:DH-DSS-CAMELLIA256-SHA:AECDH-AES256-SHA:ADH-AES256-SHA:ADH-CAMELLIA256-SHA:ECDH-RSA-AES256-SHA:ECDH-ECDSA-AES256-SHA:AES256-SHA:ECDHE-PSK-AES256-CBC-SHA:CAMELLIA256-SHA:RSA-PSK-AES256-CBC-SHA:PSK-AES256-CBC-SHA:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:SRP-DSS-AES-128-CBC-SHA:SRP-RSA-AES-128-CBC-SHA:SRP-AES-128-CBC-SHA:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA:DH-RSA-AES128-SHA:DH-DSS-AES128-SHA:DHE-RSA-SEED-SHA:DHE-DSS-SEED-SHA:DH-RSA-SEED-SHA:DH-DSS-SEED-SHA:DHE-RSA-CAMELLIA128-SHA:DHE-DSS-CAMELLIA128-SHA:DH-RSA-CAMELLIA128-SHA:DH-DSS-CAMELLIA128-SHA:AECDH-AES128-SHA:ADH-AES128-SHA:ADH-SEED-SHA:ADH-CAMELLIA128-SHA:ECDH-RSA-AES128-SHA:ECDH-ECDSA-AES128-SHA:AES128-SHA:ECDHE-PSK-AES128-CBC-SHA:DHE-PSK-AES128-CBC-SHA:SEED-SHA:CAMELLIA128-SHA:IDEA-CBC-SHA:RSA-PSK-AES128-CBC-SHA:PSK-AES128-CBC-SHA:KRB5-IDEA-CBC-SHA:KRB5-IDEA-CBC-MD5:ECDHE-RSA-DES-CBC3-SHA:ECDHE-ECDSA-DES-CBC3-SHA:SRP-DSS-3DES-EDE-CBC-SHA:SRP-RSA-3DES-EDE-CBC-SHA:SRP-3DES-EDE-CBC-SHA:EDH-RSA-DES-CBC3-SHA:EDH-DSS-DES-CBC3-SHA:DH-RSA-DES-CBC3-SHA:DH-DSS-DES-CBC3-SHA:AECDH-DES-CBC3-SHA:ADH-DES-CBC3-SHA:ECDH-RSA-DES-CBC3-SHA:ECDH-ECDSA-DES-CBC3-SHA:DES-CBC3-SHA:RSA-PSK-3DES-EDE-CBC-SHA:PSK-3DES-EDE-CBC-SHA:KRB5-DES-CBC3-SHA:KRB5-DES-CBC3-MD5:ECDHE-PSK-3DES-EDE-CBC-SHA:DHE-PSK-3DES-EDE-CBC-SHA:EXP1024-DHE-DSS-DES-CBC-SHA:EDH-RSA-DES-CBC-SHA:EDH-DSS-DES-CBC-SHA:DH-RSA-DES-CBC-SHA:DH-DSS-DES-CBC-SHA:ADH-DES-CBC-SHA:EXP1024-DES-CBC-SHA:DES-CBC-SHA:KRB5-DES-CBC-SHA:KRB5-DES-CBC-MD5:EXP-EDH-RSA-DES-CBC-SHA:EXP-EDH-DSS-DES-CBC-SHA:EXP-ADH-DES-CBC-SHA:EXP-DES-CBC-SHA:EXP-RC2-CBC-MD5:EXP-KRB5-RC2-CBC-SHA:EXP-KRB5-DES-CBC-SHA:EXP-KRB5-RC2-CBC-MD5:EXP-KRB5-DES-CBC-MD5:EXP-DH-DSS-DES-CBC-SHA:EXP-DH-RSA-DES-CBC-SHA" + cbc_cipher_list_hex="" + local has_dh_bits="$HAS_DH_BITS" + local using_sockets=true local cve="CVE-2011-3389" local cwe="CWE-20" local hint="" + "$SSL_NATIVE" && using_sockets=false + "$FAST" && using_sockets=false + [[ $TLS_NR_CIPHERS == 0 ]] && using_sockets=false + if [[ $VULN_COUNT -le $VULN_THRESHLD ]]; then outln pr_headlineln " Testing for BEAST vulnerability " @@ -8829,9 +8836,46 @@ run_beast(){ outln fi pr_bold " BEAST"; out " ($cve) " -# output in wide mode if cipher doesn't exist is not ok - >$ERRFILE + if "$using_sockets" || [[ $OSSL_VER_MAJOR -lt 1 ]]; then + for (( i=0; i < TLS_NR_CIPHERS; i++ )); do + hexc="${TLS_CIPHER_HEXCODE[i]}" + if [[ ${#hexc} -eq 9 ]] && [[ "${TLS_CIPHER_RFC_NAME[i]}" =~ CBC ]] && \ + [[ ! "${TLS_CIPHER_RFC_NAME[i]}" =~ "SHA256" ]] && [[ ! "${TLS_CIPHER_RFC_NAME[i]}" =~ "SHA384" ]]; then + cbc_cipher_list_hex+=", ${hexc:2:2},${hexc:7:2}" + ciph[nr_ciphers]="${TLS_CIPHER_OSSL_NAME[i]}" + hexcode[nr_ciphers]="${hexc:2:2},${hexc:7:2}" + rfc_ciph[nr_ciphers]="${TLS_CIPHER_RFC_NAME[i]}" + kx[nr_ciphers]="${TLS_CIPHER_KX[i]}" + enc[nr_ciphers]="${TLS_CIPHER_ENC[i]}" + export2[nr_ciphers]="${TLS_CIPHER_EXPORT[i]}" + ossl_supported[nr_ciphers]=${TLS_CIPHER_OSSL_SUPPORTED[i]} + if "$using_sockets" && "$WIDE" && ! "$has_dh_bits" && \ + ( [[ ${kx[nr_ciphers]} == "Kx=ECDH" ]] || [[ ${kx[nr_ciphers]} == "Kx=DH" ]] || [[ ${kx[nr_ciphers]} == "Kx=EDH" ]] ); then + ossl_supported[nr_ciphers]=false + fi + if [[ "${hexc:2:2}" == "00" ]]; then + normalized_hexcode[nr_ciphers]="x${hexc:7:2}" + else + normalized_hexcode[nr_ciphers]="x${hexc:2:2}${hexc:7:2}" + fi + nr_ciphers+=1 + fi + done + cbc_cipher_list_hex="${cbc_cipher_list_hex:2}" + else + while read hexc dash ciph[nr_ciphers] sslvers kx[nr_ciphers] auth enc[nr_ciphers] mac export2[nr_ciphers]; do + if [[ ":${cbc_cipher_list}:" =~ ":${ciph[nr_ciphers]}:" ]]; then + ossl_supported[nr_ciphers]=true + if [[ "${hexc:2:2}" == "00" ]]; then + normalized_hexcode[nr_ciphers]="x${hexc:7:2}" + else + normalized_hexcode[nr_ciphers]="x${hexc:2:2}${hexc:7:2}" + fi + nr_ciphers+=1 + fi + done < <($OPENSSL ciphers -tls1 -V 'ALL:COMPLEMENTOFALL:@STRENGTH' 2>>$ERRFILE) + fi # first determine whether it's mitigated by higher protocols for proto in tls1_1 tls1_2; do @@ -8842,17 +8886,21 @@ run_beast(){ done for proto in ssl3 tls1; do - if [[ "$proto" == "ssl3" ]] && ! locally_supported "-$proto"; then + if [[ "$proto" == "ssl3" ]] && ! "$using_sockets" && ! locally_supported "-$proto"; then continued=true out " " continue fi - addcmd="" - [[ ! "$proto" =~ ssl ]] && addcmd="$SNI" - $OPENSSL s_client -"$proto" $STARTTLS $BUGS -connect $NODEIP:$PORT $PROXY $addcmd >$TMPFILE 2>>$ERRFILE $TMPFILE 2>>$ERRFILE $TMPFILE 2>>$ERRFILE $TMPFILE 2>>$ERRFILE $TMPFILE 2>>$ERRFILE >$ERRFILE) # -V doesn't work with openssl < 1.0 - # ^^^^^ process substitution as shopt will either segfault or doesn't work with old bash versions - $OPENSSL s_client -cipher "$cbc_cipher" -"$proto" $STARTTLS $BUGS -connect $NODEIP:$PORT $PROXY $addcmd >$TMPFILE 2>>$ERRFILE Date: Thu, 8 Dec 2016 12:36:45 -0500 Subject: [PATCH 05/61] run_pfs() speedup + sockets This PR implements `run_pfs()` in a manner similar to `run_allciphers()`. It uses OpenSSL followed by `tls_sockets()` to test for both supported PFS cipher suites as well as elliptic curves offered. I made an attempt at addressing #548 by using different colors to print the different curve names, depending on strength. The colors chosen are exactly the same as those that would be chosen by `read_dhbits_from_file()`: ``` # bits <= 163: pr_svrty_medium 163 < # bits <= 193: pr_svrty_minor 193 < # bits <= 224: out # bits > 224: pr_done_good ``` I also added code for #464 to create a list of the DH groups from RFC 7919 that a server supports. However, since no servers seem to support this at the moment (except with TLS 1.3), I marked this code to only run if the $EXPERIMENTAL flag is set. --- testssl.sh | 375 +++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 279 insertions(+), 96 deletions(-) diff --git a/testssl.sh b/testssl.sh index 883c267..a19b18a 100755 --- a/testssl.sh +++ b/testssl.sh @@ -5781,38 +5781,98 @@ run_server_defaults() { run_pfs() { local -i sclient_success - local pfs_offered=false ecdhe_offered=false - local tmpfile - local dhlen - local hexcode dash pfs_cipher sslvers kx auth enc mac curve - local pfs_cipher_list="$ROBUST_PFS_CIPHERS" - local ecdhe_cipher_list="" + local pfs_offered=false ecdhe_offered=false ffdhe_offered=false + local hexc dash pfs_cipher sslvers auth mac export curve dhlen + local -a hexcode normalized_hexcode ciph rfc_ciph kx enc ciphers_found sigalg ossl_supported + local pfs_cipher_list="$ROBUST_PFS_CIPHERS" pfs_hex_cipher_list="" ciphers_to_test + local ecdhe_cipher_list="" ecdhe_cipher_list_hex="" ffdhe_cipher_list_hex="" + local curves_hex=("00,01" "00,02" "00,03" "00,04" "00,05" "00,06" "00,07" "00,08" "00,09" "00,0a" "00,0b" "00,0c" "00,0d" "00,0e" "00,0f" "00,10" "00,11" "00,12" "00,13" "00,14" "00,15" "00,16" "00,17" "00,18" "00,19" "00,1a" "00,1b" "00,1c" "00,1d" "00,1e") local -a curves_ossl=("sect163k1" "sect163r1" "sect163r2" "sect193r1" "sect193r2" "sect233k1" "sect233r1" "sect239k1" "sect283k1" "sect283r1" "sect409k1" "sect409r1" "sect571k1" "sect571r1" "secp160k1" "secp160r1" "secp160r2" "secp192k1" "prime192v1" "secp224k1" "secp224r1" "secp256k1" "prime256v1" "secp384r1" "secp521r1" "brainpoolP256r1" "brainpoolP384r1" "brainpoolP512r1" "X25519" "X448") local -a curves_ossl_output=("K-163" "sect163r1" "B-163" "sect193r1" "sect193r2" "K-233" "B-233" "sect239k1" "K-283" "B-283" "K-409" "B-409" "K-571" "B-571" "secp160k1" "secp160r1" "secp160r2" "secp192k1" "P-192" "secp224k1" "P-224" "secp256k1" "P-256" "P-384" "P-521" "brainpoolP256r1" "brainpoolP384r1" "brainpoolP512r1" "X25519" "X448") - local -a supported_curves=() - local -i nr_supported_ciphers=0 nr_curves=0 i j low high - local pfs_ciphers curves_offered curves_to_test temp - local curve_found curve_used + local -a ffdhe_groups_hex=("01,00" "01,01" "01,02" "01,03" "01,04") + local -a ffdhe_groups_output=("ffdhe2048" "ffdhe3072" "ffdhe4096" "ffdhe6144" "ffdhe8192") + local -a supported_curve bits + local -i nr_supported_ciphers=0 nr_curves=0 nr_ossl_curves=0 i j low high + local pfs_ciphers curves_offered="" curves_offered_text="" curves_to_test temp + local len1 len2 curve_found + local has_dh_bits="$HAS_DH_BITS" + local using_sockets=true + + "$SSL_NATIVE" && using_sockets=false + "$FAST" && using_sockets=false + [[ $TLS_NR_CIPHERS == 0 ]] && using_sockets=false outln pr_headlineln " Testing robust (perfect) forward secrecy, (P)FS -- omitting Null Authentication/Encryption, 3DES, RC4 " - if ! "$HAS_DH_BITS" && "$WIDE"; then - pr_warningln " (Your $OPENSSL cannot show DH/ECDH bits)" - fi - - nr_supported_ciphers=$(count_ciphers $(actually_supported_ciphers $pfs_cipher_list)) - debugme echo $nr_supported_ciphers - debugme echo $(actually_supported_ciphers $pfs_cipher_list) - if [[ "$nr_supported_ciphers" -le "$CLIENT_MIN_PFS" ]]; then + if ! "$using_sockets"; then + [[ $TLS_NR_CIPHERS == 0 ]] && ! "$SSL_NATIVE" && ! "$FAST" && pr_warning " Cipher mapping not available, doing a fallback to openssl" + if ! "$HAS_DH_BITS" && "$WIDE"; then + [[ $TLS_NR_CIPHERS == 0 ]] && ! "$SSL_NATIVE" && ! "$FAST" && out "." + pr_warning " (Your $OPENSSL cannot show DH/ECDH bits)" + fi outln - local_problem_ln "You only have $nr_supported_ciphers PFS ciphers on the client side " - fileout "pfs" "WARN" "(Perfect) Forward Secrecy tests: Skipped. You only have $nr_supported_ciphers PFS ciphers on the client site. ($CLIENT_MIN_PFS are required)" - return 1 fi - $OPENSSL s_client -cipher $pfs_cipher_list $STARTTLS $BUGS -connect $NODEIP:$PORT $PROXY $SNI >$TMPFILE 2>$ERRFILE $ERRFILE) + fi + export="" + + if "$using_sockets"; then + tls_sockets "03" "${pfs_hex_cipher_list:2}" + sclient_success=$? + [[ $sclient_success -eq 2 ]] && sclient_success=0 + else + debugme echo $nr_supported_ciphers + debugme echo $(actually_supported_ciphers $pfs_cipher_list) + if [[ "$nr_supported_ciphers" -le "$CLIENT_MIN_PFS" ]]; then + outln + local_problem_ln "You only have $nr_supported_ciphers PFS ciphers on the client side " + fileout "pfs" "WARN" "(Perfect) Forward Secrecy tests: Skipped. You only have $nr_supported_ciphers PFS ciphers on the client site. ($CLIENT_MIN_PFS are required)" + return 1 + fi + $OPENSSL s_client -cipher $pfs_cipher_list $STARTTLS $BUGS -connect $NODEIP:$PORT $PROXY $SNI >$TMPFILE 2>$ERRFILE $tmpfile $TMPFILE $ERRFILE) # -V doesn't work with openssl < 1.0 + done + debugme echo $pfs_offered "$WIDE" || outln - if ! "$pfs_offered"; then - pr_svrty_medium "WARN: no PFS ciphers found" - fileout "pfs_ciphers" "MEDIUM" "(Perfect) Forward Secrecy Ciphers: no PFS ciphers found" - else - fileout "pfs_ciphers" "INFO" "(Perfect) Forward Secrecy Ciphers: $pfs_ciphers" - fi + fileout "pfs_ciphers" "INFO" "(Perfect) Forward Secrecy Ciphers: $pfs_ciphers" fi + # find out what elliptic curves are supported. if "$ecdhe_offered"; then - # find out what elliptic curves are supported. - curves_offered="" for curve in "${curves_ossl[@]}"; do + ossl_supported[nr_curves]=false + supported_curve[nr_curves]=false $OPENSSL s_client -curves $curve 2>&1 | egrep -iaq "Error with command|unknown option" - [[ $? -ne 0 ]] && nr_curves+=1 && supported_curves+=("$curve") + [[ $? -ne 0 ]] && ossl_supported[nr_curves]=true && nr_ossl_curves+=1 + nr_curves+=1 done # OpenSSL limits the number of curves that can be specified in the - # "-curves" option to 28. So, the list is broken in two since there - # are currently 30 curves defined. - for i in 1 2; do - case $i in - 1) low=0; high=$nr_curves/2 ;; - 2) low=$nr_curves/2; high=$nr_curves ;; - esac - sclient_success=0 - while [[ "$sclient_success" -eq 0 ]]; do - curves_to_test="" - for (( j=low; j < high; j++ )); do - [[ ! " $curves_offered " =~ " ${supported_curves[j]} " ]] && curves_to_test+=":${supported_curves[j]}" - done - if [[ -n "$curves_to_test" ]]; then - $OPENSSL s_client -cipher "${ecdhe_cipher_list:1}" -curves "${curves_to_test:1}" $STARTTLS $BUGS -connect $NODEIP:$PORT $PROXY $SNI &>$tmpfile $TMPFILE Date: Fri, 16 Dec 2016 10:15:05 -0500 Subject: [PATCH 06/61] Fix alignment problem in test_just_one() When `test_just_one()` uses `neat_list()` with a cipher that is not available and that uses DH for key exchange, the columns do not line up correctly. `test_just_one()` adds "TBD" in gray to "DH", and while `neat_list()` tries to adjust for the presence of color codes, it doesn't seem to correctly handle the gray color code here. Rather than try to fix this in `neat_list()`, I propose to just remove the "TBD". Adding it is inconsistent with other functions (like `run_allciphers()`), and it seems inappropriate, since there is nothing "to be determined," as the cipher suite isn't supported by the server. If adding "TBD" were appropriate anywhere, it would seem to be in cases in which the server does support the cipher, but the number of bits in the ephemeral key couldn't be determined because the version of OpenSSL being used can't show DH/ECDH bits. (Not that I'm proposing this. I think the one-line warning, "(Your $OPENSSL cannot show DH/ECDH bits)", is enough. Here is an example of `test_just_one()` with some ciphers not supported by the server that use DH key exchange: ``` Testing single cipher with word pattern "CAMELLIA" (ignore case) Hexcode Cipher Suite Name (OpenSSL) KeyExch. Encryption Bits Cipher Suite Name (RFC) --------------------------------------------------------------------------------------------------------------------------- xc077 ECDHE-RSA-CAMELLIA256-SHA384 ECDH TBD Camellia 256 TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384 not a/v xc073 ECDHE-ECDSA-CAMELLIA256-SHA384 ECDH TBD Camellia 256 TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 not a/v xc4 DHE-RSA-CAMELLIA256-SHA256 DH TBD Camellia 256 TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 not a/v xc3 DHE-DSS-CAMELLIA256-SHA256 DH TBD Camellia 256 TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256 not a/v xc2 DH-RSA-CAMELLIA256-SHA256 DH/RSA Camellia 256 TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA256 not a/v xc1 DH-DSS-CAMELLIA256-SHA256 DH/DSS Camellia 256 TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA256 not a/v x88 DHE-RSA-CAMELLIA256-SHA DH 2048 Camellia 256 TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA available x87 DHE-DSS-CAMELLIA256-SHA DH TBD Camellia 256 TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA not a/v x86 DH-RSA-CAMELLIA256-SHA DH/RSA Camellia 256 TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA not a/v x85 DH-DSS-CAMELLIA256-SHA DH/DSS Camellia 256 TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA not a/v xc5 ADH-CAMELLIA256-SHA256 DH TBD Camellia 256 TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA256 not a/v x89 ADH-CAMELLIA256-SHA DH TBD Camellia 256 TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA not a/v xc079 ECDH-RSA-CAMELLIA256-SHA384 ECDH/RSA Camellia 256 TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384 not a/v xc075 ECDH-ECDSA-CAMELLIA256-SHA384 ECDH/ECDSA Camellia 256 TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 not a/v xc0 CAMELLIA256-SHA256 RSA Camellia 256 TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256 not a/v x84 CAMELLIA256-SHA RSA Camellia 256 TLS_RSA_WITH_CAMELLIA_256_CBC_SHA not a/v xc076 ECDHE-RSA-CAMELLIA128-SHA256 ECDH TBD Camellia 128 TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 not a/v xc072 ECDHE-ECDSA-CAMELLIA128-SHA256 ECDH TBD Camellia 128 TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 not a/v xbe DHE-RSA-CAMELLIA128-SHA256 DH TBD Camellia 128 TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 not a/v xbd DHE-DSS-CAMELLIA128-SHA256 DH TBD Camellia 128 TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256 not a/v xbc DH-RSA-CAMELLIA128-SHA256 DH/RSA Camellia 128 TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA256 not a/v xbb DH-DSS-CAMELLIA128-SHA256 DH/DSS Camellia 128 TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA256 not a/v x45 DHE-RSA-CAMELLIA128-SHA DH 2048 Camellia 128 TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA available x44 DHE-DSS-CAMELLIA128-SHA DH TBD Camellia 128 TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA not a/v x43 DH-RSA-CAMELLIA128-SHA DH/RSA Camellia 128 TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA not a/v x42 DH-DSS-CAMELLIA128-SHA DH/DSS Camellia 128 TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA not a/v xbf ADH-CAMELLIA128-SHA256 DH TBD Camellia 128 TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA256 not a/v x46 ADH-CAMELLIA128-SHA DH TBD Camellia 128 TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA not a/v xc078 ECDH-RSA-CAMELLIA128-SHA256 ECDH/RSA Camellia 128 TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256 not a/v xc074 ECDH-ECDSA-CAMELLIA128-SHA256 ECDH/ECDSA Camellia 128 TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 not a/v xba CAMELLIA128-SHA256 RSA Camellia 128 TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256 not a/v x41 CAMELLIA128-SHA RSA Camellia 128 TLS_RSA_WITH_CAMELLIA_128_CBC_SHA not a/v ``` --- testssl.sh | 2 -- 1 file changed, 2 deletions(-) diff --git a/testssl.sh b/testssl.sh index 648b38a..90c6b9f 100755 --- a/testssl.sh +++ b/testssl.sh @@ -2229,8 +2229,6 @@ test_just_one(){ if [[ $sclient_success -eq 0 ]]; then dhlen=$(read_dhbits_from_file $TMPFILE quiet) kx="$kx $dhlen" - else - kx="$kx$grey TBD $off " fi fi neat_list $HEXC $ciph "$kx" $enc From 7fa6455b83d2a77022cbe2a9fab7894a99a9e927 Mon Sep 17 00:00:00 2001 From: David Cooper Date: Fri, 16 Dec 2016 11:30:34 -0500 Subject: [PATCH 07/61] Fix typo --- testssl.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testssl.sh b/testssl.sh index 74e4e1b..df0afd2 100755 --- a/testssl.sh +++ b/testssl.sh @@ -2556,7 +2556,7 @@ run_cipher_per_proto() { ciphers_found[nr_ciphers]=false sigalg[nr_ciphers]="" ossl_supported[nr_ciphers]=${TLS_CIPHER_OSSL_SUPPORTED[i]} - if "$using_sockets" && ! "$has_dh_bits" && ( [[ ${kx[i]} == "Kx=ECDH" ]] || [[ ${kx[i]} == "Kx=DH" ]] || [[ ${kx[i]} == "Kx=EDH" ]] ); then + if "$using_sockets" && ! "$has_dh_bits" && ( [[ ${kx[nr_ciphers]} == "Kx=ECDH" ]] || [[ ${kx[nr_ciphers]} == "Kx=DH" ]] || [[ ${kx[nr_ciphers]} == "Kx=EDH" ]] ); then ossl_supported[nr_ciphers]=false fi if [[ ${#hexc} -eq 9 ]]; then From b1d231ff855811d90868c885b561f23d0f277493 Mon Sep 17 00:00:00 2001 From: David Cooper Date: Mon, 19 Dec 2016 16:56:12 -0500 Subject: [PATCH 08/61] Use sockets in `run_server_preference()` This PR adds the use of sockets to `run_server_preference()` to determine the "Negotiated cipher per proto." It only uses sockets in two cases: * For SSLv2, if $OPENSSL does not support SSLv2. * For SSLv2, if $OPENSSL does not support SSLv3. This PR will have no effect if the provided OpenSSL binaries are used. --- testssl.sh | 79 +++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 58 insertions(+), 21 deletions(-) diff --git a/testssl.sh b/testssl.sh index 95fbb3c..3a01050 100755 --- a/testssl.sh +++ b/testssl.sh @@ -4296,15 +4296,18 @@ read_dhbits_from_file() { run_server_preference() { local cipher1 cipher2 local default_cipher default_proto - local remark4default_cipher + local remark4default_cipher supported_sslv2_ciphers local -a cipher proto local p i - local -i ret=0 + local -i ret=0 j local list_fwd="DES-CBC3-SHA:RC4-MD5:DES-CBC-SHA:RC4-SHA:AES128-SHA:AES128-SHA256:AES256-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA:ECDH-RSA-DES-CBC3-SHA:ECDH-RSA-AES128-SHA:ECDH-RSA-AES256-SHA:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:DHE-DSS-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:AES256-SHA256" # now reversed offline via tac, see https://github.com/thomassa/testssl.sh/commit/7a4106e839b8c3033259d66697893765fc468393 : local list_reverse="AES256-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-DSS-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDH-RSA-AES256-SHA:ECDH-RSA-AES128-SHA:ECDH-RSA-DES-CBC3-SHA:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:ECDHE-RSA-AES128-SHA:AES256-SHA:AES128-SHA256:AES128-SHA:RC4-SHA:DES-CBC-SHA:RC4-MD5:DES-CBC3-SHA" local has_cipher_order=true local isok addcmd="" addcmd2="" sni="" + local using_sockets=true + + "$SSL_NATIVE" && using_sockets=false outln pr_headlineln " Testing server preferences " @@ -4463,26 +4466,60 @@ run_server_preference() { i=1 for p in ssl2 ssl3 tls1 tls1_1 tls1_2; do if [[ $p == ssl2 ]] && ! "$HAS_SSL2"; then - out " (SSLv2: "; local_problem "$OPENSSL doesn't support \"s_client -ssl2\""; outln ")"; - continue - fi - if [[ $p == ssl3 ]] && ! "$HAS_SSL3"; then - out " (SSLv3: "; local_problem "$OPENSSL doesn't support \"s_client -ssl3\"" ; outln ")"; - continue - fi - if [[ "$p" =~ ssl ]]; then - $OPENSSL s_client $STARTTLS -"$p" $BUGS -connect $NODEIP:$PORT $PROXY >$ERRFILE >$TMPFILE + if ! "$using_sockets" || [[ $TLS_NR_CIPHERS -eq 0 ]]; then + out " (SSLv2: "; local_problem "$OPENSSL doesn't support \"s_client -ssl2\""; outln ")"; + continue + else + sslv2_sockets "" "true" + if [[ $? -eq 3 ]] && [[ "$V2_HELLO_CIPHERSPEC_LENGTH" -ne 0 ]]; then + # Just arbitrarily pick the first cipher in the cipher-mapping.txt list. + proto[i]="SSLv2" + supported_sslv2_ciphers="$(grep "Supported cipher: " "$TEMPDIR/$NODEIP.parse_sslv2_serverhello.txt")" + for (( j=0; j < TLS_NR_CIPHERS; j++ )); do + if [[ "${TLS_CIPHER_SSLVERS[j]}" == "SSLv2" ]]; then + cipher1="${TLS_CIPHER_HEXCODE[j]}" + cipher1="$(tolower "x${cipher1:2:2}${cipher1:7:2}${cipher1:12:2}")" + if [[ "$supported_sslv2_ciphers" =~ "$cipher1" ]]; then + cipher[i]="${TLS_CIPHER_OSSL_NAME[j]}" + break + fi + fi + done + [[ $DEBUG -ge 2 ]] && outln "Default cipher for ${proto[i]}: ${cipher[i]}" + else + proto[i]="" + cipher[i]="" + fi + fi + elif [[ $p == ssl3 ]] && ! "$HAS_SSL3"; then + if ! "$using_sockets"; then + out " (SSLv3: "; local_problem "$OPENSSL doesn't support \"s_client -ssl3\"" ; outln ")"; + continue + else + tls_sockets "00" "$TLS_CIPHER" + if [[ $? -eq 0 ]]; then + proto[i]="SSLv3" + cipher1=$(awk '/Cipher *:/ { print $3 }' "$TEMPDIR/$NODEIP.parse_tls_serverhello.txt") + [[ $TLS_NR_CIPHERS -ne 0 ]] && cipher[i]="$(rfc2openssl "$cipher1")" + [[ -z "${cipher[i]}" ]] && cipher[i]="$cipher1" + [[ $DEBUG -ge 2 ]] && outln "Default cipher for ${proto[i]}: ${cipher[i]}" + else + proto[i]="" + cipher[i]="" + fi + fi else - $OPENSSL s_client $STARTTLS -"$p" $BUGS -connect $NODEIP:$PORT $PROXY $SNI >$ERRFILE >$TMPFILE - fi - if sclient_connect_successful $? $TMPFILE; then - proto[i]=$(grep -aw "Protocol" $TMPFILE | sed -e 's/^.*Protocol.*://' -e 's/ //g') - cipher[i]=$(grep -aw "Cipher" $TMPFILE | egrep -avw "New|is" | sed -e 's/^.*Cipher.*://' -e 's/ //g') - [[ ${cipher[i]} == "0000" ]] && cipher[i]="" # Hack! - [[ $DEBUG -ge 2 ]] && outln "Default cipher for ${proto[i]}: ${cipher[i]}" - else - proto[i]="" - cipher[i]="" + [[ "$p" =~ ssl ]] && sni="" || sni="$SNI" + $OPENSSL s_client $STARTTLS -"$p" $BUGS -connect $NODEIP:$PORT $PROXY $sni >$ERRFILE >$TMPFILE + if sclient_connect_successful $? $TMPFILE; then + proto[i]=$(grep -aw "Protocol" $TMPFILE | sed -e 's/^.*Protocol.*://' -e 's/ //g') + cipher[i]=$(grep -aw "Cipher" $TMPFILE | egrep -avw "New|is" | sed -e 's/^.*Cipher.*://' -e 's/ //g') + [[ ${cipher[i]} == "0000" ]] && cipher[i]="" # Hack! + [[ $DEBUG -ge 2 ]] && outln "Default cipher for ${proto[i]}: ${cipher[i]}" + else + proto[i]="" + cipher[i]="" + fi fi i=$(($i + 1)) done From 6492954735cc2fe446e604884052621020f7b473 Mon Sep 17 00:00:00 2001 From: David Cooper Date: Mon, 19 Dec 2016 16:59:27 -0500 Subject: [PATCH 09/61] Fix alignment --- testssl.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/testssl.sh b/testssl.sh index 3a01050..1a0c197 100755 --- a/testssl.sh +++ b/testssl.sh @@ -4517,8 +4517,8 @@ run_server_preference() { [[ ${cipher[i]} == "0000" ]] && cipher[i]="" # Hack! [[ $DEBUG -ge 2 ]] && outln "Default cipher for ${proto[i]}: ${cipher[i]}" else - proto[i]="" - cipher[i]="" + proto[i]="" + cipher[i]="" fi fi i=$(($i + 1)) From dd5487b21381e1e29b03378a920593309a69c6b6 Mon Sep 17 00:00:00 2001 From: David Cooper Date: Mon, 19 Dec 2016 17:06:45 -0500 Subject: [PATCH 10/61] Ensure cipher[i]="" in SSLv3 test --- testssl.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/testssl.sh b/testssl.sh index 1a0c197..f0a80f7 100755 --- a/testssl.sh +++ b/testssl.sh @@ -4499,6 +4499,7 @@ run_server_preference() { tls_sockets "00" "$TLS_CIPHER" if [[ $? -eq 0 ]]; then proto[i]="SSLv3" + cipher[i]="" cipher1=$(awk '/Cipher *:/ { print $3 }' "$TEMPDIR/$NODEIP.parse_tls_serverhello.txt") [[ $TLS_NR_CIPHERS -ne 0 ]] && cipher[i]="$(rfc2openssl "$cipher1")" [[ -z "${cipher[i]}" ]] && cipher[i]="$cipher1" From ea7edaf59f4a1ff3ea3e54b0679f71bae333ed43 Mon Sep 17 00:00:00 2001 From: Dirk Date: Tue, 20 Dec 2016 14:17:14 +0100 Subject: [PATCH 11/61] - unify timeout msgs on the console --- testssl.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/testssl.sh b/testssl.sh index 95fbb3c..322eadf 100755 --- a/testssl.sh +++ b/testssl.sh @@ -8435,7 +8435,7 @@ run_ccs_injection(){ fi ret=1 fi - [[ $retval -eq 3 ]] && out " (timed out)" + [[ $retval -eq 3 ]] && out ", timed out" outln close_socket @@ -8513,7 +8513,7 @@ run_renego() { echo R | $OPENSSL s_client $OPTIMAL_PROTO $BUGS $legacycmd $STARTTLS -msg -connect $NODEIP:$PORT $addcmd $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_done_good "likely not vulnerable (OK)"; outln ", timed out" # it hung fileout "sec_client_renego" "OK" "Secure Client-Initiated Renegotiation : likely not vulnerable (timed out)" "$cve" "$cwe" sec_client_renego=1 else From cfaeb51395b393f8bb95093adb85670953922f99 Mon Sep 17 00:00:00 2001 From: David Cooper Date: Tue, 20 Dec 2016 12:59:26 -0500 Subject: [PATCH 12/61] Show "exp" bits column for export ciphers --- testssl.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/testssl.sh b/testssl.sh index e77f424..84e2f5a 100755 --- a/testssl.sh +++ b/testssl.sh @@ -9180,6 +9180,7 @@ run_beast(){ first=false for (( i=0; i < nr_ciphers; i++ )); do if "${ciphers_found[i]}" || "$SHOW_EACH_C"; then + export="${export2[i]}" neat_list "$(tolower "${normalized_hexcode[i]}")" "${ciph[i]}" "${kx[i]}" "${enc[i]}" if "$SHOW_EACH_C"; then if "${ciphers_found[i]}"; then From 1a7d1f73d2d6f1670ad419ee8418c1c442aebbd6 Mon Sep 17 00:00:00 2001 From: David Cooper Date: Tue, 20 Dec 2016 13:11:03 -0500 Subject: [PATCH 13/61] Mark export ciphers in run_rc4() This PR adds ",exp" to the bits column when `run_rc4()` is run in the "--wide" mode and the cipher is an export cipher. This makes the wide mode of `run_rc4()` align with other functions, such as `run_allciphers()`. --- testssl.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/testssl.sh b/testssl.sh index 322eadf..0532945 100755 --- a/testssl.sh +++ b/testssl.sh @@ -9382,6 +9382,7 @@ run_rc4() { fi if "$WIDE"; then #FIXME: JSON+CSV in wide mode is missing + export="${export2[i]}" neat_list "${normalized_hexcode[i]}" "${ciph[i]}" "${kx[i]}" "${enc[i]}" if "$SHOW_EACH_C"; then if "${ciphers_found[i]}"; then From 4af01a6c1bc6c8e17137f11ec77504bfcccf57be Mon Sep 17 00:00:00 2001 From: David Cooper Date: Tue, 20 Dec 2016 13:14:40 -0500 Subject: [PATCH 14/61] test_just_one() sockets This PR implements `test_just_one()` in a similar manner to `run_allciphers()` --- testssl.sh | 272 ++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 238 insertions(+), 34 deletions(-) diff --git a/testssl.sh b/testssl.sh index 322eadf..2586712 100755 --- a/testssl.sh +++ b/testssl.sh @@ -2188,10 +2188,20 @@ neat_list(){ } test_just_one(){ - local hexcode n ciph sslvers kx auth enc mac export - local dhlen - local sclient_success + local hexc n auth export ciphers_to_test supported_sslv2_ciphers s + local -a hexcode normalized_hexcode ciph sslvers kx enc export2 sigalg + local -a ciphers_found ciphers_found2 ciph2 rfc_ciph rfc_ciph2 ossl_supported + local -a -i index + local -i nr_ciphers=0 nr_ossl_ciphers=0 nr_nonossl_ciphers=0 + local -i num_bundles mod_check bundle_size bundle end_of_bundle + local addcmd dhlen has_dh_bits="$HAS_DH_BITS" + local -i sclient_success local re='^[0-9A-Fa-f]+$' + local using_sockets=true + + "$SSL_NATIVE" && using_sockets=false + "$FAST" && using_sockets=false + [[ $TLS_NR_CIPHERS == 0 ]] && using_sockets=false pr_headline " Testing single cipher with " if [[ $1 =~ $re ]]; then @@ -2202,46 +2212,240 @@ test_just_one(){ tjolines="$tjolines word pattern \"$1\" (ignore case)\n\n" fi outln - ! "$HAS_DH_BITS" && pr_warningln " (Your $OPENSSL cannot show DH/ECDH bits)" + if ! "$using_sockets"; then + [[ $TLS_NR_CIPHERS == 0 ]] && ! "$SSL_NATIVE" && ! "$FAST" && pr_warning " Cipher mapping not available, doing a fallback to openssl" + if ! "$HAS_DH_BITS"; then + [[ $TLS_NR_CIPHERS == 0 ]] && ! "$SSL_NATIVE" && ! "$FAST" && out "." + pr_warningln " (Your $OPENSSL cannot show DH/ECDH bits)" + fi + fi outln neat_header #for arg in $(echo $@ | sed 's/,/ /g'); do for arg in ${*//, /}; do - # 1st check whether openssl has cipher or not - $OPENSSL ciphers -V 'ALL:COMPLEMENTOFALL:@STRENGTH' 2>$ERRFILE | while read hexcode dash ciph sslvers kx auth enc mac export ; do - # FIXME: e.g. OpenSSL < 1.0 doesn't understand "-V" --> we can't do anything about it! - normalize_ciphercode $hexcode - # is argument a number? - if [[ $arg =~ $re ]]; then - neat_list $HEXC $ciph $kx $enc | grep -qai "$arg" - else - neat_list $HEXC $ciph $kx $enc | grep -qwai "$arg" - fi - if [[ $? -eq 0 ]]; then # string matches, so we can ssl to it: - if [[ "$sslvers" == "SSLv2" ]]; then - $OPENSSL s_client -ssl2 -cipher $ciph $STARTTLS $BUGS -connect $NODEIP:$PORT $PROXY 2>$ERRFILE >$TMPFILE $ERRFILE >$TMPFILE >$ERRFILE) + fi + + # Test the SSLv2 ciphers, if any. + if "$using_sockets"; then + ciphers_to_test="" + for (( i=0; i < nr_ciphers; i++ )); do + if [[ "${sslvers[i]}" == "SSLv2" ]]; then + ciphers_to_test+=", ${hexcode[i]}" + fi + done + if [[ -n "$ciphers_to_test" ]]; then + sslv2_sockets "${ciphers_to_test:2}" "true" + if [[ $? -eq 3 ]] && [[ "$V2_HELLO_CIPHERSPEC_LENGTH" -ne 0 ]]; then + supported_sslv2_ciphers="$(grep "Supported cipher: " "$TEMPDIR/$NODEIP.parse_sslv2_serverhello.txt")" + "$SHOW_SIGALGO" && s="$($OPENSSL x509 -noout -text -in "$HOSTCERT" | awk -F':' '/Signature Algorithm/ { print $2 }' | head -1)" + for (( i=0 ; i$TMPFILE 2>$ERRFILE = 128 ciphers. So, + # test cipher suites in bundles of 128 or less. + num_bundles=$nr_ossl_ciphers/128 + mod_check=$nr_ossl_ciphers%128 + [[ $mod_check -ne 0 ]] && num_bundles=$num_bundles+1 + + bundle_size=$nr_ossl_ciphers/$num_bundles + mod_check=$nr_ossl_ciphers%$num_bundles + [[ $mod_check -ne 0 ]] && bundle_size+=1 + fi + + "$HAS_NO_SSL2" && addcmd="-no_ssl2" || addcmd="" + for (( bundle=0; bundle < num_bundles; bundle++ )); do + end_of_bundle=$bundle*$bundle_size+$bundle_size + [[ $end_of_bundle -gt $nr_ossl_ciphers ]] && end_of_bundle=$nr_ossl_ciphers + while true; do + ciphers_to_test="" + for (( i=bundle*bundle_size; i < end_of_bundle; i++ )); do + ! "${ciphers_found2[i]}" && ciphers_to_test+=":${ciph2[i]}" + done + [[ -z "$ciphers_to_test" ]] && break + $OPENSSL s_client $addcmd -cipher "${ciphers_to_test:1}" $STARTTLS $BUGS -connect $NODEIP:$PORT $PROXY $SNI >$TMPFILE 2>$ERRFILE = 128 ciphers. So, + # test cipher suites in bundles of 128 or less. + num_bundles=$nr_nonossl_ciphers/128 + mod_check=$nr_nonossl_ciphers%128 + [[ $mod_check -ne 0 ]] && num_bundles=$num_bundles+1 + + bundle_size=$nr_nonossl_ciphers/$num_bundles + mod_check=$nr_nonossl_ciphers%$num_bundles + [[ $mod_check -ne 0 ]] && bundle_size+=1 + fi + + for (( bundle=0; bundle < num_bundles; bundle++ )); do + end_of_bundle=$bundle*$bundle_size+$bundle_size + [[ $end_of_bundle -gt $nr_nonossl_ciphers ]] && end_of_bundle=$nr_nonossl_ciphers + while true; do + ciphers_to_test="" + for (( i=bundle*bundle_size; i < end_of_bundle; i++ )); do + ! "${ciphers_found2[i]}" && ciphers_to_test+=", ${hexcode2[i]}" + done + [[ -z "$ciphers_to_test" ]] && break + if "$SHOW_SIGALGO"; then + tls_sockets "03" "${ciphers_to_test:2}, 00,ff" "all" + else + tls_sockets "03" "${ciphers_to_test:2}, 00,ff" "ephemeralkey" + fi + sclient_success=$? + [[ $sclient_success -ne 0 ]] && [[ $sclient_success -ne 2 ]] && break + cipher=$(awk '/Cipher *:/ { print $3 }' "$TEMPDIR/$NODEIP.parse_tls_serverhello.txt") + for (( i=bundle*bundle_size; i < end_of_bundle; i++ )); do + [[ "$cipher" == "${rfc_ciph2[i]}" ]] && ciphers_found2[i]=true && break + done + [[ $i -eq $end_of_bundle ]] && break + i=${index[i]} + ciphers_found[i]=true + if [[ ${kx[i]} == "Kx=ECDH" ]] || [[ ${kx[i]} == "Kx=DH" ]] || [[ ${kx[i]} == "Kx=EDH" ]]; then + dhlen=$(read_dhbits_from_file "$TEMPDIR/$NODEIP.parse_tls_serverhello.txt" quiet) + kx[i]="${kx[i]} $dhlen" + fi + "$SHOW_SIGALGO" && [[ -r "$HOSTCERT" ]] && \ + sigalg[i]="$($OPENSSL x509 -noout -text -in "$HOSTCERT" | awk -F':' '/Signature Algorithm/ { print $2 }' | head -1)" + done + done + + for (( i=0; i < nr_ciphers; i++ )); do + export="${export2[i]}" + neat_list "${normalized_hexcode[i]}" "${ciph[i]}" "${kx[i]}" "${enc[i]}" + if "${ciphers_found[i]}"; then + pr_cyan " available" + fileout "cipher_${normalized_hexcode[i]}" "INFO" "$(neat_list "${normalized_hexcode[i]}" "${ciph[i]}" "${kx[i]}" "${enc[i]}") available" + else + out " not a/v" + fileout "cipher_${normalized_hexcode[i]}" "INFO" "$(neat_list "${normalized_hexcode[i]}" "${ciph[i]}" "${kx[i]}" "${enc[i]}") not a/v" + fi + outln + done + "$using_sockets" && HAS_DH_BITS="$has_dh_bits" exit done outln From 378f4439a3d5861587c5b01a78e67d9bfb23bb40 Mon Sep 17 00:00:00 2001 From: David Cooper Date: Tue, 20 Dec 2016 14:02:29 -0500 Subject: [PATCH 15/61] testssl.sh hangs on local testing In a few places testssl.sh tries to determine $OPENSSL s_client's capabilities by calling `$OPENSSL s_client` without specifying a host to which to connect. For example: ``` $OPENSSL s_client -no_ssl2 2>&1 ``` This idea is that `$OPENSSL s_client` should reveal something about its capabilities without actually trying to connect to a host. This works in most cases. However, the manual pages for s_client states: ``` -connect host:port This specifies the host and optional port to connect to. If not specified then an attempt is made to connect to the local host on port 4433. ``` So, the above call is actually trying to connect to the local host on port 4433. If the local host is running `$OPENSSL s_server`, then `$OPENSSL s_server` will by default be listening on port 4433, and the connection attempt will most likely succeed. Since the `OPENSSL s_client` command does not include a `< /dev/null`, the `OPENSSL s_client` will just hang waiting for additional input. Adding `-connect x` to the `$OPENSSL s_client` prevents $OPENSSL from trying to connect to a host, but seems to still provide the necessary information about OpenSSL's capabilities. --- testssl.sh | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/testssl.sh b/testssl.sh index 322eadf..82dfddf 100755 --- a/testssl.sh +++ b/testssl.sh @@ -3861,7 +3861,7 @@ run_client_simulation() { # generic function whether $1 is supported by s_client ($2: string to display) locally_supported() { [[ -n "$2" ]] && out "$2 " - if $OPENSSL s_client "$1" 2>&1 | grep -aq "unknown option"; then + if $OPENSSL s_client "$1" -connect x 2>&1 | grep -aq "unknown option"; then local_problem_ln "$OPENSSL doesn't support \"s_client $1\"" return 7 fi @@ -6043,7 +6043,7 @@ run_pfs() { # find out what elliptic curves are supported. curves_offered="" for curve in "${curves_ossl[@]}"; do - $OPENSSL s_client -curves $curve 2>&1 | egrep -iaq "Error with command|unknown option" + $OPENSSL s_client -curves $curve -connect x 2>&1 | egrep -iaq "Error with command|unknown option" [[ $? -ne 0 ]] && nr_curves+=1 && supported_curves+=("$curve") done @@ -9544,13 +9544,13 @@ find_openssl_binary() { OPENSSL_NR_CIPHERS=$(count_ciphers "$($OPENSSL ciphers 'ALL:COMPLEMENTOFALL:@STRENGTH' 2>/dev/null)") - $OPENSSL s_client -ssl2 2>&1 | grep -aq "unknown option" || \ + $OPENSSL s_client -ssl2 -connect x 2>&1 | grep -aq "unknown option" || \ HAS_SSL2=true - $OPENSSL s_client -ssl3 2>&1 | grep -aq "unknown option" || \ + $OPENSSL s_client -ssl3 -connect x 2>&1 | grep -aq "unknown option" || \ HAS_SSL3=true - $OPENSSL s_client -no_ssl2 2>&1 | grep -aq "unknown option" || \ + $OPENSSL s_client -no_ssl2 -connect x 2>&1 | grep -aq "unknown option" || \ HAS_NO_SSL2=true $OPENSSL s_client -help 2>$s_client_has From f450bc66cd1b1057d6a7a524663b9d446d08af8c Mon Sep 17 00:00:00 2001 From: David Cooper Date: Wed, 21 Dec 2016 10:36:09 -0500 Subject: [PATCH 16/61] Use sockets for run_ssl_poodle() This PR changes `run_ssl_poodle()` to use sockets. This PR is particularly useful when $OPENSSL is OpenSSL 1.1.0, since OpenSS 1.1.0 does not support SSLv3 by default. But, it is also useful if $OPENSSL supports some, but not all, of the CBC ciphers. As with `run_beast()`, there is a small change to `$cbc_cipher_list`. The following two ciphers were added: ``` 0x00,0x0B - EXP-DH-DSS-DES-CBC-SHA SSLv3 Kx=DH/DSS Au=DH Enc=DES(40) Mac=SHA1 export 0x00,0x0E - EXP-DH-RSA-DES-CBC-SHA SSLv3 Kx=DH/RSA Au=DH Enc=DES(40) Mac=SHA1 export ``` The ciphers that were removed are all SSLv2 ciphers: ``` 0x07,0x00,0xC0 - DES-CBC3-MD5 SSLv2 Kx=RSA Au=RSA Enc=3DES(168) Mac=MD5 0x06,0x00,0x40 - DES-CBC-MD5 SSLv2 Kx=RSA Au=RSA Enc=DES(56) Mac=MD5 0x04,0x00,0x80 - EXP-RC2-CBC-MD5 SSLv2 Kx=RSA(512) Au=RSA Enc=RC2(40) Mac=MD5 export 0x05,0x00,0x80 - IDEA-CBC-MD5 SSLv2 Kx=RSA Au=RSA Enc=IDEA(128) Mac=MD5 0x03,0x00,0x80 - RC2-CBC-MD5 SSLv2 Kx=RSA Au=RSA Enc=RC2(128) Mac=MD5 ``` (EXP-RC2-CBC-MD5 is both an SSLv2 and an SSLv3 cipher. Previously it was listed twice in `$cbc_cipher_list`, now it appears once.) --- testssl.sh | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/testssl.sh b/testssl.sh index 405e138..8b6bd61 100755 --- a/testssl.sh +++ b/testssl.sh @@ -8702,21 +8702,30 @@ run_breach() { # Padding Oracle On Downgraded Legacy Encryption, in a nutshell: don't use CBC Ciphers in SSLv3 run_ssl_poodle() { local -i sclient_success=0 - local cbc_ciphers="ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:SRP-DSS-AES-256-CBC-SHA:SRP-RSA-AES-256-CBC-SHA:SRP-AES-256-CBC-SHA:DHE-PSK-AES256-CBC-SHA:DHE-RSA-AES256-SHA:DHE-DSS-AES256-SHA:DH-RSA-AES256-SHA:DH-DSS-AES256-SHA:DHE-RSA-CAMELLIA256-SHA:DHE-DSS-CAMELLIA256-SHA:DH-RSA-CAMELLIA256-SHA:DH-DSS-CAMELLIA256-SHA:AECDH-AES256-SHA:ADH-AES256-SHA:ADH-CAMELLIA256-SHA:ECDH-RSA-AES256-SHA:ECDH-ECDSA-AES256-SHA:AES256-SHA:ECDHE-PSK-AES256-CBC-SHA:CAMELLIA256-SHA:RSA-PSK-AES256-CBC-SHA:PSK-AES256-CBC-SHA:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:SRP-DSS-AES-128-CBC-SHA:SRP-RSA-AES-128-CBC-SHA:SRP-AES-128-CBC-SHA:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA:DH-RSA-AES128-SHA:DH-DSS-AES128-SHA:DHE-RSA-SEED-SHA:DHE-DSS-SEED-SHA:DH-RSA-SEED-SHA:DH-DSS-SEED-SHA:DHE-RSA-CAMELLIA128-SHA:DHE-DSS-CAMELLIA128-SHA:DH-RSA-CAMELLIA128-SHA:DH-DSS-CAMELLIA128-SHA:AECDH-AES128-SHA:ADH-AES128-SHA:ADH-SEED-SHA:ADH-CAMELLIA128-SHA:ECDH-RSA-AES128-SHA:ECDH-ECDSA-AES128-SHA:AES128-SHA:ECDHE-PSK-AES128-CBC-SHA:DHE-PSK-AES128-CBC-SHA:SEED-SHA:CAMELLIA128-SHA:IDEA-CBC-SHA:IDEA-CBC-MD5:RC2-CBC-MD5:RSA-PSK-AES128-CBC-SHA:PSK-AES128-CBC-SHA:KRB5-IDEA-CBC-SHA:KRB5-IDEA-CBC-MD5:ECDHE-RSA-DES-CBC3-SHA:ECDHE-ECDSA-DES-CBC3-SHA:SRP-DSS-3DES-EDE-CBC-SHA:SRP-RSA-3DES-EDE-CBC-SHA:SRP-3DES-EDE-CBC-SHA:EDH-RSA-DES-CBC3-SHA:EDH-DSS-DES-CBC3-SHA:DH-RSA-DES-CBC3-SHA:DH-DSS-DES-CBC3-SHA:AECDH-DES-CBC3-SHA:ADH-DES-CBC3-SHA:ECDH-RSA-DES-CBC3-SHA:ECDH-ECDSA-DES-CBC3-SHA:DES-CBC3-SHA:DES-CBC3-MD5:RSA-PSK-3DES-EDE-CBC-SHA:PSK-3DES-EDE-CBC-SHA:KRB5-DES-CBC3-SHA:KRB5-DES-CBC3-MD5:ECDHE-PSK-3DES-EDE-CBC-SHA:DHE-PSK-3DES-EDE-CBC-SHA:EXP1024-DHE-DSS-DES-CBC-SHA:EDH-RSA-DES-CBC-SHA:EDH-DSS-DES-CBC-SHA:DH-RSA-DES-CBC-SHA:DH-DSS-DES-CBC-SHA:ADH-DES-CBC-SHA:EXP1024-DES-CBC-SHA:DES-CBC-SHA:DES-CBC-MD5:KRB5-DES-CBC-SHA:KRB5-DES-CBC-MD5:EXP-EDH-RSA-DES-CBC-SHA:EXP-EDH-DSS-DES-CBC-SHA:EXP-ADH-DES-CBC-SHA:EXP-DES-CBC-SHA:EXP-RC2-CBC-MD5:EXP-RC2-CBC-MD5:EXP-KRB5-RC2-CBC-SHA:EXP-KRB5-DES-CBC-SHA:EXP-KRB5-RC2-CBC-MD5:EXP-KRB5-DES-CBC-MD5" + local cbc_ciphers="ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:SRP-DSS-AES-256-CBC-SHA:SRP-RSA-AES-256-CBC-SHA:SRP-AES-256-CBC-SHA:DHE-PSK-AES256-CBC-SHA:DHE-RSA-AES256-SHA:DHE-DSS-AES256-SHA:DH-RSA-AES256-SHA:DH-DSS-AES256-SHA:DHE-RSA-CAMELLIA256-SHA:DHE-DSS-CAMELLIA256-SHA:DH-RSA-CAMELLIA256-SHA:DH-DSS-CAMELLIA256-SHA:AECDH-AES256-SHA:ADH-AES256-SHA:ADH-CAMELLIA256-SHA:ECDH-RSA-AES256-SHA:ECDH-ECDSA-AES256-SHA:AES256-SHA:ECDHE-PSK-AES256-CBC-SHA:CAMELLIA256-SHA:RSA-PSK-AES256-CBC-SHA:PSK-AES256-CBC-SHA:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:SRP-DSS-AES-128-CBC-SHA:SRP-RSA-AES-128-CBC-SHA:SRP-AES-128-CBC-SHA:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA:DH-RSA-AES128-SHA:DH-DSS-AES128-SHA:DHE-RSA-SEED-SHA:DHE-DSS-SEED-SHA:DH-RSA-SEED-SHA:DH-DSS-SEED-SHA:DHE-RSA-CAMELLIA128-SHA:DHE-DSS-CAMELLIA128-SHA:DH-RSA-CAMELLIA128-SHA:DH-DSS-CAMELLIA128-SHA:AECDH-AES128-SHA:ADH-AES128-SHA:ADH-SEED-SHA:ADH-CAMELLIA128-SHA:ECDH-RSA-AES128-SHA:ECDH-ECDSA-AES128-SHA:AES128-SHA:ECDHE-PSK-AES128-CBC-SHA:DHE-PSK-AES128-CBC-SHA:SEED-SHA:CAMELLIA128-SHA:IDEA-CBC-SHA:RSA-PSK-AES128-CBC-SHA:PSK-AES128-CBC-SHA:KRB5-IDEA-CBC-SHA:KRB5-IDEA-CBC-MD5:ECDHE-RSA-DES-CBC3-SHA:ECDHE-ECDSA-DES-CBC3-SHA:SRP-DSS-3DES-EDE-CBC-SHA:SRP-RSA-3DES-EDE-CBC-SHA:SRP-3DES-EDE-CBC-SHA:EDH-RSA-DES-CBC3-SHA:EDH-DSS-DES-CBC3-SHA:DH-RSA-DES-CBC3-SHA:DH-DSS-DES-CBC3-SHA:AECDH-DES-CBC3-SHA:ADH-DES-CBC3-SHA:ECDH-RSA-DES-CBC3-SHA:ECDH-ECDSA-DES-CBC3-SHA:DES-CBC3-SHA:RSA-PSK-3DES-EDE-CBC-SHA:PSK-3DES-EDE-CBC-SHA:KRB5-DES-CBC3-SHA:KRB5-DES-CBC3-MD5:ECDHE-PSK-3DES-EDE-CBC-SHA:DHE-PSK-3DES-EDE-CBC-SHA:EXP1024-DHE-DSS-DES-CBC-SHA:EDH-RSA-DES-CBC-SHA:EDH-DSS-DES-CBC-SHA:DH-RSA-DES-CBC-SHA:DH-DSS-DES-CBC-SHA:ADH-DES-CBC-SHA:EXP1024-DES-CBC-SHA:DES-CBC-SHA:KRB5-DES-CBC-SHA:KRB5-DES-CBC-MD5:EXP-EDH-RSA-DES-CBC-SHA:EXP-EDH-DSS-DES-CBC-SHA:EXP-ADH-DES-CBC-SHA:EXP-DES-CBC-SHA:EXP-RC2-CBC-MD5:EXP-KRB5-RC2-CBC-SHA:EXP-KRB5-DES-CBC-SHA:EXP-KRB5-RC2-CBC-MD5:EXP-KRB5-DES-CBC-MD5:EXP-DH-DSS-DES-CBC-SHA:EXP-DH-RSA-DES-CBC-SHA" + local cbc_ciphers_hex="c0,14, c0,0a, c0,22, c0,21, c0,20, 00,91, 00,39, 00,38, 00,37, 00,36, 00,88, 00,87, 00,86, 00,85, c0,19, 00,3a, 00,89, c0,0f, c0,05, 00,35, c0,36, 00,84, 00,95, 00,8d, c0,13, c0,09, c0,1f, c0,1e, c0,1d, 00,33, 00,32, 00,31, 00,30, 00,9a, 00,99, 00,98, 00,97, 00,45, 00,44, 00,43, 00,42, c0,18, 00,34, 00,9b, 00,46, c0,0e, c0,04, 00,2f, c0,35, 00,90, 00,96, 00,41, 00,07, 00,94, 00,8c, 00,21, 00,25, c0,12, c0,08, c0,1c, c0,1b, c0,1a, 00,16, 00,13, 00,10, 00,0d, c0,17, 00,1b, c0,0d, c0,03, 00,0a, 00,93, 00,8b, 00,1f, 00,23, c0,34, 00,8f, 00,63, 00,15, 00,12, 00,0f, 00,0c, 00,1a, 00,62, 00,09, 00,1e, 00,22, 00,14, 00,11, 00,19, 00,08, 00,06, 00,27, 00,26, 00,2a, 00,29, 00,0b, 00,0e" local cve="CVE-2014-3566" local cwe="CWE-310" local hint="" + local using_sockets=true + + "$SSL_NATIVE" && using_sockets=false [[ $VULN_COUNT -le $VULN_THRESHLD ]] && outln && pr_headlineln " Testing for SSLv3 POODLE (Padding Oracle On Downgraded Legacy Encryption) " && outln pr_bold " POODLE, SSL"; out " ($cve) " - locally_supported "-ssl3" || return 0 - cbc_ciphers=$(actually_supported_ciphers $cbc_ciphers) + if "$using_sockets"; then + tls_sockets "00" "$cbc_ciphers_hex" + sclient_success=$? + else + locally_supported "-ssl3" || return 0 + cbc_ciphers=$(actually_supported_ciphers $cbc_ciphers) - debugme echo $cbc_ciphers - $OPENSSL s_client -ssl3 $STARTTLS $BUGS -cipher $cbc_ciphers -connect $NODEIP:$PORT $PROXY >$TMPFILE 2>$ERRFILE $TMPFILE 2>$ERRFILE Date: Wed, 21 Dec 2016 13:16:10 -0500 Subject: [PATCH 17/61] Use sockets for run_freak() This PR changes `run_freak()` to use sockets. I added two ciphers to `$exportrsa_cipher_list`: EXP1024-RC4-MD5 (0x00,0x60) and EXP1024-RC2-CBC-MD5 (0x00,0x61). So, the list is now as follows: ``` 0x00,0x62 - EXP1024-DES-CBC-SHA TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA SSLv3 Kx=RSA(1024) Au=RSA Enc=DES(56) Mac=SHA1 export 0x00,0x61 - EXP1024-RC2-CBC-MD5 TLS_RSA_EXPORT1024_WITH_RC2_56_MD5 SSLv3 Kx=RSA(1024) Au=RSA Enc=RC2(56) Mac=MD5 export 0x00,0x64 - EXP1024-RC4-SHA TLS_RSA_EXPORT1024_WITH_RC4_56_SHA SSLv3 Kx=RSA(1024) Au=RSA Enc=RC4(56) Mac=SHA1 export 0x00,0x60 - EXP1024-RC4-MD5 TLS_RSA_EXPORT1024_WITH_RC4_56_MD5 SSLv3 Kx=RSA(1024) Au=RSA Enc=RC4(56) Mac=MD5 export 0x00,0x14 - EXP-EDH-RSA-DES-CBC-SHA TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA SSLv3 Kx=DH(512) Au=RSA Enc=DES(40) Mac=SHA1 export 0x00,0x08 - EXP-DES-CBC-SHA TLS_RSA_EXPORT_WITH_DES40_CBC_SHA SSLv3 Kx=RSA(512) Au=RSA Enc=DES(40) Mac=SHA1 export 0x00,0x06 - EXP-RC2-CBC-MD5 TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5 SSLv3 Kx=RSA(512) Au=RSA Enc=RC2(40) Mac=MD5 export 0x04,0x00,0x80 - EXP-RC2-CBC-MD5 SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5 SSLv2 Kx=RSA(512) Au=RSA Enc=RC2(40) Mac=MD5 export 0x00,0x0E - EXP-DH-RSA-DES-CBC-SHA TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA SSLv3 Kx=DH/RSA Au=DH Enc=DES(40) Mac=SHA1 export 0x00,0x03 - EXP-RC4-MD5 TLS_RSA_EXPORT_WITH_RC4_40_MD5 SSLv3 Kx=RSA(512) Au=RSA Enc=RC4(40) Mac=MD5 export 0x02,0x00,0x80 - EXP-RC4-MD5 SSL_CK_RC4_128_EXPORT40_WITH_MD5 SSLv2 Kx=RSA(512) Au=RSA Enc=RC4(40) Mac=MD5 export ``` --- testssl.sh | 64 ++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 52 insertions(+), 12 deletions(-) diff --git a/testssl.sh b/testssl.sh index 405e138..2de6de8 100755 --- a/testssl.sh +++ b/testssl.sh @@ -8811,18 +8811,27 @@ run_tls_fallback_scsv() { # Factoring RSA Export Keys: don't use EXPORT RSA ciphers, see https://freakattack.com/ run_freak() { local -i sclient_success=0 - local -i nr_supported_ciphers=0 - # with correct build it should list these 7 ciphers (plus the two latter as SSLv2 ciphers): - local exportrsa_cipher_list="EXP1024-DES-CBC-SHA:EXP1024-RC4-SHA:EXP-EDH-RSA-DES-CBC-SHA:EXP-DH-RSA-DES-CBC-SHA:EXP-DES-CBC-SHA:EXP-RC2-CBC-MD5:EXP-RC2-CBC-MD5:EXP-RC4-MD5:EXP-RC4-MD5" - local addcmd="" addtl_warning="" + local -i i nr_supported_ciphers=0 + # with correct build it should list these 9 ciphers (plus the two latter as SSLv2 ciphers): + local exportrsa_cipher_list="EXP1024-DES-CBC-SHA:EXP1024-RC2-CBC-MD5:EXP1024-RC4-SHA:EXP1024-RC4-MD5:EXP-EDH-RSA-DES-CBC-SHA:EXP-DH-RSA-DES-CBC-SHA:EXP-DES-CBC-SHA:EXP-RC2-CBC-MD5:EXP-RC4-MD5" + local exportrsa_tls_cipher_list_hex="00,62, 00,61, 00,64, 00,60, 00,14, 00,0E, 00,08, 00,06, 00,03" + local exportrsa_ssl2_cipher_list_hex="04,00,80, 02,00,80" + local addcmd="" addtl_warning="" hexc local cve="CVE-2015-0204" local cwe="CWE-310" local hint="" + local using_sockets=true + + "$SSL_NATIVE" && using_sockets=false [[ $VULN_COUNT -le $VULN_THRESHLD ]] && outln && pr_headlineln " Testing for FREAK attack " && outln pr_bold " FREAK"; out " ($cve) " - nr_supported_ciphers=$(count_ciphers $(actually_supported_ciphers $exportrsa_cipher_list)) + if "$using_sockets"; then + nr_supported_ciphers=$(count_words "$exportrsa_tls_cipher_list_hex")+$(count_words "$exportrsa_ssl2_cipher_list_hex") + else + nr_supported_ciphers=$(count_ciphers $(actually_supported_ciphers $exportrsa_cipher_list)) + fi #echo "========= ${PIPESTATUS[*]} case $nr_supported_ciphers in @@ -8838,12 +8847,26 @@ run_freak() { 4|5|6|7) addtl_warning=" (tested with $nr_supported_ciphers/9 ciphers)" ;; esac - [[ "$OPTIMAL_PROTO" == "-ssl2" ]] && addcmd="$OPTIMAL_PROTO" - [[ ! "$OPTIMAL_PROTO" =~ ssl ]] && addcmd="$SNI" - $OPENSSL s_client $STARTTLS $BUGS -cipher $exportrsa_cipher_list -connect $NODEIP:$PORT $PROXY $addcmd >$TMPFILE 2>$ERRFILE $TMPFILE 2>$ERRFILE $TMPFILE 2>$ERRFILE Date: Wed, 21 Dec 2016 14:55:01 -0500 Subject: [PATCH 18/61] Use sockets for run_logjam() This PR changes `run_logjam()` to use sockets. --- testssl.sh | 50 ++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 38 insertions(+), 12 deletions(-) diff --git a/testssl.sh b/testssl.sh index 405e138..6c709c5 100755 --- a/testssl.sh +++ b/testssl.sh @@ -8865,16 +8865,24 @@ run_freak() { run_logjam() { local -i sclient_success=0 local exportdhe_cipher_list="EXP1024-DHE-DSS-DES-CBC-SHA:EXP1024-DHE-DSS-RC4-SHA:EXP-EDH-RSA-DES-CBC-SHA:EXP-EDH-DSS-DES-CBC-SHA" - local -i nr_supported_ciphers=0 - local addtl_warning="" + local exportdhe_cipher_list_hex="00,63, 00,65, 00,14, 00,11" + local -i i nr_supported_ciphers=0 + local addtl_warning="" hexc local cve="CVE-2015-4000" local cwe="CWE-310" local hint="" + local using_sockets=true + + "$SSL_NATIVE" && using_sockets=false [[ $VULN_COUNT -le $VULN_THRESHLD ]] && outln && pr_headlineln " Testing for LOGJAM vulnerability " && outln pr_bold " LOGJAM"; out " ($cve), experimental " - nr_supported_ciphers=$(count_ciphers $(actually_supported_ciphers $exportdhe_cipher_list)) + if "$using_sockets"; then + nr_supported_ciphers=$(count_words "$exportdhe_cipher_list_hex") + else + nr_supported_ciphers=$(count_ciphers $(actually_supported_ciphers $exportdhe_cipher_list)) + fi case $nr_supported_ciphers in 0) @@ -8886,16 +8894,22 @@ run_logjam() { 3) addtl_warning=" (tested w/ $nr_supported_ciphers/4 ciphers)" ;; 4) ;; esac - $OPENSSL s_client $STARTTLS $BUGS -cipher $exportdhe_cipher_list -connect $NODEIP:$PORT $PROXY $SNI >$TMPFILE 2>$ERRFILE $TMPFILE 2>$ERRFILE Date: Thu, 22 Dec 2016 15:46:01 -0500 Subject: [PATCH 19/61] Use sockets for run_std_cipherlists() This PR change `run_std_cipherlists()` to use sockets. As noted in isse #554, I have some questions about the definitions of the cipher lists, but I wrote the code so that the ciphers that are tested when using sockets are the same as those that are tested when using OpenSSL. For a few of the cipherlists, the sockets version tests a few additional ciphers; but these are ciphers that are not supported by OpenSSL, and whose definitions are consistent with the ciphers that OpenSSL includes. As written, `std_cipherlists` will use sockets for testing by default, except in two cases: * If the `$SSL_NATIVE` is true, then only OpenSSL is used, and if OpenSSL doesn't support any ciphers in the cipherlist, then the test is skipped. * If `$FAST` is true (but `$SSL_NATIVE` is false), then OpenSSL is used whenever it supports at least one cipher from the cipherlist, and `tls_sockets()` (or `sslv2_sockets()`) is only used when OpenSSL doesn't support any ciphers from the cipherlist. --- testssl.sh | 160 ++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 141 insertions(+), 19 deletions(-) diff --git a/testssl.sh b/testssl.sh index 405e138..7376c7e 100755 --- a/testssl.sh +++ b/testssl.sh @@ -2008,23 +2008,42 @@ listciphers() { } -# argv[1]: cipher list to test +# argv[1]: cipher list to test in OpenSSL syntax # argv[2]: string on console # argv[3]: ok to offer? 0: yes, 1: no # argv[4]: string for fileout +# argv[5]: non-SSLv2 cipher list to test (hexcodes), if using sockets +# argv[6]: SSLv2 cipher list to test (hexcodes), if using sockets std_cipherlists() { local -i sclient_success local singlespaces proto="" addcmd="" local debugname="$(sed -e s'/\!/not/g' -e 's/\:/_/g' <<< "$1")" - [[ "$OPTIMAL_PROTO" == "-ssl2" ]] && addcmd="$OPTIMAL_PROTO" && proto="$OPTIMAL_PROTO" - [[ ! "$OPTIMAL_PROTO" =~ ssl ]] && addcmd="$SNI" + [[ "$OPTIMAL_PROTO" == "-ssl2" ]] && proto="$OPTIMAL_PROTO" pr_bold "$2 " # indenting to be in the same row as server preferences - if listciphers "$1" $proto; then # is that locally available?? - $OPENSSL s_client -cipher "$1" $BUGS $STARTTLS -connect $NODEIP:$PORT $PROXY $addcmd 2>$ERRFILE >$TMPFILE $ERRFILE >$TMPFILE $ERRFILE >$TMPFILE Date: Fri, 23 Dec 2016 11:02:31 -0500 Subject: [PATCH 20/61] Use sockets for run_http2() This PR changes `run_http2()` so that it uses `tls_sockets()` rather than failing, if `$OPENSSL` does not support the `-alpn` option. If `$OPENSSL` supports the `-alpn` option (or if `$SSL_NATIVE` is true), then this PR has no effect. --- testssl.sh | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/testssl.sh b/testssl.sh index 405e138..d531353 100755 --- a/testssl.sh +++ b/testssl.sh @@ -6146,7 +6146,7 @@ http2_pre(){ fileout "https_alpn" "WARN" "HTTP2/ALPN : HTTP/2 was not tested as proxies do not support proxying it" return 1 fi - if ! "$HAS_ALPN"; then + if ! "$HAS_ALPN" && "$SSL_NATIVE"; then local_problem_ln "$OPENSSL doesn't support HTTP2/ALPN"; fileout "https_alpn" "WARN" "HTTP2/ALPN : HTTP/2 was not tested as $OPENSSL does not support it" return 7 @@ -6191,7 +6191,7 @@ run_spdy() { run_http2() { - local tmpstr + local tmpstr alpn_extn len local -i ret=0 local had_alpn_proto=false local alpn_finding="" @@ -6203,7 +6203,21 @@ run_http2() { fi for proto in $ALPN_PROTOs; do # for some reason OpenSSL doesn't list the advertised protocols, so instead try common protocols - $OPENSSL s_client -connect $NODEIP:$PORT $BUGS $SNI -alpn $proto $ERRFILE >$TMPFILE + if "$HAS_ALPN"; then + $OPENSSL s_client -connect $NODEIP:$PORT $BUGS $SNI -alpn $proto $ERRFILE >$TMPFILE + else + alpn_extn="$(printf "%02x" ${#proto}),$(string_to_asciihex "$proto")" + len="$(printf "%04x" $((${#proto}+1)))" + alpn_extn="${len:0:2},${len:2:2},$alpn_extn" + len="$(printf "%04x" $((${#proto}+3)))" + alpn_extn="00,10,${len:0:2},${len:2:2},$alpn_extn" + tls_sockets "03" "$TLS12_CIPHER" "all" "$alpn_extn" + if [[ -r "$TEMPDIR/$NODEIP.parse_tls_serverhello.txt" ]]; then + cp "$TEMPDIR/$NODEIP.parse_tls_serverhello.txt" $TMPFILE + else + 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) From fd2e52c396785b658af5bfcb5e4a0300e62845fd Mon Sep 17 00:00:00 2001 From: David Cooper Date: Tue, 27 Dec 2016 14:14:20 -0500 Subject: [PATCH 21/61] Minor bug fixes in run_protocols() In a few places `run_protocols()` specifies the wrong TLS version as the "ID" when calling `fileout()`. --- testssl.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/testssl.sh b/testssl.sh index d531353..3413654 100755 --- a/testssl.sh +++ b/testssl.sh @@ -4135,7 +4135,7 @@ run_protocols() { fileout "tls1_1" "CRITICAL" "TLSv1.1 is not offered, server responded with higher version number ($detected_version_string) than requested by client" else pr_svrty_criticalln " -- 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}" + fileout "tls1_1" "CRITICAL" "TLSv1.1: server responded with version number ${DETECTED_TLS_VERSION:0:2}.${DETECTED_TLS_VERSION:2:2}" fi ;; 5) @@ -4168,7 +4168,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" "CRITICAL" "TLSv1.2: connection failed rather than downgrading to $latest_supported_string" + fileout "tls1_2" "CRITICAL" "TLSv1.2: connection failed rather than downgrading to $latest_supported_string" fi ;; 2) @@ -4190,7 +4190,7 @@ run_protocols() { fileout "tls1_2" "CRITICAL" "TLSv1.2 is not offered, server responded with higher version number ($detected_version_string) than requested by client" else pr_svrty_criticalln " -- server responded with version number ${DETECTED_TLS_VERSION:0:2}.${DETECTED_TLS_VERSION:2:2}" - fileout "tls1" "CRITICAL" "TLSv1.2: server responded with version number ${DETECTED_TLS_VERSION:0:2}.${DETECTED_TLS_VERSION:2:2}" + fileout "tls1_2" "CRITICAL" "TLSv1.2: server responded with version number ${DETECTED_TLS_VERSION:0:2}.${DETECTED_TLS_VERSION:2:2}" fi ;; 5) From 83d2a63e0fae7887afb58ef880a0efea44219972 Mon Sep 17 00:00:00 2001 From: Dirk Date: Wed, 28 Dec 2016 23:47:35 +0100 Subject: [PATCH 22/61] - Stronger warning if ~/etc is missing, also requires more explicit consent to continue - fix lfs for -e -E if openssl has not DH/ECDH - further minor output corrections --- testssl.sh | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/testssl.sh b/testssl.sh index 3413654..1868a2b 100755 --- a/testssl.sh +++ b/testssl.sh @@ -2350,8 +2350,8 @@ run_allciphers() { pr_headlineln " Testing $nr_ciphers_tested via OpenSSL and sockets against the server, ordered by encryption strength " else pr_headlineln " Testing all $nr_ciphers_tested locally available ciphers against the server, ordered by encryption strength " - outln [[ $TLS_NR_CIPHERS == 0 ]] && ! "$SSL_NATIVE" && ! "$FAST" && pr_warning " Cipher mapping not available, doing a fallback to openssl" + outln if ! "$HAS_DH_BITS"; then [[ $TLS_NR_CIPHERS == 0 ]] && ! "$SSL_NATIVE" && ! "$FAST" && out "." pr_warningln " Your $OPENSSL cannot show DH/ECDH bits" @@ -2526,8 +2526,8 @@ run_cipher_per_proto() { pr_headlineln " Testing per protocol via OpenSSL and sockets against the server, ordered by encryption strength " else pr_headlineln " Testing all locally available ciphers per protocol against the server, ordered by encryption strength " - outln [[ $TLS_NR_CIPHERS == 0 ]] && ! "$SSL_NATIVE" && ! "$FAST" && pr_warning " Cipher mapping not available, doing a fallback to openssl" + outln if ! "$HAS_DH_BITS"; then [[ $TLS_NR_CIPHERS == 0 ]] && ! "$SSL_NATIVE" && ! "$FAST" && out "." pr_warningln " (Your $OPENSSL cannot show DH/ECDH bits)" @@ -9483,8 +9483,11 @@ get_install_dir() { [[ -r "$TESTSSL_INSTALL_DIR/cipher-mapping.txt" ]] && CIPHERS_BY_STRENGTH_FILE="$TESTSSL_INSTALL_DIR/cipher-mapping.txt" fi - [[ ! -r "$CIPHERS_BY_STRENGTH_FILE" ]] && unset ADD_RFC_STR && pr_warningln "\nNo cipher mapping file in \$TESTSSL_INSTALL_DIR/etc/ found" + [[ ! -r "$CIPHERS_BY_STRENGTH_FILE" ]] && unset ADD_RFC_STR && pr_warningln "\nNo cipher mapping file found " debugme echo "$CIPHERS_BY_STRENGTH_FILE" + pr_warningln "Please note from 2.9dev on testssl.sh needs some files in \$TESTSSL_INSTALL_DIR/etc to function correctly" + ignore_no_or_lame "Type \"yes\" to ignore " + [[ $? -ne 0 ]] && exit -2 } @@ -9622,13 +9625,15 @@ check4openssl_oldfarts() { ;; esac if [[ $OSSL_VER_MAJOR -lt 1 ]]; then ## mm: Patch for libressl - pr_magentaln " Your \"$OPENSSL\" is way too old ( Date: Thu, 29 Dec 2016 00:09:44 +0100 Subject: [PATCH 23/61] fix for 83d2a63 --- testssl.sh | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/testssl.sh b/testssl.sh index 1868a2b..7a0a368 100755 --- a/testssl.sh +++ b/testssl.sh @@ -9483,11 +9483,14 @@ get_install_dir() { [[ -r "$TESTSSL_INSTALL_DIR/cipher-mapping.txt" ]] && CIPHERS_BY_STRENGTH_FILE="$TESTSSL_INSTALL_DIR/cipher-mapping.txt" fi - [[ ! -r "$CIPHERS_BY_STRENGTH_FILE" ]] && unset ADD_RFC_STR && pr_warningln "\nNo cipher mapping file found " - debugme echo "$CIPHERS_BY_STRENGTH_FILE" - pr_warningln "Please note from 2.9dev on testssl.sh needs some files in \$TESTSSL_INSTALL_DIR/etc to function correctly" - ignore_no_or_lame "Type \"yes\" to ignore " - [[ $? -ne 0 ]] && exit -2 + if [[ ! -r "$CIPHERS_BY_STRENGTH_FILE" ]] ; then + unset ADD_RFC_STR + pr_warningln "\nNo cipher mapping file found " + debugme echo "$CIPHERS_BY_STRENGTH_FILE" + pr_warningln "Please note from 2.9dev on testssl.sh needs some files in \$TESTSSL_INSTALL_DIR/etc to function correctly" + ignore_no_or_lame "Type \"yes\" to ignore " + [[ $? -ne 0 ]] && exit -2 + fi } From c3b300c5fb20725f70b0cdbe82f9000c6eb85efc Mon Sep 17 00:00:00 2001 From: Dirk Date: Thu, 29 Dec 2016 22:02:07 +0100 Subject: [PATCH 24/61] - cleanup ignore_no_or_lame() - reorder get_install_dir in main() so that warnings are not displayed before --help - tweak missing ~/etc msg --- testssl.sh | 34 ++++++++++++++++++---------------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/testssl.sh b/testssl.sh index 9c1907e..18612ca 100755 --- a/testssl.sh +++ b/testssl.sh @@ -573,7 +573,7 @@ pr_blue() { [[ "$COLOR" -eq 2 ]] && ( "$COLORBLIND" && out "\033[1;32m$1" pr_blueln() { pr_blue "$1"; outln; } pr_warning() { [[ "$COLOR" -eq 2 ]] && out "\033[0;35m$1" || pr_underline "$1"; pr_off; } # some local problem: one test cannot be done -pr_warningln() { pr_warning "$1"; outln; } # litemagenya +pr_warningln() { pr_warning "$1"; outln; } # litemagenta pr_magenta() { [[ "$COLOR" -eq 2 ]] && out "\033[1;35m$1" || pr_underline "$1"; pr_off; } # fatal error: quitting because of this! pr_magentaln() { pr_magenta "$1"; outln; } @@ -9511,10 +9511,11 @@ get_install_dir() { if [[ ! -r "$CIPHERS_BY_STRENGTH_FILE" ]] ; then unset ADD_RFC_STR - pr_warningln "\nNo cipher mapping file found " debugme echo "$CIPHERS_BY_STRENGTH_FILE" - pr_warningln "Please note from 2.9dev on testssl.sh needs some files in \$TESTSSL_INSTALL_DIR/etc to function correctly" - ignore_no_or_lame "Type \"yes\" to ignore " + pr_warningln "\nATTENTION: No cipher mapping file found!" + outln "Please note from 2.9dev on $PROG_NAME needs files in \"\$TESTSSL_INSTALL_DIR/etc/\" to function correctly." + outln + ignore_no_or_lame "Type \"yes\" to ignore this warning and proceed at your own risk" "yes" [[ $? -ne 0 ]] && exit -2 fi } @@ -9632,7 +9633,7 @@ find_openssl_binary() { fi else outln - ignore_no_or_lame " neccessary binary \"timeout\" not found. Continue without timeout?" + ignore_no_or_lame " Neccessary binary \"timeout\" not found. Continue without timeout? " "y" [[ $? -ne 0 ]] && exit -2 unset OPENSSL_TIMEOUT fi @@ -9662,7 +9663,7 @@ check4openssl_oldfarts() { *) outln " Update openssl binaries or compile from github.com/PeterMosmans/openssl" fileout "too_old_openssl" "WARN" "Update openssl binaries or compile from github.com/PeterMosmans/openssl .";; esac - ignore_no_or_lame " Type \"yes\" to accept false negatives or positives " + ignore_no_or_lame " Type \"yes\" to accept false negatives or positives" "yes" [[ $? -ne 0 ]] && exit -2 fi outln @@ -10020,20 +10021,21 @@ EOF return 0 } - +# arg1: text to display before "-->" +# arg2: arg needed to accept to continue ignore_no_or_lame() { local a [[ "$WARNINGS" == off ]] && return 0 [[ "$WARNINGS" == false ]] && return 0 [[ "$WARNINGS" == batch ]] && return 1 - pr_magenta "$1 " + pr_warning "$1 --> " read a - case $a in - Y|y|Yes|YES|yes) return 0;; - default) ;; - esac - return 1 + if [[ "$a" == "$(tolower "$2")" ]]; then + $ok_arg return 0 + else + return 1 + fi } # arg1: URI @@ -10445,7 +10447,7 @@ determine_optimal_proto() { debugme echo "OPTIMAL_PROTO: $OPTIMAL_PROTO" if [[ "$OPTIMAL_PROTO" == "-ssl2" ]]; then pr_magentaln "$NODEIP:$PORT appears to only support SSLv2." - ignore_no_or_lame " Type \"yes\" to accept some false negatives or positives " + ignore_no_or_lame " Type \"yes\" to proceed and accept false negatives or positives" "yes" [[ $? -ne 0 ]] && exit -2 fi fi @@ -10460,7 +10462,7 @@ determine_optimal_proto() { fi tmpfile_handle $FUNCNAME.txt pr_boldln "doesn't seem to be a TLS/SSL enabled server"; - ignore_no_or_lame " Note that the results might look ok but they are nonsense. Proceed ? " + ignore_no_or_lame " The results might look ok but they could be nonsense. Really proceed ? (\"yes\" to continue)" "yes" [[ $? -ne 0 ]] && exit -2 fi @@ -11252,10 +11254,10 @@ lets_roll() { ################# main ################# -get_install_dir initialize_globals parse_cmd_line "$@" +get_install_dir set_color_functions maketempf find_openssl_binary From ec3a644c4d042812a46d7c80e194cdf9397a17de Mon Sep 17 00:00:00 2001 From: David Cooper Date: Thu, 29 Dec 2016 16:31:42 -0500 Subject: [PATCH 25/61] Common primes test phase 1 In response to your request in #572, this PR provides a starting point for addressing #120. It adds code to `run_logjam()` to try connecting to the server using any cipher that uses an ephemeral DH key. If successful, it gets the server's ephemeral key (in OpenSSL's PEM format) and then extracts the prime from the key and places it in `$dh_p`. So, all that needs to be done at this point is to compare `$dh_p` against a set of "bad" primes. I'm not sure if I'll be able to work on that part soon, so if someone else has the time, that would be great. I actually found the `-msg` option easy to use. I moved the code in `parse_tls_serverhello()` that extracts the DH ephemeral public key from the ServerKeyExchange message into a separate function. Then, if using OpenSSL with the `-msg` option, I extract the ServerKeyExchange message from `$TMPFILE` and call this new function to extract the key and convert it to PEM format. That way the new code in `run_logjam()` can use either `$OPENSSL` or `tls_sockets()`. --- testssl.sh | 320 +++++++++++++++++++++++++++++++---------------------- 1 file changed, 188 insertions(+), 132 deletions(-) diff --git a/testssl.sh b/testssl.sh index 16b78de..68b1b73 100755 --- a/testssl.sh +++ b/testssl.sh @@ -6830,6 +6830,159 @@ get_pub_key_size() { return 0 } +# Extract the DH ephemeral key from the ServerKeyExchange message +get_dh_ephemeralkey() { + local tls_serverkeyexchange_ascii="$1" + local -i tls_serverkeyexchange_ascii_len offset + local dh_p dh_g dh_y dh_param len1 key_bitstring tmp_der_key_file + local -i i dh_p_len dh_g_len dh_y_len dh_param_len + + tls_serverkeyexchange_ascii_len=${#tls_serverkeyexchange_ascii} + dh_p_len=2*$(hex2dec "${tls_serverkeyexchange_ascii:0:4}") + offset=4+$dh_p_len + if [[ $tls_serverkeyexchange_ascii_len -lt $offset ]]; then + debugme echo "Malformed ServerKeyExchange Handshake message in ServerHello." + return 1 + fi + + # Subtract any leading 0 bytes + for (( i=4; i < offset; i=i+2 )); do + [[ "${tls_serverkeyexchange_ascii:i:2}" != "00" ]] && break + dh_p_len=$dh_p_len-2 + done + if [[ $i -ge $offset ]]; then + debugme echo "Malformed ServerKeyExchange Handshake message in ServerHello." + return 1 + fi + dh_p="${tls_serverkeyexchange_ascii:i:dh_p_len}" + + dh_g_len=2*$(hex2dec "${tls_serverkeyexchange_ascii:offset:4}") + i=4+$offset + offset+=4+$dh_g_len + if [[ $tls_serverkeyexchange_ascii_len -lt $offset ]]; then + debugme echo "Malformed ServerKeyExchange Handshake message in ServerHello." + return 1 + fi + # Subtract any leading 0 bytes + for (( 1; i < offset; i=i+2 )); do + [[ "${tls_serverkeyexchange_ascii:i:2}" != "00" ]] && break + dh_g_len=$dh_g_len-2 + done + if [[ $i -ge $offset ]]; then + debugme echo "Malformed ServerKeyExchange Handshake message in ServerHello." + return 1 + fi + dh_g="${tls_serverkeyexchange_ascii:i:dh_g_len}" + + dh_y_len=2*$(hex2dec "${tls_serverkeyexchange_ascii:offset:4}") + i=4+$offset + offset+=4+$dh_y_len + if [[ $tls_serverkeyexchange_ascii_len -lt $offset ]]; then + debugme echo "Malformed ServerKeyExchange Handshake message in ServerHello." + return 1 + fi + # Subtract any leading 0 bytes + for (( 1; i < offset; i=i+2 )); do + [[ "${tls_serverkeyexchange_ascii:i:2}" != "00" ]] && break + dh_y_len=$dh_y_len-2 + done + if [[ $i -ge $offset ]]; then + debugme echo "Malformed ServerKeyExchange Handshake message in ServerHello." + return 1 + fi + dh_y="${tls_serverkeyexchange_ascii:i:dh_y_len}" + + # The following code assumes that all lengths can be encoded using at most 2 bytes, + # which just means that the encoded length of the public key must be less than + # 65,536 bytes. If the length is anywhere close to that, it is almost certainly an + # encoding error. + if [[ $dh_p_len+$dh_g_len+$dh_y_len -ge 131000 ]]; then + debugme echo "Malformed ServerKeyExchange Handshake message in ServerHello." + return 1 + fi + # make ASN.1 INTEGER of p, g, and Y + [[ "0x${dh_p:0:1}" -ge 8 ]] && dh_p_len+=2 && dh_p="00$dh_p" + if [[ $dh_p_len -lt 256 ]]; then + len1="$(printf "%02x" $((dh_p_len/2)))" + elif [[ $dh_p_len -lt 512 ]]; then + len1="81$(printf "%02x" $((dh_p_len/2)))" + else + len1="82$(printf "%04x" $((dh_p_len/2)))" + fi + dh_p="02${len1}$dh_p" + + [[ "0x${dh_g:0:1}" -ge 8 ]] && dh_g_len+=2 && dh_g="00$dh_g" + if [[ $dh_g_len -lt 256 ]]; then + len1="$(printf "%02x" $((dh_g_len/2)))" + elif [[ $dh_g_len -lt 512 ]]; then + len1="81$(printf "%02x" $((dh_g_len/2)))" + else + len1="82$(printf "%04x" $((dh_g_len/2)))" + fi + dh_g="02${len1}$dh_g" + + [[ "0x${dh_y:0:1}" -ge 8 ]] && dh_y_len+=2 && dh_y="00$dh_y" + if [[ $dh_y_len -lt 256 ]]; then + len1="$(printf "%02x" $((dh_y_len/2)))" + elif [[ $dh_y_len -lt 512 ]]; then + len1="81$(printf "%02x" $((dh_y_len/2)))" + else + len1="82$(printf "%04x" $((dh_y_len/2)))" + fi + dh_y="02${len1}$dh_y" + + # Make a SEQUENCE of p and g + dh_param_len=${#dh_p}+${#dh_g} + if [[ $dh_param_len -lt 256 ]]; then + len1="$(printf "%02x" $((dh_param_len/2)))" + elif [[ $dh_param_len -lt 512 ]]; then + len1="81$(printf "%02x" $((dh_param_len/2)))" + else + len1="82$(printf "%04x" $((dh_param_len/2)))" + fi + dh_param="30${len1}${dh_p}${dh_g}" + + # Make a SEQUENCE of the paramters SEQUENCE and the OID + dh_param_len=22+${#dh_param} + if [[ $dh_param_len -lt 256 ]]; then + len1="$(printf "%02x" $((dh_param_len/2)))" + elif [[ $dh_param_len -lt 512 ]]; then + len1="81$(printf "%02x" $((dh_param_len/2)))" + else + len1="82$(printf "%04x" $((dh_param_len/2)))" + fi + dh_param="30${len1}06092A864886F70D010301${dh_param}" + + # Encapsulate public key, y, in a BIT STRING + dh_y_len=${#dh_y}+2 + if [[ $dh_y_len -lt 256 ]]; then + len1="$(printf "%02x" $((dh_y_len/2)))" + elif [[ $dh_y_len -lt 512 ]]; then + len1="81$(printf "%02x" $((dh_y_len/2)))" + else + len1="82$(printf "%04x" $((dh_y_len/2)))" + fi + dh_y="03${len1}00$dh_y" + + # Create the public key SEQUENCE + i=${#dh_param}+${#dh_y} + if [[ $i -lt 256 ]]; then + len1="$(printf "%02x" $((i/2)))" + elif [[ $i -lt 512 ]]; then + len1="81$(printf "%02x" $((i/2)))" + else + len1="82$(printf "%04x" $((i/2)))" + fi + key_bitstring="30${len1}${dh_param}${dh_y}" + tmp_der_key_file=$(mktemp $TEMPDIR/pub_key_der.XXXXXX) || return 1 + asciihex_to_binary_file "$key_bitstring" "$tmp_der_key_file" + key_bitstring="$($OPENSSL pkey -pubin -in $tmp_der_key_file -inform DER 2> $ERRFILE)" + rm $tmp_der_key_file + [[ -z "$key_bitstring" ]] && return 1 + out "$key_bitstring" + return 0 +} + # arg1: name of file with socket reply # arg2: true if entire server hello should be parsed parse_sslv2_serverhello() { @@ -7032,9 +7185,9 @@ parse_tls_serverhello() { local -i curve_type named_curve local -i dh_bits=0 msb mask local tmp_der_certfile tmp_pem_certfile hostcert_issuer="" ocsp_response="" - local len1 key_bitstring="" tmp_der_key_file - local dh_p dh_g dh_y dh_param ephemeral_param rfc7919_param - local -i dh_p_len dh_g_len dh_y_len dh_param_len + local key_bitstring="" + local dh_p ephemeral_param rfc7919_param + local -i dh_p_len TLS_TIME="" DETECTED_TLS_VERSION="" @@ -7735,134 +7888,8 @@ parse_tls_serverhello() { dh_bits=$dh_bits-1 done - dh_g_len=2*$(hex2dec "${tls_serverkeyexchange_ascii:offset:4}") - i=4+$offset - offset+=4+$dh_g_len - 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 bytes - for (( 1; i < offset; i=i+2 )); do - [[ "${tls_serverkeyexchange_ascii:i:2}" != "00" ]] && break - dh_g_len=$dh_g_len-2 - done - if [[ $i -ge $offset ]]; then - debugme echo "Malformed ServerKeyExchange Handshake message in ServerHello." - tmpfile_handle $FUNCNAME.txt - return 1 - fi - dh_g="${tls_serverkeyexchange_ascii:i:dh_g_len}" - - dh_y_len=2*$(hex2dec "${tls_serverkeyexchange_ascii:offset:4}") - i=4+$offset - offset+=4+$dh_y_len - 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 bytes - for (( 1; i < offset; i=i+2 )); do - [[ "${tls_serverkeyexchange_ascii:i:2}" != "00" ]] && break - dh_y_len=$dh_y_len-2 - done - if [[ $i -ge $offset ]]; then - debugme echo "Malformed ServerKeyExchange Handshake message in ServerHello." - tmpfile_handle $FUNCNAME.txt - return 1 - fi - dh_y="${tls_serverkeyexchange_ascii:i:dh_y_len}" - - # The following code assumes that all lengths can be encoded using at most 2 bytes, - # which just means that the encoded length of the public key must be less than - # 65,536 bytes. If the length is anywhere close to that, it is almost certainly an - # encoding error. - if [[ $dh_p_len+$dh_g_len+$dh_y_len -ge 131000 ]]; then - debugme echo "Malformed ServerKeyExchange Handshake message in ServerHello." - tmpfile_handle $FUNCNAME.txt - return 1 - fi - # make ASN.1 INTEGER of p, g, and Y - [[ "0x${dh_p:0:1}" -ge 8 ]] && dh_p_len+=2 && dh_p="00$dh_p" - if [[ $dh_p_len -lt 256 ]]; then - len1="$(printf "%02x" $((dh_p_len/2)))" - elif [[ $dh_p_len -lt 512 ]]; then - len1="81$(printf "%02x" $((dh_p_len/2)))" - else - len1="82$(printf "%04x" $((dh_p_len/2)))" - fi - dh_p="02${len1}$dh_p" - - [[ "0x${dh_g:0:1}" -ge 8 ]] && dh_g_len+=2 && dh_g="00$dh_g" - if [[ $dh_g_len -lt 256 ]]; then - len1="$(printf "%02x" $((dh_g_len/2)))" - elif [[ $dh_g_len -lt 512 ]]; then - len1="81$(printf "%02x" $((dh_g_len/2)))" - else - len1="82$(printf "%04x" $((dh_g_len/2)))" - fi - dh_g="02${len1}$dh_g" - - [[ "0x${dh_y:0:1}" -ge 8 ]] && dh_y_len+=2 && dh_y="00$dh_y" - if [[ $dh_y_len -lt 256 ]]; then - len1="$(printf "%02x" $((dh_y_len/2)))" - elif [[ $dh_y_len -lt 512 ]]; then - len1="81$(printf "%02x" $((dh_y_len/2)))" - else - len1="82$(printf "%04x" $((dh_y_len/2)))" - fi - dh_y="02${len1}$dh_y" - - # Make a SEQUENCE of p and g - dh_param_len=${#dh_p}+${#dh_g} - if [[ $dh_param_len -lt 256 ]]; then - len1="$(printf "%02x" $((dh_param_len/2)))" - elif [[ $dh_param_len -lt 512 ]]; then - len1="81$(printf "%02x" $((dh_param_len/2)))" - else - len1="82$(printf "%04x" $((dh_param_len/2)))" - fi - dh_param="30${len1}${dh_p}${dh_g}" - - # Make a SEQUENCE of the paramters SEQUENCE and the OID - dh_param_len=22+${#dh_param} - if [[ $dh_param_len -lt 256 ]]; then - len1="$(printf "%02x" $((dh_param_len/2)))" - elif [[ $dh_param_len -lt 512 ]]; then - len1="81$(printf "%02x" $((dh_param_len/2)))" - else - len1="82$(printf "%04x" $((dh_param_len/2)))" - fi - dh_param="30${len1}06092A864886F70D010301${dh_param}" - - # Encapsulate public key, y, in a BIT STRING - dh_y_len=${#dh_y}+2 - if [[ $dh_y_len -lt 256 ]]; then - len1="$(printf "%02x" $((dh_y_len/2)))" - elif [[ $dh_y_len -lt 512 ]]; then - len1="81$(printf "%02x" $((dh_y_len/2)))" - else - len1="82$(printf "%04x" $((dh_y_len/2)))" - fi - dh_y="03${len1}00$dh_y" - - # Create the public key SEQUENCE - i=${#dh_param}+${#dh_y} - if [[ $i -lt 256 ]]; then - len1="$(printf "%02x" $((i/2)))" - elif [[ $i -lt 512 ]]; then - len1="81$(printf "%02x" $((i/2)))" - else - len1="82$(printf "%04x" $((i/2)))" - fi - key_bitstring="30${len1}${dh_param}${dh_y}" - tmp_der_key_file=$(mktemp $TEMPDIR/pub_key_der.XXXXXX) || return 1 - asciihex_to_binary_file "$key_bitstring" "$tmp_der_key_file" - key_bitstring="$($OPENSSL pkey -pubin -in $tmp_der_key_file -inform DER 2> $ERRFILE)" - rm $tmp_der_key_file - [[ -n "$key_bitstring" ]] && echo "$key_bitstring" >> $TMPFILE + key_bitstring="$(get_dh_ephemeralkey "$tls_serverkeyexchange_ascii")" + [[ $? -eq 0 ]] && echo "$key_bitstring" >> $TMPFILE # Check to see whether the ephemeral public key uses one of the groups from # RFC 7919 for parameters @@ -9063,11 +9090,12 @@ run_logjam() { local -i sclient_success=0 local exportdhe_cipher_list="EXP1024-DHE-DSS-DES-CBC-SHA:EXP1024-DHE-DSS-RC4-SHA:EXP-EDH-RSA-DES-CBC-SHA:EXP-EDH-DSS-DES-CBC-SHA" local exportdhe_cipher_list_hex="00,63, 00,65, 00,14, 00,11" - local -i i nr_supported_ciphers=0 + local -i i nr_supported_ciphers=0 server_key_exchange_len=0 ephemeral_pub_len=0 local addtl_warning="" hexc local cve="CVE-2015-4000" local cwe="CWE-310" local hint="" + local server_key_exchange ephemeral_pub key_bitstring="" dh_p local using_sockets=true "$SSL_NATIVE" && using_sockets=false @@ -9135,6 +9163,34 @@ run_logjam() { fi debugme echo $nr_supported_ciphers + # Try all ciphers that use an ephemeral DH key. If successful, check whether the key uses a weak prime. + if "$using_sockets"; then + tls_sockets "03" "cc,15, 00,b3, 00,91, c0,97, 00,a3, 00,9f, cc,aa, c0,a3, c0,9f, 00,6b, 00,6a, 00,39, 00,38, 00,c4, 00,c3, 00,88, 00,87, 00,a7, 00,6d, 00,3a, 00,c5, 00,89, 00,ab, cc,ad, c0,a7, c0,43, c0,45, c0,47, c0,53, c0,57, c0,5b, c0,67, c0,6d, c0,7d, c0,81, c0,85, c0,91, 00,a2, 00,9e, c0,a2, c0,9e, 00,aa, c0,a6, 00,67, 00,40, 00,33, 00,32, 00,be, 00,bd, 00,9a, 00,99, 00,45, 00,44, 00,a6, 00,6c, 00,34, 00,bf, 00,9b, 00,46, 00,b2, 00,90, c0,96, c0,42, c0,44, c0,46, c0,52, c0,56, c0,5a, c0,66, c0,6c, c0,7c, c0,80, c0,84, c0,90, 00,66, 00,18, 00,8e, 00,16, 00,13, 00,1b, 00,8f, 00,63, 00,15, 00,12, 00,1a, 00,65, 00,14, 00,11, 00,19, 00,17, 00,b5, 00,b4, 00,2d" "ephemeralkey" + sclient_success=$? + if [[ $sclient_success -eq 0 ]] || [[ $sclient_success -eq 2 ]]; then + cp "$TEMPDIR/$NODEIP.parse_tls_serverhello.txt" $TMPFILE + key_bitstring="$(awk '/-----BEGIN PUBLIC KEY/,/-----END PUBLIC KEY/ { print $0 }' $TMPFILE)" + fi + else + $OPENSSL s_client $STARTTLS $BUGS -cipher kEDH -msg -connect $NODEIP:$PORT $PROXY $SNI >$TMPFILE 2>$ERRFILE Date: Thu, 29 Dec 2016 16:45:46 -0500 Subject: [PATCH 26/61] Add extra check --- testssl.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testssl.sh b/testssl.sh index 18204e2..4a71070 100755 --- a/testssl.sh +++ b/testssl.sh @@ -9386,7 +9386,7 @@ run_logjam() { server_key_exchange="${server_key_exchange%%[!0-9A-F]*}" server_key_exchange_len=${#server_key_exchange} [[ $server_key_exchange_len -gt 8 ]] && [[ "${server_key_exchange:0:2}" == "0C" ]] && ephemeral_pub_len=$(hex2dec "${server_key_exchange:2:6}") - [[ $ephemeral_pub_len -le $server_key_exchange_len ]] && key_bitstring="$(get_dh_ephemeralkey "${server_key_exchange:8}")" + [[ $ephemeral_pub_len -ne 0 ]] && [[ $ephemeral_pub_len -le $server_key_exchange_len ]] && key_bitstring="$(get_dh_ephemeralkey "${server_key_exchange:8}")" fi fi if [[ -n "$key_bitstring" ]]; then From 62aee8f8467658c5d60f5804cc7a7ff9f4cdb2ca Mon Sep 17 00:00:00 2001 From: David Cooper Date: Fri, 30 Dec 2016 11:32:41 -0500 Subject: [PATCH 27/61] Remove leading "00" byte from prime, if present The primes in https://svn.nmap.org/nmap/scripts/ssl-dh-params.nse do not include a leading "00" byte, so don't include it in `$dh_p`. --- testssl.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/testssl.sh b/testssl.sh index 4a71070..93f99ac 100755 --- a/testssl.sh +++ b/testssl.sh @@ -9392,7 +9392,9 @@ run_logjam() { if [[ -n "$key_bitstring" ]]; then dh_p="$($OPENSSL pkey -pubin -text -noout <<< "$key_bitstring" | awk '/prime:/,/generator:/' | tail -n +2 | head -n -1)" dh_p="$(strip_spaces "$(colon_to_spaces "$(newline_to_spaces "$dh_p")")")" + [[ "${dh_p:0:2}" == "00" ]] && dh_p="${dh_p:2}" # At this point the DH key's prime has been extracted into $dh_p. Compare is against known weak primes. + echo "dh_p = $dh_p" fi tmpfile_handle $FUNCNAME.txt From 83472301bc76d7da8cd14d40e7406f4e0c317f55 Mon Sep 17 00:00:00 2001 From: David Cooper Date: Fri, 30 Dec 2016 11:33:27 -0500 Subject: [PATCH 28/61] Don't "echo" the prime to the terminal --- testssl.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/testssl.sh b/testssl.sh index 93f99ac..aee84cd 100755 --- a/testssl.sh +++ b/testssl.sh @@ -9394,7 +9394,6 @@ run_logjam() { dh_p="$(strip_spaces "$(colon_to_spaces "$(newline_to_spaces "$dh_p")")")" [[ "${dh_p:0:2}" == "00" ]] && dh_p="${dh_p:2}" # At this point the DH key's prime has been extracted into $dh_p. Compare is against known weak primes. - echo "dh_p = $dh_p" fi tmpfile_handle $FUNCNAME.txt From ad5590a444b0dfcf9fbca6f19165d6e3bed8ab75 Mon Sep 17 00:00:00 2001 From: David Cooper Date: Wed, 4 Jan 2017 10:19:11 -0500 Subject: [PATCH 29/61] run_server_defaults() bugfix If `determine_tls_extensions()` does not create a temporary file (`$TEMPDIR/$NODEIP.determine_tls_extensions.txt`) then `run_server_defaults()` will display error messages when an attempt is made to copy this file or to search (grep) it. This may happen if `$OPTIMAL_PROTO` is `-ssl2` or if `determine_tls_extensions()` uses sockets and `parse_tls_serverhello()` encountered an error and did not create a temporary file (`$TEMPDIR/$NODEIP.parse_tls_serverhello.txt`). This PR fixes this by only trying to copy and search `$TEMPDIR/$NODEIP.determine_tls_extensions.txt` is `$OPTIMAL_PROTO` is not `-ssl2` and `determine_tls_extensions()` was successful (return value 0). --- testssl.sh | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/testssl.sh b/testssl.sh index 80a8ac8..fc6287e 100755 --- a/testssl.sh +++ b/testssl.sh @@ -6097,11 +6097,12 @@ run_server_defaults() { done determine_tls_extensions + if [[ $? -eq 0 ]] && [[ "$OPTIMAL_PROTO" != "-ssl2" ]]; then + cp "$TEMPDIR/$NODEIP.determine_tls_extensions.txt" $TMPFILE + >$ERRFILE - cp "$TEMPDIR/$NODEIP.determine_tls_extensions.txt" $TMPFILE - >$ERRFILE - - [[ -z "$sessticket_str" ]] && sessticket_str=$(grep -aw "session ticket" $TMPFILE | grep -a lifetime) + [[ -z "$sessticket_str" ]] && sessticket_str=$(grep -aw "session ticket" $TMPFILE | grep -a lifetime) + fi outln pr_headlineln " Testing server defaults (Server Hello) " From 5270747eb0baf7a728c1d2afd960d5716c45762d Mon Sep 17 00:00:00 2001 From: David Cooper Date: Wed, 4 Jan 2017 10:31:13 -0500 Subject: [PATCH 30/61] Check for matching SSLv2 cipher Some servers respond to an SSLv2 ClientHello with a list of all SSLv2 ciphers that the server supports rather than just a list of ciphers that it supports in common with the client (i.e., that appear in the ClientHello). This PR changes the sockets version of `run_freak()` so that, if `sslv2_sockets()` is successful, it checks whether there are any ciphers in common between the ClientHello and the ServerHello before declaring that the server supports an export RSA cipher. --- testssl.sh | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/testssl.sh b/testssl.sh index 2f1ab04..ff908a1 100755 --- a/testssl.sh +++ b/testssl.sh @@ -9212,11 +9212,12 @@ run_tls_fallback_scsv() { # Factoring RSA Export Keys: don't use EXPORT RSA ciphers, see https://freakattack.com/ run_freak() { local -i sclient_success=0 - local -i i nr_supported_ciphers=0 + local -i i nr_supported_ciphers=0 len # with correct build it should list these 9 ciphers (plus the two latter as SSLv2 ciphers): local exportrsa_cipher_list="EXP1024-DES-CBC-SHA:EXP1024-RC2-CBC-MD5:EXP1024-RC4-SHA:EXP1024-RC4-MD5:EXP-EDH-RSA-DES-CBC-SHA:EXP-DH-RSA-DES-CBC-SHA:EXP-DES-CBC-SHA:EXP-RC2-CBC-MD5:EXP-RC4-MD5" local exportrsa_tls_cipher_list_hex="00,62, 00,61, 00,64, 00,60, 00,14, 00,0E, 00,08, 00,06, 00,03" local exportrsa_ssl2_cipher_list_hex="04,00,80, 02,00,80" + local detected_ssl2_ciphers local addcmd="" addtl_warning="" hexc local cve="CVE-2015-0204" local cwe="CWE-310" @@ -9253,8 +9254,15 @@ run_freak() { sclient_success=$? [[ $sclient_success -eq 2 ]] && sclient_success=0 if [[ $sclient_success -ne 0 ]]; then - sslv2_sockets "$exportrsa_ssl2_cipher_list_hex" - [[ $? -eq 3 ]] && [[ "$V2_HELLO_CIPHERSPEC_LENGTH" -ne 0 ]] && sclient_success=0 + sslv2_sockets "$exportrsa_ssl2_cipher_list_hex" "true" + if [[ $? -eq 3 ]] && [[ "$V2_HELLO_CIPHERSPEC_LENGTH" -ne 0 ]]; then + exportrsa_ssl2_cipher_list_hex="$(strip_spaces "${exportrsa_ssl2_cipher_list_hex//,/}")" + len=${#exportrsa_ssl2_cipher_list_hex} + detected_ssl2_ciphers="$(grep "Supported cipher: " "$TEMPDIR/$NODEIP.parse_sslv2_serverhello.txt")" + for (( i=0; i Date: Wed, 4 Jan 2017 10:34:13 -0500 Subject: [PATCH 31/61] Check for matching SSLv2 cipher Some servers respond to an SSLv2 ClientHello with a list of all SSLv2 ciphers that the server supports rather than just a list of ciphers that it supports in common with the client (i.e., that appear in the ClientHello). This PR changes the sockets version of `std_cipherlists()` so that, if `sslv2_sockets()` is successful, it checks whether there are any ciphers in common between the ClientHello and the ServerHello before declaring that the server supports the specified cipher list. --- testssl.sh | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/testssl.sh b/testssl.sh index 902e43c..322db73 100755 --- a/testssl.sh +++ b/testssl.sh @@ -2015,7 +2015,8 @@ listciphers() { # argv[5]: non-SSLv2 cipher list to test (hexcodes), if using sockets # argv[6]: SSLv2 cipher list to test (hexcodes), if using sockets std_cipherlists() { - local -i sclient_success + local -i i len sclient_success + local sslv2_cipherlist detected_ssl2_ciphers local singlespaces proto="" addcmd="" local debugname="$(sed -e s'/\!/not/g' -e 's/\:/_/g' <<< "$1")" @@ -2040,8 +2041,15 @@ std_cipherlists() { sclient_success=$? debugme cat $ERRFILE elif [[ -n "$6" ]]; then - sslv2_sockets "$6" - [[ $? -eq 3 ]] && [[ "$V2_HELLO_CIPHERSPEC_LENGTH" -ne 0 ]] && sclient_success=0 + sslv2_sockets "$6" "true" + if [[ $? -eq 3 ]] && [[ "$V2_HELLO_CIPHERSPEC_LENGTH" -ne 0 ]]; then + sslv2_cipherlist="$(strip_spaces "${6//,/}")" + len=${#sslv2_cipherlist} + detected_ssl2_ciphers="$(grep "Supported cipher: " "$TEMPDIR/$NODEIP.parse_sslv2_serverhello.txt")" + for (( i=0; i Date: Wed, 4 Jan 2017 10:47:36 -0500 Subject: [PATCH 32/61] sslv2_sockets() bug fixes This PR fixes a few bugs in `sslv2_sockets()`. The main issue is that a server may not send the entire ServerHello in a single packet. If it doesn't and the full response is being parsed (i.e., certificate and list of ciphers), then `parse_sslv2_serverhello()` will encounter errors, since it assumes that it has the entire ServerHello. This PR compares the length of the response to the length of the ServerHello as specified in the first two bytes of the response and requests more data from the server if the response appears incomplete. This PR also modifies `parse_sslv2_serverhello()` to check for more errors. It compares the length of the response it has been provided to the specified length (`$v2_hello_length`) and returns an error if the response is shorter than `$v2_hello_length` and the full response is supposed to be parsed. It will also check whether there was an error in converting the certificate from DER to PEM format and will return an error if there was (and it will suppress the error message). --- testssl.sh | 40 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 37 insertions(+), 3 deletions(-) diff --git a/testssl.sh b/testssl.sh index 80a8ac8..5c133d1 100755 --- a/testssl.sh +++ b/testssl.sh @@ -7063,6 +7063,7 @@ parse_sslv2_serverhello() { "$parse_complete" && echo "======================================" > $TMPFILE v2_hello_ascii=$(hexdump -v -e '16/1 "%02X"' $1) + v2_hello_ascii="${v2_hello_ascii%%[!0-9A-F]*}" [[ "$DEBUG" -ge 5 ]] && echo "$v2_hello_ascii" if [[ -z "$v2_hello_ascii" ]]; then ret=0 # 1 line without any blanks: no server hello received @@ -7094,6 +7095,10 @@ parse_sslv2_serverhello() { echo "SSLv2 certificate length: 0x$v2_hello_cert_length" echo "SSLv2 cipher spec length: 0x$v2_hello_cipherspec_length" fi + + if "$parse_complete" && [[ 2*$(hex2dec "$v2_hello_length") -ne ${#v2_hello_ascii}-4 ]]; then + ret=7 + fi fi "$parse_complete" || return $ret @@ -7101,11 +7106,15 @@ parse_sslv2_serverhello() { rm -f $HOSTCERT $TEMPDIR/intermediatecerts.pem if [[ $ret -eq 3 ]]; then certificate_len=2*$(hex2dec "$v2_hello_cert_length") - + if [[ "$v2_cert_type" == "01" ]] && [[ "$v2_hello_cert_length" != "00" ]]; then tmp_der_certfile=$(mktemp $TEMPDIR/der_cert.XXXXXX) || return $ret asciihex_to_binary_file "${v2_hello_ascii:26:certificate_len}" "$tmp_der_certfile" - $OPENSSL x509 -inform DER -in $tmp_der_certfile -outform PEM -out $HOSTCERT + $OPENSSL x509 -inform DER -in $tmp_der_certfile -outform PEM -out $HOSTCERT 2>$ERRFILE + if [[ $? -ne 0 ]]; then + debugme echo "Malformed certificate in ServerHello." + return 1 + fi rm $tmp_der_certfile get_pub_key_size echo "======================================" >> $TMPFILE @@ -8100,6 +8109,13 @@ sslv2_sockets() { local ret local client_hello cipher_suites len_client_hello local len_ciph_suites_byte len_ciph_suites + local server_hello sock_reply_file2 + local -i response_len server_hello_len + local parse_complete=false + + if [[ "$2" == "true" ]]; then + parse_complete=true + fi if [[ -n "$1" ]]; then cipher_suites="$1" @@ -8140,13 +8156,31 @@ sslv2_sockets() { socksend_sslv2_clienthello "$client_hello" sockread_serverhello 32768 + if "$parse_complete"; then + server_hello=$(hexdump -v -e '16/1 "%02X"' "$SOCK_REPLY_FILE") + server_hello_len=2+$(hex2dec "${server_hello:1:3}") + response_len=$(wc -c "$SOCK_REPLY_FILE" | awk '{ print $1 }') + for (( 1; response_len < server_hello_len; 1 )); do + sock_reply_file2=$(mktemp $TEMPDIR/ddreply.XXXXXX) || return 7 + mv "$SOCK_REPLY_FILE" "$sock_reply_file2" + + debugme echo "requesting more server hello data..." + socksend "" $USLEEP_SND + sockread_serverhello 32768 + + [[ ! -s "$SOCK_REPLY_FILE" ]] && break + cat "$SOCK_REPLY_FILE" >> "$sock_reply_file2" + mv "$sock_reply_file2" "$SOCK_REPLY_FILE" + response_len=$(wc -c "$SOCK_REPLY_FILE" | awk '{ print $1 }') + done + fi debugme outln "reading server hello... " if [[ "$DEBUG" -ge 4 ]]; then hexdump -C "$SOCK_REPLY_FILE" | head -6 outln fi - parse_sslv2_serverhello "$SOCK_REPLY_FILE" "$2" + parse_sslv2_serverhello "$SOCK_REPLY_FILE" "$parse_complete" ret=$? close_socket From 70e6e289e1572770d52572350dc4e7ff85d6e86e Mon Sep 17 00:00:00 2001 From: Todd Swatling Date: Thu, 5 Jan 2017 14:20:19 -0500 Subject: [PATCH 33/61] removed trailing spaces --- testssl.sh | 41 ++++++++++++++++++++--------------------- 1 file changed, 20 insertions(+), 21 deletions(-) diff --git a/testssl.sh b/testssl.sh index 80a8ac8..fc010c3 100755 --- a/testssl.sh +++ b/testssl.sh @@ -148,7 +148,7 @@ BUGS=${BUGS:-""} # -bugs option from openssl, needed for DEBUG=${DEBUG:-0} # 1: normal putput the files in /tmp/ are kept for further debugging purposes # 2: list more what's going on , also lists some errors of connections # 3: slight hexdumps + other info, - # 4: display bytes sent via sockets + # 4: display bytes sent via sockets # 5: display bytes received via sockets # 6: whole 9 yards FAST=${FAST:-false} # preference: show only first cipher, run_allciphers with openssl instead of sockets @@ -159,7 +159,7 @@ CSVFILE=${CSVFILE:-""} # csvfile if used APPEND=${APPEND:-false} # append to csv/json file instead of overwriting it GIVE_HINTS=false # give an addtional info to findings HAS_IPv6=${HAS_IPv6:-false} # if you have OpenSSL with IPv6 support AND IPv6 networking set it to yes -UNBRACKTD_IPV6=${UNBRACKTD_IPV6:-false} # some versions of OpenSSL (like Gentoo) don't support [bracketed] IPv6 addresses +UNBRACKTD_IPV6=${UNBRACKTD_IPV6:-false} # some versions of OpenSSL (like Gentoo) don't support [bracketed] IPv6 addresses SERVER_SIZE_LIMIT_BUG=false # Some servers have either a ClientHello total size limit or cipher limit of ~128 ciphers (e.g. old ASAs) # tuning vars, can not be set by a cmd line switch @@ -556,7 +556,7 @@ declare TLS_CIPHER_OSSL_SUPPORTED=() ###### output functions ###### # a little bit of sanitzing with bash internal search&replace -- otherwise printf will hiccup at '%' and '--' does the rest. -out(){ +out(){ # if [[ "$BASH_VERSINFO" -eq 4 ]]; then printf -- "%b" "${1//%/%%}" # else @@ -590,10 +590,10 @@ pr_greyln() { pr_grey "$1"; outln; } pr_done_good() { [[ "$COLOR" -eq 2 ]] && ( "$COLORBLIND" && out "\033[0;34m$1" || out "\033[0;32m$1" ) || out "$1"; pr_off; } # litegreen (liteblue), This is good pr_done_goodln() { pr_done_good "$1"; outln; } -pr_done_best() { [[ "$COLOR" -eq 2 ]] && ( "$COLORBLIND" && out "\033[1;34m$1" || out "\033[1;32m$1" ) || out "$1"; pr_off; } # green (blue), This is the best +pr_done_best() { [[ "$COLOR" -eq 2 ]] && ( "$COLORBLIND" && out "\033[1;34m$1" || out "\033[1;32m$1" ) || out "$1"; pr_off; } # green (blue), This is the best pr_done_bestln() { pr_done_best "$1"; outln; } -pr_svrty_minor() { [[ "$COLOR" -eq 2 ]] && out "\033[1;33m$1" || out "$1"; pr_off; } # yellow brown | academic or minor problem +pr_svrty_minor() { [[ "$COLOR" -eq 2 ]] && out "\033[1;33m$1" || out "$1"; pr_off; } # yellow brown | academic or minor problem pr_svrty_minorln() { pr_svrty_minor "$1"; outln; } pr_svrty_medium() { [[ "$COLOR" -eq 2 ]] && out "\033[0;33m$1" || out "$1"; pr_off; } # brown | it is not a bad problem but you shouldn't do this pr_svrty_mediumln() { pr_svrty_medium "$1"; outln; } @@ -1082,7 +1082,7 @@ string_to_asciihex() { [[ -n "$string" ]] && output+="$(printf "%02x" "'${string:eos:1}")" out "$output" return 0 - + } ###### check code starts here ###### @@ -6221,7 +6221,7 @@ run_pfs() { done < <($OPENSSL ciphers -V "$pfs_cipher_list" 2>$ERRFILE) fi export="" - + if "$using_sockets"; then tls_sockets "03" "${pfs_hex_cipher_list:2}" sclient_success=$? @@ -7101,7 +7101,7 @@ parse_sslv2_serverhello() { rm -f $HOSTCERT $TEMPDIR/intermediatecerts.pem if [[ $ret -eq 3 ]]; then certificate_len=2*$(hex2dec "$v2_hello_cert_length") - + if [[ "$v2_cert_type" == "01" ]] && [[ "$v2_hello_cert_length" != "00" ]]; then tmp_der_certfile=$(mktemp $TEMPDIR/der_cert.XXXXXX) || return $ret asciihex_to_binary_file "${v2_hello_ascii:26:certificate_len}" "$tmp_der_certfile" @@ -7222,7 +7222,7 @@ parse_tls_serverhello() { local process_full="$2" 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="" tls_certificate_ascii="" + local tls_serverhello_ascii="" tls_certificate_ascii="" local tls_serverkeyexchange_ascii="" tls_certificate_status_ascii="" local -i tls_serverhello_ascii_len=0 tls_certificate_ascii_len=0 local -i tls_serverkeyexchange_ascii_len=0 tls_certificate_status_ascii_len=0 @@ -8029,7 +8029,7 @@ parse_tls_serverhello() { len1="82$(printf "%04x" $((dh_param_len/2)))" fi dh_param="30${len1}${dh_p}${dh_g}" - + # Make a SEQUENCE of the paramters SEQUENCE and the OID dh_param_len=22+${#dh_param} if [[ $dh_param_len -lt 256 ]]; then @@ -8069,7 +8069,7 @@ parse_tls_serverhello() { [[ -n "$key_bitstring" ]] && echo "$key_bitstring" >> $TMPFILE # Check to see whether the ephemeral public key uses one of the groups from - # RFC 7919 for parameters + # RFC 7919 for parameters case $dh_bits in 2048) named_curve=256; named_curve_str=" ffdhe2048," ;; 3072) named_curve=257; named_curve_str=" ffdhe3072," ;; @@ -8263,7 +8263,7 @@ socksend_tls_clienthello() { 00, 01, 00, 02, 00, 03, 00, 0f, 00, 10, 00, 11" # Supported Point Formats Extension extension_supported_point_formats=" - 00, 0b, # Type: Supported Point Formats , see RFC 4492 + 00, 0b, # Type: Supported Point Formats , see RFC 4492 00, 02, # len 01, 00" fi @@ -9641,7 +9641,7 @@ run_rc4() { ciphers_found[nr_ciphers]=false sigalg[nr_ciphers]="" ossl_supported[nr_ciphers]="${TLS_CIPHER_OSSL_SUPPORTED[i]}" - if "$using_sockets" && "$WIDE" && ! "$HAS_DH_BITS" && + if "$using_sockets" && "$WIDE" && ! "$HAS_DH_BITS" && ( [[ ${kx[nr_ciphers]} == "Kx=ECDH" ]] || [[ ${kx[nr_ciphers]} == "Kx=DH" ]] || [[ ${kx[nr_ciphers]} == "Kx=EDH" ]] ); then ossl_supported[nr_ciphers]=false fi @@ -9897,7 +9897,7 @@ get_install_dir() { fi if [[ ! -r "$CIPHERS_BY_STRENGTH_FILE" ]] ; then - unset ADD_RFC_STR + unset ADD_RFC_STR debugme echo "$CIPHERS_BY_STRENGTH_FILE" pr_warningln "\nATTENTION: No cipher mapping file found!" outln "Please note from 2.9dev on $PROG_NAME needs files in \"\$TESTSSL_INSTALL_DIR/etc/\" to function correctly." @@ -10045,9 +10045,9 @@ check4openssl_oldfarts() { pr_warningln " Your \"$OPENSSL\" is way too old (", where is: @@ -10092,7 +10092,7 @@ help() { "$PROG_NAME URI", where is: - -t, --starttls does a default run against a STARTTLS enabled does a default run against a STARTTLS enabled (latter three require supplied openssl) --xmpphost for STARTTLS enabled XMPP it supplies the XML stream to-'' domain -- sometimes needed --mx tests MX records from high to low priority (STARTTLS, port 25) @@ -10281,7 +10281,7 @@ EOF ossl_ciph="$(grep -w "$hexc" <<< "$ossl_supported_tls" | awk '{ print $3 }')" if [[ -n "$ossl_ciph" ]]; then TLS_CIPHER_OSSL_SUPPORTED[TLS_NR_CIPHERS]=true - [[ "$ossl_ciph" != "${TLS_CIPHER_OSSL_NAME[TLS_NR_CIPHERS]}" ]] && TLS_CIPHER_OSSL_NAME[TLS_NR_CIPHERS]="$ossl_ciph" + [[ "$ossl_ciph" != "${TLS_CIPHER_OSSL_NAME[TLS_NR_CIPHERS]}" ]] && TLS_CIPHER_OSSL_NAME[TLS_NR_CIPHERS]="$ossl_ciph" fi fi elif [[ $OSSL_VER_MAJOR -lt 1 ]]; then @@ -11708,4 +11708,3 @@ else fi exit $? - From 557c15607a7b82dac59b6330dff9f158660f8665 Mon Sep 17 00:00:00 2001 From: Todd Swatling Date: Thu, 5 Jan 2017 14:45:39 -0500 Subject: [PATCH 34/61] detects install dir when symlinked and realpath not present $ ls -l /usr/local/bin/testssl lrwxrwxrwx /usr/local/bin/testssl -> /home/user/testssl.sh/testssl.sh --- testssl.sh | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/testssl.sh b/testssl.sh index fc010c3..dee99e4 100755 --- a/testssl.sh +++ b/testssl.sh @@ -9896,6 +9896,16 @@ get_install_dir() { [[ -r "$TESTSSL_INSTALL_DIR/cipher-mapping.txt" ]] && CIPHERS_BY_STRENGTH_FILE="$TESTSSL_INSTALL_DIR/cipher-mapping.txt" fi + # still no cipher mapping file (and realpath is not present): + if [[ ! -r "$CIPHERS_BY_STRENGTH_FILE" ]] && which readlink &>/dev/null ; then + readlink -f ls &>/dev/null && \ + TESTSSL_INSTALL_DIR=$(dirname $(readlink -f ${BASH_SOURCE[0]})) || \ + TESTSSL_INSTALL_DIR=$(dirname $(readlink ${BASH_SOURCE[0]})) + # not sure whether Darwin has -f + CIPHERS_BY_STRENGTH_FILE="$TESTSSL_INSTALL_DIR/etc/cipher-mapping.txt" + [[ -r "$TESTSSL_INSTALL_DIR/cipher-mapping.txt" ]] && CIPHERS_BY_STRENGTH_FILE="$TESTSSL_INSTALL_DIR/cipher-mapping.txt" + fi + if [[ ! -r "$CIPHERS_BY_STRENGTH_FILE" ]] ; then unset ADD_RFC_STR debugme echo "$CIPHERS_BY_STRENGTH_FILE" From ab9eb6044efd81e8a61d80ab519ef9331aaa58a7 Mon Sep 17 00:00:00 2001 From: David Cooper Date: Thu, 5 Jan 2017 14:55:08 -0500 Subject: [PATCH 35/61] Use sockets for run_crime() This PR changes `run_crime()` to use `tls_sockets()` rather than failing if `$OPENSSL` lacks zlib support, unless `$SSL_NATIVE` is `true`. At the moment, the ClientHello created by `socksend_tls_clienthello()` only specifies the NULL compression method. So, this PR adds a new parameter to `socksend_tls_clienthello()` and `tls_sockets()` to allow to caller to request that additional compression methods (DEFLATE and LZS) be specified in the ClientHello. This PR makes another change to `run_crime()`. At the moment, if `$OPENSSL s_client` fails to connect to the server, `run_crime()` will report that the server is not vulnerable, since the output from `$OPENSSL s_client` includes the line "Compression: NONE" (see below). This PR changes that by checking whether the connection was successful, and reporting a "test failed (couldn't connect)" warning if it wasn't successful, rather than reporting "not vulnerable (OK)". ``` CONNECTED(00000003) 140338777061024:error:1407742E:SSL routines:SSL23_GET_SERVER_HELLO:tlsv1 alert protocol version:s23_clnt.c:769: --- no peer certificate available --- No client certificate CA names sent --- SSL handshake has read 7 bytes and written 389 bytes --- New, (NONE), Cipher is (NONE) Secure Renegotiation IS NOT supported Compression: NONE Expansion: NONE No ALPN negotiated SSL-Session: Protocol : TLSv1 Cipher : 0000 Session-ID: Session-ID-ctx: Master-Key: Key-Arg : None PSK identity: None PSK identity hint: None SRP username: None Start Time: 1483645971 Timeout : 300 (sec) Verify return code: 0 (ok) --- ``` --- testssl.sh | 63 ++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 47 insertions(+), 16 deletions(-) diff --git a/testssl.sh b/testssl.sh index 80a8ac8..2019b18 100755 --- a/testssl.sh +++ b/testssl.sh @@ -8159,6 +8159,7 @@ sslv2_sockets() { # ARG1: TLS version low byte (00: SSLv3, 01: TLS 1.0, 02: TLS 1.1, 03: TLS 1.2) # ARG2: CIPHER_SUITES string # ARG3: (optional) additional request extensions +# ARG4: (optional): "true" if ClientHello should advertise compression methods other than "NULL" socksend_tls_clienthello() { local tls_low_byte="$1" local tls_word_reclayer="03, 01" # the first TLS version number is the record layer and always 0301 -- except: SSLv3 @@ -8174,6 +8175,10 @@ socksend_tls_clienthello() { local extension_session_ticket extension_next_protocol extension_padding local extension_supported_groups="" extension_supported_point_formats="" local extra_extensions extra_extensions_list="" + local offer_compression=false compression_metods + + # TLSv1.3 ClientHello messages MUST specify only the NULL compression method. + [[ "$4" == "true" ]] && [[ "0x$tls_low_byte" -le "0x03" ]] && offer_compression=true code2network "$(tolower "$2")" # convert CIPHER_SUITES cipher_suites="$NW_STR" # we don't have the leading \x here so string length is two byte less, see next @@ -8337,6 +8342,7 @@ socksend_tls_clienthello() { # If the length of the Client Hello would be between 256 and 511 bytes, # then add a padding extension (see RFC 7685) len_all=$((0x$len_ciph_suites + 0x2b + 0x$len_extension_hex + 0x2)) + "$offer_compression" && len_all+=2 if [[ $len_all -ge 256 ]] && [[ $len_all -le 511 ]] && [[ ! "$extra_extensions_list" =~ " 0015 " ]]; then if [[ $len_all -gt 508 ]]; then len_padding_extension=0 @@ -8361,24 +8367,35 @@ socksend_tls_clienthello() { # RFC 3546 doesn't specify SSLv3 to have SNI, openssl just ignores the switch if supplied if [[ "$tls_low_byte" == "00" ]]; then - len2twobytes $(printf "%02x\n" $((0x$len_ciph_suites + 0x27))) + len_all=$((0x$len_ciph_suites + 0x27)) else - len2twobytes $(printf "%02x\n" $((0x$len_ciph_suites + 0x27 + 0x$len_extension_hex + 0x2))) + len_all=$((0x$len_ciph_suites + 0x27 + 0x$len_extension_hex + 0x2)) fi + "$offer_compression" && len_all+=2 + len2twobytes $(printf "%02x\n" $len_all) len_client_hello_word="$LEN_STR" #[[ $DEBUG -ge 3 ]] && echo $len_client_hello_word if [[ "$tls_low_byte" == "00" ]]; then - len2twobytes $(printf "%02x\n" $((0x$len_ciph_suites + 0x2b))) + len_all=$((0x$len_ciph_suites + 0x2b)) else - len2twobytes $(printf "%02x\n" $((0x$len_ciph_suites + 0x2b + 0x$len_extension_hex + 0x2))) + len_all=$((0x$len_ciph_suites + 0x2b + 0x$len_extension_hex + 0x2)) fi + "$offer_compression" && len_all+=2 + len2twobytes $(printf "%02x\n" $len_all) len_all_word="$LEN_STR" #[[ $DEBUG -ge 3 ]] && echo $len_all_word # if we have SSLv3, the first occurence of TLS protocol -- record layer -- is SSLv3, otherwise TLS 1.0 [[ $tls_low_byte == "00" ]] && tls_word_reclayer="03, 00" + if "$offer_compression"; then + # See http://www.iana.org/assignments/comp-meth-ids/comp-meth-ids.xhtml#comp-meth-ids-2 + compression_metods="03,01,40,00" # Offer NULL, DEFLATE, and LZS compression + else + compression_metods="01,00" # Only offer NULL compression (0x00) + fi + TLS_CLIENT_HELLO=" # TLS header ( 5 bytes) ,16, $tls_word_reclayer # TLS Version: in wireshark this is always 01 for TLS 1.0-1.2 @@ -8395,8 +8412,7 @@ socksend_tls_clienthello() { ,00 # Session ID length ,$len_ciph_suites_word # Cipher suites length ,$cipher_suites - ,01 # Compression methods length - ,00" # Compression method (x00 for NULL) + ,$compression_metods" fd_socket 5 || return 6 @@ -8415,6 +8431,7 @@ socksend_tls_clienthello() { # arg3: (optional): "all" - process full response (including Certificate and certificate_status handshake messages) # "ephemeralkey" - extract the server's ephemeral key (if any) # arg4: (optional) additional request extensions +# arg5: (optional) "true" if ClientHello should advertise compression methods other than "NULL" tls_sockets() { local -i ret=0 local -i save=0 @@ -8423,8 +8440,9 @@ tls_sockets() { local cipher_list_2send local sock_reply_file2 sock_reply_file3 local tls_hello_ascii next_packet hello_done=0 - local process_full="$3" + local process_full="$3" offer_compression=false + [[ "$5" == "true" ]] && offer_compression=true tls_low_byte="$1" if [[ -n "$2" ]]; then # use supplied string in arg2 if there is one cipher_list_2send="$2" @@ -8437,7 +8455,7 @@ tls_sockets() { fi debugme echo "sending client hello..." - socksend_tls_clienthello "$tls_low_byte" "$cipher_list_2send" "$4" + socksend_tls_clienthello "$tls_low_byte" "$cipher_list_2send" "$4" "$offer_compression" ret=$? # 6 means opening socket didn't succeed, e.g. timeout # if sending didn't succeed we don't bother @@ -8950,7 +8968,7 @@ run_renego() { } run_crime() { - local -i ret=0 + local -i ret=0 sclient_success local addcmd="" local cve="CVE-2012-4929" local cwe="CWE-310" @@ -8968,14 +8986,27 @@ run_crime() { # first we need to test whether OpenSSL binary has zlib support $OPENSSL zlib -e -a -in /dev/stdin &>/dev/stdout $TMPFILE + sclient_connect_successful $? $TMPFILE + sclient_success=$? fi - - [[ "$OSSL_VER" == "0.9.8"* ]] && addcmd="-no_ssl2" - $OPENSSL s_client $OPTIMAL_PROTO $BUGS $addcmd $STARTTLS -connect $NODEIP:$PORT $PROXY $SNI $TMPFILE - if grep -a Compression $TMPFILE | grep -aq NONE >/dev/null; then + if [[ $sclient_success -ne 0 ]]; then + pr_warning "test failed (couldn't connect)" + fileout "crime" "WARN" "CRIME, TLS: 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)" if [[ $SERVICE != "HTTP" ]] && ! $CLIENT_AUTH; then out " (not using HTTP anyway)" From 95c75f1792837753023e60a9f227d033973d07d6 Mon Sep 17 00:00:00 2001 From: David Cooper Date: Thu, 5 Jan 2017 15:45:18 -0500 Subject: [PATCH 36/61] Add support for OpenSSL 1.1.0 Starting with OpenSSL 1.1.0, s_client will not offer TLS compression methods, even if OpenSSL is compiled with zlib support, unless the `-comp` flag is included in the command line. --- testssl.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/testssl.sh b/testssl.sh index 2019b18..64310c4 100755 --- a/testssl.sh +++ b/testssl.sh @@ -8998,6 +8998,9 @@ run_crime() { fi else [[ "$OSSL_VER" == "0.9.8"* ]] && addcmd="-no_ssl2" + if [[ $OSSL_VER_MAJOR.$OSSL_VER_MINOR == "1.1.0"* ]] || [[ $OSSL_VER_MAJOR.$OSSL_VER_MINOR == "1.1.1"* ]]; then + addcmd="-comp" + fi $OPENSSL s_client $OPTIMAL_PROTO $BUGS $addcmd $STARTTLS -connect $NODEIP:$PORT $PROXY $SNI $TMPFILE sclient_connect_successful $? $TMPFILE sclient_success=$? From c9119dd8eeabc9c7e9c8d8676f475db63e3fbd3a Mon Sep 17 00:00:00 2001 From: David Cooper Date: Thu, 12 Jan 2017 13:09:11 -0500 Subject: [PATCH 37/61] Use static lists for sockets --- testssl.sh | 124 +++++++++++++---------------------------------------- 1 file changed, 29 insertions(+), 95 deletions(-) diff --git a/testssl.sh b/testssl.sh index 0a3c523..1ecd025 100755 --- a/testssl.sh +++ b/testssl.sh @@ -4440,105 +4440,39 @@ run_protocols() { run_std_cipherlists() { local hexc hexcode strength local -i i - local null_ciphers="" anon_ciphers="" adh_ciphers="" exp40_ciphers="" - local exp56_ciphers="" exp_ciphers="" low_ciphers="" des_ciphers="" - local medium_ciphers="" tdes_ciphers="" high_ciphers="" - local sslv2_null_ciphers="" sslv2_anon_ciphers="" sslv2_adh_ciphers="" sslv2_exp40_ciphers="" - local sslv2_exp56_ciphers="" sslv2_exp_ciphers="" sslv2_low_ciphers="" sslv2_des_ciphers="" - local sslv2_medium_ciphers="" sslv2_tdes_ciphers="" sslv2_high_ciphers="" + local null_ciphers="c0,10, c0,06, c0,15, c0,0b, c0,01, c0,3b, c0,3a, c0,39, 00,b9, 00,b8, 00,b5, 00,b4, 00,2e, 00,2d, 00,b1, 00,b0, 00,2c, 00,3b, 00,02, 00,01, 00,82, 00,83, ff,87, 00,ff" + local sslv2_null_ciphers="" + local anon_ciphers="c0,19, 00,a7, 00,6d, 00,3a, 00,c5, 00,89, c0,47, c0,5b, c0,85, c0,18, 00,a6, 00,6c, 00,34, 00,bf, 00,9b, 00,46, c0,46, c0,5a, c0,84, c0,16, 00,18, c0,17, 00,1b, 00,1a, 00,19, 00,17, c0,15, 00,ff" + local sslv2_anon_ciphers="" + local adh_ciphers="00,a7, 00,6d, 00,3a, 00,c5, 00,89, c0,47, c0,5b, c0,85, 00,a6, 00,6c, 00,34, 00,bf, 00,9b, 00,46, c0,46, c0,5a, c0,84, 00,18, 00,1b, 00,1a, 00,19, 00,17, 00,ff" + local sslv2_adh_ciphers="" + local exp40_ciphers="00,14, 00,11, 00,19, 00,08, 00,06, 00,27, 00,26, 00,2a, 00,29, 00,0b, 00,0e, 00,17, 00,03, 00,28, 00,2b, 00,ff" + local sslv2_exp40_ciphers="04,00,80, 02,00,80" + local exp56_ciphers="00,63, 00,62, 00,61, 00,65, 00,64, 00,60, 00,ff" + local sslv2_exp56_ciphers="" + local exp_ciphers="00,63, 00,62, 00,61, 00,65, 00,64, 00,60, 00,14, 00,11, 00,19, 00,08, 00,06, 00,27, 00,26, 00,2a, 00,29, 00,0b, 00,0e, 00,17, 00,03, 00,28, 00,2b, 00,ff" + local sslv2_exp_ciphers="04,00,80, 02,00,80" + local low_ciphers="00,15, 00,12, 00,0f, 00,0c, 00,09, 00,1e, 00,22, fe,fe, ff,e1, 00,ff" + local sslv2_low_ciphers="08,00,80, 06,00,40" + local des_ciphers="00,15, 00,12, 00,0f, 00,0c, 00,09, 00,1e, 00,22, fe,fe, ff,e1, 00,ff" + local sslv2_des_ciphers="06,00,40" + local medium_ciphers="00,9a, 00,99, 00,98, 00,97, 00,96, 00,07, 00,21, 00,25, c0,11, c0,07, 00,66, c0,0c, c0,02, 00,05, 00,04, 00,92, 00,8a, 00,20, 00,24, c0,33, 00,8e, 00,ff" + local sslv2_medium_ciphers="" + local tdes_ciphers="c0,12, c0,08, c0,1c, c0,1b, c0,1a, 00,16, 00,13, 00,10, 00,0d, c0,0d, c0,03, 00,0a, 00,93, 00,8b, 00,1f, 00,23, c0,34, 00,8f, fe,ff, ff,e0, 00,ff" + local sslv2_tdes_ciphers="07,00,c0" + local high_ciphers="13,02, 13,03, cc,14, cc,13, cc,15, c0,30, c0,2c, c0,28, c0,24, c0,14, c0,0a, c0,22, c0,21, c0,20, 00,b7, 00,b3, 00,91, c0,9b, c0,99, c0,97, 00,af, c0,95, 00,a5, 00,a3, 00,a1, 00,9f, cc,a9, cc,a8, cc,aa, c0,af, c0,ad, c0,a3, c0,9f, 00,6b, 00,6a, 00,69, 00,68, 00,39, 00,38, 00,37, 00,36, c0,77, c0,73, 00,c4, 00,c3, 00,c2, 00,c1, 00,88, 00,87, 00,86, 00,85, 00,ad, 00,ab, cc,ae, cc,ad, cc,ac, c0,ab, c0,a7, c0,32, c0,2e, c0,2a, c0,26, c0,0f, c0,05, c0,79, c0,75, 00,9d, c0,a1, c0,9d, 00,a9, cc,ab, c0,a9, c0,a5, 00,3d, 00,35, 00,c0, c0,38, c0,36, 00,84, 00,95, 00,8d, c0,3d, c0,3f, c0,41, c0,43, c0,45, c0,49, c0,4b, c0,4d, c0,4f, c0,51, c0,53, c0,55, c0,57, c0,59, c0,5d, c0,5f, c0,61, c0,63, c0,65, c0,67, c0,69, c0,6b, c0,6d, c0,6f, c0,71, c0,7b, c0,7d, c0,7f, c0,81, c0,83, c0,87, c0,89, c0,8b, c0,8d, c0,8f, c0,91, c0,93, 00,80, 00,81, ff,00, ff,01, ff,02, ff,03, ff,85, 16,b7, 16,b8, 16,b9, 16,ba, 13,01, 13,04, 13,05, c0,2f, c0,2b, c0,27, c0,23, c0,13, c0,09, c0,1f, c0,1e, c0,1d, 00,a4, 00,a2, 00,a0, 00,9e, c0,ae, c0,ac, c0,a2, c0,9e, 00,ac, 00,aa, c0,aa, c0,a6, c0,a0, c0,9c, 00,a8, c0,a8, c0,a4, 00,67, 00,40, 00,3f, 00,3e, 00,33, 00,32, 00,31, 00,30, c0,76, c0,72, 00,be, 00,bd, 00,bc, 00,bb, 00,45, 00,44, 00,43, 00,42, c0,31, c0,2d, c0,29, c0,25, c0,0e, c0,04, c0,78, c0,74, 00,9c, 00,3c, 00,2f, 00,ba, c0,37, c0,35, 00,b6, 00,b2, 00,90, 00,41, c0,9a, c0,98, c0,96, 00,ae, c0,94, 00,94, 00,8c, c0,3c, c0,3e, c0,40, c0,42, c0,44, c0,48, c0,4a, c0,4c, c0,4e, c0,50, c0,52, c0,54, c0,56, c0,58, c0,5c, c0,5e, c0,60, c0,62, c0,64, c0,66, c0,68, c0,6a, c0,6c, c0,6e, c0,70, c0,7a, c0,7c, c0,7e, c0,80, c0,82, c0,86, c0,88, c0,8a, c0,8c, c0,8e, c0,90, c0,92, 00,ff" + local sslv2_high_ciphers="" local using_sockets=true "$SSL_NATIVE" && using_sockets=false - [[ $TLS_NR_CIPHERS == 0 ]] && using_sockets=false - if "$using_sockets"; then - for (( i=0; i < TLS_NR_CIPHERS; i++ )); do - hexc="${TLS_CIPHER_HEXCODE[i]}" - strength="${TLS_CIPHER_ENC[i]}" - strength="${strength//\)/}" - strength="${strength#*\(}" - - if [[ ${#hexc} -eq 9 ]]; then - hexcode="${hexc:2:2},${hexc:7:2}" - [[ "${TLS_CIPHER_ENC[i]}" == "Enc=None" ]] && \ - null_ciphers+=", $hexcode" - [[ "${TLS_CIPHER_AUTH[i]}" == "Au=None" ]] && \ - anon_ciphers+=", $hexcode" - [[ "${TLS_CIPHER_RFC_NAME[i]}" =~ "TLS_DH_anon_" ]] && \ - adh_ciphers+=", $hexcode" - [[ $strength -eq 40 ]] && exp40_ciphers+=", $hexcode" -# [[ $strength -eq 56 ]] && exp56_ciphers+=", $hexcode" - [[ $strength -eq 56 ]] && \ - [[ "${TLS_CIPHER_EXPORT[i]}" == "export" ]] && \ - exp56_ciphers+=", $hexcode" - [[ "${TLS_CIPHER_EXPORT[i]}" == "export" ]] && \ - exp_ciphers+=", $hexcode" - if [[ "${TLS_CIPHER_AUTH[i]}" != "Au=None" ]]; then -# [[ $strength -le 64 ]] && low_ciphers+=", $hexcode" - [[ "${TLS_CIPHER_ENC[i]}" != "Enc=None" ]] && \ - [[ $strength -le 64 ]] && \ - [[ "${TLS_CIPHER_EXPORT[i]}" != "export" ]] && \ - low_ciphers+=", $hexcode" - [[ "${TLS_CIPHER_ENC[i]}" == "Enc=DES(56)" ]] && \ - [[ "${TLS_CIPHER_EXPORT[i]}" != "export" ]] && \ - des_ciphers+=", $hexcode" - [[ "${TLS_CIPHER_ENC[i]}" == "Enc=SEED(128)" ]] && \ - medium_ciphers+=", $hexcode" - [[ "${TLS_CIPHER_ENC[i]}" == "Enc=RC4(128)" ]] && \ - medium_ciphers+=", $hexcode" - [[ "${TLS_CIPHER_ENC[i]}" == "Enc=IDEA(128)" ]] && \ - medium_ciphers+=", $hexcode" - [[ "${TLS_CIPHER_ENC[i]}" == "Enc=3DES(168)" ]] && \ - tdes_ciphers+=", $hexcode" - [[ "${TLS_CIPHER_ENC[i]}" == "Enc=AES"* ]] && \ - high_ciphers+=", $hexcode" - [[ "${TLS_CIPHER_ENC[i]}" == "Enc=Camellia"* ]] && \ - high_ciphers+=", $hexcode" - [[ "${TLS_CIPHER_ENC[i]}" == "Enc=ChaCha20"* ]] && \ - high_ciphers+=", $hexcode" - [[ "${TLS_CIPHER_ENC[i]}" == "Enc=GOST"* ]] && \ - high_ciphers+=", $hexcode" - [[ "${TLS_CIPHER_ENC[i]}" == "Enc=ARIA"* ]] && \ - high_ciphers+=", $hexcode" - fi - else - hexcode="${hexc:2:2},${hexc:7:2},${hexc:12:2}" - [[ $strength -eq 40 ]] && sslv2_exp40_ciphers+=", $hexcode" -# [[ $strength -eq 56 ]] && sslv2_exp56_ciphers+=", $hexcode" - [[ "${TLS_CIPHER_EXPORT[i]}" == "export" ]] && \ - sslv2_exp_ciphers+=", $hexcode" -# [[ $strength -le 64 ]] && sslv2_low_ciphers+=", $hexcode" - [[ $strength -le 64 ]] && \ - [[ "${TLS_CIPHER_EXPORT[i]}" != "export" ]] && \ - sslv2_low_ciphers+=", $hexcode" - [[ "${TLS_CIPHER_ENC[i]}" == "Enc=DES(56)" ]] && \ - sslv2_des_ciphers+=", $hexcode" - [[ "${TLS_CIPHER_ENC[i]}" == "Enc=3DES(168)" ]] && \ - sslv2_tdes_ciphers+=", $hexcode" - fi - done - [[ -n "$null_ciphers" ]] && null_ciphers="${null_ciphers:2}, 00,ff" - [[ -n "$anon_ciphers" ]] && anon_ciphers="${anon_ciphers:2}, 00,ff" - [[ -n "$adh_ciphers" ]] && adh_ciphers="${adh_ciphers:2}, 00,ff" - [[ -n "$exp40_ciphers" ]] && exp40_ciphers="${exp40_ciphers:2}, 00,ff" - [[ -n "$exp56_ciphers" ]] && exp56_ciphers="${exp56_ciphers:2}, 00,ff" - [[ -n "$exp_ciphers" ]] && exp_ciphers="${exp_ciphers:2}, 00,ff" - [[ -n "$low_ciphers" ]] && low_ciphers="${low_ciphers:2}, 00,ff" - [[ -n "$des_ciphers" ]] && des_ciphers="${des_ciphers:2}, 00,ff" - [[ -n "$medium_ciphers" ]] && medium_ciphers="${medium_ciphers:2}, 00,ff" - [[ -n "$tdes_ciphers" ]] && tdes_ciphers="${tdes_ciphers:2}, 00,ff" - [[ -n "$high_ciphers" ]] && high_ciphers="${high_ciphers:2}, 00,ff" - [[ -n "$sslv2_null_ciphers" ]] && sslv2_null_ciphers="${sslv2_null_ciphers:2}" - [[ -n "$sslv2_anon_ciphers" ]] && sslv2_anon_ciphers="${sslv2_anon_ciphers:2}" - [[ -n "$sslv2_adh_ciphers" ]] && sslv2_adh_ciphers="${sslv2_adh_ciphers:2}" - [[ -n "$sslv2_exp40_ciphers" ]] && sslv2_exp40_ciphers="${sslv2_exp40_ciphers:2}" - [[ -n "$sslv2_exp56_ciphers" ]] && sslv2_exp56_ciphers="${sslv2_exp56_ciphers:2}" - [[ -n "$sslv2_exp_ciphers" ]] && sslv2_exp_ciphers="${sslv2_exp_ciphers:2}" - [[ -n "$sslv2_low_ciphers" ]] && sslv2_low_ciphers="${sslv2_low_ciphers:2}" - [[ -n "$sslv2_des_ciphers" ]] && sslv2_des_ciphers="${sslv2_des_ciphers:2}" - [[ -n "$sslv2_medium_ciphers" ]] && sslv2_medium_ciphers="${sslv2_medium_ciphers:2}" - [[ -n "$sslv2_tdes_ciphers" ]] && sslv2_tdes_ciphers="${sslv2_tdes_ciphers:2}" - [[ -n "$sslv2_high_ciphers" ]] && sslv2_high_ciphers="${sslv2_high_ciphers:2}" + if ! "$using_sockets"; then + null_ciphers=""; anon_ciphers=""; adh_ciphers=""; exp40_ciphers="" + exp56_ciphers=""; exp_ciphers=""; low_ciphers=""; des_ciphers="" + medium_ciphers=""; tdes_ciphers=""; high_ciphers="" + sslv2_null_ciphers=""; sslv2_anon_ciphers=""; sslv2_adh_ciphers=""; sslv2_exp40_ciphers="" + sslv2_exp56_ciphers=""; sslv2_exp_ciphers=""; sslv2_low_ciphers=""; sslv2_des_ciphers="" + sslv2_medium_ciphers=""; sslv2_tdes_ciphers=""; sslv2_high_ciphers="" fi outln From 0bc2b1c4bb5abd6ee340328210b82a8a90b4dfb2 Mon Sep 17 00:00:00 2001 From: David Cooper Date: Thu, 12 Jan 2017 13:17:04 -0500 Subject: [PATCH 38/61] Create static cipher lists for testssl.sh This PR adds a new utility that generates the various static cipher lists that appear in testssl.sh. This utility serves two purposes: * It can be run whenever new ciphers are added to cipher-mapping.txt to see if any of the lists in testssl.sh need to be updated. (This includes if cipher-mapping.txt is modified to add OpenSSL-style names for ciphers that are currently listed, but that have not yet been assigned such names.) * It can be used as a reference in order to understand how each of the lists is defined. --- utils/generate_static_cipher_lists.sh | 336 ++++++++++++++++++++++++++ 1 file changed, 336 insertions(+) create mode 100644 utils/generate_static_cipher_lists.sh diff --git a/utils/generate_static_cipher_lists.sh b/utils/generate_static_cipher_lists.sh new file mode 100644 index 0000000..b85914d --- /dev/null +++ b/utils/generate_static_cipher_lists.sh @@ -0,0 +1,336 @@ +#!/usr/bin/env bash +# +# vim:ts=5:sw=5:expandtab +# we have a spaces softtab, that ensures readability with other editors too + +[ -z "$BASH_VERSINFO" ] && printf "\n\033[1;35m Please make sure you're using \"bash\"! Bye...\033[m\n\n" >&2 && exit 245 +[ $(kill -l | grep -c SIG) -eq 0 ] && printf "\n\033[1;35m Please make sure you're calling me without leading \"sh\"! Bye...\033[m\n\n" >&2 && exit 245 + +# This shell script generates the various static cipher lists that are used in testssl.sh. +# It should be re-run whenever new ciphers are added to cipher-mapping.txt to determine +# whether any of the variables in testssl.sh containing cipher lists need to be updated. + +# debugging help: +readonly PS4='${LINENO}> ${FUNCNAME[0]:+${FUNCNAME[0]}(): }' + +COLOR=${COLOR:-2} # 2: Full color, 1: b/w+positioning, 0: no ESC at all +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 +CIPHERS_BY_STRENGTH_FILE="" + +###### Cipher suite information ##### +declare -i TLS_NR_CIPHERS=0 +declare TLS_CIPHER_HEXCODE=() +declare TLS_CIPHER_OSSL_NAME=() +declare TLS_CIPHER_RFC_NAME=() +declare TLS_CIPHER_SSLVERS=() +declare TLS_CIPHER_KX=() +declare TLS_CIPHER_AUTH=() +declare TLS_CIPHER_ENC=() +declare TLS_CIPHER_EXPORT=() + +###### output functions ###### +# a little bit of sanitzing with bash internal search&replace -- otherwise printf will hiccup at '%' and '--' does the rest. +out(){ +# if [[ "$BASH_VERSINFO" -eq 4 ]]; then + printf -- "%b" "${1//%/%%}" +# else +# /usr/bin/printf -- "${1//%/%%}" +# fi +} +outln() { out "$1\n"; } +pr_off() { [[ "$COLOR" -ne 0 ]] && out "\033[m"; } +pr_underline() { [[ "$COLOR" -ne 0 ]] && out "\033[4m$1" || out "$1"; pr_off; } + +if [[ $(uname) == "Linux" ]] ; then + toupper() { echo -n "${1^^}" ; } + tolower() { echo -n "${1,,}" ; } +else + toupper() { echo -n "$1" | tr 'a-z' 'A-Z'; } + tolower() { echo -n "$1" | tr 'A-Z' 'a-z' ; } +fi + +# try very hard to determine the install path to get ahold of the mapping file. +# TESTSSL_INSTALL_DIR can be supplied via environment so that the cipher mapping and CA bundles can be found +# www.carbonwind.net/TLS_Cipher_Suites_Project/tls_ssl_cipher_suites_simple_table_all.htm +get_mapping_file() { + local mac + + [[ -z "$TESTSSL_INSTALL_DIR" ]] && TESTSSL_INSTALL_DIR="$(dirname ${BASH_SOURCE[0]})" + + [[ -r "$RUN_DIR/etc/cipher-mapping.txt" ]] && CIPHERS_BY_STRENGTH_FILE="$RUN_DIR/etc/cipher-mapping.txt" + [[ -r "$RUN_DIR/../etc/cipher-mapping.txt" ]] && CIPHERS_BY_STRENGTH_FILE="$RUN_DIR/../etc/cipher-mapping.txt" + [[ -r "$TESTSSL_INSTALL_DIR/etc/cipher-mapping.txt" ]] && CIPHERS_BY_STRENGTH_FILE="$TESTSSL_INSTALL_DIR/etc/cipher-mapping.txt" + if [[ ! -r "$CIPHERS_BY_STRENGTH_FILE" ]]; then + [[ -r "$RUN_DIR/cipher-mapping.txt" ]] && CIPHERS_BY_STRENGTH_FILE="$RUN_DIR/cipher-mapping.txt" + [[ -r "$TESTSSL_INSTALL_DIR/cipher-mapping.txt" ]] && CIPHERS_BY_STRENGTH_FILE="$TESTSSL_INSTALL_DIR/cipher-mapping.txt" + fi + + # we haven't found the cipher file yet... + if [[ ! -r "$CIPHERS_BY_STRENGTH_FILE" ]] && which readlink &>/dev/null ; then + readlink -f ls &>/dev/null && \ + TESTSSL_INSTALL_DIR=$(readlink -f $(basename ${BASH_SOURCE[0]})) || \ + TESTSSL_INSTALL_DIR=$(readlink $(basename ${BASH_SOURCE[0]})) + # not sure whether Darwin has -f + TESTSSL_INSTALL_DIR=$(dirname $TESTSSL_INSTALL_DIR 2>/dev/null) + [[ -r "$TESTSSL_INSTALL_DIR/cipher-mapping.txt" ]] && CIPHERS_BY_STRENGTH_FILE="$TESTSSL_INSTALL_DIR/cipher-mapping.txt" + [[ -r "$TESTSSL_INSTALL_DIR/etc/cipher-mapping.txt" ]] && CIPHERS_BY_STRENGTH_FILE="$TESTSSL_INSTALL_DIR/etc/cipher-mapping.txt" + fi + + # still no cipher mapping file: + if [[ ! -r "$CIPHERS_BY_STRENGTH_FILE" ]] && which realpath &>/dev/null ; then + TESTSSL_INSTALL_DIR=$(dirname $(realpath ${BASH_SOURCE[0]})) + CIPHERS_BY_STRENGTH_FILE="$TESTSSL_INSTALL_DIR/etc/cipher-mapping.txt" + [[ -r "$TESTSSL_INSTALL_DIR/cipher-mapping.txt" ]] && CIPHERS_BY_STRENGTH_FILE="$TESTSSL_INSTALL_DIR/cipher-mapping.txt" + fi + + # still no cipher mapping file (and realpath is not present): + if [[ ! -r "$CIPHERS_BY_STRENGTH_FILE" ]] && which readlink &>/dev/null ; then + readlink -f ls &>/dev/null && \ + TESTSSL_INSTALL_DIR=$(dirname $(readlink -f ${BASH_SOURCE[0]})) || \ + TESTSSL_INSTALL_DIR=$(dirname $(readlink ${BASH_SOURCE[0]})) + # not sure whether Darwin has -f + CIPHERS_BY_STRENGTH_FILE="$TESTSSL_INSTALL_DIR/etc/cipher-mapping.txt" + [[ -r "$TESTSSL_INSTALL_DIR/cipher-mapping.txt" ]] && CIPHERS_BY_STRENGTH_FILE="$TESTSSL_INSTALL_DIR/cipher-mapping.txt" + fi + + if [[ ! -r "$CIPHERS_BY_STRENGTH_FILE" ]] ; then + outln "\nATTENTION: No cipher mapping file found!" + exit -2 + fi + + while read TLS_CIPHER_HEXCODE[TLS_NR_CIPHERS] n TLS_CIPHER_OSSL_NAME[TLS_NR_CIPHERS] TLS_CIPHER_RFC_NAME[TLS_NR_CIPHERS] TLS_CIPHER_SSLVERS[TLS_NR_CIPHERS] TLS_CIPHER_KX[TLS_NR_CIPHERS] TLS_CIPHER_AUTH[TLS_NR_CIPHERS] TLS_CIPHER_ENC[TLS_NR_CIPHERS] mac TLS_CIPHER_EXPORT[TLS_NR_CIPHERS]; do + TLS_NR_CIPHERS+=1 + done < $CIPHERS_BY_STRENGTH_FILE +} + +get_robust_pfs_ciphers() { + local -i i + local pfs_cipher hexc pfs_cipher_list="" pfs_hex_cipher_list="" + + for (( i=0; i < TLS_NR_CIPHERS; i++ )); do + pfs_cipher="${TLS_CIPHER_RFC_NAME[i]}" + if ( [[ "$pfs_cipher" == "TLS_DHE_"* ]] || [[ "$pfs_cipher" == "TLS_ECDHE_"* ]] ) && \ + [[ ! "$pfs_cipher" =~ "NULL" ]] && [[ ! "$pfs_cipher" =~ "DES" ]] && [[ ! "$pfs_cipher" =~ "RC4" ]] && \ + [[ ! "$pfs_cipher" =~ "PSK" ]]; then + hexc="${TLS_CIPHER_HEXCODE[i]}" + pfs_hex_cipher_list+=", ${hexc:2:2},${hexc:7:2}" + [[ "${TLS_CIPHER_OSSL_NAME[i]}" != "-" ]] && pfs_cipher_list+=":${TLS_CIPHER_OSSL_NAME[i]}" + fi + done + outln ; pr_underline "Robust PFS Cipher Lists for SSLv3 - TLSv1.2" ; outln + echo "ROBUST_PFS_CIPHERS=\"${pfs_cipher_list:1}\"" + echo "ROBUST_PFS_CIPHERS_HEX=\"$(tolower "${pfs_hex_cipher_list:2}")\"" +} + +get_std_cipherlists() { + local hexc hexcode strength + local -i i + local null_ciphers="" anon_ciphers="" adh_ciphers="" exp40_ciphers="" + local exp56_ciphers="" exp_ciphers="" low_ciphers="" des_ciphers="" + local medium_ciphers="" tdes_ciphers="" high_ciphers="" + local sslv2_null_ciphers="" sslv2_anon_ciphers="" sslv2_adh_ciphers="" sslv2_exp40_ciphers="" + local sslv2_exp56_ciphers="" sslv2_exp_ciphers="" sslv2_low_ciphers="" sslv2_des_ciphers="" + local sslv2_medium_ciphers="" sslv2_tdes_ciphers="" sslv2_high_ciphers="" + local using_sockets=true + + for (( i=0; i < TLS_NR_CIPHERS; i++ )); do + hexc="${TLS_CIPHER_HEXCODE[i]}" + strength="${TLS_CIPHER_ENC[i]}" + strength="${strength//\)/}" + strength="${strength#*\(}" + + if [[ ${#hexc} -eq 9 ]]; then + hexcode="${hexc:2:2},${hexc:7:2}" + [[ "${TLS_CIPHER_ENC[i]}" == "Enc=None" ]] && \ + null_ciphers+=", $hexcode" + [[ "${TLS_CIPHER_AUTH[i]}" == "Au=None" ]] && \ + anon_ciphers+=", $hexcode" + [[ "${TLS_CIPHER_RFC_NAME[i]}" =~ "TLS_DH_anon_" ]] && \ + adh_ciphers+=", $hexcode" + [[ $strength -eq 40 ]] && exp40_ciphers+=", $hexcode" +# [[ $strength -eq 56 ]] && exp56_ciphers+=", $hexcode" + [[ $strength -eq 56 ]] && \ + [[ "${TLS_CIPHER_EXPORT[i]}" == "export" ]] && \ + exp56_ciphers+=", $hexcode" + [[ "${TLS_CIPHER_EXPORT[i]}" == "export" ]] && \ + exp_ciphers+=", $hexcode" + if [[ "${TLS_CIPHER_AUTH[i]}" != "Au=None" ]]; then +# [[ $strength -le 64 ]] && low_ciphers+=", $hexcode" + [[ "${TLS_CIPHER_ENC[i]}" != "Enc=None" ]] && \ + [[ $strength -le 64 ]] && \ + [[ "${TLS_CIPHER_EXPORT[i]}" != "export" ]] && \ + low_ciphers+=", $hexcode" + [[ "${TLS_CIPHER_ENC[i]}" == "Enc=DES(56)" ]] && \ + [[ "${TLS_CIPHER_EXPORT[i]}" != "export" ]] && \ + des_ciphers+=", $hexcode" + [[ "${TLS_CIPHER_ENC[i]}" == "Enc=SEED(128)" ]] && \ + medium_ciphers+=", $hexcode" + [[ "${TLS_CIPHER_ENC[i]}" == "Enc=RC4(128)" ]] && \ + medium_ciphers+=", $hexcode" + [[ "${TLS_CIPHER_ENC[i]}" == "Enc=IDEA(128)" ]] && \ + medium_ciphers+=", $hexcode" + [[ "${TLS_CIPHER_ENC[i]}" == "Enc=3DES(168)" ]] && \ + tdes_ciphers+=", $hexcode" + [[ "${TLS_CIPHER_ENC[i]}" == "Enc=AES"* ]] && \ + high_ciphers+=", $hexcode" + [[ "${TLS_CIPHER_ENC[i]}" == "Enc=Camellia"* ]] && \ + high_ciphers+=", $hexcode" + [[ "${TLS_CIPHER_ENC[i]}" == "Enc=ChaCha20"* ]] && \ + high_ciphers+=", $hexcode" + [[ "${TLS_CIPHER_ENC[i]}" == "Enc=GOST"* ]] && \ + high_ciphers+=", $hexcode" + [[ "${TLS_CIPHER_ENC[i]}" == "Enc=ARIA"* ]] && \ + high_ciphers+=", $hexcode" + fi + else + hexcode="${hexc:2:2},${hexc:7:2},${hexc:12:2}" + [[ $strength -eq 40 ]] && sslv2_exp40_ciphers+=", $hexcode" +# [[ $strength -eq 56 ]] && sslv2_exp56_ciphers+=", $hexcode" + [[ "${TLS_CIPHER_EXPORT[i]}" == "export" ]] && \ + sslv2_exp_ciphers+=", $hexcode" +# [[ $strength -le 64 ]] && sslv2_low_ciphers+=", $hexcode" + [[ $strength -le 64 ]] && \ + [[ "${TLS_CIPHER_EXPORT[i]}" != "export" ]] && \ + sslv2_low_ciphers+=", $hexcode" + [[ "${TLS_CIPHER_ENC[i]}" == "Enc=DES(56)" ]] && \ + sslv2_des_ciphers+=", $hexcode" + [[ "${TLS_CIPHER_ENC[i]}" == "Enc=3DES(168)" ]] && \ + sslv2_tdes_ciphers+=", $hexcode" + fi + done + [[ -n "$null_ciphers" ]] && null_ciphers="${null_ciphers:2}, 00,ff" + [[ -n "$anon_ciphers" ]] && anon_ciphers="${anon_ciphers:2}, 00,ff" + [[ -n "$adh_ciphers" ]] && adh_ciphers="${adh_ciphers:2}, 00,ff" + [[ -n "$exp40_ciphers" ]] && exp40_ciphers="${exp40_ciphers:2}, 00,ff" + [[ -n "$exp56_ciphers" ]] && exp56_ciphers="${exp56_ciphers:2}, 00,ff" + [[ -n "$exp_ciphers" ]] && exp_ciphers="${exp_ciphers:2}, 00,ff" + [[ -n "$low_ciphers" ]] && low_ciphers="${low_ciphers:2}, 00,ff" + [[ -n "$des_ciphers" ]] && des_ciphers="${des_ciphers:2}, 00,ff" + [[ -n "$medium_ciphers" ]] && medium_ciphers="${medium_ciphers:2}, 00,ff" + [[ -n "$tdes_ciphers" ]] && tdes_ciphers="${tdes_ciphers:2}, 00,ff" + [[ -n "$high_ciphers" ]] && high_ciphers="${high_ciphers:2}, 00,ff" + [[ -n "$sslv2_null_ciphers" ]] && sslv2_null_ciphers="${sslv2_null_ciphers:2}" + [[ -n "$sslv2_anon_ciphers" ]] && sslv2_anon_ciphers="${sslv2_anon_ciphers:2}" + [[ -n "$sslv2_adh_ciphers" ]] && sslv2_adh_ciphers="${sslv2_adh_ciphers:2}" + [[ -n "$sslv2_exp40_ciphers" ]] && sslv2_exp40_ciphers="${sslv2_exp40_ciphers:2}" + [[ -n "$sslv2_exp56_ciphers" ]] && sslv2_exp56_ciphers="${sslv2_exp56_ciphers:2}" + [[ -n "$sslv2_exp_ciphers" ]] && sslv2_exp_ciphers="${sslv2_exp_ciphers:2}" + [[ -n "$sslv2_low_ciphers" ]] && sslv2_low_ciphers="${sslv2_low_ciphers:2}" + [[ -n "$sslv2_des_ciphers" ]] && sslv2_des_ciphers="${sslv2_des_ciphers:2}" + [[ -n "$sslv2_medium_ciphers" ]] && sslv2_medium_ciphers="${sslv2_medium_ciphers:2}" + [[ -n "$sslv2_tdes_ciphers" ]] && sslv2_tdes_ciphers="${sslv2_tdes_ciphers:2}" + [[ -n "$sslv2_high_ciphers" ]] && sslv2_high_ciphers="${sslv2_high_ciphers:2}" + + outln ; pr_underline "Cipher lists for run_std_cipherlists()"; outln + outln "null_ciphers=\"$(tolower "$null_ciphers")\"" + outln "sslv2_null_ciphers=\"$(tolower "$sslv2_null_ciphers")\"" + outln "anon_ciphers=\"$(tolower "$anon_ciphers")\"" + outln "sslv2_anon_ciphers=\"$(tolower "$sslv2_anon_ciphers")\"" + outln "adh_ciphers=\"$(tolower "$adh_ciphers")\"" + outln "sslv2_adh_ciphers=\"$(tolower "$sslv2_adh_ciphers")\"" + outln exp40_ciphers"=\"$(tolower "$exp40_ciphers")\"" + outln "sslv2_exp40_ciphers=\"$(tolower "$sslv2_exp40_ciphers")\"" + outln "exp56_ciphers=\"$(tolower "$exp56_ciphers")\"" + outln "sslv2_exp56_ciphers=\"$(tolower "$sslv2_exp56_ciphers")\"" + outln "exp_ciphers=\"$(tolower "$exp_ciphers")\"" + outln "sslv2_exp_ciphers=\"$(tolower "$sslv2_exp_ciphers")\"" + outln "low_ciphers=\"$(tolower "$low_ciphers")\"" + outln "sslv2_low_ciphers=\"$(tolower "$sslv2_low_ciphers")\"" + outln "des_ciphers=\"$(tolower "$des_ciphers")\"" + outln "sslv2_des_ciphers=\"$(tolower "$sslv2_des_ciphers")\"" + outln "medium_ciphers=\"$(tolower "$medium_ciphers")\"" + outln "sslv2_medium_ciphers=\"$(tolower "$sslv2_medium_ciphers")\"" + outln "tdes_ciphers=\"$(tolower "$tdes_ciphers")\"" + outln "sslv2_tdes_ciphers=\"$(tolower "$sslv2_tdes_ciphers")\"" + outln "high_ciphers=\"$(tolower "$high_ciphers")\"" + outln "sslv2_high_ciphers=\"$(tolower "$sslv2_high_ciphers")\"" +} + +get_cbc_ciphers() { + local -i + local hexc cbc_cipher_list="" cbc_cipher_list_hex="" + + # Want to keep ciphers lists to under 128 ciphers. Since there are a number of CBC ciphers + # that do not currently have OpenSSL names, the ciphers with Null authentication can be + # included in the OpenSSL list, but need to be excluded from the hex list. + for (( i=0; i < TLS_NR_CIPHERS; i++ )); do + if [[ "${TLS_CIPHER_SSLVERS[i]}" != "SSLv2" ]] && [[ "${TLS_CIPHER_RFC_NAME[i]}" =~ CBC ]] && \ + [[ ! "${TLS_CIPHER_RFC_NAME[i]}" =~ PSK ]] && [[ ! "${TLS_CIPHER_RFC_NAME[i]}" =~ SRP ]] && \ + [[ ! "${TLS_CIPHER_RFC_NAME[i]}" =~ KRB5 ]]; then + hexc="${TLS_CIPHER_HEXCODE[i]}" + [[ "${TLS_CIPHER_AUTH[i]}" != "Au=None" ]] && cbc_cipher_list_hex+=", ${hexc:2:2},${hexc:7:2}" + [[ "${TLS_CIPHER_OSSL_NAME[i]}" != "-" ]] && cbc_cipher_list+=":${TLS_CIPHER_OSSL_NAME[i]}" + fi + done + + outln ; pr_underline "CBC Ciphers for determine_tls_extensions()"; outln + outln "cbc_cipher_list=\"${cbc_cipher_list:1}\"" + outln "cbc_cipher_list_hex=\"$(tolower "${cbc_cipher_list_hex:2}")\"" +} + +get_sslv3_tls1_cbc_ciphers() { + local -i + local hexc cbc_ciphers="" cbc_ciphers_hex="" + + for (( i=0; i < TLS_NR_CIPHERS; i++ )); do + if [[ "${TLS_CIPHER_SSLVERS[i]}" != "SSLv2" ]] && [[ "${TLS_CIPHER_RFC_NAME[i]}" =~ CBC ]] && \ + [[ "${TLS_CIPHER_RFC_NAME[i]}" != *SHA256 ]] && [[ "${TLS_CIPHER_RFC_NAME[i]}" != *SHA384 ]]; then + hexc="${TLS_CIPHER_HEXCODE[i]}" + cbc_ciphers_hex+=", ${hexc:2:2},${hexc:7:2}" + [[ "${TLS_CIPHER_OSSL_NAME[i]}" != "-" ]] && cbc_ciphers+=":${TLS_CIPHER_OSSL_NAME[i]}" + fi + done + + outln ; pr_underline "SSLv3/TLSv1.0 CBC Ciphers for run_ssl_poodle() and run_beast()"; outln + outln "cbc_ciphers=\"${cbc_ciphers:1}\"" + outln "cbc_ciphers_hex=\"$(tolower "${cbc_ciphers_hex:2}")\"" +} + +get_export_rsa_ciphers() { + local -i i + local exportrsa_cipher_list="" exportrsa_tls_cipher_list_hex="" exportrsa_ssl2_cipher_list_hex="" + + for (( i=0; i < TLS_NR_CIPHERS; i++ )); do + if [[ "${TLS_CIPHER_EXPORT[i]}" == "export" ]] && \ + ( [[ "${TLS_CIPHER_KX[i]}" =~ RSA ]] || [[ "${TLS_CIPHER_AUTH[i]}" =~ RSA ]] ); then + hexc="${TLS_CIPHER_HEXCODE[i]}" + [[ "${TLS_CIPHER_SSLVERS[i]}" == "SSLv2" ]] && exportrsa_ssl2_cipher_list_hex+=", ${hexc:2:2},${hexc:7:2},${hexc:12:2}" + [[ "${TLS_CIPHER_SSLVERS[i]}" != "SSLv2" ]] && exportrsa_tls_cipher_list_hex+=", ${hexc:2:2},${hexc:7:2}" + [[ ! ":${exportrsa_cipher_list}:" =~ "${TLS_CIPHER_OSSL_NAME[i]}" ]] && exportrsa_cipher_list+=":${TLS_CIPHER_OSSL_NAME[i]}" + fi + done + + outln ; pr_underline "Export RSA ciphers for run_freak()"; outln + outln "exportrsa_cipher_list=\"${exportrsa_cipher_list:1}\"" + outln "exportrsa_tls_cipher_list_hex=\"${exportrsa_tls_cipher_list_hex:2}\"" + outln "exportrsa_ssl2_cipher_list_hex=\"${exportrsa_ssl2_cipher_list_hex:2}\"" +} + +get_weak_dh_ciphers() { + local -i + local hexc exportdhe_cipher_list="" exportdhe_cipher_list_hex="" + + for (( i=0; i < TLS_NR_CIPHERS; i++ )); do + if [[ "${TLS_CIPHER_RFC_NAME[i]}" == "TLS_DHE_"* ]] && [[ "${TLS_CIPHER_EXPORT[i]}" == "export" ]]; then + hexc="${TLS_CIPHER_HEXCODE[i]}" + [[ "${TLS_CIPHER_OSSL_NAME[i]}" != "-" ]] && exportdhe_cipher_list+=":${TLS_CIPHER_OSSL_NAME[i]}" + exportdhe_cipher_list_hex+=", ${hexc:2:2},${hexc:7:2}" + fi + done + + outln; pr_underline "Weak DH ciphers for run_logjam()"; outln + outln "exportdhe_cipher_list=\"${exportdhe_cipher_list:1}\"" + outln "exportdhe_cipher_list_hex=\"${exportdhe_cipher_list_hex:2}\"" +} + +get_mapping_file +get_robust_pfs_ciphers +get_std_cipherlists +get_cbc_ciphers +get_sslv3_tls1_cbc_ciphers +get_export_rsa_ciphers +get_weak_dh_ciphers +outln + +exit $? From 1a705f900fc7090723942008d7ca4dcef3a61d55 Mon Sep 17 00:00:00 2001 From: David Cooper Date: Thu, 12 Jan 2017 14:59:29 -0500 Subject: [PATCH 39/61] run_client_simulation() bugfix There are two places in `run_client_simulation()` in which `$OPENSSL s_client` is called, after which there is a `debugme echo` line to display the `$OPENSSL s_client` command line when testssl.sh is being run in debug mode, and then `sclient_connect_successful $? $TMPFILE` is called to determine whether `$OPENSSL s_client` successfully established a connection. So, `sclient_connect_successful()` is being passed the result of the `debugme()` call, which always returns 0, rather than the result of the `$OPENSSL s_client` call. This PR fixes the problem by moving the `debugme()` line to before the call to `$OPENSSL s_client`, so that `sclient_connect_successful()` is passed the results of the `$OPENSSL s_client` call. --- testssl.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/testssl.sh b/testssl.sh index 063785c..1227b17 100755 --- a/testssl.sh +++ b/testssl.sh @@ -3991,8 +3991,8 @@ run_client_simulation() { fi else ! "$HAS_NO_SSL2" && protos[i]="$(sed 's/-no_ssl2//' <<< "${protos[i]}")" - $OPENSSL s_client -cipher ${ciphers[i]} ${protos[i]} $STARTTLS $BUGS $PROXY -connect $NODEIP:$PORT ${sni[i]} $TMPFILE 2>$ERRFILE debugme echo "$OPENSSL s_client -cipher ${ciphers[i]} ${protos[i]} $STARTTLS $BUGS $PROXY -connect $NODEIP:$PORT ${sni[i]} $TMPFILE 2>$ERRFILE sclient_connect_successful $? $TMPFILE sclient_success=$? fi @@ -4018,8 +4018,8 @@ run_client_simulation() { if [[ "$proto" == TLSv1.2 ]] && ( ! "$using_sockets" || [[ -z "${handshakebytes[i]}" ]] ); then # OpenSSL reports TLS1.2 even if the connection is TLS1.1 or TLS1.0. Need to figure out which one it is... for tls in ${tlsvers[i]}; do - $OPENSSL s_client $tls -cipher ${ciphers[i]} ${protos[i]} $STARTTLS $BUGS $PROXY -connect $NODEIP:$PORT ${sni[i]} $TMPFILE 2>$ERRFILE debugme echo "$OPENSSL s_client $tls -cipher ${ciphers[i]} ${protos[i]} $STARTTLS $BUGS $PROXY -connect $NODEIP:$PORT ${sni[i]} $TMPFILE 2>$ERRFILE sclient_connect_successful $? $TMPFILE sclient_success=$? if [[ $sclient_success -eq 0 ]]; then From 42da64d601d5059836689ecbb39a8cb6705dd02f Mon Sep 17 00:00:00 2001 From: David Cooper Date: Fri, 13 Jan 2017 10:28:48 -0500 Subject: [PATCH 40/61] Show selected curve This PR changes `read_dhbits_from_file()` so that, when the "quiet" parameter is absent, the selected curve is shown in addition to the number of bits. This PR only affects the output of `run_client_simulation()` and the `Negotiated cipher` in `run_server_preference()`. --- testssl.sh | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/testssl.sh b/testssl.sh index 9ec0d6e..6349037 100755 --- a/testssl.sh +++ b/testssl.sh @@ -4498,7 +4498,7 @@ run_std_cipherlists() { # arg1: file with input for grepping the bit length for ECDH/DHE # arg2: whether to print warning "old fart" or not (empty: no) read_dhbits_from_file() { - local bits what_dh temp + local bits what_dh temp curve="" local add="" local old_fart=" (openssl cannot show DH bits)" @@ -4506,14 +4506,23 @@ read_dhbits_from_file() { what_dh=$(awk -F',' '{ print $1 }' <<< $temp) bits=$(awk -F',' '{ print $3 }' <<< $temp) # RH's backport has the DH bits in second arg after comma - grep -q bits <<< $bits || bits=$(awk -F',' '{ print $2 }' <<< $temp) + if grep -q bits <<< $bits; then + curve="$(strip_spaces "$(awk -F',' '{ print $2 }' <<< $temp)")" + else + bits=$(awk -F',' '{ print $2 }' <<< $temp) + fi bits=$(tr -d ' bits' <<< $bits) if [[ "$what_dh" == "X25519" ]] || [[ "$what_dh" == "X448" ]]; then + curve="$what_dh" what_dh="ECDH" fi - debugme echo ">$HAS_DH_BITS|$what_dh|$bits<" + if [[ -n "$curve" ]]; then + debugme echo ">$HAS_DH_BITS|$what_dh($curve)|$bits<" + else + debugme echo ">$HAS_DH_BITS|$what_dh|$bits<" + fi [[ -n "$what_dh" ]] && HAS_DH_BITS=true # FIX 190 if [[ -z "$what_dh" ]] && ! "$HAS_DH_BITS"; then @@ -4525,7 +4534,10 @@ read_dhbits_from_file() { [[ -n "$bits" ]] && [[ -z "$2" ]] && out ", " if [[ $what_dh == "DH" ]] || [[ $what_dh == "EDH" ]]; then - [[ -z "$2" ]] && add="bit DH" + if [[ -z "$2" ]]; then + add="bit DH" + [[ -n "$curve" ]] && add+=" ($curve)" + fi if [[ "$bits" -le 600 ]]; then pr_svrty_critical "$bits $add" elif [[ "$bits" -le 800 ]]; then @@ -4539,7 +4551,10 @@ read_dhbits_from_file() { fi # https://wiki.openssl.org/index.php/Elliptic_Curve_Cryptography, http://www.keylength.com/en/compare/ elif [[ $what_dh == "ECDH" ]]; then - [[ -z "$2" ]] && add="bit ECDH" + if [[ -z "$2" ]]; then + add="bit ECDH" + [[ -n "$curve" ]] && add+=" ($curve)" + fi if [[ "$bits" -le 80 ]]; then # has that ever existed? pr_svrty_critical "$bits $add" elif [[ "$bits" -le 108 ]]; then # has that ever existed? From 91e0da3485d8ad1ebaf8edeafbaf29241aad9e04 Mon Sep 17 00:00:00 2001 From: David Cooper Date: Fri, 13 Jan 2017 12:13:20 -0500 Subject: [PATCH 41/61] Detect support for encrypt-then-mac extension In some cases, the "TLS extensions" line output for the "--server-defaults" option will not show `"encrypt-then-mac/#22"` even if the server supports this extension. The reason is that a server will only include this extension in the ServerHello message if it supports the extension and the selected cipher is a CBC cipher. So, if `determine_tls_extensions()` connects to the server with a non-CBC cipher, then it will not detect if the server supports the encrypt-then-mac extension. It is possible that support for the extension will be detected by `get_server_certificate()`, but only if one of the calls to that function results in a CBC cipher being selected and OpenSSL 1.1.0 is being used (as prior versions did not support the encrypt-then-mac extension). In this PR, if `determine_tls_extensions()` is called and `$TLS_EXTENSIONS` does not already contain `"encrypt-then-mac/#22"`, then an attempt will be made to connect to the server with only CBC ciphers specified in the ClientHello. If the connection is not successful (presumably because the server does not support any CBC ciphers), then a second connection attempt will be made with the "default" ciphers being specified in the ClientHello. en.wikipedia.org is an example of a server that supports the encrypt-then-mac extension, but for which the support is not currently detected (unless OpenSSL 1.1.0 is used) since in the call to `determine_tls_extension()` a non-CBC cipher is selected. --- testssl.sh | 33 ++++++++++++++++++++++++--------- 1 file changed, 24 insertions(+), 9 deletions(-) diff --git a/testssl.sh b/testssl.sh index 9ec0d6e..92fb2b9 100755 --- a/testssl.sh +++ b/testssl.sh @@ -5165,16 +5165,19 @@ sclient_connect_successful() { # ALPN extensions in the same ServerHello. determine_tls_extensions() { local addcmd - local -i success + local -i success=1 local line params="" tls_extensions="" local alpn_proto alpn="" alpn_list_len_hex alpn_extn_len_hex local -i alpn_list_len alpn_extn_len + local cbc_cipher_list="ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA256:DH-RSA-AES256-SHA256:DH-DSS-AES256-SHA256:DHE-RSA-AES256-SHA:DHE-DSS-AES256-SHA:DH-RSA-AES256-SHA:DH-DSS-AES256-SHA:ECDHE-RSA-CAMELLIA256-SHA384:ECDHE-ECDSA-CAMELLIA256-SHA384:DHE-RSA-CAMELLIA256-SHA256:DHE-DSS-CAMELLIA256-SHA256:DH-RSA-CAMELLIA256-SHA256:DH-DSS-CAMELLIA256-SHA256:DHE-RSA-CAMELLIA256-SHA:DHE-DSS-CAMELLIA256-SHA:DH-RSA-CAMELLIA256-SHA:DH-DSS-CAMELLIA256-SHA:ECDH-RSA-AES256-SHA384:ECDH-ECDSA-AES256-SHA384:ECDH-RSA-AES256-SHA:ECDH-ECDSA-AES256-SHA:ECDH-RSA-CAMELLIA256-SHA384:ECDH-ECDSA-CAMELLIA256-SHA384:AES256-SHA256:AES256-SHA:CAMELLIA256-SHA256:CAMELLIA256-SHA:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:DHE-RSA-AES128-SHA256:DHE-DSS-AES128-SHA256:DH-RSA-AES128-SHA256:DH-DSS-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA:DH-RSA-AES128-SHA:DH-DSS-AES128-SHA:ECDHE-RSA-CAMELLIA128-SHA256:ECDHE-ECDSA-CAMELLIA128-SHA256:DHE-RSA-CAMELLIA128-SHA256:DHE-DSS-CAMELLIA128-SHA256:DH-RSA-CAMELLIA128-SHA256:DH-DSS-CAMELLIA128-SHA256:DHE-RSA-SEED-SHA:DHE-DSS-SEED-SHA:DH-RSA-SEED-SHA:DH-DSS-SEED-SHA:DHE-RSA-CAMELLIA128-SHA:DHE-DSS-CAMELLIA128-SHA:DH-RSA-CAMELLIA128-SHA:DH-DSS-CAMELLIA128-SHA:ECDH-RSA-AES128-SHA256:ECDH-ECDSA-AES128-SHA256:ECDH-RSA-AES128-SHA:ECDH-ECDSA-AES128-SHA:ECDH-RSA-CAMELLIA128-SHA256:ECDH-ECDSA-CAMELLIA128-SHA256:AES128-SHA256:AES128-SHA:CAMELLIA128-SHA256:SEED-SHA:CAMELLIA128-SHA:IDEA-CBC-SHA:ECDHE-RSA-DES-CBC3-SHA:ECDHE-ECDSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:EDH-DSS-DES-CBC3-SHA:DH-RSA-DES-CBC3-SHA:DH-DSS-DES-CBC3-SHA:ECDH-RSA-DES-CBC3-SHA:ECDH-ECDSA-DES-CBC3-SHA:DES-CBC3-SHA:EXP1024-DHE-DSS-DES-CBC-SHA:EDH-RSA-DES-CBC-SHA:EDH-DSS-DES-CBC-SHA:DH-RSA-DES-CBC-SHA:DH-DSS-DES-CBC-SHA:EXP1024-DES-CBC-SHA:DES-CBC-SHA:EXP-EDH-RSA-DES-CBC-SHA:EXP-EDH-DSS-DES-CBC-SHA:EXP-DES-CBC-SHA:EXP-RC2-CBC-MD5:EXP-DH-DSS-DES-CBC-SHA:EXP-DH-RSA-DES-CBC-SHA" + local cbc_cipher_list_hex="c0,28, c0,24, c0,14, c0,0a, 00,6b, 00,6a, 00,69, 00,68, 00,39, 00,38, 00,37, 00,36, c0,77, c0,73, 00,c4, 00,c3, 00,c2, 00,c1, 00,88, 00,87, 00,86, 00,85, c0,2a, c0,26, c0,0f, c0,05, c0,79, c0,75, 00,3d, 00,35, 00,c0, 00,84, c0,3d, c0,3f, c0,41, c0,43, c0,45, c0,49, c0,4b, c0,4d, c0,4f, c0,27, c0,23, c0,13, c0,09, 00,67, 00,40, 00,3f, 00,3e, 00,33, 00,32, 00,31, 00,30, c0,76, c0,72, 00,be, 00,bd, 00,bc, 00,bb, 00,9a, 00,99, 00,98, 00,97, 00,45, 00,44, 00,43, 00,42, c0,29, c0,25, c0,0e, c0,04, c0,78, c0,74, 00,3c, 00,2f, 00,ba, 00,96, 00,41, 00,07, c0,3c, c0,3e, c0,40, c0,42, c0,44, c0,48, c0,4a, c0,4c, c0,4e, c0,12, c0,08, 00,16, 00,13, 00,10, 00,0d, c0,0d, c0,03, 00,0a, fe,ff, ff,e0, 00,63, 00,15, 00,12, 00,0f, 00,0c, 00,62, 00,09, fe,fe, ff,e1, 00,14, 00,11, 00,08, 00,06, 00,0b, 00,0e" local using_sockets=true [[ "$OPTIMAL_PROTO" == "-ssl2" ]] && return 0 "$SSL_NATIVE" && using_sockets=false if "$using_sockets"; then + tls_extensions="00,01,00,01,02, 00,02,00,00, 00,04,00,00, 00,12,00,00, 00,16,00,00, 00,17,00,00" if [[ -z $STARTTLS ]]; then for alpn_proto in $ALPN_PROTOs; do alpn+=",$(printf "%02x" ${#alpn_proto}),$(string_to_asciihex "$alpn_proto")" @@ -5183,11 +5186,16 @@ determine_tls_extensions() { alpn_list_len_hex=$(printf "%04x" $alpn_list_len) alpn_extn_len=$alpn_list_len+2 alpn_extn_len_hex=$(printf "%04x" $alpn_extn_len) - tls_sockets "03" "$TLS12_CIPHER" "all" "00,01,00,01,02, 00,02,00,00, 00,04,00,00, 00,12,00,00, 00,16,00,00, 00,17,00,00, 00,10,${alpn_extn_len_hex:0:2},${alpn_extn_len_hex:2:2},${alpn_list_len_hex:0:2},${alpn_list_len_hex:2:2}$alpn" - else - tls_sockets "03" "$TLS12_CIPHER" "all" "00,01,00,01,02, 00,02,00,00, 00,04,00,00, 00,12,00,00, 00,16,00,00, 00,17,00,00" + tls_extensions+=", 00,10,${alpn_extn_len_hex:0:2},${alpn_extn_len_hex:2:2},${alpn_list_len_hex:0:2},${alpn_list_len_hex:2:2}$alpn" + fi + if [[ ! "$TLS_EXTENSIONS" =~ "encrypt-then-mac" ]]; then + tls_sockets "03" "$cbc_cipher_list_hex, 00,ff" "all" "$tls_extensions" + success=$? + fi + if [[ $success -ne 0 ]] && [[ $success -ne 2 ]]; then + tls_sockets "03" "$TLS12_CIPHER" "all" "$tls_extensions" + success=$? fi - success=$? [[ $success -eq 2 ]] && success=0 [[ $success -eq 0 ]] && tls_extensions="$(grep -a 'TLS Extensions: ' "$TEMPDIR/$NODEIP.parse_tls_serverhello.txt" | sed 's/TLS Extensions: //' )" if [[ -r "$TEMPDIR/$NODEIP.parse_tls_serverhello.txt" ]]; then @@ -5200,16 +5208,23 @@ determine_tls_extensions() { elif "$HAS_SPDY" && [[ -z $STARTTLS ]]; then params="-nextprotoneg \"$NPN_PROTOs\"" fi - success=1 addcmd="" if [[ -z "$OPTIMAL_PROTO" ]] && [[ -z "$SNI" ]] && "$HAS_NO_SSL2"; then addcmd="-no_ssl2" elif [[ ! "$OPTIMAL_PROTO" =~ ssl ]]; then addcmd="$SNI" fi - $OPENSSL s_client $STARTTLS $BUGS -connect $NODEIP:$PORT $PROXY $addcmd $OPTIMAL_PROTO -tlsextdebug $params $ERRFILE >$TMPFILE - sclient_connect_successful $? $TMPFILE - if [[ $? -eq 0 ]]; then + if [[ ! "$TLS_EXTENSIONS" =~ "encrypt-then-mac" ]]; then + $OPENSSL s_client $STARTTLS $BUGS -connect $NODEIP:$PORT $PROXY $addcmd $OPTIMAL_PROTO -tlsextdebug $params -cipher $cbc_cipher_list $ERRFILE >$TMPFILE + sclient_connect_successful $? $TMPFILE + success=$? + fi + if [[ $success -ne 0 ]]; then + $OPENSSL s_client $STARTTLS $BUGS -connect $NODEIP:$PORT $PROXY $addcmd $OPTIMAL_PROTO -tlsextdebug $params $ERRFILE >$TMPFILE + sclient_connect_successful $? $TMPFILE + success=$? + fi + if [[ $success -eq 0 ]]; then success=0 tls_extensions=$(grep -a 'TLS server extension ' $TMPFILE | sed -e 's/TLS server extension //g' -e 's/\" (id=/\/#/g' -e 's/,.*$/,/g' -e 's/),$/\"/g') tls_extensions=$(echo $tls_extensions) # into one line From c5dcaf476f20414e44fac32408804a84ef7c3edc Mon Sep 17 00:00:00 2001 From: David Cooper Date: Fri, 13 Jan 2017 12:18:32 -0500 Subject: [PATCH 42/61] Remove redundant setting to success to 0 --- testssl.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/testssl.sh b/testssl.sh index 92fb2b9..f110a1d 100755 --- a/testssl.sh +++ b/testssl.sh @@ -5225,7 +5225,6 @@ determine_tls_extensions() { success=$? fi if [[ $success -eq 0 ]]; then - success=0 tls_extensions=$(grep -a 'TLS server extension ' $TMPFILE | sed -e 's/TLS server extension //g' -e 's/\" (id=/\/#/g' -e 's/,.*$/,/g' -e 's/),$/\"/g') tls_extensions=$(echo $tls_extensions) # into one line fi From cdbdc51f5dc032ac6213285e238e5e79bee3a509 Mon Sep 17 00:00:00 2001 From: Dirk Date: Mon, 16 Jan 2017 14:06:32 +0100 Subject: [PATCH 43/61] fix #587 --- testssl.sh | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/testssl.sh b/testssl.sh index 5d29dd9..9994bb9 100755 --- a/testssl.sh +++ b/testssl.sh @@ -6000,11 +6000,19 @@ certificate_info() { out "$indent"; pr_bold " # of certificates provided"; outln " $certificates_provided" fileout "${json_prefix}certcount" "INFO" "# of certificates provided : $certificates_provided" + # Get both CRL and OCSP URL upfront. If there's none, this is not good. And we need to penalize this in the output + crl="$($OPENSSL x509 -in $HOSTCERT -noout -text 2>>$ERRFILE | awk '/CRL Distribution/,/URI/ { print $0 }' | awk -F'URI:' '/URI/ { print $2 }')" + ocsp_uri=$($OPENSSL x509 -in $HOSTCERT -noout -ocsp_uri 2>>$ERRFILE) + out "$indent"; pr_bold " Certificate Revocation List " - 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" "HIGH" "No CRL provided" + if [[ -z "$crl" ]] ; then + if [[ -n "$ocsp_uri" ]]; then + outln "--" + fileout "${json_prefix}crl" "INFO" "No CRL provided" + else + pr_svrty_highln "-- (NOT ok)" + fileout "${json_prefix}crl" "HIGH" "Neither CRL nor OCSP URL provided" + fi elif grep -q http <<< "$crl"; then if [[ $(count_lines "$crl") -eq 1 ]]; then outln "$crl" @@ -6019,10 +6027,9 @@ certificate_info() { fi out "$indent"; pr_bold " OCSP URI " - ocsp_uri=$($OPENSSL x509 -in $HOSTCERT -noout -ocsp_uri 2>>$ERRFILE) - if [[ -z "$ocsp_uri" ]]; then - pr_svrty_highln "--" - fileout "${json_prefix}ocsp_uri" "HIGH" "OCSP URI : --" + if [[ -z "$ocsp_uri" ]] && [[ -n "$crl" ]]; then + outln "--" + fileout "${json_prefix}ocsp_uri" "INFO" "OCSP URI : --" else outln "$ocsp_uri" fileout "${json_prefix}ocsp_uri" "INFO" "OCSP URI : $ocsp_uri" From a3a30c7fa5e7dbae46e7804d1b21feb643b1cdb2 Mon Sep 17 00:00:00 2001 From: Dirk Date: Tue, 17 Jan 2017 11:19:57 +0100 Subject: [PATCH 44/61] - CAA RR (expertimental) - replace some sed+grep by awk in get_mx_record() --- testssl.sh | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 51 insertions(+), 2 deletions(-) diff --git a/testssl.sh b/testssl.sh index 9994bb9..0bdc5c7 100755 --- a/testssl.sh +++ b/testssl.sh @@ -6056,6 +6056,20 @@ certificate_info() { fi fi fi + outln + + if "$EXPERIMENTAL"; then + out "$indent"; pr_bold " DNS CAA RR record " + caa="$(get_caa_rr_record $NODE)" + if [[ -n "$caa" ]]; then + pr_done_good "OK ($caa)" + fileout "${json_prefix}CAA_record" "OK" "DNS Certification Authority Authorization (CAA) Resource Record / RFC6844 : offered" + else + pr_svrty_minor "--" + fileout "${json_prefix}CAA_record" "LOW" "DNS Certification Authority Authorization (CAA) Resource Record / RFC6844 : not offered" + fi + fi + outln "\n" return $ret @@ -10961,6 +10975,41 @@ determine_rdns() { return 0 } +# RFC6844: DNS Certification Authority Authorization (CAA) Resource Record +# arg1: domain to check for +get_caa_rr_record() { + local caa="" + local saved_openssl_conf="$OPENSSL_CONF" + + OPENSSL_CONF="" + if which dig &> /dev/null; then + caa="$(dig $1 type257 +short | awk '{ print $3 }')" + # empty if no CAA record + elif which host &> /dev/null; then + caa="$(host -t type257 $1)" + if grep -wq issue <<< "$caa" && grep -wvq "has no CAA" <<< "$caa"; then + caa="$(awk '/issue/ { print $NF }' <<< "$caa")" + fi + elif which nslookup &> /dev/null; then + caa="$(nslookup -type=type257 $1)" + if grep -wq issue <<< "$caa" && grep -wvq "No answer" <<< "$caa"; then + caa="$(awk '/issue/ { print $NF }' <<< "$caa")" + fi + else + return 1 + # No dig, host, or nslookup --> complaint was elsewhere already and except for one which has drill only we don't get here + fi + OPENSSL_CONF="$saved_openssl_conf" # see https://github.com/drwetter/testssl.sh/issues/134 + echo "$caa" + return 0 +# to do: +# 1: check old binaries whether they support this record at all +# 2: check whether hexstring is returned and deal with it +# 3: check more than domainname, see https://tools.ietf.org/html/rfc6844#section-3 +# 4: check whether $1 is a CNAME and take this +# 5: query with drill +} + get_mx_record() { local mx="" local saved_openssl_conf="$OPENSSL_CONF" @@ -10968,13 +11017,13 @@ get_mx_record() { OPENSSL_CONF="" # see https://github.com/drwetter/testssl.sh/issues/134 check_resolver_bins if which host &> /dev/null; then - mxs=$(host -t MX "$1" 2>/dev/null | grep 'handled by' | sed -e 's/^.*by //g' -e 's/\.$//') + mxs=$(host -t MX "$1" 2>/dev/null | awk '/is handled by/ { print $(NF-1), $NF }') elif which dig &> /dev/null; then mxs=$(dig +short -t MX "$1" 2>/dev/null) elif which drill &> /dev/null; then mxs=$(drill mx "$1" 2>/dev/null | awk '/^\;\;\sANSWER\sSECTION\:$/,/\;\;\sAUTHORITY\sSECTION\:$/ { print $5,$6 }' | sed '/^\s$/d') elif which nslookup &> /dev/null; then - mxs=$(nslookup -type=MX "$1" 2>/dev/null | grep 'mail exchanger = ' | sed 's/^.*mail exchanger = //g') + mxs=$(nslookup -type=MX "$1" 2>/dev/null | awk '/mail exchanger/ { print $(NF-1), $NF }') else fatal "No dig, host, drill or nslookup" -3 fi From e7a35934ae1bd51e0b2e8872e58c8b0da0cdfae6 Mon Sep 17 00:00:00 2001 From: Dirk Date: Tue, 17 Jan 2017 12:00:18 +0100 Subject: [PATCH 45/61] add lf before -E --- testssl.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/testssl.sh b/testssl.sh index 1683e14..7c0d0fe 100755 --- a/testssl.sh +++ b/testssl.sh @@ -2753,6 +2753,7 @@ run_cipher_per_proto() { "$FAST" && using_sockets=false [[ $TLS_NR_CIPHERS == 0 ]] && using_sockets=false + outln if "$using_sockets"; then pr_headlineln " Testing per protocol via OpenSSL and sockets against the server, ordered by encryption strength " else From e9916dd1f44e772255a6656e53d4c1e92dc38d50 Mon Sep 17 00:00:00 2001 From: Dirk Date: Tue, 17 Jan 2017 13:57:14 +0100 Subject: [PATCH 46/61] - FIX #566 - reorder get__record() for better overview - move CMDLINE__IP away from main into determine_ip_addresses() where it belongs to --- testssl.sh | 167 +++++++++++++++++++++++++++++------------------------ 1 file changed, 90 insertions(+), 77 deletions(-) diff --git a/testssl.sh b/testssl.sh index 7c0d0fe..f7aa549 100755 --- a/testssl.sh +++ b/testssl.sh @@ -10951,79 +10951,6 @@ get_aaaa_record() { echo "$ip6" } - -# now get all IP addresses -determine_ip_addresses() { - local ip4="" - local ip6="" - - if is_ipv4addr "$NODE"; then - ip4="$NODE" # only an IPv4 address was supplied as an argument, no hostname - SNI="" # override Server Name Indication as we test the IP only - else - ip4=$(get_local_a $NODE) # is there a local host entry? - if [[ -z $ip4 ]]; then # empty: no (LOCAL_A is predefined as false) - check_resolver_bins - ip4=$(get_a_record $NODE) - else - LOCAL_A=true # we have the ip4 from local host entry and need to signal this to testssl - fi - # same now for ipv6 - ip6=$(get_local_aaaa $NODE) - if [[ -z $ip6 ]]; then - check_resolver_bins - ip6=$(get_aaaa_record $NODE) - else - LOCAL_AAAA=true # we have a local ipv6 entry and need to signal this to testssl - fi - fi - if [[ -z "$ip4" ]]; then # IPv6 only address - if "$HAS_IPv6"; then - IPADDRs=$(newline_to_spaces "$ip6") - IP46ADDRs="$IPADDRs" # IP46ADDRs are the ones to display, IPADDRs the ones to test - fi - else - if "$HAS_IPv6" && [[ -n "$ip6" ]]; then - IPADDRs=$(newline_to_spaces "$ip4 $ip6") - IP46ADDRs="$IPADDRs" - else - IPADDRs=$(newline_to_spaces "$ip4") - IP46ADDRs=$(newline_to_spaces "$ip4 $ip6") - fi - fi - if [[ -z "$IPADDRs" ]] && [[ -z "$CMDLINE_IP" ]]; then - fatal "No IPv4 address for \"$NODE\" available" -1 - fi - return 0 # IPADDR and IP46ADDR is set now -} - -determine_rdns() { - local saved_openssl_conf="$OPENSSL_CONF" - local nodeip="$(tr -d '[]' <<< $NODEIP)" # for DNS we do not need the square brackets of IPv6 addresses - - "$NODNS" && rDNS="--" && return 0 - OPENSSL_CONF="" # see https://github.com/drwetter/testssl.sh/issues/134 - if [[ "$NODE" == *.local ]]; then - if which avahi-resolve &>/dev/null; then - rDNS=$(avahi-resolve -a $nodeip 2>/dev/null | awk '{ print $2 }') - elif which dig &>/dev/null; then - rDNS=$(dig -x $nodeip @224.0.0.251 -p 5353 +notcp +noall +answer | awk '/PTR/ { print $NF }') - fi - elif which dig &> /dev/null; then - rDNS=$(dig -x $nodeip +noall +answer | awk '/PTR/ { print $NF }') # +short returns also CNAME, e.g. openssl.org - elif which host &> /dev/null; then - rDNS=$(host -t PTR $nodeip 2>/dev/null | awk '/pointer/ { print $NF }') - elif which drill &> /dev/null; then - rDNS=$(drill -x ptr $nodeip 2>/dev/null | awk '/^\;\;\sANSWER\sSECTION\:$/,/\;\;\sAUTHORITY\sSECTION\:$/ { print $5,$6 }' | sed '/^\s$/d') - elif which nslookup &> /dev/null; then - rDNS=$(nslookup -type=PTR $nodeip 2>/dev/null | grep -v 'canonical name =' | grep 'name = ' | awk '{ print $NF }' | sed 's/\.$//') - fi - OPENSSL_CONF="$saved_openssl_conf" # see https://github.com/drwetter/testssl.sh/issues/134 - rDNS="$(echo $rDNS)" - [[ -z "$rDNS" ]] && rDNS="--" - return 0 -} - # RFC6844: DNS Certification Authority Authorization (CAA) Resource Record # arg1: domain to check for get_caa_rr_record() { @@ -11080,6 +11007,94 @@ get_mx_record() { echo "$mxs" } + +# set IPADDRs and IP46ADDRs +# +determine_ip_addresses() { + local ip4="" + local ip6="" + + if [[ -n "$CMDLINE_IP" ]]; then + # command line has supplied an IP address + [[ "$CMDLINE_IP" == "one" ]] && \ + CMDLINE_IP="$(get_a_record $NODE | head -1)" + # use first IPv4 address + NODEIP="$CMDLINE_IP" + if is_ipv4addr "$NODEIP"; then + ip4="$NODEIP" + elif is_ipv6addr "$NODEIP"; then + ip6="$NODEIP" + else + fatal "couldn't identify supplied \"CMDLINE_IP\"" 2 + fi + elif is_ipv4addr "$NODE"; then + ip4="$NODE" # only an IPv4 address was supplied as an argument, no hostname + SNI="" # override Server Name Indication as we test the IP only + else + ip4=$(get_local_a $NODE) # is there a local host entry? + if [[ -z $ip4 ]]; then # empty: no (LOCAL_A is predefined as false) + check_resolver_bins + ip4=$(get_a_record $NODE) + else + LOCAL_A=true # we have the ip4 from local host entry and need to signal this to testssl + fi + # same now for ipv6 + ip6=$(get_local_aaaa $NODE) + if [[ -z $ip6 ]]; then + check_resolver_bins + ip6=$(get_aaaa_record $NODE) + else + LOCAL_AAAA=true # we have a local ipv6 entry and need to signal this to testssl + fi + fi + + if [[ -z "$ip4" ]]; then # IPv6 only address + if "$HAS_IPv6"; then + IPADDRs=$(newline_to_spaces "$ip6") + IP46ADDRs="$IPADDRs" # IP46ADDRs are the ones to display, IPADDRs the ones to test + fi + else + if "$HAS_IPv6" && [[ -n "$ip6" ]]; then + IPADDRs=$(newline_to_spaces "$ip4 $ip6") + IP46ADDRs="$IPADDRs" + else + IPADDRs=$(newline_to_spaces "$ip4") + IP46ADDRs=$(newline_to_spaces "$ip4 $ip6") + fi + fi + if [[ -z "$IPADDRs" ]]; then + fatal "No IPv4 address for \"$NODE\" available" -1 + fi + return 0 # IPADDR and IP46ADDR is set now +} + +determine_rdns() { + local saved_openssl_conf="$OPENSSL_CONF" + local nodeip="$(tr -d '[]' <<< $NODEIP)" # for DNS we do not need the square brackets of IPv6 addresses + + "$NODNS" && rDNS="--" && return 0 + OPENSSL_CONF="" # see https://github.com/drwetter/testssl.sh/issues/134 + if [[ "$NODE" == *.local ]]; then + if which avahi-resolve &>/dev/null; then + rDNS=$(avahi-resolve -a $nodeip 2>/dev/null | awk '{ print $2 }') + elif which dig &>/dev/null; then + rDNS=$(dig -x $nodeip @224.0.0.251 -p 5353 +notcp +noall +answer | awk '/PTR/ { print $NF }') + fi + elif which dig &> /dev/null; then + rDNS=$(dig -x $nodeip +noall +answer | awk '/PTR/ { print $NF }') # +short returns also CNAME, e.g. openssl.org + elif which host &> /dev/null; then + rDNS=$(host -t PTR $nodeip 2>/dev/null | awk '/pointer/ { print $NF }') + elif which drill &> /dev/null; then + rDNS=$(drill -x ptr $nodeip 2>/dev/null | awk '/^\;\;\sANSWER\sSECTION\:$/,/\;\;\sAUTHORITY\sSECTION\:$/ { print $5,$6 }' | sed '/^\s$/d') + elif which nslookup &> /dev/null; then + rDNS=$(nslookup -type=PTR $nodeip 2>/dev/null | grep -v 'canonical name =' | grep 'name = ' | awk '{ print $NF }' | sed 's/\.$//') + fi + OPENSSL_CONF="$saved_openssl_conf" # see https://github.com/drwetter/testssl.sh/issues/134 + rDNS="$(echo $rDNS)" + [[ -z "$rDNS" ]] && rDNS="--" + return 0 +} + # We need to get the IP address of the proxy so we can use it in fd_socket # check_proxy() { @@ -12011,13 +12026,11 @@ if $do_mx_all_ips; then else parse_hn_port "${URI}" # NODE, URL_PATH, PORT, IPADDR and IP46ADDR is set now prepare_logging - if ! determine_ip_addresses && [[ -z "$CMDLINE_IP" ]]; then + if ! determine_ip_addresses; then fatal "No IP address could be determined" 2 fi if [[ -n "$CMDLINE_IP" ]]; then - [[ "$CMDLINE_IP" == "one" ]] && \ - CMDLINE_IP=$(echo -n "$IPADDRs" | awk '{ print $1 }') - NODEIP="$CMDLINE_IP" # specific ip address for NODE was supplied + # we just test the one supplied lets_roll "${STARTTLS_PROTOCOL}" ret=$? else # no --ip was supplied From b1c80512e684140af2608ac9d3e5a4d7cd3d91d4 Mon Sep 17 00:00:00 2001 From: Dirk Date: Wed, 18 Jan 2017 12:44:15 +0100 Subject: [PATCH 47/61] first bunch of common primes, see #589 + #576 + #120. License of nmap is also GPLv2: no conflicts --- etc/common-primes.txt | 112 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 112 insertions(+) create mode 100644 etc/common-primes.txt diff --git a/etc/common-primes.txt b/etc/common-primes.txt new file mode 100644 index 0000000..94727b2 --- /dev/null +++ b/etc/common-primes.txt @@ -0,0 +1,112 @@ + +## taken from https://svn.nmap.org/nmap/scripts/ssl-dh-params.nse + +# "mod_ssl 2.0.x/512-bit MODP group with safe prime modulus" +D4BCD5206F69B3994B88D5DB8968C8157F6D8F3363EE5772F1F05AB2D6B51459F241E5CC31FF00A4BC7148976F7795094E1E790359F5A824B + +# "mod_ssl 2.2.x/512-bit MODP group with safe prime modulus" +E6969D3495BE327CF180CBDD479891B781851BB0552A206494A79A77FA15A25CBD523AA6EF09C3048D5A2F971F320129B4000E6ED061CBC03E371D74E5327D611EBBB1BAC9B56044CF03D76E05EA9BAD91B13A63974E9EF839EB5D125136F262E56A871538DD823C655085E210DD5C86 + +# "mod_ssl 2.2.x/512-bit MODP group with safe prime modulus" +9FDB8B8004544F045F173D0BA2E0274CDF19F58821FB43531A16E37471FD19DD8F37C3BF863FD0E3E30080A30306E4C375D08F70EAA87103 + +# "mod_ssl 2.2.x/1024-bit MODP group with safe prime modulus" +D67DE44CBBBDC136D693D4AFD0AD0C84D23A45F520B88174C98BCE95849F912639C72F13B4B4D177E16D5AC179B420B2A2FE324A47A635E8FF590137BEDDCF33168A41AAD3B7DAE886078045B0A7DBCA774087D110EA9FC9DDD33007DD62D88AEAA77DE0F4DE2BD68BE7393E024218EB3 + +# "nginx/1024-bit MODP group with safe prime modulus" +BBBC2DCD8467497C43FCF80E9CFDD958A3F68B42D408EED4E0FB35046C03027E7108005CCBBAA922614CBEECA56A5FDF1D87A2BC09BE677860E91A9A757E308F68B07F7D36CCF29BA5D81DC2CA25ECE6670CC9A535D8CECEF9EA024A63AB158FAFD488D0F65146757D071DF04CFE16B9B + +# "sun.security.provider/512-bit DSA group with 160-bit prime order subgroup" +FCA682C8E12CAB26EFCCF110E526B078B05DECBCD1B4A208FAE1617A01F35B9A47E6DF3413C5E2ED0899CD132AC50D9915BDC43EE37592E17 + +# "sun.security.provider/768-bit DSA group with 160-bit prime order subgroup" +E9E64259D355F3C97FFD367120B825C9CD4E927B3A670FBECD89014122D2C3BAD2480037998691E846AA49FAB0A26D2CE622219D40BCE7D77D4A21FE9C270B7F60700F3CEF833694CF4EE3688C1A8C56A127A3DAF + +# "sun.security.provider/1024-bit DSA group with 160-bit prime order subgroup" +FD7F5381D7512252DF4A92EECE4EF611B753CEF440C31E3F8B651266455D40251FB5938D58FABC5F5BA3F6CB9B56CD7813801D346F26660B6B9950AA49F9FE047B102C24FBBAD7FEB7C1BF83B5E7C6A8A150F04F83F6D3C1EC302354135A19132F67F3AE2B6D72AEFF2203199D14801C7 + +# "openssl/512-bit MODP group with safe prime modulus" +DA583C1D985228D0E4AF76F4CCA9DD4BE53B804FB0ED94EF98A4403E574650D6999DB2D776276A2D3D41E218F4D1E084CFD8003E74774E833 + +# "openssl/1024-bit MODP group with safe prime modulus" +97F6426CAB505D2828E131D68B6DDBD0F31047F40E56DA58C13B8A1B2B783A46D59D5F2AFC6CF3D693F7B23D4F360A95023EFAF7A5E1AD5A5E55431828DA839FF2D94DEE9568FADAEA036ADDF171FE63520AF47064603C2E059F54650AD8F0CF7012C74799D587132B9B999BBB787E8AB + +# "openssl/2048-bit MODP group with safe prime modulus" +ED92893824555C3BFBA275A69046BF21F3A53D2CD2DAFF7811152F10C1E255B686F68053B92262FE49A31F65CC5328ABDBDB49EDDA71266CFD2104718F07FDF75851172827B2A9341812FCB21C6D92AE4B6A829C27A3CB0C5F2E5F0AA4598A2BDAD4F0B3ADFE08135ED983B3CAEEAEB6E6A9576B9F128A3F2280D0BA6F67939B810F85A90ECCCA6F65F7AC011A1EF0F2DB60806228B0EDB8928E0CA83D69469166533C53613B02BAD48287A1C729E435FCC27E951DE685FC19976600F3F86BB3C520E29C07E8901CCCC001B6ADC3A308B33AAFD88C89D01DBAC4DD7F0BD6F38C3 + +# "openssl/2048-bit MODP group with safe prime modulus" +AED037CBDF33FAEEDC439B70A2087B77017E9B92EB0F8061CD4B5A59723C793FDA9F9F274490F50647285BE05921C4F2C05A4EE75A36613F382DBD44DE8A4A322122EC730A833E4800EBD6F854A518171BA54523C843FAC175FFAF49C440D446D846C1C345149EFA82F5C48A47BAC7F67EE00011AA9ED8101B36A5C39AAFEC54A3FF97C1B7F406DCB2DC092ABAA0625EFEB3FA12B42692E8F3EFB3F7B4C302A24CAA4213D45035CEA8ADD31816616F9E21A5C50805978980AD6814E3585B79E684491527552B72BC78D8D6993A7368486B3088B8F1B7E896688BD3F13DC517D4B + +# "openssl/4096-bit MODP group with safe prime modulus" +FEEAD19BEAF90F1CFCA105D69DB0839A2A26AEF248ABD7531BB3E4627DCECEFCEDCBBBF56549E95153058188C3D72941666AABA0A5CC85559125503180E9034C7F39CA3452F342EE72A7DFFC74528DB6D76D9C64F55D0839CDE74FE7424136947661D2670F2F6D59FFD7C3BDDED41E2B2CCDD9E12F1056AB88C44D7F9BA7651ED1A4D407A2D71895F77AB6C763CC00EF1C30B2E7944697E74BC7B8431B5011AF5A1515E63C1DE83C802ECE7FC71FBD179F8E4D7F1B43BA75D5AC3B11D41B0B5A088A9AACCCC105126DC841E41693E8591E31E2F5AFDAEDE1221277FC20BE4D251137A58E961EACF27D4C7E239190DD6AB27ECE5BD664C79B16C2D208D63A4B7F8DAE63DBE2C886BA10778A8DF5CE214A4B3D03C9175FBA578146CE5EC0177574481AD86F485465F5DA4B67F88260CE0BC0ACD157A377F10091AD0B6889303ECA33CDB61BA8CE32A87AF5D8B7F26734D209679232D70ADEF4A51D888BC57D2A638E014D66936776FFF355FEDF52201FA0CB8DB3FB54949951A70104AD49D71B74D09CAA8C05E833A2291D697F918F255C769BDE4BB72A4A1AFE60BBAD183EACC7B54AF4084F1CCB2B9AE576DAE2D1A8F43D27741DB19EDC3B815E569645F8C3363 + +# "RFC2409/Oakley Group 1" +FFFFFFFFFFFFFFC90FDAA2168C23C4C662880DC1CD29024E08A67CC7020BBEA3B139B2514A0878E3404DEF9519BCD3A431302B0A6F25F1434FE13566D51C24E485B57625E7ECF44C42EA63A362FFFFFFFFFFFFFFF + +# "RFC2409/Oakley Group 2" +FFFFFFFFFFFFFFC90FDAA2168C23C4C662880DC1CD29024E08A67CC7020BBEA3B139B2514A0878E3404DEF9519BCD3A431302B0A6F25F1434FE13566D51C24E485B57625E7ECF44C42EA637ED60BFF5CBF406B7EEE386BF5A899FAAE9F2417C4B1FE4928665ECE6538FFFFFFFFFFFFFFF + +# "RFC3526/Oakley Group 5" +FFFFFFFFFFFFFFC90FDAA2168C23C4C662880DC1CD29024E08A67CC7020BBEA3B139B2514A0878E3404DEF9519BCD3A431302B0A6F25F1434FE13566D51C24E485B57625E7ECF44C42EA637ED60BFF5CBF406B7EEE386BF5A899FAAE9F2417C4B1FE4928665ECE45B3C2007CBA163BF098DA4831C55D3969163FAFD24CF583655D2DCA3AD91C62F35208552B9ED52907096966670C3544ABC980F1746C0CA23732FFFFFFFFFFFFFFF + +# "RFC3526/Oakley Group 14" +FFFFFFFFFFFFFFC90FDAA2168C23C4C662880DC1CD29024E08A67CC7020BBEA3B139B2514A0878E3404DEF9519BCD3A431302B0A6F25F1434FE13566D51C24E485B57625E7ECF44C42EA637ED60BFF5CBF406B7EEE386BF5A899FAAE9F2417C4B1FE4928665ECE45B3C2007CBA163BF098DA4831C55D3969163FAFD24CF583655D2DCA3AD91C62F35208552B9ED52907096966670C3544ABC980F1746C0CA1821732905E42E36CE3E39E772180E8609B2783AEC07A28B5C55DF6F4C52CDE2BCBF95581713995497EA956AE15D226198FA05115728E58AACAA6FFFFFFFFFFFFFFF + +# "RFC3526/Oakley Group 15" +FFFFFFFFFFFFFFC90FDAA2168C23C4C662880DC1CD29024E08A67CC7020BBEA3B139B2514A0878E3404DEF9519BCD3A431302B0A6F25F1434FE13566D51C24E485B57625E7ECF44C42EA637ED60BFF5CBF406B7EEE386BF5A899FAAE9F2417C4B1FE4928665ECE45B3C2007CBA163BF098DA4831C55D3969163FAFD24CF583655D2DCA3AD91C62F35208552B9ED52907096966670C3544ABC980F1746C0CA1821732905E42E36CE3E39E772180E8609B2783AEC07A28B5C55DF6F4C52CDE2BCBF95581713995497EA956AE15D226198FA05115728E58AAAC42AD3317004507A3A85521ADF1CBA6ECFB85058DBEF08AEA7155D060C7B3970F8A6E1E4CABF5AE8DB0933D1E8C94E4A25619CEE3D221AD2EE6F12FFA0D98A086D8760273EC86A6521F2B1177B200BBE11757A615D6770988CBAD946E08E24FA74E5AB343DB5BFE0FD1084B82D12A93AD2CFFFFFFFFFFFFFFF + +# "RFC3526/Oakley Group 16" +FFFFFFFFFFFFFFC90FDAA2168C23C4C662880DC1CD29024E08A67CC7020BBEA3B139B2514A0878E3404DEF9519BCD3A431302B0A6F25F1434FE13566D51C24E485B57625E7ECF44C42EA637ED60BFF5CBF406B7EEE386BF5A899FAAE9F2417C4B1FE4928665ECE45B3C2007CBA163BF098DA4831C55D3969163FAFD24CF583655D2DCA3AD91C62F35208552B9ED52907096966670C3544ABC980F1746C0CA1821732905E42E36CE3E39E772180E8609B2783AEC07A28B5C55DF6F4C52CDE2BCBF95581713995497EA956AE15D226198FA05115728E58AAAC42AD3317004507A3A85521ADF1CBA6ECFB85058DBEF08AEA7155D060C7B3970F8A6E1E4CABF5AE8DB0933D1E8C94E4A25619CEE3D221AD2EE6F12FFA0D98A086D8760273EC86A6521F2B1177B200BBE11757A615D6770988CBAD946E08E24FA74E5AB343DB5BFE0FD1084B82D12A9210801A723C1A787E6D88719A1BDBA5B299C32716AF4E231A94683B6150BD2583E9C2AD44CEDBBBC2D04DE8EF2E8EFC11FBECAA287C5944E6BC0599B2964A090C3A233BA18515BE7E1F61297CEE2D7AB81BDD72170481D006912D5B05AA93B4EA98D8FDDC86FFB7D90A6C084DF435C3406319FFFFFFFFFFFFFFF + +# "RFC5114/1024-bit DSA group with 160-bit prime order subgroup" +B10B8F9A080E01DE92DE5AE5D54E52C99FBFB06A3C9A6A9DC52D23B66073E2875A23D19838EF12EE652C13ECB4AA90611224975C3D49B83BACCBDD790C4BD798488E9219A7374EFFD6FE564473FAA31A4F55BCCCA151AF50DC8B4B45BF37D365C1A6E68CFDA6D4DA70DF1FB2B2E4A4371 + +# "RFC5114/2048-bit DSA group with 224-bit prime order subgroup" +AD107E19123A9DD660FAA9559C51A20D64E683B9FDB54B159B61D0A7E6FA141F95A56DAF9A3C47BA1DF1EB3D688309C1801DE6B851274A0A6D3F815AD6AC219037C9EEFDA4DFD91E8FE55B73947AD5B7DB6C1220C9F98D1ED34DBFC6BA0B28BBC27B6A00E0AB9C4970B3BF8A370918838128613BC8985D1602E71415D933278273CDE31EFD7310F711FD5A0715987D9DC0A486CDF93AC4432838315D75E98C641A80CD86AB9E587EBE60E69C928B2BC52172E13042E923F10B016E7976C9B53DC4BA80A2E3FB73C6B8E75B7EF363EFFA31F7CF9DE534E71B810AC4DFF0C10E64F + +# "RFC5114/2048-bit DSA group with 256-bit prime order subgroup" +87A8E61B4B6663FFBBD1965195998CEEF60660DD0F5D2CEED435E3B0E00DF8FD61957DFAF7DF461B2AA316C3D9134096FA3BF4296830E9A7209E0C697517AB5A8A9D36BCF67E91F9E675B4758C22E0B1E4275BF76C5BFC1D45F908B941F54B1E59BBBC39A0B12307F54FDB70C81B23F7B63ACAECAA6B792D5252635488A0F13C6D951BFA4A3AD834796524D8F6A167BA41825D67E144E14056421CCACB8E6B486FB3CA3F77150602C0B857F8996285DED4010BD0BE62C3A396054E710C75F2637D701410A4B5433C198AF16116D226E11715693877FD7EF09CDB094AE1E1A1597 + +# "weakdh.org/1024-bit MODP group with non-safe prime modulus" +D6C094A57F537468D58C7096872D45CEE1F2664E054421E1DE3C8E98C3F0A6A8F92F193FEF933B99B9C9A055D5596E42574005A68D47040FF00A5596EBA4B9F64CBA1004E451611C9B27438A70A2060C238D0CFAFFBBA48B9DAC4B450DC58B0320A017E2A3144A0278C657FB00CBEC11D + +# "weakdh.org/1024-bit MODP group with safe prime modulus" +C9BBF5F74A82970F97CDD3A3468C117B6BF99A13D91F5DAC47B2241F95EFB132855DFDF898B3F9188E24DF326DD8C76CC853728352D46F193129C69364D8C7202EABBEBC85C1F53907FD0B7EB40AD0BC928968680C46AB0BF7CDD9D425E6F25592EB258A065D75E93B671746A349E721B + +"weakdh.org/1024-bit MODP group with safe prime modulus" +829FEBFE3EE043862D336A62BDE765F0C743A53B55291414FAE5E86D34B16DBCC952B15EB443B154B3B4662E811E1D8BC7334018A5A7B5B6A720D84B28B7482C5AF24C04E5BB5DABF8FFA5ED7B46688D6CB82F8AF188A4563ED62D2EACF6BDFD47337884DFA0F0A3D6975E3580E3AE9593 + +# "weakdh.org/1024-bit MODP group with safe prime modulus" +9240243C3A12E4D3730D878CADFA8E2F5B5A956BFFDB8E5653E9695E3E32506FEB912FA77D22E1BB54C880893B8AD1BCF37F7F779D3FB96881D9BA17034ABF1F97B314CF3203663E8190B7E0906C4C5EEA0E57EC74D3E84D9E72E6C7DA6AE12DF297131854FF21AC4E79C23BB60B4F753 + +# "weakdh.org/1024-bit MODP group with safe prime modulus" +A9A3481446C7B6A29FF997C2181EFAAAD13CCDE245755D42F2E700AF86779D58A7C07C5DE423361117D05773F249C331AFA1B08EF360A14D4046F2762DA36A47D9FDE92B8815598C3A9546E7ED95D22EC9119F5B22CC41B0AF220F47BDE1B8334AD281DDC5E923F11CDDD3B22949DC41B + +# "weakdh.org/1024-bit MODP group with safe prime modulus" +CA6B8566DC21767605DACE801FAD59845384AF126CCC765E081014F293546ABDDE5C67C32D5B005B1BBF4C5DBFA253ADB3205B7D867DF98CBCE81C713F9FC215F1C33F953AB3CE8B7FEE3951FB31314074D5489BB17C6879A2EAF8195A8DE0A165E4B752077B167A00A5629FD5A9A25F3 + +# "weakdh.org/1024-bit MODP group with safe prime modulus" +EB373E9AB618DF20D233E93E3EBC319BDAC0994C1D003986A9FAFFF754151CCE06413192698B4496F5FDFAF1289679D8BC1580D7D1CD83F8529C7953D58EC62E0E87FD008C13E3E5861B2D3A024D372CE4F220FE2C9039A997664AEBB75446AA69EBE0EF3C6F91C2632B54EC3A970A7BB + +# "weakdh.org/1024-bit MODP group with safe prime modulus" +80A68AD5327E05AAD07C464B8ADE908432A9651B23F47A7A8F84D568DFDAFAB6621C0C28450F155F7D4AECE383F7D6055ADF60C4B37DCC1EB8374E3995179239FDC3BB428511C8B4A9FFCE4DD5AA23F992647C39CE4D8BB2E773F4EB786CE4CD0C3D4C31D75D1CF9E970C45EE8ECDABAB + +# "weakdh.org/1024-bit MODP group with safe prime modulus" +C0EB5F34CB30A9FE3786E4C0381469B52035AD49F5EFD8CAA31A69B273CC9F5B4B8F802C5FB683913B612042D2EBD533815E59769C9E97BD488DB335581320DD4AF9CE4A4EBE9118C6828E5B3989C26720B4FDC210C288B174D77E0AAD9C117EA5ED7CF971BB19A8718E52982591CA14B + +# "weakdh.org/1024-bit MODP group with safe prime modulus" +8FC0E1E0574D6A3C76DDE64524C276446B698E5B6B2614F969A5061D99034DB819780E8EE28A466B5C4EA634E47F9C981AEC4908E1B83A41813165A0AB6BDCD325718AC49399541C16F960F9D6B9C51EC85AD0BBFE3890118F0CD665D4B1B1C72395B83217FB3EBF878160E827911754B + +# "haproxy 1.5 builtin" +EC86F87A03316E051A735CD1F8BF29E4D2C52DDC228DB5389FB5CA4EB2DACE65074A684D4B1D3B82BF31E9A72D071E781D8B595235F430B6F1DB07B086B1B2EE4DCC90E43A01DF438CEBEBE90B5154B927B647645DD42EAC29EAE54359C779C503C0ED73045F14C762D8F8CFF3440D1B4261846423904F68B262D55ED1B77591E0C69C1315DB7B442CE845801E660CC449EFD408675DFA7768F01187E99F97DC4B745520D4A412F4421AC1F9717492376B2F87E1CA0A899227D565A71C56377E39D05E7E5D8F821BCE9C293082F9FC9AE49DD054B4D754DFA0B8D6384B71F77F + +# "postfix builtin" +B0FEB4CD45507ECC885901726C50A54A9228178DA8AA4C130BF5D2F9BC96B85009D0C075ADFD3B17E7143F9154144B83021CEBDF79C4CF180D683F98EA4FB78918B291690019668C5384E273D9E75A7AAD5ECE27FAED011C278255065C39FCD4954AC1B1EA4F953D0D6DAFD49E7BAAE9B + +# "IronPort SMTPbuiltin" +F8D5CCE7A3961BF5CBC8340C5185E0E6FA65AB283178C86761CA46CA7D7FA3BAF75B833C69937D36920FE39A653E8F0725A6E2D297537558E27E7844B549BEB558927A30C8BD1DACDCA93027B5CE1BC1770AF7DEE81149AD7D632DB80A639CEBCC7A619CCF3288EA3D2328774B04E6FB3 + + +## taken from https://github.com/cryptosense/diffie-hellman-groups/blob/master/gen/common.json +# to be continueed + From 4433345b16c754d46ea04ae1421dd332603c269b Mon Sep 17 00:00:00 2001 From: Dirk Date: Wed, 18 Jan 2017 15:53:01 +0100 Subject: [PATCH 48/61] - first implementation (draft) of LOGJAM common primes, see #589, #120 - output polishing of run_drown() - polishing of run_logjam() - decrease severity to high for LOGJAM, see CVE rating --- testssl.sh | 58 ++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 41 insertions(+), 17 deletions(-) diff --git a/testssl.sh b/testssl.sh index f7aa549..49a1508 100755 --- a/testssl.sh +++ b/testssl.sh @@ -9526,6 +9526,7 @@ run_logjam() { local -i sclient_success=0 local exportdhe_cipher_list="EXP1024-DHE-DSS-DES-CBC-SHA:EXP1024-DHE-DSS-RC4-SHA:EXP-EDH-RSA-DES-CBC-SHA:EXP-EDH-DSS-DES-CBC-SHA" local exportdhe_cipher_list_hex="00,63, 00,65, 00,14, 00,11" + local all_dhe_ciphers="cc,15, 00,b3, 00,91, c0,97, 00,a3, 00,9f, cc,aa, c0,a3, c0,9f, 00,6b, 00,6a, 00,39, 00,38, 00,c4, 00,c3, 00,88, 00,87, 00,a7, 00,6d, 00,3a, 00,c5, 00,89, 00,ab, cc,ad, c0,a7, c0,43, c0,45, c0,47, c0,53, c0,57, c0,5b, c0,67, c0,6d, c0,7d, c0,81, c0,85, c0,91, 00,a2, 00,9e, c0,a2, c0,9e, 00,aa, c0,a6, 00,67, 00,40, 00,33, 00,32, 00,be, 00,bd, 00,9a, 00,99, 00,45, 00,44, 00,a6, 00,6c, 00,34, 00,bf, 00,9b, 00,46, 00,b2, 00,90, c0,96, c0,42, c0,44, c0,46, c0,52, c0,56, c0,5a, c0,66, c0,6c, c0,7c, c0,80, c0,84, c0,90, 00,66, 00,18, 00,8e, 00,16, 00,13, 00,1b, 00,8f, 00,63, 00,15, 00,12, 00,1a, 00,65, 00,14, 00,11, 00,19, 00,17, 00,b5, 00,b4, 00,2d" local -i i nr_supported_ciphers=0 server_key_exchange_len=0 ephemeral_pub_len=0 local addtl_warning="" hexc local cve="CVE-2015-4000" @@ -9533,6 +9534,7 @@ run_logjam() { local hint="" local server_key_exchange ephemeral_pub key_bitstring="" dh_p local using_sockets=true + local spaces=" " "$SSL_NATIVE" && using_sockets=false @@ -9546,8 +9548,7 @@ run_logjam() { fi case $nr_supported_ciphers in - 0) - local_problem_ln "$OPENSSL doesn't have any DHE EXPORT ciphers configured" + 0) local_problem_ln "$OPENSSL doesn't have any DHE EXPORT ciphers configured" fileout "logjam" "WARN" "LOGJAM: Not tested. $OPENSSL doesn't have any DHE EXPORT ciphers configured" "$cve" "$cwe" return 3 ;; @@ -9565,23 +9566,14 @@ run_logjam() { sclient_success=$? debugme egrep -a "error|failure" $ERRFILE | egrep -av "unable to get local|verify error" fi - addtl_warning="$addtl_warning, common primes not checked." - if "$HAS_DH_BITS" || ( ! "$SSL_NATIVE" && ! "$FAST" && [[ $TLS_NR_CIPHERS -ne 0 ]] ); then - if ! "$do_allciphers" && ! "$do_cipher_per_proto"; then - addtl_warning="$addtl_warning \"$PROG_NAME -E/-e\" spots candidates" - else - addtl_warning="$addtl_warning See below for any DH ciphers + bit size" - fi - fi if [[ $sclient_success -eq 0 ]]; then - pr_svrty_critical "VULNERABLE (NOT ok)"; out ", uses DHE EXPORT ciphers, common primes not checked." - fileout "logjam" "CRITICAL" "LOGJAM: VULNERABLE, uses DHE EXPORT ciphers, common primes not checked." "$cve" "$cwe" "$hint" + pr_svrty_high "VULNERABLE (NOT ok):"; out " uses DHE EXPORT ciphers," + fileout "logjam" "HIGH" "LOGJAM: VULNERABLE, uses DHE EXPORT ciphers" "$cve" "$cwe" "$hint" else - pr_done_best "not vulnerable (OK)"; out "$addtl_warning" - fileout "logjam" "OK" "LOGJAM: not vulnerable $addtl_warning" "$cve" "$cwe" + pr_done_good "not vulnerable (OK):"; out " no DHE EXPORT ciphers,"; out "$addtl_warning" + fileout "logjam" "OK" "LOGJAM: not vulnerable (no DHE EXPORT ciphers) $addtl_warning" "$cve" "$cwe" fi - outln if [[ $DEBUG -ge 2 ]]; then if "$using_sockets"; then @@ -9601,7 +9593,7 @@ run_logjam() { # Try all ciphers that use an ephemeral DH key. If successful, check whether the key uses a weak prime. if "$using_sockets"; then - tls_sockets "03" "cc,15, 00,b3, 00,91, c0,97, 00,a3, 00,9f, cc,aa, c0,a3, c0,9f, 00,6b, 00,6a, 00,39, 00,38, 00,c4, 00,c3, 00,88, 00,87, 00,a7, 00,6d, 00,3a, 00,c5, 00,89, 00,ab, cc,ad, c0,a7, c0,43, c0,45, c0,47, c0,53, c0,57, c0,5b, c0,67, c0,6d, c0,7d, c0,81, c0,85, c0,91, 00,a2, 00,9e, c0,a2, c0,9e, 00,aa, c0,a6, 00,67, 00,40, 00,33, 00,32, 00,be, 00,bd, 00,9a, 00,99, 00,45, 00,44, 00,a6, 00,6c, 00,34, 00,bf, 00,9b, 00,46, 00,b2, 00,90, c0,96, c0,42, c0,44, c0,46, c0,52, c0,56, c0,5a, c0,66, c0,6c, c0,7c, c0,80, c0,84, c0,90, 00,66, 00,18, 00,8e, 00,16, 00,13, 00,1b, 00,8f, 00,63, 00,15, 00,12, 00,1a, 00,65, 00,14, 00,11, 00,19, 00,17, 00,b5, 00,b4, 00,2d" "ephemeralkey" + tls_sockets "03" "$all_dhe_ciphers" "ephemeralkey" sclient_success=$? if [[ $sclient_success -eq 0 ]] || [[ $sclient_success -eq 2 ]]; then cp "$TEMPDIR/$NODEIP.parse_tls_serverhello.txt" $TMPFILE @@ -9625,13 +9617,45 @@ run_logjam() { dh_p="$($OPENSSL pkey -pubin -text -noout <<< "$key_bitstring" | awk '/prime:/,/generator:/' | tail -n +2 | head -n -1)" dh_p="$(strip_spaces "$(colon_to_spaces "$(newline_to_spaces "$dh_p")")")" [[ "${dh_p:0:2}" == "00" ]] && dh_p="${dh_p:2}" - # At this point the DH key's prime has been extracted into $dh_p. Compare is against known weak primes. + debugme outln "dh_p: $dh_p" + echo "$dh_p" > $TEMPDIR/dh_p.txt + common_primes_test $dh_p + else + outln " no DH key detected" + fileout "LOGJAM_common primes" "OK" "no DH key detected" fi + outln tmpfile_handle $FUNCNAME.txt return $sclient_success } +# takes one arg and compares against a predefined set in $TESTSSL_INSTALL_DIR +common_primes_test() { + local common_primes_file="$TESTSSL_INSTALL_DIR/etc/common-primes.txt" + local -i lineno_matched=0 + local comment="" + + if [[ ! -s "$common_primes_file" ]]; then + pr_warningln "couldn't read common primes file $common_primes_file" + fileout "LOGJAM_common primes" "WARN" "couldn't read common primes file $common_primes_file" + return 1 + else + lineno_matched=$(grep -n "$dh_p" "$common_primes_file" 2>/dev/null) + if [[ "$lineno_matched" -ne 0 ]]; then + # get comment + comment="$(awk "NR == $lineno_matched-1" "$common_primes_file" | awk -F'"' '{ print $2 }')" +#FiXME: probably the high groups/bit sizes whould get a different rating, see paper + pr_svrty_high "common prime $comment detected" + fileout "LOGJAM_common primes" "HIGH" "common prime $comment detected" + else + pr_done_good " no common primes detected" + fileout "LOGJAM_common primes" "OK" "no common primes detected" + fi + fi + return 0 +} + run_drown() { local nr_ciphers_detected ret From 8bf7b6b31b1140d001af3649c8ba28d5f4e48c4f Mon Sep 17 00:00:00 2001 From: Dirk Date: Wed, 18 Jan 2017 16:23:18 +0100 Subject: [PATCH 49/61] forgot to save work, followup to 4433345b16c754d46ea04ae1421dd332603c269b , #120, #589 --- testssl.sh | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/testssl.sh b/testssl.sh index 49a1508..38f39f4 100755 --- a/testssl.sh +++ b/testssl.sh @@ -9619,9 +9619,9 @@ run_logjam() { [[ "${dh_p:0:2}" == "00" ]] && dh_p="${dh_p:2}" debugme outln "dh_p: $dh_p" echo "$dh_p" > $TEMPDIR/dh_p.txt - common_primes_test $dh_p + common_primes_test $dh_p "$spaces" else - outln " no DH key detected" + out " no DH key detected" fileout "LOGJAM_common primes" "OK" "no DH key detected" fi outln @@ -9631,13 +9631,15 @@ run_logjam() { } # takes one arg and compares against a predefined set in $TESTSSL_INSTALL_DIR +# spaces to indent common_primes_test() { local common_primes_file="$TESTSSL_INSTALL_DIR/etc/common-primes.txt" local -i lineno_matched=0 local comment="" if [[ ! -s "$common_primes_file" ]]; then - pr_warningln "couldn't read common primes file $common_primes_file" + outln + pr_warning "${2}couldn't read common primes file $common_primes_file" fileout "LOGJAM_common primes" "WARN" "couldn't read common primes file $common_primes_file" return 1 else @@ -9671,7 +9673,7 @@ run_drown() { outln fi # if we want to use OPENSSL: check for < openssl 1.0.2g, openssl 1.0.1s if native openssl - pr_bold " DROWN"; out " ($cve) " + pr_bold " DROWN"; out " ($cve) " sslv2_sockets case $? in @@ -9715,7 +9717,11 @@ run_drown() { # not advertising it as it after 5 tries and account is needed cert_fingerprint_sha2=${cert_fingerprint_sha2/SHA256 /} outln "$spaces https://censys.io/ipv4?q=$cert_fingerprint_sha2 could help you to find out" + fileout "drown" "INFO" "make sure you don't use this certificate elsewhere with SSLv2 enabled services, see https://censys.io/ipv4?q=$cert_fingerprint_sha2" fi + else + outln "$spaces no RSA certificate, thus certificate can't be used with SSLv2 elsewhere" + fileout "drown" "INFO" "no RSA certificate, thus certificate can't be used with SSLv2 elsewhere" fi ret=0 ;; From 61b16a078abd151296bfe1379a7e0f4198358fc3 Mon Sep 17 00:00:00 2001 From: Dirk Date: Wed, 18 Jan 2017 16:38:09 +0100 Subject: [PATCH 50/61] - file etc/common-primes was not edited correctly! --- testssl.sh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/testssl.sh b/testssl.sh index 38f39f4..64a3513 100755 --- a/testssl.sh +++ b/testssl.sh @@ -9619,7 +9619,8 @@ run_logjam() { [[ "${dh_p:0:2}" == "00" ]] && dh_p="${dh_p:2}" debugme outln "dh_p: $dh_p" echo "$dh_p" > $TEMPDIR/dh_p.txt - common_primes_test $dh_p "$spaces" +# attention: file etc/common-primes.txt is not correct! + # common_primes_test $dh_p "$spaces" else out " no DH key detected" fileout "LOGJAM_common primes" "OK" "no DH key detected" @@ -9643,7 +9644,7 @@ common_primes_test() { fileout "LOGJAM_common primes" "WARN" "couldn't read common primes file $common_primes_file" return 1 else - lineno_matched=$(grep -n "$dh_p" "$common_primes_file" 2>/dev/null) + lineno_matched=$(grep -ni "$dh_p" "$common_primes_file" 2>/dev/null) if [[ "$lineno_matched" -ne 0 ]]; then # get comment comment="$(awk "NR == $lineno_matched-1" "$common_primes_file" | awk -F'"' '{ print $2 }')" From 05d27ff1be056122471b01fa3c643c430dcb88f3 Mon Sep 17 00:00:00 2001 From: Dirk Date: Wed, 18 Jan 2017 18:09:39 +0100 Subject: [PATCH 51/61] - FIX for the last mess submitted ;-) --- etc/common-primes.txt | 74 +++++++++++++++++++++---------------------- testssl.sh | 20 ++++++++---- 2 files changed, 50 insertions(+), 44 deletions(-) diff --git a/etc/common-primes.txt b/etc/common-primes.txt index 94727b2..e5fb6c5 100644 --- a/etc/common-primes.txt +++ b/etc/common-primes.txt @@ -2,111 +2,111 @@ ## taken from https://svn.nmap.org/nmap/scripts/ssl-dh-params.nse # "mod_ssl 2.0.x/512-bit MODP group with safe prime modulus" -D4BCD5206F69B3994B88D5DB8968C8157F6D8F3363EE5772F1F05AB2D6B51459F241E5CC31FF00A4BC7148976F7795094E1E790359F5A824B +D4BCD52406F69B35994B88DE5DB89682C8157F62D8F33633EE5772F11F05AB22D6B5145B9F241E5ACC31FF090A4BC71148976F76795094E71E7903529F5A824B # "mod_ssl 2.2.x/512-bit MODP group with safe prime modulus" -E6969D3495BE327CF180CBDD479891B781851BB0552A206494A79A77FA15A25CBD523AA6EF09C3048D5A2F971F320129B4000E6ED061CBC03E371D74E5327D611EBBB1BAC9B56044CF03D76E05EA9BAD91B13A63974E9EF839EB5D125136F262E56A871538DD823C655085E210DD5C86 +E6969D3D495BE32C7CF180C3BDD4798E91B7818251BB055E2A2064904A79A770FA15A259CBD523A6A6EF09C43048D5A22F971F3C20129B48000E6EDD061CBC053E371D794E5327DF611EBBBE1BAC9B5C6044CF023D76E05EEA9BAD991B13A63C974E9EF1839EB5DB125136F7262E56A8871538DFD823C6505085E21F0DD5C86B # "mod_ssl 2.2.x/512-bit MODP group with safe prime modulus" -9FDB8B8004544F045F173D0BA2E0274CDF19F58821FB43531A16E37471FD19DD8F37C3BF863FD0E3E30080A30306E4C375D08F70EAA87103 +9FDB8B8A004544F0045F1737D0BA2E0B274CDF1A9F588218FB435316A16E374171FD19D8D8F37C39BF863FD60E3E300680A3030C6E4C3757D08F70E6AA871033 # "mod_ssl 2.2.x/1024-bit MODP group with safe prime modulus" -D67DE44CBBBDC136D693D4AFD0AD0C84D23A45F520B88174C98BCE95849F912639C72F13B4B4D177E16D5AC179B420B2A2FE324A47A635E8FF590137BEDDCF33168A41AAD3B7DAE886078045B0A7DBCA774087D110EA9FC9DDD33007DD62D88AEAA77DE0F4DE2BD68BE7393E024218EB3 +D67DE440CBBBDC1936D693D34AFD0AD50C84D239A45F520BB88174CB98BCE951849F912E639C72FB13B4B4D7177E16D55AC179BA420B2A29FE324A467A635E81FF5901377BEDDCFD33168A461AAD3B72DAE8860078045B07A7DBCA7874087D1510EA9FCC9DDD330507DD62DB88AEAA747DE0F4D6E2BD68B0E7393E0F24218EB3 # "nginx/1024-bit MODP group with safe prime modulus" -BBBC2DCD8467497C43FCF80E9CFDD958A3F68B42D408EED4E0FB35046C03027E7108005CCBBAA922614CBEECA56A5FDF1D87A2BC09BE677860E91A9A757E308F68B07F7D36CCF29BA5D81DC2CA25ECE6670CC9A535D8CECEF9EA024A63AB158FAFD488D0F65146757D071DF04CFE16B9B +BBBC2DCAD84674907C43FCF580E9CFDBD958A3F568B42D4B08EED4EB0FB3504C6C030276E710800C5CCBBAA8922614C5BEECA565A5FDF1D287A2BC049BE6778060E91A92A757E3048F68B076F7D36CC8F29BA5DF81DC2CA725ECE66270CC9A5035D8CECEEF9EA0274A63AB1E58FAFD4988D0F65D146757DA071DF045CFE16B9B # "sun.security.provider/512-bit DSA group with 160-bit prime order subgroup" -FCA682C8E12CAB26EFCCF110E526B078B05DECBCD1B4A208FAE1617A01F35B9A47E6DF3413C5E2ED0899CD132AC50D9915BDC43EE37592E17 +FCA682CE8E12CABA26EFCCF7110E526DB078B05EDECBCD1EB4A208F3AE1617AE01F35B91A47E6DF63413C5E12ED0899BCD132ACD50D99151BDC43EE737592E17 # "sun.security.provider/768-bit DSA group with 160-bit prime order subgroup" -E9E64259D355F3C97FFD367120B825C9CD4E927B3A670FBECD89014122D2C3BAD2480037998691E846AA49FAB0A26D2CE622219D40BCE7D77D4A21FE9C270B7F60700F3CEF833694CF4EE3688C1A8C56A127A3DAF +E9E642599D355F37C97FFD3567120B8E25C9CD43E927B3A9670FBEC5D890141922D2C3B3AD2480093799869D1E846AAB49FAB0AD26D2CE6A22219D470BCE7D777D4A21FBE9C270B57F607002F3CEF8393694CF45EE3688C11A8C56AB127A3DAF # "sun.security.provider/1024-bit DSA group with 160-bit prime order subgroup" -FD7F5381D7512252DF4A92EECE4EF611B753CEF440C31E3F8B651266455D40251FB5938D58FABC5F5BA3F6CB9B56CD7813801D346F26660B6B9950AA49F9FE047B102C24FBBAD7FEB7C1BF83B5E7C6A8A150F04F83F6D3C1EC302354135A19132F67F3AE2B6D72AEFF2203199D14801C7 +FD7F53811D75122952DF4A9C2EECE4E7F611B7523CEF4400C31E3F80B6512669455D402251FB593D8D58FABFC5F5BA30F6CB9B556CD7813B801D346FF26660B76B9950A5A49F9FE8047B1022C24FBBA9D7FEB7C61BF83B57E7C6A8A6150F04FB83F6D3C51EC3023554135A169132F675F3AE2B61D72AEFF22203199DD14801C7 # "openssl/512-bit MODP group with safe prime modulus" -DA583C1D985228D0E4AF76F4CCA9DD4BE53B804FB0ED94EF98A4403E574650D6999DB2D776276A2D3D41E218F4D1E084CFD8003E74774E833 +DA583C16D9852289D0E4AF756F4CCA92DD4BE533B804FB0FED94EF9C8A4403ED574650D36999DB29D776276BA2D3D412E218F4DD1E084CF6D8003E7C4774E833 # "openssl/1024-bit MODP group with safe prime modulus" -97F6426CAB505D2828E131D68B6DDBD0F31047F40E56DA58C13B8A1B2B783A46D59D5F2AFC6CF3D693F7B23D4F360A95023EFAF7A5E1AD5A5E55431828DA839FF2D94DEE9568FADAEA036ADDF171FE63520AF47064603C2E059F54650AD8F0CF7012C74799D587132B9B999BBB787E8AB +97F64261CAB505DD2828E13F1D68B6D3DBD0F313047F40E856DA58CB13B8A1BF2B783A4C6D59D5F92AFC6CFF3D693F78B23D4F3160A9502E3EFAF7AB5E1AD5A65E554313828DA83B9FF2D941DEE95689FADAEA0936ADDF1971FE635B20AF470364603C2DE059F54B650AD8FA0CF70121C74799D7587132BE9B999BB9B787E8AB # "openssl/2048-bit MODP group with safe prime modulus" -ED92893824555C3BFBA275A69046BF21F3A53D2CD2DAFF7811152F10C1E255B686F68053B92262FE49A31F65CC5328ABDBDB49EDDA71266CFD2104718F07FDF75851172827B2A9341812FCB21C6D92AE4B6A829C27A3CB0C5F2E5F0AA4598A2BDAD4F0B3ADFE08135ED983B3CAEEAEB6E6A9576B9F128A3F2280D0BA6F67939B810F85A90ECCCA6F65F7AC011A1EF0F2DB60806228B0EDB8928E0CA83D69469166533C53613B02BAD48287A1C729E435FCC27E951DE685FC19976600F3F86BB3C520E29C07E8901CCCC001B6ADC3A308B33AAFD88C89D01DBAC4DD7F0BD6F38C3 +ED928935824555CB3BFBA2765A690461BF21F3AB53D2CD21DAFF78191152F10EC1E255BD686F680053B9226A2FE49A341F65CC59328ABDB1DB49EDDFA71266C3FD21047018F07FD6F758511972827B22A934181D2FCB21CF6D92AE43B6A829C727A3CB00C5F2E5FB0AA45985A2BDAD45F0B3ADF9E08135EED983B3CCAEEAEB66E6A95766B9F128A53F2280D70BA6F671939B810EF85A90E6CCCA6F665F7AC0101A1EF0FC2DB6080C6228B0ECDB8928EE0CA83D6594691669533C536013B02BA7D48287AD1C729E4135FCC27CE951DE6185FC199B76600F33F86BB3CA520E29C307E89016CCCC0019B6ADC3A4308B33A1AFD88C8D9D01DBA4C4DD7F0BBD6F38C3 # "openssl/2048-bit MODP group with safe prime modulus" -AED037CBDF33FAEEDC439B70A2087B77017E9B92EB0F8061CD4B5A59723C793FDA9F9F274490F50647285BE05921C4F2C05A4EE75A36613F382DBD44DE8A4A322122EC730A833E4800EBD6F854A518171BA54523C843FAC175FFAF49C440D446D846C1C345149EFA82F5C48A47BAC7F67EE00011AA9ED8101B36A5C39AAFEC54A3FF97C1B7F406DCB2DC092ABAA0625EFEB3FA12B42692E8F3EFB3F7B4C302A24CAA4213D45035CEA8ADD31816616F9E21A5C50805978980AD6814E3585B79E684491527552B72BC78D8D6993A7368486B3088B8F1B7E896688BD3F13DC517D4B +AED037C3BDF33FA2EEDC4390B70A20897B770175E9B92EB20F8061CCD4B5A591723C7934FDA9F9F3274490F8506472835BE059271C4F2C035A4EE756A36613F1382DBD474DE8A4A0322122E8C730A83C3E4800EEBD6F8548A5181711BA545231C843FAC4175FFAF849C440DB446D8462C1C3451B49EFA829F5C48A4C7BAC7F647EE000151AA9ED81101B36AB5C39AAFFEC54A3F8F97C1B7BF406DCB42DC092A5BAA06259EFEB3FAB12B426982E8F3EF4B3F7B4C3302A24C8AA4213D845035CE4A8ADD31F816616F19E21A5C95080597F8980AD6B814E35855B79E6844491527D552B72B7C78D8D6B993A736F8486B30588B8F1B87E89668A8BD3F13DDC517D4B # "openssl/4096-bit MODP group with safe prime modulus" -FEEAD19BEAF90F1CFCA105D69DB0839A2A26AEF248ABD7531BB3E4627DCECEFCEDCBBBF56549E95153058188C3D72941666AABA0A5CC85559125503180E9034C7F39CA3452F342EE72A7DFFC74528DB6D76D9C64F55D0839CDE74FE7424136947661D2670F2F6D59FFD7C3BDDED41E2B2CCDD9E12F1056AB88C44D7F9BA7651ED1A4D407A2D71895F77AB6C763CC00EF1C30B2E7944697E74BC7B8431B5011AF5A1515E63C1DE83C802ECE7FC71FBD179F8E4D7F1B43BA75D5AC3B11D41B0B5A088A9AACCCC105126DC841E41693E8591E31E2F5AFDAEDE1221277FC20BE4D251137A58E961EACF27D4C7E239190DD6AB27ECE5BD664C79B16C2D208D63A4B7F8DAE63DBE2C886BA10778A8DF5CE214A4B3D03C9175FBA578146CE5EC0177574481AD86F485465F5DA4B67F88260CE0BC0ACD157A377F10091AD0B6889303ECA33CDB61BA8CE32A87AF5D8B7F26734D209679232D70ADEF4A51D888BC57D2A638E014D66936776FFF355FEDF52201FA0CB8DB3FB54949951A70104AD49D71B74D09CAA8C05E833A2291D697F918F255C769BDE4BB72A4A1AFE60BBAD183EACC7B54AF4084F1CCB2B9AE576DAE2D1A8F43D27741DB19EDC3B815E569645F8C3363 +FEEAD19DBEAF90F61CFCA1065D69DB08839A2A2B6AEF2488ABD7531FBB3E462E7DCECEFBCEDCBBBDF56549EE951530568188C3D97294166B6AABA0AA5CC8555F9125503A180E90324C7F39C6A3452F3142EE72AB7DFFC74C528DB6DA76D9C644F55D083E9CDE74F7E742413B69476617D2670F2BF6D59FFCD7C3BDDEED41E2BD2CCDD9E612F1056CAB88C441D7F9BA74651ED1A84D407A27D71895F777AB6C7763CC00E6F1C30B2FE79446927E74BC73B8431B53011AF5AD1515E63DC1DE83CC802ECE7DFC71FBDF179F8E41D7F1B43EBA75D5A9C3B11D4F1B0B5A0988A9AACBCCC1051226DC8410E41693EC8591E31EE2F5AFDFAEDE122D1277FC270BE4D25C1137A58BE961EAC9F27D4C71E2391904DD6AB27BECE5BD6C64C79B146C2D208CD63A4B74F8DAE638DBE2C8806BA107738A8DF5CFE214A4B73D03C91275FBA5728146CE5FEC01775B74481ADF86F4854D65F5DA4BB67F882A60CE0BCA0ACD157AA377F10B091AD0B568893039ECA33CDCB61BA8C9E32A87A2F5D8B7FD26734D2F096792352D70ADE9F4A51D8488BC57D32A638E0B14D6693F6776FFFB355FEDF652201FA70CB8DB34FB549490951A701E04AD49D671B74D089CAA8C0E5E833A21291D6978F918F25D5C769BDBE4BB72A84A1AFE6A0BBAD18D3EACC7B454AF408D4F1CCB23B9AE576FDAE2D1A68F43D275741DB19EEDC3B81B5E56964F5F8C3363 # "RFC2409/Oakley Group 1" -FFFFFFFFFFFFFFC90FDAA2168C23C4C662880DC1CD29024E08A67CC7020BBEA3B139B2514A0878E3404DEF9519BCD3A431302B0A6F25F1434FE13566D51C24E485B57625E7ECF44C42EA63A362FFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A63A3620FFFFFFFFFFFFFFFF # "RFC2409/Oakley Group 2" -FFFFFFFFFFFFFFC90FDAA2168C23C4C662880DC1CD29024E08A67CC7020BBEA3B139B2514A0878E3404DEF9519BCD3A431302B0A6F25F1434FE13566D51C24E485B57625E7ECF44C42EA637ED60BFF5CBF406B7EEE386BF5A899FAAE9F2417C4B1FE4928665ECE6538FFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381FFFFFFFFFFFFFFFF # "RFC3526/Oakley Group 5" -FFFFFFFFFFFFFFC90FDAA2168C23C4C662880DC1CD29024E08A67CC7020BBEA3B139B2514A0878E3404DEF9519BCD3A431302B0A6F25F1434FE13566D51C24E485B57625E7ECF44C42EA637ED60BFF5CBF406B7EEE386BF5A899FAAE9F2417C4B1FE4928665ECE45B3C2007CBA163BF098DA4831C55D3969163FAFD24CF583655D2DCA3AD91C62F35208552B9ED52907096966670C3544ABC980F1746C0CA23732FFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA237327FFFFFFFFFFFFFFFF # "RFC3526/Oakley Group 14" -FFFFFFFFFFFFFFC90FDAA2168C23C4C662880DC1CD29024E08A67CC7020BBEA3B139B2514A0878E3404DEF9519BCD3A431302B0A6F25F1434FE13566D51C24E485B57625E7ECF44C42EA637ED60BFF5CBF406B7EEE386BF5A899FAAE9F2417C4B1FE4928665ECE45B3C2007CBA163BF098DA4831C55D3969163FAFD24CF583655D2DCA3AD91C62F35208552B9ED52907096966670C3544ABC980F1746C0CA1821732905E42E36CE3E39E772180E8609B2783AEC07A28B5C55DF6F4C52CDE2BCBF95581713995497EA956AE15D226198FA05115728E58AACAA6FFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AACAA68FFFFFFFFFFFFFFFF # "RFC3526/Oakley Group 15" -FFFFFFFFFFFFFFC90FDAA2168C23C4C662880DC1CD29024E08A67CC7020BBEA3B139B2514A0878E3404DEF9519BCD3A431302B0A6F25F1434FE13566D51C24E485B57625E7ECF44C42EA637ED60BFF5CBF406B7EEE386BF5A899FAAE9F2417C4B1FE4928665ECE45B3C2007CBA163BF098DA4831C55D3969163FAFD24CF583655D2DCA3AD91C62F35208552B9ED52907096966670C3544ABC980F1746C0CA1821732905E42E36CE3E39E772180E8609B2783AEC07A28B5C55DF6F4C52CDE2BCBF95581713995497EA956AE15D226198FA05115728E58AAAC42AD3317004507A3A85521ADF1CBA6ECFB85058DBEF08AEA7155D060C7B3970F8A6E1E4CABF5AE8DB0933D1E8C94E4A25619CEE3D221AD2EE6F12FFA0D98A086D8760273EC86A6521F2B1177B200BBE11757A615D6770988CBAD946E08E24FA74E5AB343DB5BFE0FD1084B82D12A93AD2CFFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6BF12FFA06D98A0864D87602733EC86A64521F2B18177B200CBBE117577A615D6C770988C0BAD946E208E24FA074E5AB3143DB5BFCE0FD108E4B82D120A93AD2CAFFFFFFFFFFFFFFFF # "RFC3526/Oakley Group 16" -FFFFFFFFFFFFFFC90FDAA2168C23C4C662880DC1CD29024E08A67CC7020BBEA3B139B2514A0878E3404DEF9519BCD3A431302B0A6F25F1434FE13566D51C24E485B57625E7ECF44C42EA637ED60BFF5CBF406B7EEE386BF5A899FAAE9F2417C4B1FE4928665ECE45B3C2007CBA163BF098DA4831C55D3969163FAFD24CF583655D2DCA3AD91C62F35208552B9ED52907096966670C3544ABC980F1746C0CA1821732905E42E36CE3E39E772180E8609B2783AEC07A28B5C55DF6F4C52CDE2BCBF95581713995497EA956AE15D226198FA05115728E58AAAC42AD3317004507A3A85521ADF1CBA6ECFB85058DBEF08AEA7155D060C7B3970F8A6E1E4CABF5AE8DB0933D1E8C94E4A25619CEE3D221AD2EE6F12FFA0D98A086D8760273EC86A6521F2B1177B200BBE11757A615D6770988CBAD946E08E24FA74E5AB343DB5BFE0FD1084B82D12A9210801A723C1A787E6D88719A1BDBA5B299C32716AF4E231A94683B6150BD2583E9C2AD44CEDBBBC2D04DE8EF2E8EFC11FBECAA287C5944E6BC0599B2964A090C3A233BA18515BE7E1F61297CEE2D7AB81BDD72170481D006912D5B05AA93B4EA98D8FDDC86FFB7D90A6C084DF435C3406319FFFFFFFFFFFFFFF +FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6BF12FFA06D98A0864D87602733EC86A64521F2B18177B200CBBE117577A615D6C770988C0BAD946E208E24FA074E5AB3143DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D788719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA2583E9CA2AD44CE8DBBBC2DB04DE8EF92E8EFC141FBECAA6287C59474E6BC05D99B2964FA090C3A2233BA186515BE7ED1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA993B4EA988D8FDDC186FFB7DC90A6C08F4DF435C934063199FFFFFFFFFFFFFFFF # "RFC5114/1024-bit DSA group with 160-bit prime order subgroup" -B10B8F9A080E01DE92DE5AE5D54E52C99FBFB06A3C9A6A9DC52D23B66073E2875A23D19838EF12EE652C13ECB4AA90611224975C3D49B83BACCBDD790C4BD798488E9219A7374EFFD6FE564473FAA31A4F55BCCCA151AF50DC8B4B45BF37D365C1A6E68CFDA6D4DA70DF1FB2B2E4A4371 +B10B8F96A080E01DDE92DE5EAE5D54EC52C99FBCFB06A3C69A6A9DCA52D23B616073E28675A23D189838EF1E2EE652C013ECB4AEA906112324975C3CD49B83BFACCBDD7D90C4BD7098488E9C219A73724EFFD6FAE5644738FAA31A4FF55BCCC0A151AF5F0DC8B4BD45BF37DF365C1A65E68CFDA76D4DA708DF1FB2BC2E4A4371 # "RFC5114/2048-bit DSA group with 224-bit prime order subgroup" -AD107E19123A9DD660FAA9559C51A20D64E683B9FDB54B159B61D0A7E6FA141F95A56DAF9A3C47BA1DF1EB3D688309C1801DE6B851274A0A6D3F815AD6AC219037C9EEFDA4DFD91E8FE55B73947AD5B7DB6C1220C9F98D1ED34DBFC6BA0B28BBC27B6A00E0AB9C4970B3BF8A370918838128613BC8985D1602E71415D933278273CDE31EFD7310F711FD5A0715987D9DC0A486CDF93AC4432838315D75E98C641A80CD86AB9E587EBE60E69C928B2BC52172E13042E923F10B016E7976C9B53DC4BA80A2E3FB73C6B8E75B7EF363EFFA31F7CF9DE534E71B810AC4DFF0C10E64F +AD107E1E9123A9D0D660FAA79559C51FA20D64E5683B9FD1B54B1597B61D0A75E6FA141DF95A56DBAF9A3C407BA1DF15EB3D688A309C180E1DE6B85A1274A0A66D3F8152AD6AC2129037C9EDEFDA4DF8D91E8FEF55B7394B7AD5B7D0B6C12207C9F98D11ED34DBF6C6BA0B2C8BBC27BE6A00E0A0B9C49708B3BF8A317091883681286130BC8985DB1602E714415D9330278273C7DE31EFDC7310F7121FD5A07415987D9ADC0A486DCDF93ACC44328387315D75E198C641A480CD86A1B9E587E8BE60E69CC928B2B9C52172E413042E9B23F10B0E16E79763C9B53DCF4BA80A29E3FB73C16B8E75B97EF363E2FFA31F71CF9DE5384E71B81C0AC4DFFE0C10E64F # "RFC5114/2048-bit DSA group with 256-bit prime order subgroup" -87A8E61B4B6663FFBBD1965195998CEEF60660DD0F5D2CEED435E3B0E00DF8FD61957DFAF7DF461B2AA316C3D9134096FA3BF4296830E9A7209E0C697517AB5A8A9D36BCF67E91F9E675B4758C22E0B1E4275BF76C5BFC1D45F908B941F54B1E59BBBC39A0B12307F54FDB70C81B23F7B63ACAECAA6B792D5252635488A0F13C6D951BFA4A3AD834796524D8F6A167BA41825D67E144E14056421CCACB8E6B486FB3CA3F77150602C0B857F8996285DED4010BD0BE62C3A396054E710C75F2637D701410A4B5433C198AF16116D226E11715693877FD7EF09CDB094AE1E1A1597 +87A8E61DB4B6663CFFBBD19C651959998CEEF608660DD0F25D2CEED4435E3B00E00DF8F1D61957D4FAF7DF4561B2AA3016C3D91134096FAA3BF4296D830E9A7C209E0C6497517ABD5A8A9D306BCF67ED91F9E6725B4758C022E0B1EF4275BF7B6C5BFC11D45F9088B941F54EB1E59BB8BC39A0BF12307F5C4FDB70C581B23F76B63ACAE1CAA6B7902D52526735488A0EF13C6D9A51BFA4AB3AD8347796524D8EF6A167B5A41825D967E144E5140564251CCACB83E6B486F6B3CA3F7971506026C0B857F689962856DED4010ABD0BE621C3A3960A54E710C375F26375D7014103A4B54330C198AF126116D2276E11715F693877FAD7EF09CADB094AE91E1A1597 # "weakdh.org/1024-bit MODP group with non-safe prime modulus" -D6C094A57F537468D58C7096872D45CEE1F2664E054421E1DE3C8E98C3F0A6A8F92F193FEF933B99B9C9A055D5596E42574005A68D47040FF00A5596EBA4B9F64CBA1004E451611C9B27438A70A2060C238D0CFAFFBBA48B9DAC4B450DC58B0320A017E2A3144A0278C657FB00CBEC11D +D6C094AD57F5374F68D58C7B096872D945CEE1F82664E0594421E1D5E3C8E98BC3F0A6AF8F92F19E3FEF9337B99B9C93A055D55A96E425734005A68ED47040FDF00A55936EBA4B93F64CBA1A004E4513611C9B217438A703A2060C2038D0CFAAFFBBA48FB9DAC4B2450DC58CB0320A0317E2A31B44A02787C657FB0C0CBEC11D # "weakdh.org/1024-bit MODP group with safe prime modulus" -C9BBF5F74A82970F97CDD3A3468C117B6BF99A13D91F5DAC47B2241F95EFB132855DFDF898B3F9188E24DF326DD8C76CC853728352D46F193129C69364D8C7202EABBEBC85C1F53907FD0B7EB40AD0BC928968680C46AB0BF7CDD9D425E6F25592EB258A065D75E93B671746A349E721B +C9BBF5F774A8297B0F97CDDA3A3468C7117B6BF799A13D9F1F5DAC487B2241FE95EFB13C2855DFD2F898B3F99188E24EDF326DD68C76CC85537283512D46F1953129C693364D8C71202EABB3EBC85C1DF53907FBD0B7EB490AD0BC99289686800C46AB04BF7CDD9AD425E6FB25592EB6258A0655D75E93B2671746AE349E721B "weakdh.org/1024-bit MODP group with safe prime modulus" -829FEBFE3EE043862D336A62BDE765F0C743A53B55291414FAE5E86D34B16DBCC952B15EB443B154B3B4662E811E1D8BC7334018A5A7B5B6A720D84B28B7482C5AF24C04E5BB5DABF8FFA5ED7B46688D6CB82F8AF188A4563ED62D2EACF6BDFD47337884DFA0F0A3D6975E3580E3AE9593 +829FEBFCE3EE0434862D3364A62BDE7B65F0C74A3A53B555291414FCAE5E86D734B16DBDCC952B1C5EB443B154B3B46662E811E11D8BC73134018A5EA7B5B6A9720D84BC28B74822C5AF24C904E5BB5ADABF8FF2A5ED7B456688D6CAB82F8AF0188A456C3ED62D2FEACF6BD3FD47337D884DFA09F0A3D69675E35806E3AE9593 # "weakdh.org/1024-bit MODP group with safe prime modulus" -9240243C3A12E4D3730D878CADFA8E2F5B5A956BFFDB8E5653E9695E3E32506FEB912FA77D22E1BB54C880893B8AD1BCF37F7F779D3FB96881D9BA17034ABF1F97B314CF3203663E8190B7E0906C4C5EEA0E57EC74D3E84D9E72E6C7DA6AE12DF297131854FF21AC4E79C23BB60B4F753 +92402435C3A12E44D3730D8E78CADFA78E2F5B51A956BFF4DB8E56523E9695E63E32506CFEB912F2A77D22E71BB54C8680893B82AD1BCF337F7F7796D3FB968181D9BA1F7034ABFB1F97B3104CF3203F663E81990B7E090F6C4C5EE1A0E57EC174D3E84AD9E72E6AC7DA6AEA12DF297C131854FBF21AC4E879C23BBC60B4F753 # "weakdh.org/1024-bit MODP group with safe prime modulus" -A9A3481446C7B6A29FF997C2181EFAAAD13CCDE245755D42F2E700AF86779D58A7C07C5DE423361117D05773F249C331AFA1B08EF360A14D4046F2762DA36A47D9FDE92B8815598C3A9546E7ED95D22EC9119F5B22CC41B0AF220F47BDE1B8334AD281DDC5E923F11CDDD3B22949DC41B +A9A34811446C7B69A29FF9997C2181ECFAAAD139CCDE2455755D42F42E700AFD86779D548A7C07CA5DE4233261117D0A5773F2459C331AF1A1B08EF8360A14DE4046F27462DA36AA47D9FDE292B8815D598C3A9C546E7ED395D22EC39119F5B922CC41B30AF220FF47BDE1B88334AD2981DDC5ED923F11C3DDD3B22C949DC41B # "weakdh.org/1024-bit MODP group with safe prime modulus" -CA6B8566DC21767605DACE801FAD59845384AF126CCC765E081014F293546ABDDE5C67C32D5B005B1BBF4C5DBFA253ADB3205B7D867DF98CBCE81C713F9FC215F1C33F953AB3CE8B7FEE3951FB31314074D5489BB17C6879A2EAF8195A8DE0A165E4B752077B167A00A5629FD5A9A25F3 +CA6B85646DC217657605DACFE801FAD7598453834AF126C8CC765E0F81014F2493546AB7DDE5C677C32D5B0605B1BBFA4C5DBFA3253ADB33205B7D8C67DF98C4BCE81C7813F9FC2615F1C332F953AB39CE8B7FE7E3951FB73131407F4D5489B6B17C68759A2EAF8B195A8DE80A165E4EB7520774B167A00FA5629FDC5A9A25F3 # "weakdh.org/1024-bit MODP group with safe prime modulus" -EB373E9AB618DF20D233E93E3EBC319BDAC0994C1D003986A9FAFFF754151CCE06413192698B4496F5FDFAF1289679D8BC1580D7D1CD83F8529C7953D58EC62E0E87FD008C13E3E5861B2D3A024D372CE4F220FE2C9039A997664AEBB75446AA69EBE0EF3C6F91C2632B54EC3A970A7BB +EB373E94AB618DF820D233ED93E3EBCB319BDAC20994C1DF003986A79FAFFF7654151CC9E064131492698B47496F5FDCFAF12892679D8BC31580D7D41CD83F81529C79513D58EC672E0E87FCD008C137E3E5861AB2D3A02F4D372CEE4F220FEB2C9039AC997664A7EBB754446AA69EB3E0EF3C60F91C26392B54EC35A970A7BB # "weakdh.org/1024-bit MODP group with safe prime modulus" -80A68AD5327E05AAD07C464B8ADE908432A9651B23F47A7A8F84D568DFDAFAB6621C0C28450F155F7D4AECE383F7D6055ADF60C4B37DCC1EB8374E3995179239FDC3BB428511C8B4A9FFCE4DD5AA23F992647C39CE4D8BB2E773F4EB786CE4CD0C3D4C31D75D1CF9E970C45EE8ECDABAB +80A68ADC5327E05CAAD07C4464B8ADEA908432AF9651B237F47A7A8BF84D568FDFDAFAB06621C0C428450F1C55F7D4A8ECE383F27D6055ADDF60C4B837DCC1E3B8374E379951792939FDC3BBB4285112C8B4A9F6FCE4DD53AA23F99E2647C394CE4D8BB82E773F41EB786CE84CD0C3DD4C31D755D1CF9E9B70C45EE28ECDABAB # "weakdh.org/1024-bit MODP group with safe prime modulus" -C0EB5F34CB30A9FE3786E4C0381469B52035AD49F5EFD8CAA31A69B273CC9F5B4B8F802C5FB683913B612042D2EBD533815E59769C9E97BD488DB335581320DD4AF9CE4A4EBE9118C6828E5B3989C26720B4FDC210C288B174D77E0AAD9C117EA5ED7CF971BB19A8718E52982591CA14B +C0EB5F3A4CB30A9FFE3786E84C03814169B520305AD49F54EFD8CAAC31A69B2973CC9F57B4B8F80D2C5FB68B3913B6172042D2E5BD53381A5E597696C9E97BD6488DB3395581320DDD4AF9CDE4A4EBE29118C68828E5B39289C267280B4FDC2510C288B2174D77EE0AAD9C1E17EA5ED37CF971B6B19A87118E529826591CA14B # "weakdh.org/1024-bit MODP group with safe prime modulus" -8FC0E1E0574D6A3C76DDE64524C276446B698E5B6B2614F969A5061D99034DB819780E8EE28A466B5C4EA634E47F9C981AEC4908E1B83A41813165A0AB6BDCD325718AC49399541C16F960F9D6B9C51EC85AD0BBFE3890118F0CD665D4B1B1C72395B83217FB3EBF878160E827911754B +8FC0E1E20574D6AB3C76DDEA64524C2076446B6798E5B6BD2614F9669A5061D699034DB4819780EC8EE28A4E66B5C4E0A634E47BF9C981A5EC4908EE1B83A410813165AC0AB6BDCFD3257188AC49399D541C16F2960F9D64B9C51EC085AD0BB4FE38901318F0CD6165D4B1B31C723953B83217F8B3EBF8708160E82D7911754B # "haproxy 1.5 builtin" -EC86F87A03316E051A735CD1F8BF29E4D2C52DDC228DB5389FB5CA4EB2DACE65074A684D4B1D3B82BF31E9A72D071E781D8B595235F430B6F1DB07B086B1B2EE4DCC90E43A01DF438CEBEBE90B5154B927B647645DD42EAC29EAE54359C779C503C0ED73045F14C762D8F8CFF3440D1B4261846423904F68B262D55ED1B77591E0C69C1315DB7B442CE845801E660CC449EFD408675DFA7768F01187E99F97DC4B745520D4A412F4421AC1F9717492376B2F87E1CA0A899227D565A71C56377E39D05E7E5D8F821BCE9C293082F9FC9AE49DD054B4D754DFA0B8D6384B71F77F +EC86F870A03316EC051A7359CD1F8BF829E4D2CF52DDC2248DB5389AFB5CA4E4B2DACE665074A6854D4B1D30B82BF310E9A72D0571E781DF8B59523B5F430B68F1DB07BE086B1B23EE4DCC9E0E43A01EDF438CECBEBE90B45154B92F7B64764E5DD42EAEC29EAE514359C7779C503C0EED73045FF14C762AD8F8CFFC3440D1B442618466423904F868B262D755ED1B747591E0C569C1315CDB7B442ECE84580D1E660CC8449EFD4008675DFBA7768F001187E993F97DC4BC745520D44A412F43421AC1F297174927376B2F887E1CA0A1899227D9565A71C156377E3A9D05E7EE5D8F8217BCE9C2933082F9F4C9AE49DBD054B4D9754DFA06B8D63841B71F77F3 # "postfix builtin" -B0FEB4CD45507ECC885901726C50A54A9228178DA8AA4C130BF5D2F9BC96B85009D0C075ADFD3B17E7143F9154144B83021CEBDF79C4CF180D683F98EA4FB78918B291690019668C5384E273D9E75A7AAD5ECE27FAED011C278255065C39FCD4954AC1B1EA4F953D0D6DAFD49E7BAAE9B +B0FEB4CFD45507E7CC88590D1726C50CA54A92238178DA88AA4C1306BF5D2F9EBC96B851009D0C0D75ADFD3BB17E714F3F91541444B830251CEBDF729C4CF1890D683F948EA4FB768918B29116900199668C53814E273D99E75A7AAFD5ECE27EFAED0118C2782559065C39F6CD4954AFC1B1EA4AF953D0DF6DAFD493E7BAAE9B -# "IronPort SMTPbuiltin" -F8D5CCE7A3961BF5CBC8340C5185E0E6FA65AB283178C86761CA46CA7D7FA3BAF75B833C69937D36920FE39A653E8F0725A6E2D297537558E27E7844B549BEB558927A30C8BD1DACDCA93027B5CE1BC1770AF7DEE81149AD7D632DB80A639CEBCC7A619CCF3288EA3D2328774B04E6FB3 +# "IronPort SMTPD builtin" +F8D5CCE87A3961B5F5CBC83440C51856E0E6FA6D5AB2831078C867621CA46CA87D7FA3B1AF75B8343C699374D36920F2E39A653DE8F0725AA6E2D2977537558CE27E784F4B549BEFB558927BA30C8BD81DACDCAE93027B5DCE1BC17670AF7DECE81149ABD7D632D9B80A6397CEBCC7A9619CCF38288EA3D523287743B04E6FB3 ## taken from https://github.com/cryptosense/diffie-hellman-groups/blob/master/gen/common.json -# to be continueed +# to be continued diff --git a/testssl.sh b/testssl.sh index 64a3513..14a7e61 100755 --- a/testssl.sh +++ b/testssl.sh @@ -9568,10 +9568,10 @@ run_logjam() { fi if [[ $sclient_success -eq 0 ]]; then - pr_svrty_high "VULNERABLE (NOT ok):"; out " uses DHE EXPORT ciphers," + pr_svrty_high "VULNERABLE (NOT ok):"; out " uses DHE EXPORT ciphers" fileout "logjam" "HIGH" "LOGJAM: VULNERABLE, uses DHE EXPORT ciphers" "$cve" "$cwe" "$hint" else - pr_done_good "not vulnerable (OK):"; out " no DHE EXPORT ciphers,"; out "$addtl_warning" + pr_done_good "not vulnerable (OK):"; out " no DHE EXPORT ciphers"; out "$addtl_warning" fileout "logjam" "OK" "LOGJAM: not vulnerable (no DHE EXPORT ciphers) $addtl_warning" "$cve" "$cwe" fi @@ -9620,9 +9620,9 @@ run_logjam() { debugme outln "dh_p: $dh_p" echo "$dh_p" > $TEMPDIR/dh_p.txt # attention: file etc/common-primes.txt is not correct! - # common_primes_test $dh_p "$spaces" + common_primes_test $dh_p "$spaces" else - out " no DH key detected" + out ", no DH key detected" fileout "LOGJAM_common primes" "OK" "no DH key detected" fi outln @@ -9637,6 +9637,7 @@ common_primes_test() { local common_primes_file="$TESTSSL_INSTALL_DIR/etc/common-primes.txt" local -i lineno_matched=0 local comment="" + local dhp="$1" if [[ ! -s "$common_primes_file" ]]; then outln @@ -9644,14 +9645,19 @@ common_primes_test() { fileout "LOGJAM_common primes" "WARN" "couldn't read common primes file $common_primes_file" return 1 else - lineno_matched=$(grep -ni "$dh_p" "$common_primes_file" 2>/dev/null) + dh_p="$(toupper "$dh_p")" + # the most elegant thing to get the previous line " awk '/regex/ { print x }; { x=$0 }' " doesn't work with GNU grep + # this is bascially the hint we want to echo + lineno_matched=$(grep -n "$dh_p" "$common_primes_file" 2>/dev/null | awk -F':' '{ print $1 }') if [[ "$lineno_matched" -ne 0 ]]; then # get comment comment="$(awk "NR == $lineno_matched-1" "$common_primes_file" | awk -F'"' '{ print $2 }')" #FiXME: probably the high groups/bit sizes whould get a different rating, see paper - pr_svrty_high "common prime $comment detected" - fileout "LOGJAM_common primes" "HIGH" "common prime $comment detected" + out "\n${2}" + pr_svrty_high "common prime \"$comment\" detected" + fileout "LOGJAM_common primes" "HIGH" "common prime \"$comment\" detected" else + out ", " pr_done_good " no common primes detected" fileout "LOGJAM_common primes" "OK" "no common primes detected" fi From dcd37729f4e226138ce392c84dc1d496b8deae2a Mon Sep 17 00:00:00 2001 From: David Cooper Date: Wed, 18 Jan 2017 15:16:13 -0500 Subject: [PATCH 52/61] Generate list of all DHE ciphers This PR adds a function that generates a list of all DHE ciphers for `run_logjam()`. --- utils/generate_static_cipher_lists.sh | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/utils/generate_static_cipher_lists.sh b/utils/generate_static_cipher_lists.sh index b85914d..f2b5fe2 100644 --- a/utils/generate_static_cipher_lists.sh +++ b/utils/generate_static_cipher_lists.sh @@ -324,6 +324,21 @@ get_weak_dh_ciphers() { outln "exportdhe_cipher_list_hex=\"${exportdhe_cipher_list_hex:2}\"" } +get_dhe_ciphers() { + local -i + local hexc all_dhe_ciphers="" + + for (( i=0; i < TLS_NR_CIPHERS; i++ )); do + if [[ "${TLS_CIPHER_RFC_NAME[i]}" == "TLS_DHE_"* ]] || [[ "${TLS_CIPHER_RFC_NAME[i]}" == "TLS_DH_anon_"* ]]; then + hexc="${TLS_CIPHER_HEXCODE[i]}" + all_dhe_ciphers+=", ${hexc:2:2},${hexc:7:2}" + fi + done + + outln; pr_underline "All DHE ciphers for run_logjam()"; outln + outln "all_dhe_ciphers=\"$(tolower "${all_dhe_ciphers:2}")\"" +} + get_mapping_file get_robust_pfs_ciphers get_std_cipherlists @@ -331,6 +346,7 @@ get_cbc_ciphers get_sslv3_tls1_cbc_ciphers get_export_rsa_ciphers get_weak_dh_ciphers +get_dhe_ciphers outln exit $? From e3d183e9099103c303ea5fe9bc33413565319e67 Mon Sep 17 00:00:00 2001 From: Dirk Date: Wed, 18 Jan 2017 22:05:27 +0100 Subject: [PATCH 53/61] -output correction run_logjam - rename dhe to dh --- testssl.sh | 146 +++++++++++++++++++++++++++++++---------------------- 1 file changed, 87 insertions(+), 59 deletions(-) diff --git a/testssl.sh b/testssl.sh index 14a7e61..1e87fa4 100755 --- a/testssl.sh +++ b/testssl.sh @@ -9524,8 +9524,8 @@ run_freak() { # see https://weakdh.org/logjam.html run_logjam() { local -i sclient_success=0 - local exportdhe_cipher_list="EXP1024-DHE-DSS-DES-CBC-SHA:EXP1024-DHE-DSS-RC4-SHA:EXP-EDH-RSA-DES-CBC-SHA:EXP-EDH-DSS-DES-CBC-SHA" - local exportdhe_cipher_list_hex="00,63, 00,65, 00,14, 00,11" + local exportdh_cipher_list="EXP1024-DHE-DSS-DES-CBC-SHA:EXP1024-DHE-DSS-RC4-SHA:EXP-EDH-RSA-DES-CBC-SHA:EXP-EDH-DSS-DES-CBC-SHA" + local exportdh_cipher_list_hex="00,63, 00,65, 00,14, 00,11" local all_dhe_ciphers="cc,15, 00,b3, 00,91, c0,97, 00,a3, 00,9f, cc,aa, c0,a3, c0,9f, 00,6b, 00,6a, 00,39, 00,38, 00,c4, 00,c3, 00,88, 00,87, 00,a7, 00,6d, 00,3a, 00,c5, 00,89, 00,ab, cc,ad, c0,a7, c0,43, c0,45, c0,47, c0,53, c0,57, c0,5b, c0,67, c0,6d, c0,7d, c0,81, c0,85, c0,91, 00,a2, 00,9e, c0,a2, c0,9e, 00,aa, c0,a6, 00,67, 00,40, 00,33, 00,32, 00,be, 00,bd, 00,9a, 00,99, 00,45, 00,44, 00,a6, 00,6c, 00,34, 00,bf, 00,9b, 00,46, 00,b2, 00,90, c0,96, c0,42, c0,44, c0,46, c0,52, c0,56, c0,5a, c0,66, c0,6c, c0,7c, c0,80, c0,84, c0,90, 00,66, 00,18, 00,8e, 00,16, 00,13, 00,1b, 00,8f, 00,63, 00,15, 00,12, 00,1a, 00,65, 00,14, 00,11, 00,19, 00,17, 00,b5, 00,b4, 00,2d" local -i i nr_supported_ciphers=0 server_key_exchange_len=0 ephemeral_pub_len=0 local addtl_warning="" hexc @@ -9535,6 +9535,11 @@ run_logjam() { local server_key_exchange ephemeral_pub key_bitstring="" dh_p local using_sockets=true local spaces=" " + local vuln_exportdh_ciphers=false + local common_primes_file="$TESTSSL_INSTALL_DIR/etc/common-primes.txt" + local comment="" + local -i lineno_matched=0 + local -i ret "$SSL_NATIVE" && using_sockets=false @@ -9542,42 +9547,40 @@ run_logjam() { pr_bold " LOGJAM"; out " ($cve), experimental " if "$using_sockets"; then - nr_supported_ciphers=$(count_words "$exportdhe_cipher_list_hex") + nr_supported_ciphers=$(count_words "$exportdh_cipher_list_hex") else - nr_supported_ciphers=$(count_ciphers $(actually_supported_ciphers $exportdhe_cipher_list)) + nr_supported_ciphers=$(count_ciphers $(actually_supported_ciphers $exportdh_cipher_list)) fi + debugme echo $nr_supported_ciphers case $nr_supported_ciphers in - 0) local_problem_ln "$OPENSSL doesn't have any DHE EXPORT ciphers configured" - fileout "logjam" "WARN" "LOGJAM: Not tested. $OPENSSL doesn't have any DHE EXPORT ciphers configured" "$cve" "$cwe" - return 3 + 0) local_problem_ln "$OPENSSL doesn't have any DH EXPORT ciphers configured" + fileout "logjam" "WARN" "LOGJAM: Not tested. $OPENSSL doesn't have any DH EXPORT ciphers configured" "$cve" "$cwe" +# FIXME: needed to be handled below ;; 1|2) addtl_warning=" ($magenta""tested w/ $nr_supported_ciphers/4 ciphers only!$off)" ;; 3) addtl_warning=" (tested w/ $nr_supported_ciphers/4 ciphers)" ;; 4) ;; esac + + # test for DH export ciphers first if "$using_sockets"; then - tls_sockets "03" "$exportdhe_cipher_list_hex" + tls_sockets "03" "$exportdh_cipher_list_hex" sclient_success=$? [[ $sclient_success -eq 2 ]] && sclient_success=0 else - $OPENSSL s_client $STARTTLS $BUGS -cipher $exportdhe_cipher_list -connect $NODEIP:$PORT $PROXY $SNI >$TMPFILE 2>$ERRFILE $TMPFILE 2>$ERRFILE $TEMPDIR/dh_p.txt -# attention: file etc/common-primes.txt is not correct! - common_primes_test $dh_p "$spaces" - else - out ", no DH key detected" - fileout "LOGJAM_common primes" "OK" "no DH key detected" - fi - outln - - tmpfile_handle $FUNCNAME.txt - return $sclient_success -} - -# takes one arg and compares against a predefined set in $TESTSSL_INSTALL_DIR -# spaces to indent -common_primes_test() { - local common_primes_file="$TESTSSL_INSTALL_DIR/etc/common-primes.txt" - local -i lineno_matched=0 - local comment="" - local dhp="$1" - - if [[ ! -s "$common_primes_file" ]]; then - outln - pr_warning "${2}couldn't read common primes file $common_primes_file" - fileout "LOGJAM_common primes" "WARN" "couldn't read common primes file $common_primes_file" - return 1 - else - dh_p="$(toupper "$dh_p")" - # the most elegant thing to get the previous line " awk '/regex/ { print x }; { x=$0 }' " doesn't work with GNU grep - # this is bascially the hint we want to echo - lineno_matched=$(grep -n "$dh_p" "$common_primes_file" 2>/dev/null | awk -F':' '{ print $1 }') - if [[ "$lineno_matched" -ne 0 ]]; then - # get comment - comment="$(awk "NR == $lineno_matched-1" "$common_primes_file" | awk -F'"' '{ print $2 }')" -#FiXME: probably the high groups/bit sizes whould get a different rating, see paper - out "\n${2}" - pr_svrty_high "common prime \"$comment\" detected" - fileout "LOGJAM_common primes" "HIGH" "common prime \"$comment\" detected" + if [[ ! -s "$common_primes_file" ]]; then + local_problem_ln "couldn't read common primes file $common_primes_file" + out "${spaces}" + fileout "LOGJAM_common primes" "WARN" "couldn't read common primes file $common_primes_file" + ret=7 else - out ", " - pr_done_good " no common primes detected" + dh_p="$(toupper "$dh_p")" + # In the previous line of the match is bascially the hint we want to echo + # the most elegant thing to get the previous line [ awk '/regex/ { print x }; { x=$0 }' ] doesn't work with GNU grep + lineno_matched=$(grep -n "$dh_p" "$common_primes_file" 2>/dev/null | awk -F':' '{ print $1 }') + if [[ "$lineno_matched" -ne 0 ]]; then + # get comment + comment="$(awk "NR == $lineno_matched-1" "$common_primes_file" | awk -F'"' '{ print $2 }')" +#FiXME: probably the high groups/bit sizes whould get a different rating, see paper + ret=1 + # vulnerable: common prime + else + ret=0 + # not vulnerable: no known common prime + fi + fi + else + ret=3 + # no DH key detected + fi + + # now the final verdict + # we only use once the color here on the screen, so screen and fileout SEEM to be inconsistent + if "$vuln_exportdh_ciphers"; then + pr_svrty_high "VULNERABLE (NOT ok):"; out " uses DH EXPORT ciphers" + fileout "logjam" "HIGH" "LOGJAM: VULNERABLE, uses DH EXPORT ciphers" "$cve" "$cwe" "$hint" + if [[ $ret -eq 3 ]]; then + out ", no DH key detected" + fileout "LOGJAM_common primes" "OK" "no DH key detected" + elif [[ $ret -eq 1 ]]; then + out "\n${spaces}" + pr_svrty_high "VULNERABLE (NOT ok):"; out "common prime \"$comment\" detected" + fileout "LOGJAM_common primes" "HIGH" "common prime \"$comment\" detected" + elif [[ $ret -eq 0 ]]; then + out " no common primes detected" + fileout "LOGJAM_common primes" "INFO" "no common primes detected" + elif [[ $ret -eq 7 ]]; then + out "FIXME 1" + fi + else + if [[ $ret -eq 1 ]]; then + pr_svrty_high "VULNERABLE (NOT ok):" ; out " uses common prime \"$comment\"" + fileout "LOGJAM_common primes" "HIGH" "common prime \"$comment\" detected" + out ", but no DH EXPORT ciphers${addtl_warning}" + fileout "logjam" "OK" "LOGJAM: 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}" + fileout "logjam" "OK" "LOGJAM: not vulnerable, no DH EXPORT ciphers, $addtl_warning" "$cve" "$cwe" + out ", no DH key detected" + fileout "LOGJAM_common primes" "OK" "no DH key detected" + elif [[ $ret -eq 0 ]]; then + pr_done_good "not vulnerable (OK):"; out " no DH EXPORT ciphers${ddtl_warning}" + fileout "logjam" "OK" "LOGJAM: not vulnerable, no DH EXPORT ciphers, $addtl_warning" "$cve" "$cwe" + out ", no common primes detected" fileout "LOGJAM_common primes" "OK" "no common primes detected" + elif [[ $ret -eq 7 ]]; then + pr_done_good "partly not vulnerable:"; out " no DH EXPORT ciphers${ddtl_warning}" + fileout "logjam" "OK" "LOGJAM: not vulnerable, no DH EXPORT ciphers, $addtl_warning" "$cve" "$cwe" fi fi + outln + tmpfile_handle $FUNCNAME.txt return 0 } From e083fab1307649b01443e4b0819b7208b8bc93ec Mon Sep 17 00:00:00 2001 From: Dirk Date: Thu, 19 Jan 2017 14:45:19 +0100 Subject: [PATCH 54/61] - run_logjam(): run_logjam(0 fixed error where logjam couldn't parse "ServerKeyExchange" message using SSL_NATIVE -- if TLS != 1.2 was returned - run_logjam(): determine dh bit size and based on this mark the common primes as more or less vulnerable - run_logjam(): renamed remaining dhe variable to dh - further house keeping in run_logjam() --- testssl.sh | 98 ++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 65 insertions(+), 33 deletions(-) diff --git a/testssl.sh b/testssl.sh index 1e87fa4..5f8c392 100755 --- a/testssl.sh +++ b/testssl.sh @@ -9526,42 +9526,43 @@ run_logjam() { local -i sclient_success=0 local exportdh_cipher_list="EXP1024-DHE-DSS-DES-CBC-SHA:EXP1024-DHE-DSS-RC4-SHA:EXP-EDH-RSA-DES-CBC-SHA:EXP-EDH-DSS-DES-CBC-SHA" local exportdh_cipher_list_hex="00,63, 00,65, 00,14, 00,11" - local all_dhe_ciphers="cc,15, 00,b3, 00,91, c0,97, 00,a3, 00,9f, cc,aa, c0,a3, c0,9f, 00,6b, 00,6a, 00,39, 00,38, 00,c4, 00,c3, 00,88, 00,87, 00,a7, 00,6d, 00,3a, 00,c5, 00,89, 00,ab, cc,ad, c0,a7, c0,43, c0,45, c0,47, c0,53, c0,57, c0,5b, c0,67, c0,6d, c0,7d, c0,81, c0,85, c0,91, 00,a2, 00,9e, c0,a2, c0,9e, 00,aa, c0,a6, 00,67, 00,40, 00,33, 00,32, 00,be, 00,bd, 00,9a, 00,99, 00,45, 00,44, 00,a6, 00,6c, 00,34, 00,bf, 00,9b, 00,46, 00,b2, 00,90, c0,96, c0,42, c0,44, c0,46, c0,52, c0,56, c0,5a, c0,66, c0,6c, c0,7c, c0,80, c0,84, c0,90, 00,66, 00,18, 00,8e, 00,16, 00,13, 00,1b, 00,8f, 00,63, 00,15, 00,12, 00,1a, 00,65, 00,14, 00,11, 00,19, 00,17, 00,b5, 00,b4, 00,2d" - local -i i nr_supported_ciphers=0 server_key_exchange_len=0 ephemeral_pub_len=0 + local all_dh_ciphers="cc,15, 00,b3, 00,91, c0,97, 00,a3, 00,9f, cc,aa, c0,a3, c0,9f, 00,6b, 00,6a, 00,39, 00,38, 00,c4, 00,c3, 00,88, 00,87, 00,a7, 00,6d, 00,3a, 00,c5, 00,89, 00,ab, cc,ad, c0,a7, c0,43, c0,45, c0,47, c0,53, c0,57, c0,5b, c0,67, c0,6d, c0,7d, c0,81, c0,85, c0,91, 00,a2, 00,9e, c0,a2, c0,9e, 00,aa, c0,a6, 00,67, 00,40, 00,33, 00,32, 00,be, 00,bd, 00,9a, 00,99, 00,45, 00,44, 00,a6, 00,6c, 00,34, 00,bf, 00,9b, 00,46, 00,b2, 00,90, c0,96, c0,42, c0,44, c0,46, c0,52, c0,56, c0,5a, c0,66, c0,6c, c0,7c, c0,80, c0,84, c0,90, 00,66, 00,18, 00,8e, 00,16, 00,13, 00,1b, 00,8f, 00,63, 00,15, 00,12, 00,1a, 00,65, 00,14, 00,11, 00,19, 00,17, 00,b5, 00,b4, 00,2d" + local -i i nr_supported_ciphers=0 server_key_exchange_len=0 ephemeral_pub_len=0 len_dh_p=0 local addtl_warning="" hexc local cve="CVE-2015-4000" local cwe="CWE-310" local hint="" - local server_key_exchange ephemeral_pub key_bitstring="" dh_p - local using_sockets=true + local server_key_exchange ephemeral_pub key_bitstring="" + local dh_p="" local spaces=" " local vuln_exportdh_ciphers=false local common_primes_file="$TESTSSL_INSTALL_DIR/etc/common-primes.txt" - local comment="" + local comment="" str="" local -i lineno_matched=0 local -i ret + local using_sockets=true "$SSL_NATIVE" && using_sockets=false + # Also as the openssl binary distributed has everything we need measurements show that + # there's no impact whether we use sockets or TLS here, so the default is sockets here [[ $VULN_COUNT -le $VULN_THRESHLD ]] && outln && pr_headlineln " Testing for LOGJAM vulnerability " && outln pr_bold " LOGJAM"; out " ($cve), experimental " - if "$using_sockets"; then - nr_supported_ciphers=$(count_words "$exportdh_cipher_list_hex") - else + if ! "$using_sockets"; then nr_supported_ciphers=$(count_ciphers $(actually_supported_ciphers $exportdh_cipher_list)) - fi - debugme echo $nr_supported_ciphers + debugme echo $nr_supported_ciphers - case $nr_supported_ciphers in - 0) local_problem_ln "$OPENSSL doesn't have any DH EXPORT ciphers configured" - fileout "logjam" "WARN" "LOGJAM: Not tested. $OPENSSL doesn't have any DH EXPORT ciphers configured" "$cve" "$cwe" + case $nr_supported_ciphers in + 0) local_problem_ln "$OPENSSL doesn't have any DH EXPORT ciphers configured" + fileout "logjam" "WARN" "LOGJAM: Not tested. $OPENSSL doesn't have any DH EXPORT ciphers configured" "$cve" "$cwe" # FIXME: needed to be handled below - ;; - 1|2) addtl_warning=" ($magenta""tested w/ $nr_supported_ciphers/4 ciphers only!$off)" ;; - 3) addtl_warning=" (tested w/ $nr_supported_ciphers/4 ciphers)" ;; - 4) ;; - esac + ;; + 1|2) addtl_warning=" ($magenta""tested w/ $nr_supported_ciphers/4 ciphers only!$off)" ;; + 3) addtl_warning=" (tested w/ $nr_supported_ciphers/4 ciphers)" ;; + 4) ;; + esac + fi # test for DH export ciphers first if "$using_sockets"; then @@ -9595,7 +9596,7 @@ run_logjam() { # Try all ciphers that use an ephemeral DH key. If successful, check whether the key uses a weak prime. if "$using_sockets"; then - tls_sockets "03" "$all_dhe_ciphers" "ephemeralkey" + tls_sockets "03" "$all_dh_ciphers" "ephemeralkey" sclient_success=$? if [[ $sclient_success -eq 0 ]] || [[ $sclient_success -eq 2 ]]; then cp "$TEMPDIR/$NODEIP.parse_tls_serverhello.txt" $TMPFILE @@ -9605,7 +9606,12 @@ run_logjam() { $OPENSSL s_client $STARTTLS $BUGS -cipher kEDH -msg -connect $NODEIP:$PORT $PROXY $SNI >$TMPFILE 2>$ERRFILE $TEMPDIR/dh_p.txt if [[ ! -s "$common_primes_file" ]]; then local_problem_ln "couldn't read common primes file $common_primes_file" @@ -9634,19 +9641,14 @@ run_logjam() { # the most elegant thing to get the previous line [ awk '/regex/ { print x }; { x=$0 }' ] doesn't work with GNU grep lineno_matched=$(grep -n "$dh_p" "$common_primes_file" 2>/dev/null | awk -F':' '{ print $1 }') if [[ "$lineno_matched" -ne 0 ]]; then - # get comment comment="$(awk "NR == $lineno_matched-1" "$common_primes_file" | awk -F'"' '{ print $2 }')" -#FiXME: probably the high groups/bit sizes whould get a different rating, see paper - ret=1 - # vulnerable: common prime + ret=1 # vulnerable: common prime else - ret=0 - # not vulnerable: no known common prime + ret=0 # not vulnerable: no known common prime fi fi else - ret=3 - # no DH key detected + ret=3 # no DH key detected fi # now the final verdict @@ -9659,8 +9661,23 @@ run_logjam() { fileout "LOGJAM_common primes" "OK" "no DH key detected" elif [[ $ret -eq 1 ]]; then out "\n${spaces}" - pr_svrty_high "VULNERABLE (NOT ok):"; out "common prime \"$comment\" detected" - fileout "LOGJAM_common primes" "HIGH" "common prime \"$comment\" detected" + # now size matters -- i.e. the bit size ;-) + if [[ $len_dh_p -le 512 ]]; then + pr_svrty_critical "VULNERABLE (NOT ok):"; out " common prime \"$comment\" detected ($len_dh_p bits)" + fileout "LOGJAM_common primes" "CRITICAL" "common prime \"$comment\" detected" + elif [[ $len_dh_p -le 1024 ]]; then + pr_svrty_high "VULNERABLE (NOT ok):"; out " common prime \"$comment\" detected ($len_dh_p bits)" + fileout "LOGJAM_common primes" "HIGH" "common prime \"$comment\" detected" + elif [[ $len_dh_p -le 1536 ]]; then + pr_svrty_medium "common prime with $len_dh_p bits detected: \"$comment\"" + fileout "LOGJAM_common primes" "MEDIUM" "common prime \"$comment\" detected" + elif [[ $len_dh_p -le 2048 ]]; then + pr_svrty_minor "common prime with $len_dh_p bits detected: \"$comment\"" + fileout "LOGJAM_common primes" "LOW" "common prime \"$comment\" detected" + else + out "common prime with $len_dh_p bits detected: \"$comment\"" + fileout "LOGJAM_common primes" "INFO" "common prime \"$comment\" detected" + fi elif [[ $ret -eq 0 ]]; then out " no common primes detected" fileout "LOGJAM_common primes" "INFO" "no common primes detected" @@ -9669,8 +9686,23 @@ run_logjam() { fi else if [[ $ret -eq 1 ]]; then - pr_svrty_high "VULNERABLE (NOT ok):" ; out " uses common prime \"$comment\"" - fileout "LOGJAM_common primes" "HIGH" "common prime \"$comment\" detected" + # now size matters -- i.e. the bit size ;-) + if [[ $len_dh_p -le 512 ]]; then + pr_svrty_critical "VULNERABLE (NOT ok):" ; out " uses common prime \"$comment\" ($len_dh_p bits)" + fileout "LOGJAM_common primes" "CRITICAL" "common prime \"$comment\" detected" + elif [[ $len_dh_p -le 1024 ]]; then + pr_svrty_high "VULNERABLE (NOT ok):"; out " common prime \"$comment\" detected ($len_dh_p bits)" + fileout "LOGJAM_common primes" "HIGH" "common prime \"$comment\" detected" + elif [[ $len_dh_p -le 1536 ]]; then + pr_svrty_medium "Common prime with $len_dh_p bits detected: \"$comment\"" + fileout "LOGJAM_common primes" "MEDIUM" "common prime \"$comment\" detected" + elif [[ $len_dh_p -le 2048 ]]; then + pr_svrty_minor "Common prime with $len_dh_p bits detected: \"$comment\"" + fileout "LOGJAM_common primes" "LOW" "common prime \"$comment\" detected" + else + out "Common prime with $len_dh_p bits detected: \"$comment\"" + fileout "LOGJAM_common primes" "INFO" "common prime \"$comment\" detected" + fi out ", but no DH EXPORT ciphers${addtl_warning}" fileout "logjam" "OK" "LOGJAM: not vulnerable, no DH EXPORT ciphers, $addtl_warning" "$cve" "$cwe" elif [[ $ret -eq 3 ]]; then From f3666a13c5cd136778adaa9bce2b86da5b7bb691 Mon Sep 17 00:00:00 2001 From: Dirk Date: Fri, 20 Jan 2017 18:14:48 +0100 Subject: [PATCH 55/61] - add crypotsense prefined DH groups - final FIX #589 --- etc/common-primes.txt | 260 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 260 insertions(+) diff --git a/etc/common-primes.txt b/etc/common-primes.txt index e5fb6c5..e9230b8 100644 --- a/etc/common-primes.txt +++ b/etc/common-primes.txt @@ -110,3 +110,263 @@ F8D5CCE87A3961B5F5CBC83440C51856E0E6FA6D5AB2831078C867621CA46CA87D7FA3B1AF75B834 ## taken from https://github.com/cryptosense/diffie-hellman-groups/blob/master/gen/common.json # to be continued +# "Oakley 1 from RFC 2409" +1552518092300708935130918131258481755631334049434514313202351194902966239949102107258669453876591642442910007680288864229150803718918046342632727613031282983744380820890196288509170691316593175367469551763119843371637221007210577919 + +# "Oakley 2 from RFC 2409" +179769313486231590770839156793787453197860296048756011706444423684197180216158519368947833795864925541502180565485980503646440548199239100050792877003355816639229553136239076508735759914822574862575007425302077447712589550957937778424442426617334727629299387668709205606050270810842907692932019128194467627007 + +# "MODP from RFC 3526" +2410312426921032588552076022197566074856950548502459942654116941958108831682612228890093858261341614673227141477904012196503648957050582631942730706805009223062734745341073406696246014589361659774041027169249453200378729434170325843778659198143763193776859869524088940195577346119843545301547043747207749969763750084308926339295559968882457872412993810129130294592999947926365264059284647209730384947211681434464714438488520940127459844288859336526896320919633919 + +# "MODP from RFC 3526" +32317006071311007300338913926423828248817941241140239112842009751400741706634354222619689417363569347117901737909704191754605873209195028853758986185622153212175412514901774520270235796078236248884246189477587641105928646099411723245426622522193230540919037680524235519125679715870117001058055877651038861847280257976054903569732561526167081339361799541336476559160368317896729073178384589680639671900977202194168647225871031411336429319536193471636533209717077448227988588565369208645296636077250268955505928362751121174096972998068410554359584866583291642136218231078990999448652468262416972035911852507045361090559 + +# "MODP from RFC 3526" +5809605995369958062791915965639201402176612226902900533702900882779736177890990861472094774477339581147373410185646378328043729800750470098210924487866935059164371588168047540943981644516632755067501626434556398193186628990071248660819361205119793693985433297036118232914410171876807536457391277857011849897410207519105333355801121109356897459426271845471397952675959440793493071628394122780510124618488232602464649876850458861245784240929258426287699705312584509625419513463605155428017165714465363094021609290561084025893662561222573202082865797821865270991145082200656978177192827024538990239969175546190770645685893438011714430426409338676314743571154537142031573004276428701433036381801705308659830751190352946025482059931306571004727362479688415574702596946457770284148435989129632853918392117997472632693078113129886487399347796982772784615865232621289656944284216824611318709764535152507354116344703769998514148343807 + +# "MODP from RFC 3526" +1044388881413152506679602719846529545831269060992135009022588756444338172022322690710444046669809783930111585737890362691860127079270495454517218673016928427459146001866885779762982229321192368303346235204368051010309155674155697460347176946394076535157284994895284821633700921811716738972451834979455897010306333468590751358365138782250372269117968985194322444535687415522007151638638141456178420621277822674995027990278673458629544391736919766299005511505446177668154446234882665961680796576903199116089347634947187778906528008004756692571666922964122566174582776707332452371001272163776841229318324903125740713574141005124561965913888899753461735347970011693256316751660678950830027510255804846105583465055446615090444309583050775808509297040039680057435342253926566240898195863631588888936364129920059308455669454034010391478238784189888594672336242763795138176353222845524644040094258962433613354036104643881925238489224010194193088911666165584229424668165441688927790460608264864204237717002054744337988941974661214699689706521543006262604535890998125752275942608772174376107314217749233048217904944409836238235772306749874396760463376480215133461333478395682746608242585133953883882226786118030184028136755970045385534758453247 + +# "MODP from RFC 3526" +33751521821438561184518523159967412330064897805741846548173890474429429901326672445203235101919165483964194359460994881062089387893762814044257438204432573941083014827006090258925875161018096327732335800595831915976014208822304007327848132734933297885803213675261564962603340457220776826322500058091310967253976619973988033663666385188155212656268079501726223369693427999804134467810120772356498596945532366527400517575471969335854905274504119509592366013711954148258884879224599915203456315881034776553083676995718335598586395591169999570824515035017543533352697525287753332500527176569576894926734950469293596134095086603716860086302051544539652689091299099784588919052383463057789440565460681441902442399956419060521629604697347879024654313800186078316526964529288062740879011035175920059192178561473199006205896719435014765345518490882366607110905303449152556221163232127426440691921134648766635695850239231304591744215610985029636895406718880766308249227315984267542266259489684372223916445411015900506239419267909716320331208988978180868987431623710347617992356201449023892203230133009421463914291201346063125219636964261683591541014344239275340735690997732222069758773963390876360546515755280517042160525487302898122311669799679447530453600399342697032714458549591285939453949034981248114322322367238645042515984447890788917823576330019151696568654314153058547592091366014550143819685170068343700104677609041166369760080933413605498962382077778845599834907475953430787446201384567328530675275792962354883770806900827183685718353469574731680520621944540947734619035177180057973022652571032196598229259194875709994709721793154158686515748507274224181316948797104601068212015232921691482496346854413698719750190601102705274481050543239815130686073601076304512284549218459846046082253596762433827419060089029417044871218316020923109988915707117567 + +# "MODP from RFC 3526" +1090748135619415929450294929359784500348155124953172211774101106966150168922785639028532473848836817769712164169076432969224698752674677662739994265785437233596157045970922338040698100507861033047312331823982435279475700199860971612732540528796554502867919746776983759391475987142521315878719577519148811830879919426939958487087540965716419167467499326156226529675209172277001377591248147563782880558861083327174154014975134893125116015776318890295960698011614157721282527539468816519319333337503114777192360412281721018955834377615480468479252748867320362385355596601795122806756217713579819870634321561907813255153703950795271232652404894983869492174481652303803498881366210508647263668376514131031102336837488999775744046733651827239395353540348414872854639719294694323450186884189822544540647226987292160693184734654941906936646576130260972193280317171696418971553954161446191759093719524951116705577362073481319296041201283516154269044389257727700289684119460283480452306204130024913879981135908026983868205969318167819680850998649694416907952712904962404937775789698917207356355227455066183815847669135530549755439819480321732925869069136146085326382334628745456398071603058051634209386708703306545903199608523824513729625136659128221100967735450519952404248198262813831097374261650380017277916975324134846574681307337017380830353680623216336949471306191686438249305686413380231046096450953594089375540285037292470929395114028305547452584962074309438151825437902976012891749355198678420603722034900311364893046495761404333938686140037848030916292543273684533640032637639100774502371542479302473698388692892420946478947733800387782741417786484770190108867879778991633218628640533982619322466154883011452291890252336487236086654396093853898628805813177559162076363154436494477507871294119841637867701722166609831201845484078070518041336869808398454625586921201308185638888082699408686536045192649569198110353659943111802300636106509865023943661829436426563007917282050894429388841748885398290707743052973605359277515749619730823773215894755121761467887865327707115573804264519206349215850195195364813387526811742474131549802130246506341207020335797706780705406945275438806265978516209706795702579244075380490231741030862614968783306207869687868108423639971983209077624758080499988275591392787267627182442892809646874228263172435642368588260139161962836121481966092745325488641054238839295138992979335446110090325230955276870524611359124918392740353154294858383359 + +# "MODP from RFC 5114" +124325339146889384540494091085456630009856882741872806181731279018491820800119460022367403769795008250021191767583423221479185609066059226301250167164084041279837566626881119772675984258163062926954046545485368458404445166682380071370274810671501916789361956272226105723317679562001235501455748016154805420913 + +# "MODP from RFC 5114" +21847359589888208475506724917162265063571401985325370367631361781114029653025956815157605328190411141044160689815741319381196532979871500038979862309158738250945118554961626824152307536605872616502884288878062467052777605227846709781850614792748458838951342204812601838112937805371782600380106020522884406452823818824455683982042882928183431194593189171431066371138510252979648513553078762584596147427456837289623008879364829477705183636149304120998948654278133874026711188494311770883514889363351380064520413459602696141353949407971810071848354127868725934057811052285511726070951954828625761984797831079801857828431 + +# "MODP from RFC 5114" +17125458317614137930196041979257577826408832324037508573393292981642667139747621778802438775238728592968344613589379932348475613503476932163166973813218698343816463289144185362912602522540494983090531497232965829536524507269848825658311420299335922295709743267508322525966773950394919257576842038771632742044142471053509850123605883815857162666917775193496157372656195558305727009891276006514000409365877218171388319923896309377791762590614311849642961380224851940460421710449368927252974870395873936387909672274883295377481008150475878590270591798350563488168080923804611822387520198054002990623911454389104774092183 + +# "FFDHE group from RFC 7919" +32317006071311007300153513477825163362488057133489075174588434139269806834136210002792056362640164685458556357935330816928829023080573472625273554742461245741026202527916572972862706300325263428213145766931414223654220941111348629991657478268034230553086349050635557712219187890332729569696129743856241741236237225197346402691855797767976823014625397933058015226858730761197532436467475855460715043896844940366130497697812854295958659597567051283852132784468522925504568272879113720098931873959143374175837826000278034973198552060607533234122603254684088120031105907484281003994966956119696956248629032338072839127039 + +# "FFDHE group from RFC 7919" +5809605995369958062758586654274580047791722104970656507438869740087793294939022179753100900150316602414836960597893531254315756065700170507943025794723871619068282822579148207659984331724286057133800207014820356957933334364535176201393094406964280368146360322417397201921556656310696298417414318434929392806928868314831784332237038568260988712237196665742900353512788403877776568945491183287529096888884348887176901995757588549340219807606149955056871781046117195453427070254533858964729101754281121787330325506574928503501334937579191349178901801866451262831560570379780282604068262795024384318599710948857446185134652829941527736472860172354516733867877780829051346167153594329592339252295871976889069885964128038593002336846153522149026229984394781638501125312676451837144945451331832522946684620954184360294871798125320434686136230055213248587935623124338652624786221871129902570119964134282018641257113252046271726747647 + +# "FFDHE group from RFC 7919" +1044388881413152506673611132423542708364181673367771525125030890756881099188024532056304793061869328458723091803972939229793654985168401497491717574483844225116618212565649899896238061528255690984013755361148305106047581812557457571303413897964307070369153233034916545609049161117676542252417034306148432734874401682098205055813065377495410934435776008569464677021023433005437163880753068613673525551966829473007537177831003494630326494021352410947409155250518131329542947165352164089215019548909074312164647627938366550236314760864116934087960021077839688388383033906117940935023026686459274599124189299486771919466921436930468113859003854695674493896608503326776616230412252016237753188005160515672431703429026925450722225213972891936880551722374424500117253400391608019951133386097176734162660461073160502839490488652900367939577292447038637156268014222959401811270825513710710113193757653852931049810187522670964988718456427706279024201400130351029277257873323362974483425793829163819060563081096261611614988801585554385004830748976181157545121697905898543562330970182151097394600286811868072516047394404389555706298311761588649133904051123770516767707951778179308436153604841663369568605395358405635911568855382987714763476172799 + +# "FFDHE group from RFC 7919" +33751521821438561184324892992841956031256524096764762523080427484131368183681238652286303439277919364419605375975741556865385545908845926426890806171934808386673338677817446992026011784349026750519375730205067498701350657030856602039247991829540145540001367697563530312238373189195859410680196740818496273776863982316239487439125584973486191474973070378586678136324790578680454630958344992260559731819239256040561423139407134895441043521777796400880951101664061960549417775619248830729218197463598192224062477224088661984618875141239361375810191700348746470517603586330742337739315086785758610522626080327305070861763732997096646270232538049631764978124370714033713690749348727603833565215088374348155839869467418301934486261774031333194202002514049598635757051715292153270068806927857370077400854342621469193035173582620808395011965872285119963665326566931152118419683195410230531880091058340135241442529412915698052541447285219904877547903853970539536057866360165883117245413187530187706879654021604384751733362734886086447963479243086334556742008371133320333144330529868075901065270101499033142677098456216621473599132476055885593228992805674421717912030137492923124370487889214032208165952268509981501451774970889626262931401169981636584425302941104561318586295950568633223864381392065855785614286866466034588630668284169362643876828113430270351563540045399616908093185001539414731258530233312567034617287652871707877648601789117465138822759448972467259851264567429611605233655993068745892528795005477239451835762239158148450946495583269774730192968123453831376884299400027264972551783838651516361577307080496493669697500674115993933560984134638146861375527138211765789496434131148421504162050232089029807657513443213647811723915569891007483031985943458980395910188354328838067537352640645494922975415613895710751245784814785127169311178294820863 + +# "FFDHE group from RFC 7919" +1090748135619415929444037382073202164125305063117061359021210911270577744302484095783585256262132857867507012151327745319420949480631077659230943007731372290338916318467056551341312388724237204552630979526938946243971958249567992270660707645223444998212375042421215776901548713954608377879903140801084739259304885738884241557789963639848414142435545413461220375392883746746009571997041033445022502762816331857033727315823681421531580986559568582495054304419334754793864359536511580585755680437972489876200744058648895832633694632513670176667389094435272527511943458451278617893700596377728765952665861962906447628133961178002643746220845591569312550242539556477924846824431386227398784372946565741502410953510925086230339755945668395462836859386976915262545264219099083866412323338929445556193690276085130255735707017517324908584556020047122304601806052013210478673966121765822384984613134062610932880821764360557629800471942620120350089258471142266672486905811824890197561222168259425622075380074970894661940191022351313937794403179128925897399112543950028771599485900567258712506491423242565563135524281249329012935005778031068703683453260896098798641811119050812310043452672866472626886632040451127891259822859833579017734578653167790168028670602474730129723339966367629299069464612922206043242915619930604287973659968151168649532362252217391606094542229202850891990149423286722373933582772946978151293864418092658361871788530836011433246848517279350728403540496593224145424561966649653985963026020941223187837459880455379494869707430746485961836217272806165182791750397289355418934743450060932235238237908010122017218143239665855653767803345566744660974127130587188591627469364051467546830550982678041483517603551345004201416166657317979133177076850863915723452487089990921274837044452675718747451622274394568025709298240157360143554038242669443266557467589294627069491899039816156659993760960331555864960579941903669595533661959937683218286259759942024512967175841717416769943853374953316002333533954475281180536503757029544656828281916590129722443603212328905281386443054134068074845098476931062612287259260077268525729384552957078890543508903050684066466350832645258291471581992414681774952272964607180615323323707230823981670673369901279153005955624089037761236230721391005676907275360233030103877306374767486038871773571307196997482447151534288054433129088702568193019402125710114040359224543481208871491986232520827933323475832217514514887471827867630829567 + +# "OpenSSL" +11435638110073884015312138951374632602058080675070521707579703088370446597672067452229024566834732449017970455481029703480957707976441965258194321262569523 + +# "Apache httpd" +11141973616799305182672125953821539621789863864652082189484418383755797726500394212227314338509410225240621127512913527972129628050063918116985983184044619 + +# "Apache httpd" +161924636724157236995539194603424135829045460791094305399572880130740597902511283656435607474782334562452295847429354234894102736530695296652601242468041123426186888474417097353027907965636446587415802158180476224678572126072378632347236490658815309740591429281572158171557380347843452583426729104575168890987 + +# "Apache httpd" +8372421755538377327377912526045445423027732035562313241965800453667849685158691589507936013805295187219621475007123900107532269487803598942841993804845107 + +# "Apache httpd" +150621238998402554141426358892807528070450929584024050594746304264729573805267992507071188730865440785012329520820489313721494359461887733932969896388657569112847289565683617995554301683431835378300250205597326665273328905597509521195196490490065048848345935446963329447852572726043146337361398005701852368563 + +# "Nginx" +131832052042219009527839525934268128127355300704472845128573174908898587826481581974548040446189688518070214483643209695723925616113897243950922364670371766056432630785982773485713108424273657672047098239473476944390258716112687012012440120129627988472009949456811428528912427249964927042573604085259319733147 + +# "SKIP" +171718397966129586011229151993178480901904202533705695869569760169920539808075437788747086722975900425740754301098468647941395164593810074170462799608062493021989285837416815548721035874378548121236050948528229416139585571568998066586304075565145536350296006867635076744949977849997684222020336013226588207303 + +# "SKIP" +31087337795061487877547416545715496334920954980132212151448781444321393445568157959166911302972918628838917381555939620290244963511997037011253946065678925033455872043721454426215650798450188675325621498188688302603627388365642425546473761584899398546726625631228589029183157123265299738241899897560139599077166257814263354432724020387267456594044458497157226037520021564951601668256091905149808373739011153824316842260356584928931097012930709279713696588076097146536216639697002502410139891180002231258705541413293860269631209702305813614701588402302998104362562812340366960005570331931340105075488237470969553357627 + +# "SUN JDK" +13232376895198612407547930718267435757728527029623408872245156039757713029036368719146452186041204237350521785240337048752071462798273003935646236777459223 + +# "SUN JDK" +1418488780399624169246918906980830188668962659968489177172519612007411971965075884911751185624649475197807409457369163882960326663412481439463507475025544888587052733646843233033458377686354235239579046252542291754237282749312023983 + +# "SUN JDK" +178011905478542266528237562450159990145232156369120674273274450314442865788737020770612695252123463079567156784778466449970650770920727857050009668388144034129745221171818506047231150039301079959358067395348717066319802262019714966524135060945913707594956514672855690606794135837542707371727429551343320695239 + +# "Postfix" +11351928295969362153680318143899638392634652084406809180721126850912534429957010348519890331306577360308702381391458869083885638571113632680200730760851979 + +# "Postfix" +24131293777886374118584606661678552444065113984688942136778980647818164970852105655088429124396761599838827087514740364394273667387502830998781367142799184218851559149661801594513163362372771874046737233840092368303597660206162593808771774336440959680029703901794663844140996661787853155797815168383327259460283094609626756009315263214901338027934420086863770577133358328638467072634923150631754665130537846660356778764277584029327763941442223552847441902193518153870526066148265594588320847125072665688996554047265314983737297427106179945662121632266549409922372350824775582437869586864262636578117679890847409111979 + +# "Postfix" +7135787487680160723158987360172009509857780973879356519050893028700610616910042141909504379139750530669840288414588708459507347709411497939019689914055259 + +# "Postfix" +124290078192881725888826880475608268121546479080319401588411202759306021711058769574616590974367222833180545066528602465043919413058514740355249599358163921882995239255028847197529491772541340375114213691923735762979921709723984230280341119838110698845565638766769901880452341248731603339034272624514428481179 + +# "Postfix" +10096187981066053559335535449169282457945760362469786309557937686443731234028465097513776908358954978429010128113292083701478593065474911189952431940546219 + +# "Postfix" +1089090311023821486807062646667755441663974766415146023889746307964280220954453097088413985218587552379044355794097665552117500934098507055783139454648372005227264905074027069250089786740659823130740976279817510828079511169071325147 + +# "Postfix" +136123388004568009176875286135055183919622133760505398783397401047902962378621318101100481790979982216519828483232429970364693220922572981049575270176219908104060081734736799288400844770528117178481382626351711182233806272597979705666996232841536687325828096814721669135261423885453987983624180097457782693179 + +# "Postfix" +2056362021987869040866222775971525526713848817411256130367970754396969557869817702606903423615283059303930616438676624104640204217164473099856199216305279508718747202276171819868432314839088974911801002129018672739575945202076259230302103370863451826447174518117143102638489276724376611076549917224491477706108610356540170718925518289818980666063927549928069325768537343367153162067020241995073818799850549182710199952635278668959071457969808520304484680273215899 + +# "Postfix" +26371476087150474532132008655311203525984191621650037797335673054271351883338792851526864908736384515015553905714370466910888328281569556512680757420248619460502802406103896590120987564792497073052858573915284877543392830972701922295410164673203260676695786443597509581751209037220443274164352656996468549138046641990095766583932817878707309357841837078365072329679282667717608853872093084680474764076406402800742626159266353107911079809322117978690117000544919386308980746878875294902444713440174790300512221828280260208844137639082842338734111456679990753248043046594738798915627967835625360741492443851601099267219 + +# "Postfix" +13337623048342799034827489986910318393008849763036733997149839779963204489425757309012715340523200875542318060972273326641217824631730700039857742855624939 + +# "Postfix" +1533772406382956570152763108431991954831079405833258610827703555135606586893527939272614759361191561110646045114047738154033517920758341678370617073220477513898951427441733234099780163358327483548965595558112565701277519466897981283 + +# "Postfix" +144637424961850425159905784027136014061880826531818983352585061296526368581179214296922065913823633724228503264147831887830254308079169948903074953931411083056118836353233843818642834810107342452429640402033606357719495510563519638658174142659182338760323238086948118168424439691568418572594944219477298153263 + +# "Postfix" +2042713559934185643384327549527952458750622217167335751028047396411788957162246741725543190665668416817031839560334887966601364296103416314875607373600606218726870529318758852284243260138607080937306070901820694908266357001271027028958097194186248177918896517910126113641694455442417769493899505072159312860025674661873706392362014784672110060931972136138821276444318148803052032775491121430546126966329795445327961129787860725363402062777363244414680356473486443 + +# "Postfix" +9759154167025958083571250365552992993534466195928785797208140837064455011559008409756152457212745575772062478546361342515389863167056447063023865399211283 + +# "Postfix" +1364948145886991617895978559358903167966290416143667578394285325644381185372799885861597343368522645272011717362014967121205629440617659315582294484305490057030886926126158500711976814177825019653800069743928883494887162161622087307 + +# "Postfix" +170509805985945428967563804421085700024309580001072283516862390953398284789689265180987459434776023075205610950717188546433293071493512609789324612714292386941858855686900608567108340703947439969571374674464812699728499679347745006429584325043673764959755753323095048465275743217839659384932866032300078439107 + +# "Postfix" +1399756687522921964208442265587277224590999291970020878117413585753624587517145241012458149142229516760446050107835226455178997986671341265900784797102850306784040754165031733011704700434845054226208232294383130796490713540743213929432845289812563992089777728134866354306530112982376728691670345857960914971155568106763073589329112068058914650276150476331492500275579709331992458078664551226290003097390552576077474939787303074332596329599148724157114197518536243 + +# "Postfix" +30665078773665433984679390022488424719778975164146202083131251833892119277576018817470613424046186801389172270027910937409609108491794879785967303818331364169223881734218065480981193865887637105068086059746777211418404547623912175779761293496184572560489062892861925196800372347853683709369252088792223794330075784696968081981902086985383387978231015947493852904756936918233163868719135240372874496529063971007348736606704972376420631489422417247291206292728386525387923483221986802035152273686134933880580692993177449671583228524148903686102484113995181746319098939406274514609994062637696036007964340964533117834243 + +# "ProFTPD" +132996212497555757714839577520009599982229563766990814349170419213831793150518344581415624091585295362723791618044438047032948658522696342563919889163541989736011703719977966038136834855002285771085403405914099274079071528415842277349009763640550881468502896685974195502523576590837887774944220227692918505803 + +# "ProFTPD" +18858581929742317527029478184638854842724462225720836179117188808917671531240871347611118225573584796605541571727033806983637845587663011540549398931093362137864722376547296516821251924303406852009430817109406449016925627536728768913299637717356641023929230337606449236348118535296673960534958260471470936207746899744229699227402402594684686990419598035403972292138232693389441133450887303721307090039985977409326551114653393248153491003945999649497125303737739578242143102865505268997450435612946830940154792978896702775943651552752271560923011637181201283076815030600233147165141152749108754455161316496472774445347 + +# "ProFTPD" +1690599963976092471219037714997293855906302310875281420968063614328589925828056077695246555017889987035500367344808224338477443561578625431475483707580988822589648483623980475499118810285212591091135830604537640714865512873460169015344343192483199148216608008625051676959634598080985210766854387762630074527385892020512178705520293062481006218780660207277235008828769064469617081682669959711930850913832434916213132582786972860232373841378773014990861911716877783 + +# "ProFTPD" +104550704091518462875794517239932803228795640080961293447673045687504879049730788416000819314820105958147984905210586942301309304289196753528645175163277955936437052460041407055113432460397792985373298283729666329986343854287860035912543769966125530991956674119731252342212248133977944642911919848432245755403 + +# "ProFTPD" +123120551618399898699275185207010546211742537321803360244900958280768207448346752310214792790377162714025492878116518422402416452790435000574976635965888758275326899087155471405218243739016862932542478973649475145841047404561698683215439607643411122685696959117693582083223293718196252180492595190774509386403 + +# "ProFTPD" +2072532323310501692602322388268833396123289164730332267469573021914276523184450666618978234290563818735721031645764083012063719326736169342391072129575572421888510449733093943436432405362027186491718086792358334086233189779026493592066693945045050284042918422370589842816833223211080055541474219925354652062740315569261166622364419630766422792649520961544329870455119648896215813081694106880913531338140089714955197662175239587929209024190072822404107630757857067 + +# "ProFTPD" +104853848541625611565027567937000048853298267079325188824720224546354701006518045430304636072499713382704797349764784338122087988075844159399738334488490583340241104498736369527027446023860951495356349935003007271644770819847539446840368531546048297372864850341715016643407939469252235645642453257754265084027 + +# "ProFTPD" +2147497872306889053504904888759358275602695222009945054108052972067120354595691834400135034995896341236547003124573230676535767835278508796798134916404709542900609890895920026678765629400534329817345465508784448555078707537307882450019948089258345775683170910399405732489472619533026653306913904331961818133065102121154500321487478024465642145780362841606890007568595945037955647568957020977173073532849222461327972617348846814678566932700323274394446127558666907 + +# "ProFTPD" +111213710907361843217505524310927976465342092915425056395273336147179504107691110941903277407929302520103543347451222500858487011084274592106195452422261247548928103551991676417076675303218099117588229418345583422831960086789112908165814516444053324246610424153249337581410600100580389709994157679621299828623 + +# "ProFTPD" +30654731759923165109068549394646174606854727560270885171118455001834361039508262661339420809312767964610651844011506730705488517327796540861106897019325049871148405402236945049178642616972180268973325675055028097791829107978290394470119050766353933419488529294688328656740595673735495568398070771353558240253633506948715867154144045422013754218964484403591502950454747491574863086439822125629822452768189179177186539594550005550512898625828856416703741709780468562505839527127374406418271774990679091276656962041750605852553264770538287381580788100834107772346595084204530201157938144045756467942963206230969457893123 + +# "ProFTPD" +560453074889691084801508706747087803540613692838919659785572557415210631700643171604008221497013769908348013955874542884136354619137507720741899179238077988760004797077407812589900838688215076167450301205296447158745926229854739807818394106988261586396065090531475950636513903415267816803946418255520553693928436321340106430173695312279494235116237531042948629210283927454523812977173250155350409330845643548406174146370597398556675488785763553330369703618129430493080622359701457094947003591314994652685327155023420916183839907422844528253242557377002612852746197024635489493049498059762863383013077143319094717952017020036623946911388362291925754554145419902368333149508480700775304575863975993149105461894793388252798498052849927907736752612092770718880461605439373769712890534662083206525052790244797011392130835414585618712008750755694714606901923862380817372512163207489817525845729942023195028797148511734227873744682215926584339267728914054388398633829371406140091339600806643048726940156953947581944854744710145129208742582630965096415508072574658541836819320370543388222808743323853519111716840418501630881509493931126128051519749175014728034045603456558927435106155725323305574697528346609104862763919932824531184872477603 + +# "ProFTPD" +150247087203561355396392008605529599655265834016635685469479449170859963959446007961115768712036600163521320731233612979799726616542001443845031140881081476904672802767897302854393730990568959543431711914873544079199847213133315505824087329022680038499751501391472888045916637294419666350825877503188897147459 + +# "ProFTPD" +18755180141969143456719975490837299591661486864459177699347875191706943914337986945386993995828353706677617962649773753118865573252060087883492944819935042481061008351675891635789201271724722361772070519804796837601882165443561099647909860614358193001345124267045197407694355612018622267446950565235314913858029731861206146245083838508844063168098555243333600136059862005176947895926651361888272982357941329686992778843183857144326689862707154576500901134210456017229817418566122925198531060399072996158681589950738698582455848231588244562186580518380274577297965754367635749015721785225113626288303327758476594353492369673848915934227183776466162783119384190746961294042730022282533429474416217028782256985135499635186282818066176169066342864593516738317060183918641512104154959421700551502662531671060038685015232875757774746837013433410576301022052765766846360448260461798693323354583565275772757616487405118046473468040823807511862525841580430993366421786369713630767092491474732889477248883458413461697623532468385915560450742063076541098142596017865409212782228095291119074456755890648431348998467982439387249601358951311235550685074753771953235731292210445082899805267502606627215954297070962074179567656154781185995223610364040992233060243700690008404416268632104351187679644467896703035503011582445888585285643676624860824735219703168909443935692401339337973046031557855017438946499678302281454753221394836333932887051009032097287981799112327592659498982018134507815905529545600073217344336226176431386420504173713460602953964086767062800509341512637491432576105574511855949772755697886081233241895351608225518868884105051920163797783211704251614835795783619509187811273307721738804469716604103147736420435819693891673679549229810732077298529434732256753519128140787901554575275042084335576301463248436034910144072894694989973553779093182267 + +# "ProFTPD" +932614255716527426954194994893899443909587134717378000432839868236070873898603890199268954946230437836347598137289981490576265408987539907417814723830713466576148733233948875588872099899259973963876962911687774757252586321413731977669018933516110752356399918199969341105291513921295107439970501327003341880045051040607453969130527403651621523642867493175187109244410649447543051923977286351228641391584836232388340490928501453737056493642959144891566665266741989939395777161562837874922032904822211886432052992526410005023212811670921327701168514850842580610390961290804165151896351027698919616772111286176110774619757231843037570261318458683119146718530026599865420373898076199297113860513124130129642439162193625573382190306693208066775159336188992433884373423283888634990227229613290062353442882883814897613354162938799905014787766831590510683978574804178530566885876139182208112335475740743645358444335923578926581553787899507658135759969179665698240446604058961836540194721926903451607542473634061286487416075337212225270050252982709979003118673510823200519580882640921942656114863134103393093830299287983604073902542901481419517401448876432673164347319122212645087187893760841941747029826837455871820207021713457766359649664872755306267250016087958888262104061954114160281469417045032466897125681180954407864004854588273392554731639697744811495996158775565749253746509502712462630592967709761458213810401561164084981049795535139007859077837868799585937381155086342987588522510916597567815798713371610392396558783587268291276315638899899271483796418864808847875941402509378066344818876245109902804629626172034939807792153692477664189232944054519301986365498402204268869738103542360867827692774295351629924678870083278850942327036492706939882094521489455174654743338377916502241034245292826876438640977079089793026036061471920052264377503480373876982968241791339245438947719115558656378512512497926881726706471637308636797054646492009814335204611503870814749526336662640726950102818501582045460849840054285207453216588715750257633261109807491738295865709442594697074958538342316716407046367490887001556105415594262664900743919039268744236208927920962742626010051103113451721549101718874466476463653295775409095876118838803444475368968314681435270565439725470847559140534126935810393547990516635875286265092731940469309826898122583490810764696585155594623850610509624688744894442844171181116789538336468889633772702399667673046560254172554006933134177498414986043 + +# "ProFTPD" +128460946572822262057359109306605120772451327533031647046625697221005732816665725901582946504212374736582818589836761178529999012485342871381674433934353393937303106712438735820534568896236420093178574902954502039513652666078431761586990279191008772869049831986918279797303432637267752244583339163523262623643 + +# "ProFTPD" +144925986429746329552319820211520001198989689176458552347438337389405507299463218365770747208357804009826749164370407427351276485954367950795093335821830458863503379180661384347840601756810647040055797609071953593697579555534066046571617409999432650177627552951650427754499891734160186052184139722486900923483 + +# "ProFTPD" +115162289007948959755657135233438729113808855787722937014935613706821575983337028768883681648388956686229161829703909111979084624504403672089018965372485741289747502371975937088906812611362368895727043787370958107098559031733347943729595606679849892712753349171734318745015574338866049075316732439658885274307 + +# "ProFTPD" +136796884348914309433608566178313687173477692302500107653566211211886143478606291610252339969266161044433128956125387787447345706509140162356735699069609133141538999649842144594045984234748008239998576251245899854136813090217059279013819988558531082979779602360431032271817804377771999740652865493583728547303 + +# "ProFTPD" +167751911251691477400879168696973893472387251048307155134997654386932267855467967675338388425759898758981392239026462776070750197535524070674716116167771442673416216658566234928237166647224963890836829465768360527937853986670204218960020207654931004080097826367749677059265522971537599345586589563008771305059 + +# "ProFTPD" +90164112263583338872045552783608529087937979270683138336948143992111523095218561519057070103401534340240697917506462801522299075514460931473642651447181996848483449888359288699250956320806573454874473973166568685155864072031363366921611564598072165832915957792883701137348264610414343290967731930063824725523 + +# "ProFTPD" +1442082006420025285159048195407350832162451354970727441133114815200914015675297262845335883189790640384931267049070886793124058848180908982173726908054069855043135110045340492943413515577525797209781974671102061281077459318689101368052740455819513045346254302071645059475553268741739489000477622236056274600429885650766582188185564690881741381462043125996673253248961545216598867257791307298215427433001483949235232717793476313459024860432728272050874931213595543 + +# "ProFTPD" +1585267470767244273044107663411169303444883303191939904174462520657404014028566831965120807716340792526253441221740134643826007654998109460881572295636122928199853275034486996345453512356656712709629564297195683210604077436291604158194789653214040565692878135040130963708681515701288131697612156474638618573223280842292723454482563231109090559440909013349743163959067476699032060125379522318966848788470719660815660412055027428122460054977514444278077846789140699 + +# "ProFTPD" +2027766136735054769692379678403255418818352577167303861335714333049379030090903093887869111474427579026561918086896224997168323675945249165494863186546471863929461941407265046037911955365720627362818156592478752178915959040090408810560235675280619805603404439626888305039177460099695421975520079420001810213018995340062647953760877418185168989345014659622446222339712804272314984374647918446112020640013288816174836923301139404463463159658546593644846797623482923 + +# "ProFTPD" +29484431161230878152548870180958612754250230197705809571290478589909187981720717685327735273387416511274057781294076748771444807842553242819102107757103675878102175387855561386503916507221692084302102359372588227910590771528112112856108416996288552081116686364356381435943745142719402860898585982794136162970587185956742225497736703577210839049706015718648500509085628043135139402801209501498241421336809228371150021215528408022319773340435671934310371912646075629079601730607295032571519366354063983890572309223314476915221032441338898377696388617564377362158157334188156699167381895735324335732582041667913252512339 + +# "ProFTPD" +20688119750554625784709846317430718604169888731173941060581442021098396942101427300358256348908553454806288636971267059394068813630582665414307851229838617027065211823085367080874124091537030423091584189698731707608557359950179235778276430021081065695196384877883587752768974269274074180903734141862488218377743758988416168389576813181864016049843544101343494860617717109149721309615800057724024705772317174615817205727113392329227090895224468437228745291852197014264433563112388673140491448319770113906687867727988355155701700335344209966921434310712825277548504570050704170163646175008580262305320441541340196602703 + +# "ProFTPD" +645868159978225073498704495697101773837481732083889030828697397430998185294944185818778800364926531087610270569949609446772452302904635644201670284146523758813217144725041150244115308384750705236253076075188453436625954610345035236534446855967744287431950156190789571091011854278700670531536912583922257645541317940119683111443923751620097011653189398599735703771999227032202963009069882926539423644450214016849434013829538599255036114761442172565277135223452624054477098036115982499671808162028050955668311207489457471010358794390103880425866128957522089961396308079232621894437169401162215285543789377719164063329046592626125976477479709124174318014574525250156016654997445159564178612366124714025569006884547117369368843212678931012687323779005827189754176310749455258878214164398218410163448740275793790113640555375589552530143644409903650344879129909378258261046399655584779042320658036298011378163736663869520949776271215514718102599236666372363567947974597269076589991846941327440252517269575438041639963143249745243796698950602352896520319455865717885980269548846149368902316645841537870674040234260941295377801835362656637366134214004824734706415754513555226769625405638314662659282918991789098323957007561825608356119964603 + +# "ProFTPD" +31299473534312262776425585492872330648898007475573747686511734533328843377054251000045337408640658643264777560550523652263716601967176021713029220618273321087807676031915223187879494755339030407780244487639956841690467129259284576162376239566152314068303021299461898619317640459488786021015123334339921211897846553287404450314470911079848329350347046577029639345466054095814382010516205267740099541235363694198715777796169544664810154881122665461185273937211724586450592366925966393024278919419574283529710926728803238795528416569360987351800921729831369276960005974548939066127119765083306460492060736118246566151755503561706165861572368561978504076098847660139156840111982846401560123448591728973128192259759580278807734868856595412056429035280718359847430311787278134413193695716868295672987371620068042879459593130554382131322339411378217673319273009027571639567626114985119515200759689903758838061767312610782792700237194736839164466309921101135672054215046819635912790752355357249804715909081903201733166554922770438583955901743268012067299672347629249982918408962970797147947027855406862179415455385306004066906739523024233008933511709923873662404228654082360291780827241784990030817026055762510356711196368838367264247823150023167545981544406834091224811427570626426272131990685874614188233431450822290214430703253555583186494613174252440684800577816154030657730208536882045974575095463981743799188804168788441642058964538514209775797824451158993176322530092928544443396922088920205925062091318673906840961166987519290583959067005736044543309783511553338707364181695819720702592991495668337910517783701695066142396936980930636856963977831213837145011721411970160808448991469329389678849355939240258600705492169500867910979393652221370465448972399953433155089590971657181833473583765013644815832101086309219349468785600901303847019864807765787 + +# "ProFTPD" +842583000993045072637278642109901152103261923931236175788452043395835931872848482669580216429166310471893963002813982523507744183298035638380633699708788872007339195053363676210543188458982814648244285781891977789350854145845098767617917105439116573111107035713188720795327868690656824703579200074379067793808150376553099987803804062916278558688049193255223197184566162760070112846375799470594721161807479862158946955386596628536212815471482014247214513855881948470070791860002882588595556426782479616904272003587260891105308747001427205143410668530481850441975443068998762424989279375170481022004413516522026179757627369105917089325647184882951700083963497493525907573983062565422732475779643483560757033174230275171854369260515982564284558350426664891192930108154986087328112229293571621203441594349831442705426364202644536996077010112617051367371064084652438935604841234964912659138743739041431129200444928047130102954349346924659898296062267241077089892252283481159087533143061715075886314960787135245606388142954893159629656874505520343164833970456391996719250239756800849389727710302745421395697831477996940551839957110177892706519603094970138252930404570091890868494473034640779001880720250621626160122361360957600205875229974984765052104576962073906145469829806988741037404682346915918868247985475386777043652184076056075266432579619819843583483912192964862050178460166612303892771730993644094803736153930194451391094174838154400870059520143467898002852746911676266052857342128737513327388606257353970560411505075314710468391209342555665824899345489319400327140237283631183721278412481250255675770072765717605270444344602304767192635834999918745562496880294620898158754640701488018939456852939480684562565907219397080802741584232790265448896765357000388625159482028737161115217778260089059925769844896898457401102148237004351214279658006655945162471509279769621477001618734509392661225025427494080610698768725431986210060156537977812536098473372555128858118524663410057866784971094191896608754164811842347647862656062193237071472596009345104467720936174369502112957735120605230796536550526073320107058503539363665491662843858007004414547619637692127649556924570381450258194999012433531463917738796372800143851458398329058266603497557872154278268111650749903192875364273234576142545565560132387939493677439588722552015918122167805855557322418557066911853301356571738165573273023707816337475166068640316082202616532954193827365634369494484973753516615125445659 + +# "LibTomCrypt" +101745825697019260773923519755878567461315282017759829107608914364075275235254395622580447400994175578963163918967182013639660669771108475957692810857098847138903161308502419410142185759152435680068435915159402496058513611411688900243039 + +# "LibTomCrypt" +736335108039604595805923406147184530889923370574768772191969612422073040099331944991573923112581267542507986451953227192970402893063850485730703075899286013451337291468249027691733891486704001513279827771740183629161065194874727962517148100775228363421083691764065477590823919364012917984605619526140821798437127 + +# "LibTomCrypt" +5328861283668172329945723047610411795771014270600552860323385523406647326552760472582266594166949982639319866344591875989188385919141614032967632182106788230617154308807280817035869875026730777842155223320417183340387162699544821179884800708832389269366962629279314344211669291534466869589107113928150426545698929768007946765669598970231274510785562045304927693165937003804520022122096407 + +# "LibTomCrypt" +38564998830736521417281865696453025806593491967131023221754800625044118265468851210705360385717536794615180260494208076605798671660719333199513807806252394423283413430106003596332513246682903994829528690198205120921557533726473585751382193953592127439965050261476810842071573684505878854588706623484573925925903505747545471088867712185004135201289273405614415899438276535626346098904241020877974002916168099951885406379295536200413493190419727789712076165162175783 + +# "LibTomCrypt" +279095111627852376407822673918065072905887935345660252615989519488029661278604994789701101367875859521849524793382568057369148405837577299984720398976429790087982805274893437406788716103454867635208144157749912668657006085226160261808841484862703257771979713923863820038729637520989894984676774385364934677289947762340313157123529922421738738162392233756507666339799675257002539356619747080176786496732679854783185583233878234270370065954615221443190595445898747930123678952192875629172092437548194134594886873249778512829119416327678197159 + +# "LibTomCrypt" +542189391331696172661670440619180536749994166415993334151601745392193484590296600979602378676624808129613777993466242203025054573692562689251250471628358318743978285860720148446448885701001277560572526947619392551574490839286458454994488665744991822837769918095117129546414124448777033941223565831420390846864429504774477949153794689948747680362212954278693335653935890352619041936727463717926744868338358149568368643403037768649616778526013610493696186055899318268339432671541328195724261329606699831016666359440874843103020666106568222401047720269951530296879490444224546654729111504346660859907296364097126834834235287147 + +# "LibTomCrypt" +1487259134814709264092032648525971038895865645148901180585340454985524155135260217788758027400478312256339496385275012465661575576202252063145698732079880294664220579764848767704076761853197216563262660046602703973050798218246170835962005598561669706844469447435461092542265792444947706769615695252256130901271870341005768912974433684521436211263358097522726462083917939091760026658925757076733484173202927141441492573799914240222628795405623953109131594523623353044898339481494120112723445689647986475279242446083151413667587008191682564376412347964146113898565886683139407005941383669325997475076910488086663256335689181157957571445067490187939553165903773554290260531009121879044170766615232300936675369451260747671432073394867530820527479172464106442450727640226503746586340279816318821395210726268291535648506190714616083163403189943334431056876038286530365757187367147446004855912033137386225053275419626102417236133948503 + +# "LibTomCrypt" +1095121115716677802856811290392395128588168592409109494900178008967955253005183831872715423151551999734857184538199864469605657805519106717529655044054833197687459782636297255219742994736751541815269727940751860670268774903340296040006114013971309257028332849679096824800250742691718610670812374272414086863715763724622797509437062518082383056050144624962776302147890521249477060215148275163688301275847155316042279405557632639366066847442861422164832655874655824221577849928863023018366835675399949740429332468186340518172487073360822220449055340582568461568645259954873303616953776393853174845132081121976327462740354930744487429617202585015510744298530101547706821590188733515880733527449780963163909830077616357506845523215289297624086914545378511082534229620116563260168494523906566709418166011112754529766183554579321224940951177394088465596712620076240067370589036924024728375076210477267488679008016579588696191194060127319035195370137160936882402244399699172017835144537488486396906144217720028992863941288217185353914991583400421682751000603596655790990815525126154394344641336397793791497068253936771017031980867706707490224041075826337383538651825493679503771934836094655802776331664261631740148281763487765852746577808019633679 + +# "Socat" +27788893276069724796504555675597658900595616769773727063231875314156885361379100133264804184710789407128574011804155595735704837674243828066040543912171576627544718762752948158991754559261759162739343094515270757451837630913502740443023902769553802723685440839891240497710460941757089246131322686180648463540974702859210630184042730717698427486397505787974799692901205514386555272667298045803284972074823213104807295638814082142694729938965663710648170010420323923305528998108799706139846097432481556448740855888110797022123731105964852194684036975049177742094726795060211226322344210328442014189175085444396370522979 + +# "Socat" +143319364394905942617148968085785991039146683740268996579566827015580969124702493833109074343879894586653465192222251909074832038151585448034731101690454685781999248641772509287801359980318348021809541131200479989220793925941518568143721972993251823166164933334796625008174851430377966394594186901123322297453 + +# "HAProxy" +176239444111649184001807886764937833964048435503795244999892081768789022375735129915740662180068334018339161388592958930526963170519019882900807402416607478066376591136260438873107131022267101489325892860968978786211058103300402499464852578205304343633112813894051715807017599329349818891389130497782833296267 + +# "HAProxy" +29858796390615156579005888939269198307245905232681039735701203577782476926154873335426127695897301754922870128756842593030151414119709262645229012441727298368711743410459247864230844928652844066470778453407016731127877523140218134153576484186182950525935914709244296481672185142305068112555406408976796124878635827772120777258550853683439376087177772896228263369772738298975007811505514162302230875939649849577860441810207979136789694197146933683702582561144371423098825724758001276881551281910063375037847674958425455182508146273563179524764981626911867808039229817688516441992282273960105156684293367156005318653939 + +# "HAProxy" +906040840570581628380102443042533861539556557517936170926193455423730027837035343802588461339798237837475447988178812029134850861021153585005063335617996553768213337860774575502160795277533287464627066487807717589999181053196180624799186875227432140901857022126832808904656375633414194414552334492747951247501836622316403471110676048569777319299601171704677234861055585859735781271577798830532249564558234177966202320578834072694239353656761041903937825662368907675656932130031869732503793672833030422034909702170861654194326037695796389172599276354651108744948500830717852813901958647978225693799997790190075499683046859044427630083214486625672563853418910161815638591520186500612691900810077498517067960122593264771259949610494243682989807680057883660184291039606834485529416614329435402077543694418214174659819337306416572722289656707277110121619222229511207971018486819624504829653498154535139686575250457271762799716977128710497523899453049153699793530242644384117668637391534890493031631537822163431401923603177775997568711241483941019767613162887962063507644816337503418727944508950664649444861084128865053119474215353946462261884758016198125443516882791862273977681960435739151437484804278673499862950433100913752693192967979 + +# "HAProxy" +102700630561259395087032918003696203215413680966205093401719261420927348617434421199810037690244910311348546427618773468138363558097981635746622031353236427233047123501573548251948502109660464742170278233192733579208742792462937581596612734833735829907594549504874993126473577377037753456164875577780679800659 From 2b440f15ea942fbe1edc033e12b04cf9374ca848 Mon Sep 17 00:00:00 2001 From: Dirk Date: Sat, 21 Jan 2017 16:52:02 +0100 Subject: [PATCH 56/61] - polishing #570 - run_logjam() terminates if no local DH export ciphers are configured --- testssl.sh | 61 +++++++++++++++++++++++++++++++----------------------- 1 file changed, 35 insertions(+), 26 deletions(-) diff --git a/testssl.sh b/testssl.sh index 3b8e34c..002d729 100755 --- a/testssl.sh +++ b/testssl.sh @@ -9319,20 +9319,25 @@ run_ssl_poodle() { local cve="CVE-2014-3566" local cwe="CWE-310" local hint="" + local -i nr_cbc_ciphers=0 local using_sockets=true - "$SSL_NATIVE" && using_sockets=false - [[ $VULN_COUNT -le $VULN_THRESHLD ]] && outln && pr_headlineln " Testing for SSLv3 POODLE (Padding Oracle On Downgraded Legacy Encryption) " && outln pr_bold " POODLE, SSL"; out " ($cve) " + + "$SSL_NATIVE" && using_sockets=false + # The openssl binary distributed has almost everything we need (PSK and KRB5 ciphers are typically missing). + # Measurements show that there's little impact whether we use sockets or TLS here, so the default is sockets here if "$using_sockets"; then tls_sockets "00" "$cbc_ciphers_hex" sclient_success=$? else - locally_supported "-ssl3" || return 0 - cbc_ciphers=$(actually_supported_ciphers $cbc_ciphers) - - debugme echo $cbc_ciphers + if ! "$HAS_SSL3"; then + local_problem_ln "Your $OPENSSL doesn't support SSLv3" + return 1 + fi + nr_cbc_ciphers=$(count_ciphers $cbc_ciphers) + nr_supported_ciphers=$(count_ciphers $(actually_supported_ciphers $cbc_ciphers)) $OPENSSL s_client -ssl3 $STARTTLS $BUGS -cipher $cbc_ciphers -connect $NODEIP:$PORT $PROXY >$TMPFILE 2>$ERRFILE $TMPFILE 2>$ERRFILE Date: Sat, 21 Jan 2017 18:08:31 +0100 Subject: [PATCH 57/61] - poodle output polishing - minor polish of #552 --- testssl.sh | 23 +++++++++-------------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/testssl.sh b/testssl.sh index 2987c11..e194780 100755 --- a/testssl.sh +++ b/testssl.sh @@ -9349,12 +9349,12 @@ run_ssl_poodle() { else pr_done_best "not vulnerable (OK)"; if [[ "$nr_supported_ciphers" -ge 83 ]]; then - # KRB and PSK cipher only missing: display discrepancy but no warning + # Likely only KRB and PSK cipher are missing: display discrepancy but no warning out ", $nr_supported_ciphers/$nr_cbc_ciphers local ciphers" else pr_warning ", $nr_supported_ciphers/$nr_cbc_ciphers local ciphers" fi - fileout "poodle_ssl" "OK" "POODLE, SSL: not vulnerable (using $nr_supported_ciphers of $nr_cbc_ciphers" "$cve" "$cwe" + fileout "poodle_ssl" "OK" "POODLE, SSL: not vulnerable ($nr_supported_ciphers of $nr_cbc_ciphers local ciphers" "$cve" "$cwe" fi outln tmpfile_handle $FUNCNAME.txt @@ -9564,7 +9564,7 @@ run_logjam() { pr_bold " LOGJAM"; out " ($cve), experimental " "$SSL_NATIVE" && using_sockets=false - # Also as the openssl binary distributed has everything we need measurements show that + # Also as the openssl binary distributed has everything we need measurements show that # there's no impact whether we use sockets or TLS here, so the default is sockets here if ! "$using_sockets"; then nr_supported_ciphers=$(count_ciphers $(actually_supported_ciphers $exportdh_cipher_list)) @@ -9670,10 +9670,8 @@ run_logjam() { # now the final verdict # we only use once the color here on the screen, so screen and fileout SEEM to be inconsistent if "$vuln_exportdh_ciphers"; then - if [[ "$nr_supported_ciphers" -ne 0 ]]; then - pr_svrty_high "VULNERABLE (NOT ok):"; out " uses DH EXPORT ciphers" - fileout "logjam" "HIGH" "LOGJAM: VULNERABLE, uses DH EXPORT ciphers" "$cve" "$cwe" "$hint" - fi + pr_svrty_high "VULNERABLE (NOT ok):"; out " uses DH EXPORT ciphers" + fileout "logjam" "HIGH" "LOGJAM: VULNERABLE, uses DH EXPORT ciphers" "$cve" "$cwe" "$hint" if [[ $ret -eq 3 ]]; then out ", no DH key detected" fileout "LOGJAM_common primes" "OK" "no DH key detected" @@ -9831,17 +9829,13 @@ run_beast(){ local first=true local continued=false local cbc_cipher_list="ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:SRP-DSS-AES-256-CBC-SHA:SRP-RSA-AES-256-CBC-SHA:SRP-AES-256-CBC-SHA:DHE-PSK-AES256-CBC-SHA:DHE-RSA-AES256-SHA:DHE-DSS-AES256-SHA:DH-RSA-AES256-SHA:DH-DSS-AES256-SHA:DHE-RSA-CAMELLIA256-SHA:DHE-DSS-CAMELLIA256-SHA:DH-RSA-CAMELLIA256-SHA:DH-DSS-CAMELLIA256-SHA:AECDH-AES256-SHA:ADH-AES256-SHA:ADH-CAMELLIA256-SHA:ECDH-RSA-AES256-SHA:ECDH-ECDSA-AES256-SHA:AES256-SHA:ECDHE-PSK-AES256-CBC-SHA:CAMELLIA256-SHA:RSA-PSK-AES256-CBC-SHA:PSK-AES256-CBC-SHA:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:SRP-DSS-AES-128-CBC-SHA:SRP-RSA-AES-128-CBC-SHA:SRP-AES-128-CBC-SHA:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA:DH-RSA-AES128-SHA:DH-DSS-AES128-SHA:DHE-RSA-SEED-SHA:DHE-DSS-SEED-SHA:DH-RSA-SEED-SHA:DH-DSS-SEED-SHA:DHE-RSA-CAMELLIA128-SHA:DHE-DSS-CAMELLIA128-SHA:DH-RSA-CAMELLIA128-SHA:DH-DSS-CAMELLIA128-SHA:AECDH-AES128-SHA:ADH-AES128-SHA:ADH-SEED-SHA:ADH-CAMELLIA128-SHA:ECDH-RSA-AES128-SHA:ECDH-ECDSA-AES128-SHA:AES128-SHA:ECDHE-PSK-AES128-CBC-SHA:DHE-PSK-AES128-CBC-SHA:SEED-SHA:CAMELLIA128-SHA:IDEA-CBC-SHA:RSA-PSK-AES128-CBC-SHA:PSK-AES128-CBC-SHA:KRB5-IDEA-CBC-SHA:KRB5-IDEA-CBC-MD5:ECDHE-RSA-DES-CBC3-SHA:ECDHE-ECDSA-DES-CBC3-SHA:SRP-DSS-3DES-EDE-CBC-SHA:SRP-RSA-3DES-EDE-CBC-SHA:SRP-3DES-EDE-CBC-SHA:EDH-RSA-DES-CBC3-SHA:EDH-DSS-DES-CBC3-SHA:DH-RSA-DES-CBC3-SHA:DH-DSS-DES-CBC3-SHA:AECDH-DES-CBC3-SHA:ADH-DES-CBC3-SHA:ECDH-RSA-DES-CBC3-SHA:ECDH-ECDSA-DES-CBC3-SHA:DES-CBC3-SHA:RSA-PSK-3DES-EDE-CBC-SHA:PSK-3DES-EDE-CBC-SHA:KRB5-DES-CBC3-SHA:KRB5-DES-CBC3-MD5:ECDHE-PSK-3DES-EDE-CBC-SHA:DHE-PSK-3DES-EDE-CBC-SHA:EXP1024-DHE-DSS-DES-CBC-SHA:EDH-RSA-DES-CBC-SHA:EDH-DSS-DES-CBC-SHA:DH-RSA-DES-CBC-SHA:DH-DSS-DES-CBC-SHA:ADH-DES-CBC-SHA:EXP1024-DES-CBC-SHA:DES-CBC-SHA:KRB5-DES-CBC-SHA:KRB5-DES-CBC-MD5:EXP-EDH-RSA-DES-CBC-SHA:EXP-EDH-DSS-DES-CBC-SHA:EXP-ADH-DES-CBC-SHA:EXP-DES-CBC-SHA:EXP-RC2-CBC-MD5:EXP-KRB5-RC2-CBC-SHA:EXP-KRB5-DES-CBC-SHA:EXP-KRB5-RC2-CBC-MD5:EXP-KRB5-DES-CBC-MD5:EXP-DH-DSS-DES-CBC-SHA:EXP-DH-RSA-DES-CBC-SHA" - cbc_cipher_list_hex="" + local cbc_ciphers_hex="c0,14, c0,0a, c0,22, c0,21, c0,20, 00,91, 00,39, 00,38, 00,37, 00,36, 00,88, 00,87, 00,86, 00,85, c0,19, 00,3a, 00,89, c0,0f, c0,05, 00,35, c0,36, 00,84, 00,95, 00,8d, c0,13, c0,09, c0,1f, c0,1e, c0,1d, 00,33, 00,32, 00,31, 00,30, 00,9a, 00,99, 00,98, 00,97, 00,45, 00,44, 00,43, 00,42, c0,18, 00,34, 00,9b, 00,46, c0,0e, c0,04, 00,2f, c0,35, 00,90, 00,96, 00,41, 00,07, 00,94, 00,8c, 00,21, 00,25, c0,12, c0,08, c0,1c, c0,1b, c0,1a, 00,16, 00,13, 00,10, 00,0d, c0,17, 00,1b, c0,0d, c0,03, 00,0a, 00,93, 00,8b, 00,1f, 00,23, c0,34, 00,8f, 00,63, 00,15, 00,12, 00,0f, 00,0c, 00,1a, 00,62, 00,09, 00,1e, 00,22, 00,14, 00,11, 00,19, 00,08, 00,06, 00,27, 00,26, 00,2a, 00,29, 00,0b, 00,0e" local has_dh_bits="$HAS_DH_BITS" local using_sockets=true local cve="CVE-2011-3389" local cwe="CWE-20" local hint="" - "$SSL_NATIVE" && using_sockets=false - "$FAST" && using_sockets=false - [[ $TLS_NR_CIPHERS == 0 ]] && using_sockets=false - if [[ $VULN_COUNT -le $VULN_THRESHLD ]]; then outln pr_headlineln " Testing for BEAST vulnerability " @@ -9851,6 +9845,8 @@ run_beast(){ fi pr_bold " BEAST"; out " ($cve) " + "$SSL_NATIVE" && using_sockets=false + [[ $TLS_NR_CIPHERS == 0 ]] && using_sockets=false if "$using_sockets" || [[ $OSSL_VER_MAJOR -lt 1 ]]; then for (( i=0; i < TLS_NR_CIPHERS; i++ )); do hexc="${TLS_CIPHER_HEXCODE[i]}" @@ -9928,7 +9924,6 @@ run_beast(){ fi fi # protocol succeeded - # now we test in one shot with the precompiled ciphers if "$using_sockets"; then case "$proto" in @@ -9943,7 +9938,7 @@ run_beast(){ fi detected_cbc_ciphers="" - for (( i=0; i < nr_ciphers; i++ )); do + for ((i=0; i Date: Sat, 21 Jan 2017 19:43:07 +0100 Subject: [PATCH 58/61] - enable CAA per default (#588) - hex2ascii() for converting strings - swap quoted output in -S to italic (mostly) --- testssl.sh | 50 +++++++++++++++++++++++++++++++------------------- 1 file changed, 31 insertions(+), 19 deletions(-) diff --git a/testssl.sh b/testssl.sh index e194780..6667e69 100755 --- a/testssl.sh +++ b/testssl.sh @@ -892,6 +892,13 @@ hex2dec() { echo $((16#$1)) } +# convert 414243 into ABC +hex2ascii() { + for (( i=0; i<${#1}; i+=2 )); do + printf "\x${1:$i:2}" + done +} + # trim spaces for BSD and old sed count_lines() { #echo "${$(wc -l <<< "$1")// /}" @@ -5748,7 +5755,7 @@ certificate_info() { cnfinding="Common Name (CN) : " cn="$(get_cn_from_cert $HOSTCERT)" if [[ -n "$cn" ]]; then - pr_dquoted "$cn" + pr_italic "$cn" cnfinding="$cn" else cn="no CN field in subject" @@ -5786,7 +5793,7 @@ certificate_info() { outln ", (request w/o SNI: $cn_nosni)" cnfinding+=", (request w/o SNI: $cn_nosni)" else - out " (CN in response to request w/o SNI: "; pr_dquoted "$cn_nosni"; outln ")" + out " (CN in response to request w/o SNI: "; pr_italic "$cn_nosni"; outln ")" cnfinding+=" (CN in response to request w/o SNI: \"$cn_nosni\")" fi fileout "${json_prefix}cn" "$cnok" "$cnfinding" @@ -5800,7 +5807,7 @@ certificate_info() { out "$indent"; pr_bold " subjectAltName (SAN) " if [[ -n "$sans" ]]; then while read san; do - [[ -n "$san" ]] && pr_dquoted "$san" + [[ -n "$san" ]] && pr_italic "$san" out " " done <<< "$sans" fileout "${json_prefix}san" "INFO" "subjectAltName (SAN) : $sans" @@ -5821,7 +5828,7 @@ certificate_info() { pr_svrty_criticalln "self-signed (NOT ok)" fileout "${json_prefix}issuer" "CRITICAL" "Issuer: selfsigned" else - issuerfinding="$(pr_dquoted "$issuer_CN")" + issuerfinding="$(pr_italic "$issuer_CN")" if [[ -z "$issuer_O" ]] && [[ -n "$issuer_DC" ]]; then for san in $issuer_DC; do if [[ -z "$issuer_O" ]]; then @@ -5833,10 +5840,10 @@ certificate_info() { fi if [[ -n "$issuer_O" ]]; then issuerfinding+=" (" - issuerfinding+="$(pr_dquoted "$issuer_O")" + issuerfinding+="$(pr_italic "$issuer_O")" if [[ -n "$issuer_C" ]]; then issuerfinding+=" from " - issuerfinding+="$(pr_dquoted "$issuer_C")" + issuerfinding+="$(pr_italic "$issuer_C")" fi issuerfinding+=")" fi @@ -6059,20 +6066,17 @@ certificate_info() { fi outln - if "$EXPERIMENTAL"; then - out "$indent"; pr_bold " DNS CAA RR record " - caa="$(get_caa_rr_record $NODE)" - if [[ -n "$caa" ]]; then - pr_done_good "OK ($caa)" - fileout "${json_prefix}CAA_record" "OK" "DNS Certification Authority Authorization (CAA) Resource Record / RFC6844 : offered" - else - pr_svrty_minor "--" - fileout "${json_prefix}CAA_record" "LOW" "DNS Certification Authority Authorization (CAA) Resource Record / RFC6844 : not offered" - fi + out "$indent"; pr_bold " DNS CAA RR"; out " (experimental) " + caa="$(get_caa_rr_record $NODE)" + if [[ -n "$caa" ]]; then + pr_done_good "OK"; out " (" ; pr_italic "$caa"; out ")" + fileout "${json_prefix}CAA_record" "OK" "DNS Certification Authority Authorization (CAA) Resource Record / RFC6844 : offered" + else + pr_svrty_minor "--" + fileout "${json_prefix}CAA_record" "LOW" "DNS Certification Authority Authorization (CAA) Resource Record / RFC6844 : not offered" fi outln "\n" - return $ret } # FIXME: revoked, see checkcert.sh @@ -11185,14 +11189,22 @@ get_caa_rr_record() { # No dig, host, or nslookup --> complaint was elsewhere already and except for one which has drill only we don't get here fi OPENSSL_CONF="$saved_openssl_conf" # see https://github.com/drwetter/testssl.sh/issues/134 + + # try to convert old return values + if [[ "$caa" =~ ^[A-F0-9]+$ ]]; then + caa=${caa:4:100} # ignore the first 4 bytes + caa=$(hex2ascii "$caa" | sed 's/^issue//g') + else + caa=${caa//\"/} # strip " + fi echo "$caa" - return 0 # to do: # 1: check old binaries whether they support this record at all -# 2: check whether hexstring is returned and deal with it +# done (2: check whether hexstring is returned and deal with it) # 3: check more than domainname, see https://tools.ietf.org/html/rfc6844#section-3 # 4: check whether $1 is a CNAME and take this # 5: query with drill + return 0 } get_mx_record() { From 4911aaf05bcc7dc093a44b595072f118120c4e3d Mon Sep 17 00:00:00 2001 From: Dirk Date: Mon, 23 Jan 2017 11:33:18 +0100 Subject: [PATCH 59/61] Fix #593 --- testssl.sh | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/testssl.sh b/testssl.sh index 9f4c054..4d763a1 100755 --- a/testssl.sh +++ b/testssl.sh @@ -9390,13 +9390,17 @@ run_ssl_poodle() { fileout "poodle_ssl" "HIGH" "POODLE, SSL: VULNERABLE, uses SSLv3+CBC" "$cve" "$cwe" "$hint" else pr_done_best "not vulnerable (OK)"; - if [[ "$nr_supported_ciphers" -ge 83 ]]; then - # Likely only KRB and PSK cipher are missing: display discrepancy but no warning - out ", $nr_supported_ciphers/$nr_cbc_ciphers local ciphers" + if "$using_sockets"; then + fileout "poodle_ssl" "OK" "POODLE, SSL: not vulnerable" "$cve" "$cwe" else - pr_warning ", $nr_supported_ciphers/$nr_cbc_ciphers local ciphers" + if [[ "$nr_supported_ciphers" -ge 83 ]]; then + # Likely only KRB and PSK cipher are missing: display discrepancy but no warning + out ", $nr_supported_ciphers/$nr_cbc_ciphers local ciphers" + else + pr_warning ", $nr_supported_ciphers/$nr_cbc_ciphers local ciphers" + fi + fileout "poodle_ssl" "OK" "POODLE, SSL: not vulnerable ($nr_supported_ciphers of $nr_cbc_ciphers local ciphers" "$cve" "$cwe" fi - fileout "poodle_ssl" "OK" "POODLE, SSL: not vulnerable ($nr_supported_ciphers of $nr_cbc_ciphers local ciphers" "$cve" "$cwe" fi outln tmpfile_handle $FUNCNAME.txt From 2a5d56a9d66e753b9ddacb22d31f8d135c1592f5 Mon Sep 17 00:00:00 2001 From: Dirk Date: Tue, 24 Jan 2017 08:37:19 +0100 Subject: [PATCH 60/61] help aviod misunderstanding, see #594 and some reordering --- testssl.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/testssl.sh b/testssl.sh index 4d763a1..f4a38ce 100755 --- a/testssl.sh +++ b/testssl.sh @@ -10671,12 +10671,12 @@ single check as ("$PROG_NAME URI" does everything except -E): -B, --heartbleed tests for heartbleed vulnerability -I, --ccs, --ccs-injection tests for CCS injection vulnerability -R, --renegotiation tests for renegotiation vulnerabilities - -C, --compression, --crime tests for CRIME vulnerability - -T, --breach tests for BREACH vulnerability + -C, --compression, --crime tests for CRIME vulnerability (TLS compression issue) + -A, --beast tests for BEAST vulnerability (HTTP compression issue) -O, --poodle tests for POODLE (SSL) vulnerability -Z, --tls-fallback checks TLS_FALLBACK_SCSV mitigation + -T, --breach tests for BREACH vulnerability -F, --freak tests for FREAK vulnerability - -A, --beast tests for BEAST vulnerability -J, --logjam tests for LOGJAM vulnerability -D, --drown tests for DROWN vulnerability -s, --pfs, --fs, --nsa checks (perfect) forward secrecy settings From 1ee75689e0170c70ebecc6b65bbb2e02be9f50d4 Mon Sep 17 00:00:00 2001 From: David Cooper Date: Wed, 25 Jan 2017 08:57:20 -0500 Subject: [PATCH 61/61] Fix typo in tls_sockets() This PR just fixes a minor bug in `tls_sockets()`, changing ``` debugme "stuck on sending: $ret" ``` to ``` debugme echo "stuck on sending: $ret" ``` --- testssl.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testssl.sh b/testssl.sh index 9a3f7fd..f70c699 100755 --- a/testssl.sh +++ b/testssl.sh @@ -8882,7 +8882,7 @@ tls_sockets() { fi debugme outln else - debugme "stuck on sending: $ret" + debugme echo "stuck on sending: $ret" fi close_socket