From c6db49066fbac12712011ac8dd7bb67cf5f7ad34 Mon Sep 17 00:00:00 2001 From: David Cooper Date: Mon, 11 Apr 2016 15:51:53 -0400 Subject: [PATCH 1/3] run_allciphers(),run_cipher_per_proto(), and SSLv2 This PR addresses two problems related to SSLv2 in run_allciphers() and run_cipher_per_proto(). In run_cipher_per_proto(), the call to "$OPENSSL s_client" is changed to that $SNI is not included if $proto is -sslv2 or -sslv3. As noted in a comment within run_prototest_openssl(), "newer openssl throw an error if SNI is supplied with SSLv2" and "SSLv3 doesn't have SNI (openssl doesn't complain though -- yet)." run_allciphers() will sometimes incorrectly report that a server supports an SSLv2 cipher, even if the server does not support SSLv2 at all. The problem occurs if there is a supported SSLv3 cipher suite that has the same OpenSSL name as an SSLv2 cipher suite (e.g., RC4-MD5). Since the call to "$OPENSSL s_client" only uses the OpenSSL name, but the results report both the name, hexcode, and RFC cipher suite name, both the SSLv2 and SSLv3 cipher suites are reported as being supported (e.g., 0x04=RC4-MD5=TLS_RSA_WITH_RC4_128_MD5 and x010080=RC4-MD5=SSL_CK_RC4_128_WITH_MD5). This PR fixes the problem by testing SSLv2 cipher suites separately from non-SSLv2 cipher suites. --- testssl.sh | 38 +++++++++++++++++++++++++++++--------- 1 file changed, 29 insertions(+), 9 deletions(-) diff --git a/testssl.sh b/testssl.sh index fb66226..a820aee 100755 --- a/testssl.sh +++ b/testssl.sh @@ -1571,16 +1571,18 @@ test_just_one(){ run_allciphers() { local tmpfile local -i nr_ciphers=0 - local n sslvers auth mac export - local -a hexcode ciph kx enc export2 + local n auth mac export + local -a hexcode ciph sslvers 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 available local ciphers_to_test + local sslv2_locally_supported=false sslv2_supported=false - # get a list of all the cipher suites to test (only need the hexcode, ciph, kx, enc, and export values) - while read hexcode[nr_ciphers] n ciph[nr_ciphers] sslvers kx[nr_ciphers] auth enc[nr_ciphers] mac export2[nr_ciphers]; do + # get a list of all the cipher suites to test (only need the hexcode, ciph, sslvers, kx, enc, and export values) + while read hexcode[nr_ciphers] n ciph[nr_ciphers] sslvers[nr_ciphers] kx[nr_ciphers] auth enc[nr_ciphers] mac export2[nr_ciphers]; do + [[ "${sslvers[nr_ciphers]}" == "SSLv2" ]] && sslv2_locally_supported=true nr_ciphers=$nr_ciphers+1 done < <($OPENSSL ciphers -V 'ALL:COMPLEMENTOFALL:@STRENGTH' 2>>$ERRFILE) @@ -1590,6 +1592,12 @@ run_allciphers() { outln neat_header + if $sslv2_locally_supported; then + $OPENSSL s_client $STARTTLS $BUGS -connect $NODEIP:$PORT $PROXY -ssl2 >$TMPFILE 2>$ERRFILE $TMPFILE 2>$ERRFILE $TMPFILE 2>$ERRFILE $TMPFILE 2>$ERRFILE $TMPFILE 2>$ERRFILE $TMPFILE 2>$ERRFILE $TMPFILE 2>$ERRFILE Date: Tue, 19 Apr 2016 09:47:52 -0400 Subject: [PATCH 2/3] Use $HAS_SSL2 I changed the code to use the global $HAS_SSL2 rather than $sslv2_locally_supported. I don't think there's a need to use $HAS_SSL3 in run_allciphers(), since the call to "$OPENSSL s_client" for non-SSLv2 ciphers does not specify a protocol. It's also not needed in run_cipher_per_proto(), since there is already a call to locally_supported() before anything further is done with a protocol. --- testssl.sh | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/testssl.sh b/testssl.sh index a820aee..6478a9d 100755 --- a/testssl.sh +++ b/testssl.sh @@ -1578,11 +1578,10 @@ run_allciphers() { local dhlen local available local ciphers_to_test - local sslv2_locally_supported=false sslv2_supported=false + local sslv2_supported=false # get a list of all the cipher suites to test (only need the hexcode, ciph, sslvers, kx, enc, and export values) while read hexcode[nr_ciphers] n ciph[nr_ciphers] sslvers[nr_ciphers] kx[nr_ciphers] auth enc[nr_ciphers] mac export2[nr_ciphers]; do - [[ "${sslvers[nr_ciphers]}" == "SSLv2" ]] && sslv2_locally_supported=true nr_ciphers=$nr_ciphers+1 done < <($OPENSSL ciphers -V 'ALL:COMPLEMENTOFALL:@STRENGTH' 2>>$ERRFILE) @@ -1592,7 +1591,7 @@ run_allciphers() { outln neat_header - if $sslv2_locally_supported; then + if "$HAS_SSL2"; then $OPENSSL s_client $STARTTLS $BUGS -connect $NODEIP:$PORT $PROXY -ssl2 >$TMPFILE 2>$ERRFILE Date: Thu, 21 Apr 2016 14:05:19 -0400 Subject: [PATCH 3/3] "$OPENSSL ciphers" ignores "-tls1_1" and "-tls1_2" Versions of OpenSSL prior to 1.1.0 ignore the options "-tls1_1" and "-tls1_2". So, a call of the form "$OPENSSL ciphers -tls1_2 -V 'ALL:COMPLEMENTOFALL:@STRENGTH' would list all supported ciphers (including SSLv2 ciphers), not just ciphers appropriate for TLS1.2. This changes the code to use "-tls1" instead of "-tls1_1" or "-tls1_2" if a version of OpenSSL other than 1.1.0 is being used. --- testssl.sh | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/testssl.sh b/testssl.sh index 6478a9d..abb8156 100755 --- a/testssl.sh +++ b/testssl.sh @@ -1686,7 +1686,7 @@ 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 + local proto proto_text ossl_ciphers_proto local -i nr_ciphers local n sslvers auth mac export local -a hexcode ciph kx enc export2 @@ -1704,11 +1704,17 @@ run_cipher_per_proto() { locally_supported "$proto" "$proto_text" || continue outln + # 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"* ]]; 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) 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 $proto -V 'ALL:COMPLEMENTOFALL:@STRENGTH' 2>$ERRFILE) + 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