From c98bbdc36dbdcb65dde68a9d465a427edaecd0d6 Mon Sep 17 00:00:00 2001 From: Steve Mokris Date: Sat, 2 Oct 2021 12:22:05 -0400 Subject: [PATCH 1/3] In determine_trust(), use the OpenSSL '-trusted_first' flag to ignore the now-expired DST Root CA X3 root certificate. Fixes #1995. --- testssl.sh | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/testssl.sh b/testssl.sh index 7f21f38..65233b5 100755 --- a/testssl.sh +++ b/testssl.sh @@ -7264,9 +7264,9 @@ determine_trust() { # in a subshell because that should be valid here only (export SSL_CERT_DIR="/dev/null"; export SSL_CERT_FILE="/dev/null" if [[ $certificates_provided -ge 2 ]]; then - $OPENSSL verify -purpose sslserver -CAfile <(cat $ADDTL_CA_FILES "$bundle_fname") -untrusted $TEMPDIR/intermediatecerts.pem $HOSTCERT >$TEMPDIR/${certificate_file[i]}.1 2>$TEMPDIR/${certificate_file[i]}.2 + $OPENSSL verify $TRUSTED1ST -purpose sslserver -CAfile <(cat $ADDTL_CA_FILES "$bundle_fname") -untrusted $TEMPDIR/intermediatecerts.pem $HOSTCERT >$TEMPDIR/${certificate_file[i]}.1 2>$TEMPDIR/${certificate_file[i]}.2 else - $OPENSSL verify -purpose sslserver -CAfile <(cat $ADDTL_CA_FILES "$bundle_fname") $HOSTCERT >$TEMPDIR/${certificate_file[i]}.1 2>$TEMPDIR/${certificate_file[i]}.2 + $OPENSSL verify $TRUSTED1ST -purpose sslserver -CAfile <(cat $ADDTL_CA_FILES "$bundle_fname") $HOSTCERT >$TEMPDIR/${certificate_file[i]}.1 2>$TEMPDIR/${certificate_file[i]}.2 fi) verify_retcode[i]=$(awk '/error [1-9][0-9]? at [0-9]+ depth lookup:/ { if (!found) {print $2; found=1} }' $TEMPDIR/${certificate_file[i]}.1 $TEMPDIR/${certificate_file[i]}.2) [[ -z "${verify_retcode[i]}" ]] && verify_retcode[i]=0 @@ -19326,6 +19326,8 @@ find_openssl_binary() { [[ "$(echo -e "\x78\x9C\xAB\xCA\xC9\x4C\xE2\x02\x00\x06\x20\x01\xBC" | $OPENSSL zlib -d 2>/dev/null)" == zlib ]] && HAS_ZLIB=true + $OPENSSL verify -trusted_first &1 | grep -q '^usage' || TRUSTED1ST="-trusted_first" + if [[ -n "$CONNECT_TIMEOUT" ]] || [[ -n "$OPENSSL_TIMEOUT" ]]; then # We don't set a general timeout as we might not have "timeout" installed and we only # do what is instructed. Thus we check first what the command line params were, From 0012adf47efc36cc508c8b313ddeb8cbf95c2f88 Mon Sep 17 00:00:00 2001 From: Steve Mokris Date: Tue, 5 Oct 2021 13:53:58 -0400 Subject: [PATCH 2/3] Add a test to verify that expired.badssl.com's chain of trust is expired. --- t/51_badssl.com.t | 1 + 1 file changed, 1 insertion(+) diff --git a/t/51_badssl.com.t b/t/51_badssl.com.t index 9b9e278..40b6e91 100755 --- a/t/51_badssl.com.t +++ b/t/51_badssl.com.t @@ -22,6 +22,7 @@ cmp_ok(@$okjson,'>',10,"We have more then 10 findings"); $tests++; # Expiration pass("Running testssl against expired.badssl.com"); $tests++; $out = `./testssl.sh -S --jsonfile tmp.json --color 0 expired.badssl.com`; +like($out, qr/Chain of trust\s+NOT ok \(expired\)/,"The chain of trust should be expired"); $tests++; like($out, qr/Certificate Validity \(UTC\)\s+expired/,"The certificate should be expired"); $tests++; $json = json('tmp.json'); unlink 'tmp.json'; From 5c4500ea4f3f2fb86ed3ccd8511cc38a8e9a7b80 Mon Sep 17 00:00:00 2001 From: Steve Mokris Date: Wed, 6 Oct 2021 16:01:13 -0400 Subject: [PATCH 3/3] Initialize/reset the TRUSTED1ST variable, in case determine_optimal_proto() changes the active openssl binary partway through execution --- testssl.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/testssl.sh b/testssl.sh index 65233b5..beed0ec 100755 --- a/testssl.sh +++ b/testssl.sh @@ -410,6 +410,7 @@ KEY_EXCH_SCORE=100 # Keeps track of the score for category CIPH_STR_BEST=0 # Keeps track of the best bit size for category 3 "Cipher Strength" CIPH_STR_WORST=100000 # Keeps track of the worst bit size for category 3 "Cipher Strength" # Intentionally set very high, so it can be set to 0, if necessary +TRUSTED1ST="" # Contains the `-trusted_first` flag, if this version of openssl supports it ########### Global variables for parallel mass testing # @@ -19238,6 +19239,7 @@ find_openssl_binary() { HAS_ZLIB=false HAS_UDS=false HAS_UDS2=false + TRUSTED1ST="" $OPENSSL ciphers -s 2>&1 | grep -aiq "unknown option" || OSSL_CIPHERS_S="-s"