From 69bdbeb982c53c03b3bca4249b032f22ce26becd Mon Sep 17 00:00:00 2001 From: Magnus Larsen Date: Wed, 18 Sep 2024 09:08:07 +0200 Subject: [PATCH 01/41] feat(rating): line-wrapping comments for grade_cap_reasons --- testssl.sh | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/testssl.sh b/testssl.sh index 4068440..a17ea56 100755 --- a/testssl.sh +++ b/testssl.sh @@ -22933,15 +22933,20 @@ run_rating() { pr_headlineln " Rating (experimental) " outln - [[ -n "$STARTTLS_PROTOCOL" ]] && set_grade_cap "T" "STARTTLS encryption is not mandatory for clients. STARTTLS can only be secured client-side" - # TL;DR: E-mail transfer via port 25 is broken and the amendments suggested so far are duct tape. So please do not expect testssl.sh to shut up. + if [[ -n "$STARTTLS_PROTOCOL" ]]; then + read -r -d '' grade_cap_reason <<'EOF' +TL;DR: E-mail transfer via port 25 is broken and the amendments suggested so far are duct tape. So please do not expect testssl.sh to shut up. - # Explanation: For other than SMTP you should use TLS as per RFC 8314 . For SMTP however there's this thing named reality: A mail server cannot - # just switch to the mail submission port 587 only and continue to receive mail from everyone. Even if you advertise this via SRV record (RFC 6186). - # For STARTTLS there's no way to tell for testssl.sh whether it is secure. A MitM can always intercept the connection, unless the client checks - # the certificate accordingly (it's getting better but some just don't). TLSA Records/DANE and MTA-STS (RFC-8461) on the server side can help too. - # But as said, it's useless unless the client MTA checks all that which no tool can check. +Explanation: For other than SMTP you should use TLS as per RFC 8314. For SMTP however there's this thing named reality: A mail server cannot +just switch to the mail submission port 587 only and continue to receive mail from everyone. Even if you advertise this via SRV record (RFC 6186). +For STARTTLS there's no way to tell for testssl.sh whether it is secure. A MitM can always intercept the connection, unless the client checks +the certificate accordingly (it's getting better but some just don't). TLSA Records/DANE and MTA-STS (RFC-8461) on the server side can help too. +But as said, it's useless unless the client MTA checks all that which no tool can check. +EOF + # We can't use newlines in the message, as the grade-sorting function will mess up the reason + set_grade_cap "T" "$(tr '\n' ' ' <<<$grade_cap_reason)" + fi pr_bold " Rating specs"; out " (not complete) "; outln "SSL Labs's 'SSL Server Rating Guide' (version 2009q from 2020-01-30)" pr_bold " Specification documentation "; pr_url "https://github.com/ssllabs/research/wiki/SSL-Server-Rating-Guide" @@ -23127,9 +23132,9 @@ run_rating() { # Pretty print - again, it's just nicer to read for reason in "${sorted_reasons[@]}"; do if [[ $reason_nr -eq 0 ]]; then - pr_bold " Grade cap reasons "; outln "$reason" + pr_bold " Grade cap reasons "; out_row_aligned_max_width "$reason\n" ' ' $TERM_WIDTH else - outln " $reason" + out_row_aligned_max_width " $reason\n" ' ' $TERM_WIDTH fi ((reason_nr++)) fileout "grade_cap_reason_${reason_nr}" "INFO" "$reason" From 34ebe22e48184c4b7849fda430309e530da121cf Mon Sep 17 00:00:00 2001 From: dselen <80752476+DaanSelen@users.noreply.github.com> Date: Fri, 20 Sep 2024 10:19:21 +0200 Subject: [PATCH 02/41] Minor English Readme.md changes --- Readme.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Readme.md b/Readme.md index 3fb943e..795d55f 100644 --- a/Readme.md +++ b/Readme.md @@ -7,7 +7,7 @@ [![License](https://img.shields.io/github/license/drwetter/testssl.sh)](https://github.com/drwetter/testssl.sh/LICENSE) [![Docker](https://img.shields.io/docker/pulls/drwetter/testssl.sh)](https://github.com/drwetter/testssl.sh/blob/3.2/Dockerfile.md) -`testssl.sh` is a free command line tool which checks a server's service on +`testssl.sh` is a free command line tool which checks a server its service on any port for the support of TLS/SSL ciphers, protocols as well as some cryptographic flaws. @@ -73,7 +73,7 @@ For more please consult [Dockerfile.md](https://github.com/drwetter/testssl.sh/b ### No Warranty -Usage of the program is without any warranty. Use it at yor own risk. +Usage of the program is without any warranty. Use it at your own risk. Testssl.sh is intended to be used as a standalone CLI tool. While we tried to apply best practise security measures, we can't guarantee that the program is without any vulnerabilities. Running as a service may pose security risks and you're recommended to apply additional security measures. From 53c07eff19b4e4befdda5244cfa0f34d7a141aa1 Mon Sep 17 00:00:00 2001 From: dselen <80752476+DaanSelen@users.noreply.github.com> Date: Fri, 20 Sep 2024 10:20:58 +0200 Subject: [PATCH 03/41] Confusion ensues --- Readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Readme.md b/Readme.md index 795d55f..da26026 100644 --- a/Readme.md +++ b/Readme.md @@ -7,7 +7,7 @@ [![License](https://img.shields.io/github/license/drwetter/testssl.sh)](https://github.com/drwetter/testssl.sh/LICENSE) [![Docker](https://img.shields.io/docker/pulls/drwetter/testssl.sh)](https://github.com/drwetter/testssl.sh/blob/3.2/Dockerfile.md) -`testssl.sh` is a free command line tool which checks a server its service on +`testssl.sh` is a free command line tool which checks a server's service on any port for the support of TLS/SSL ciphers, protocols as well as some cryptographic flaws. From 67fd81a9bf8377b8fe0a31653b5abeb5803345b6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 30 Sep 2024 00:49:02 +0000 Subject: [PATCH 04/41] Bump docker/build-push-action from 6.7.0 to 6.8.0 Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 6.7.0 to 6.8.0. - [Release notes](https://github.com/docker/build-push-action/releases) - [Commits](https://github.com/docker/build-push-action/compare/v6.7.0...v6.8.0) --- updated-dependencies: - dependency-name: docker/build-push-action dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- .github/workflows/docker-3.2.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docker-3.2.yml b/.github/workflows/docker-3.2.yml index 2c6128b..800acf4 100644 --- a/.github/workflows/docker-3.2.yml +++ b/.github/workflows/docker-3.2.yml @@ -48,7 +48,7 @@ jobs: password: ${{ secrets.GITHUB_TOKEN }} - name: Build and push - uses: docker/build-push-action@v6.7.0 + uses: docker/build-push-action@v6.8.0 with: push: ${{ github.event_name != 'pull_request' }} context: . From 89fe5ebe7e5b4fa1d1d77a50760e3bdb54cddd4d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 1 Oct 2024 00:08:37 +0000 Subject: [PATCH 05/41] Bump docker/build-push-action from 6.8.0 to 6.9.0 Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 6.8.0 to 6.9.0. - [Release notes](https://github.com/docker/build-push-action/releases) - [Commits](https://github.com/docker/build-push-action/compare/v6.8.0...v6.9.0) --- updated-dependencies: - dependency-name: docker/build-push-action dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- .github/workflows/docker-3.2.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docker-3.2.yml b/.github/workflows/docker-3.2.yml index 800acf4..b08b9eb 100644 --- a/.github/workflows/docker-3.2.yml +++ b/.github/workflows/docker-3.2.yml @@ -48,7 +48,7 @@ jobs: password: ${{ secrets.GITHUB_TOKEN }} - name: Build and push - uses: docker/build-push-action@v6.8.0 + uses: docker/build-push-action@v6.9.0 with: push: ${{ github.event_name != 'pull_request' }} context: . From 6110843fd0cc1186e8deaeea5db5dd5ac55a1299 Mon Sep 17 00:00:00 2001 From: Dirk Wetter Date: Wed, 9 Oct 2024 15:47:50 +0200 Subject: [PATCH 06/41] The F5 cookie decoder doesn't detect IPs in the 10.x.x.x space for non-encrypted cookies. This fixes the regex pattern, see also https://github.com/drwetter/F5-BIGIP-Decoder/pull/4/files --- testssl.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testssl.sh b/testssl.sh index 4068440..61282a9 100755 --- a/testssl.sh +++ b/testssl.sh @@ -3284,7 +3284,7 @@ sub_f5_bigip_check() { [[ -z "$cookievalue" ]] && break cookievalue=${cookievalue/;/} debugme echo $cookiename : $cookievalue - if grep -Eq '[0-9]{9,10}\.[0-9]{3,5}\.0000' <<< "$cookievalue"; then + if grep -Eq '[0-9]{8,10}\.[0-9]{3,5}\.0000' <<< "$cookievalue"; then ip="$(f5_ip_oldstyle "$cookievalue")" port="$(f5_port_decode $cookievalue)" out "${spaces}F5 cookie (default IPv4 pool member): "; pr_italic "$cookiename "; prln_svrty_medium "${ip}:${port}" From 7c0ccb3da789673b0c0593764da0987c203a5894 Mon Sep 17 00:00:00 2001 From: Dirk Date: Mon, 14 Oct 2024 13:08:45 +0200 Subject: [PATCH 07/41] Fix HTML output in #2568 --- testssl.sh | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/testssl.sh b/testssl.sh index 9511703..2975d13 100755 --- a/testssl.sh +++ b/testssl.sh @@ -23132,9 +23132,11 @@ EOF # Pretty print - again, it's just nicer to read for reason in "${sorted_reasons[@]}"; do if [[ $reason_nr -eq 0 ]]; then - pr_bold " Grade cap reasons "; out_row_aligned_max_width "$reason\n" ' ' $TERM_WIDTH + pr_bold " Grade cap reasons " + outln "$(out_row_aligned_max_width "$reason" " " $TERM_WIDTH)" else - out_row_aligned_max_width " $reason\n" ' ' $TERM_WIDTH + outln "$(out_row_aligned_max_width " $reason" " " $TERM_WIDTH)" + fi ((reason_nr++)) fileout "grade_cap_reason_${reason_nr}" "INFO" "$reason" From fa5664f43479edfe812b2fba0a2a8511040bd49a Mon Sep 17 00:00:00 2001 From: Dirk Date: Mon, 14 Oct 2024 14:17:02 +0200 Subject: [PATCH 08/41] Polish comment + grade cap reason for STARTTLS --- testssl.sh | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/testssl.sh b/testssl.sh index 2975d13..697b9a0 100755 --- a/testssl.sh +++ b/testssl.sh @@ -22933,20 +22933,18 @@ run_rating() { pr_headlineln " Rating (experimental) " outln + [[ -n "$STARTTLS_PROTOCOL" ]] && set_grade_cap "T" "STARTTLS is prone to MITM downgrade attacks. A secure TLS upgrade can only be ensured client-side. You should use TLS only (=implicit TLS) rather than STARTTLS as per RFC 8314, for other than SMTP and SIEVE" - if [[ -n "$STARTTLS_PROTOCOL" ]]; then - read -r -d '' grade_cap_reason <<'EOF' -TL;DR: E-mail transfer via port 25 is broken and the amendments suggested so far are duct tape. So please do not expect testssl.sh to shut up. + # TL;DR: STARTTLS connections are inherently insecure. A MITM can always intercept the connection, unless the client checks e.g. the + # certificate accordingly. A secure STARTTLS client is the key but we can't test for it. For other than SMTP and SIEVE (there's no implicit TLS port) + # you should use implicit TLS as per RFC 8314. Especially e-mail transfer via port 25 is broken and amendments so far are duct tape. -Explanation: For other than SMTP you should use TLS as per RFC 8314. For SMTP however there's this thing named reality: A mail server cannot -just switch to the mail submission port 587 only and continue to receive mail from everyone. Even if you advertise this via SRV record (RFC 6186). -For STARTTLS there's no way to tell for testssl.sh whether it is secure. A MitM can always intercept the connection, unless the client checks -the certificate accordingly (it's getting better but some just don't). TLSA Records/DANE and MTA-STS (RFC-8461) on the server side can help too. -But as said, it's useless unless the client MTA checks all that which no tool can check. -EOF - # We can't use newlines in the message, as the grade-sorting function will mess up the reason - set_grade_cap "T" "$(tr '\n' ' ' <<<$grade_cap_reason)" - fi + # Explanation: There are active MitM attacks possible when using STARTTLS like https://github.com/tintinweb/striptls or + # https://github.com/libcrack/starttlsstrip. It depends on the client only whether it can detect such downgrade attack. + # As some SMTP servers are still misconfigured with wrong certificates it's is still common practice for SMTP client MTAs to + # accept those wrong certificates -- delivering e-mails is more important. There is an e-mail submission port 587 but a mail server + # cannot just switch to it and continue to receive mail from everyone. Even if you advertise this via SRV record (RFC 6186). + # TLSA Records/DANE and MTA-STS (RFC-8461) on the server side can help too, pr_bold " Rating specs"; out " (not complete) "; outln "SSL Labs's 'SSL Server Rating Guide' (version 2009q from 2020-01-30)" pr_bold " Specification documentation "; pr_url "https://github.com/ssllabs/research/wiki/SSL-Server-Rating-Guide" From 33fd749af84eeaad5c885bea024670542342c58e Mon Sep 17 00:00:00 2001 From: Dirk Date: Mon, 14 Oct 2024 16:15:18 +0200 Subject: [PATCH 09/41] Fix json/csv output when STARTTLS problem is passed back In rare cases testssl.sh writes in the terminal output "likely not offered" but misses the "likely" in the json/csv output. This fixes #2575 by adding that word and amending the return value 4 with a comment. --- testssl.sh | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/testssl.sh b/testssl.sh index 697b9a0..93ec230 100755 --- a/testssl.sh +++ b/testssl.sh @@ -5487,7 +5487,8 @@ run_protocols() { fileout "$jsonID" "OK" "not offered" add_proto_offered ssl2 no ;; - 4) out "likely "; pr_svrty_best "not offered (OK), " + 4) # STARTTLS problem + out "likely "; pr_svrty_best "not offered (OK), " fileout "$jsonID" "OK" "likely not offered" add_proto_offered ssl2 no pr_warning "received 4xx/5xx after STARTTLS handshake"; outln "$debug_recomm" @@ -5665,7 +5666,7 @@ run_protocols() { pr_warning "TLS downgraded to STARTTLS plaintext"; outln fileout "$jsonID" "WARN" "TLS downgraded to STARTTLS plaintext" ;; - 4) out "likely not offered, " + 4) out "likely not offered, " # STARTTLS problem fileout "$jsonID" "INFO" "likely not offered" add_proto_offered tls1 no pr_warning "received 4xx/5xx after STARTTLS handshake"; outln "$debug_recomm" @@ -5750,8 +5751,8 @@ run_protocols() { pr_warning "TLS downgraded to STARTTLS plaintext"; outln fileout "$jsonID" "WARN" "TLS downgraded to STARTTLS plaintext" ;; - 4) out "likely not offered, " - fileout "$jsonID" "INFO" "not offered" + 4) out "likely not offered, " # STARTTLS problem + fileout "$jsonID" "INFO" "likely not offered" add_proto_offered tls1_1 no pr_warning "received 4xx/5xx after STARTTLS handshake"; outln "$debug_recomm" fileout "$jsonID" "WARN" "received 4xx/5xx after STARTTLS handshake${debug_recomm}" @@ -6022,8 +6023,8 @@ run_protocols() { pr_warning "TLS downgraded to STARTTLS plaintext"; outln fileout "$jsonID" "WARN" "TLS downgraded to STARTTLS plaintext" ;; - 4) out "likely not offered, " - fileout "$jsonID" "INFO" "not offered" + 4) out "likely not offered, " # STARTTLS problem + fileout "$jsonID" "INFO" "likely not offered" add_proto_offered tls1_3 no pr_warning "received 4xx/5xx after STARTTLS handshake"; outln "$debug_recomm" fileout "$jsonID" "WARN" "received 4xx/5xx after STARTTLS handshake${debug_recomm}" From 9b48c1641b47a8a040e892e5dd6df771af4fcbf1 Mon Sep 17 00:00:00 2001 From: Dirk Date: Mon, 14 Oct 2024 17:08:12 +0200 Subject: [PATCH 10/41] Minor polish unit tests This PR (re-)names the unit test starter properly and improves for some unit tests the phrasing and formatting. --- .github/workflows/{test.yml => unit_tests.yml} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename .github/workflows/{test.yml => unit_tests.yml} (100%) diff --git a/.github/workflows/test.yml b/.github/workflows/unit_tests.yml similarity index 100% rename from .github/workflows/test.yml rename to .github/workflows/unit_tests.yml From ae77349f3a3c0a760b200638dd25e481e7912628 Mon Sep 17 00:00:00 2001 From: Dirk Date: Mon, 14 Oct 2024 17:11:55 +0200 Subject: [PATCH 11/41] see previous commit --- t/00_testssl_help.t | 6 +++--- t/05_ca_hashes_up_to_date.t | 2 +- t/32_isHTML_valid.t | 22 +++++++++++----------- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/t/00_testssl_help.t b/t/00_testssl_help.t index bedcb8c..b979fa8 100755 --- a/t/00_testssl_help.t +++ b/t/00_testssl_help.t @@ -24,10 +24,10 @@ printf "\n%s\n", "Testing whether just calling \"./testssl.sh\" produces no erro my $info = stat($prg); my $retMode = $info->mode; -is($retMode & 0400, 0400, "Checking \"./testssl.sh\" for read permission"); +is($retMode & 0400, 0400, "Checking \"./testssl.sh\" for read permission"); $tests++; -is($retMode & 0100, 0100, "Checking \"./testssl.sh\" for execute permission"); +is($retMode & 0100, 0100, "Checking \"./testssl.sh\" for execute permission"); $tests++; $fileout = `timeout 10 bash $prg 2>&1`; @@ -55,7 +55,7 @@ $out=`grep -E "$debug_regexp" $prg`; unlike($out, qr/$debug_regexp/, "Debug RegEx"); $tests++; -printf "\n"; +printf "\n\n"; done_testing($tests); diff --git a/t/05_ca_hashes_up_to_date.t b/t/05_ca_hashes_up_to_date.t index 434b7a0..7124e5f 100755 --- a/t/05_ca_hashes_up_to_date.t +++ b/t/05_ca_hashes_up_to_date.t @@ -6,7 +6,7 @@ use Test::More; printf "\n%s\n", "Testing whether CA certificates are newer their SPKI hashes \"~/etc/ca_hashes.txt\" ..."; my $newer_bundles=`find etc/*.pem -newer etc/ca_hashes.txt`; -is($newer_bundles,"","If there's an output with a *.pem file run \"~/utils/create_ca_hashes.sh\""); +is($newer_bundles,"","Checking if there's an output with a *.pem file run \"~/utils/create_ca_hashes.sh\""); printf "\n"; done_testing; diff --git a/t/32_isHTML_valid.t b/t/32_isHTML_valid.t index 84db98d..afb5d64 100755 --- a/t/32_isHTML_valid.t +++ b/t/32_isHTML_valid.t @@ -46,15 +46,16 @@ $edited_html =~ s/>/>/g; $edited_html =~ s/"/"/g; $edited_html =~ s/'/'/g; -cmp_ok($edited_html, "eq", $out, "HTML file matches terminal output"); -$tests++; - $diff = diff \$edited_html, \$out; -printf "\n%s\n", "$diff"; + +cmp_ok($edited_html, "eq", $out, "Checking if HTML file matches terminal output") or + diag ("\n%s\n", "$diff"); + +$tests++; #2 -printf "\n%s\n", " .. running again $prg against \"$uri\", now with --debug 4 to create HTML output (may take another ~2 minutes)"; +printf "%s\n", " .. running again $prg against \"$uri\", now with --debug 4 to create HTML output (may take another ~2 minutes)"; # Redirect stderr to /dev/null in order to avoid some unexplained "date: invalid date" error messages $out = `TERM_WIDTH=120 $prg $check2run --debug 4 $uri 2> /dev/null`; $debughtml = `cat $htmlfile`; @@ -79,15 +80,14 @@ $debughtml =~ s/.*built: .*\n//g; $debughtml =~ s/.*Using bash .*\n//g; # is whole line: s/.* .*\n//g; -cmp_ok($debughtml, "eq", $html, "HTML file created with --debug 4 matches HTML file created without --debug"); +$diff = diff \$debughtml, \$html; + +cmp_ok($debughtml, "eq", $html, "Checking if HTML file created with --debug 4 matches HTML file created without --debug") or + diag ("\n%s\n", "$diff"); $tests++; -$diff = diff \$debughtml, \$html; -printf "\n%s\n", "$diff"; - - -printf "\n"; +printf "\n\n"; done_testing($tests); From e0e742379c8136caea63f469aaf5077542d8642f Mon Sep 17 00:00:00 2001 From: Dirk Date: Mon, 14 Oct 2024 17:15:43 +0200 Subject: [PATCH 12/41] see previous commit --- t/51_badssl.com.t | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/t/51_badssl.com.t b/t/51_badssl.com.t index 40b6e91..db734e4 100755 --- a/t/51_badssl.com.t +++ b/t/51_badssl.com.t @@ -17,7 +17,7 @@ pass("Running testssl.sh against badssl.com to create a baseline (may take 2~3 m my $okout = `./testssl.sh -S -e --freak --logjam --drown --rc4 --sweet32 --breach --winshock --crime --jsonfile tmp.json --color 0 badssl.com`; my $okjson = json('tmp.json'); unlink 'tmp.json'; -cmp_ok(@$okjson,'>',10,"We have more then 10 findings"); $tests++; +cmp_ok(@$okjson,'>',10,"We should have more then 10 findings"); $tests++; # Expiration pass("Running testssl against expired.badssl.com"); $tests++; @@ -35,7 +35,7 @@ foreach my $f ( @$json ) { last; } } -is($found,1,"We had a finding for this in the JSON output"); $tests++; +is($found,1,"We should have a finding for this in the JSON output"); $tests++; # Self signed and not-expired pass("Running testssl against self-signed.badssl.com"); $tests++; @@ -52,7 +52,7 @@ foreach my $f ( @$json ) { last; } } -is($found,1,"We had a finding for this in the JSON output"); $tests++; +is($found,1,"We should a finding for this in the JSON output"); $tests++; like($out, qr/Chain of trust.*?NOT ok.*\(self signed\)/,"Chain of trust should fail because of self signed"); $tests++; $found = 0; @@ -64,7 +64,7 @@ foreach my $f ( @$json ) { last; } } -is($found,1,"We had a finding for this in the JSON output"); $tests++; +is($found,1,"We should have a finding for this in the JSON output"); $tests++; like($okout, qr/Chain of trust[^\n]*?Ok/,"Chain of trust should be ok"); $tests++; $found = 0; @@ -77,7 +77,7 @@ foreach my $f ( @$okjson ) { last; } } -is($found,1,"We had a finding for this in the JSON output"); $tests++; +is($found,1,"We should have a finding for this in the JSON output"); $tests++; # Wrong host #pass("Running testssl against wrong.host.badssl.com"); $tests++; @@ -111,7 +111,7 @@ foreach my $f ( @$json ) { last; } } -is($found,1,"We had a finding for this in the JSON output"); $tests++; +is($found,1,"We should have a finding for this in the JSON output"); $tests++; # TODO: RSA 8192 From 0f44d6777aee35b0b2a58cf2a2cd6d7c553df6b5 Mon Sep 17 00:00:00 2001 From: Dirk Date: Mon, 14 Oct 2024 17:51:24 +0200 Subject: [PATCH 13/41] Upgrade Dockerfile to leap 15.6 As EOL comes closer for openSUSE Leap 15.5 (https://en.opensuse.org/Lifetime) an update is needed. ``busybox-util-linux`` and ``busybox-vi`` had to be removed as they don't exist anymore. Busybox was added but hexdump was not provided by the vendor. As busybox was compiled "properly" hexdump can be added by just linking to it. This fixes #2563 --- Dockerfile | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index 3767781..704797b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,6 +1,6 @@ # syntax=docker.io/docker/dockerfile:1 -ARG LEAP_VERSION=15.5 +ARG LEAP_VERSION=15.6 ARG INSTALL_ROOT=/rootfs FROM opensuse/leap:${LEAP_VERSION} as builder @@ -18,7 +18,8 @@ RUN source /etc/os-release \ && zypper "${ZYPPER_OPTIONS[@]}" --gpg-auto-import-keys refresh \ && rpm -e util-linux --nodeps \ && zypper "${ZYPPER_OPTIONS[@]}" --non-interactive install --download-in-advance --no-recommends \ - bash procps grep gawk sed coreutils busybox-util-linux busybox-vi ldns libidn2-0 socat openssl curl \ + bash procps grep gawk sed coreutils busybox ldns libidn2-0 socat openssl curl \ + && ln -s /usr/bin/busybox /usr/bin/hexdump \ && zypper up -y \ && zypper "${ZYPPER_OPTIONS[@]}" clean --all ## Cleanup (reclaim approx 13 MiB): From fc309b7ee0167c8a9e56169a26621466b1fe3fab Mon Sep 17 00:00:00 2001 From: Dirk Date: Tue, 15 Oct 2024 09:54:35 +0200 Subject: [PATCH 14/41] Add link for hexdump correctly ... in Dockerfile, see #2586 --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 704797b..6c5db47 100644 --- a/Dockerfile +++ b/Dockerfile @@ -19,7 +19,6 @@ RUN source /etc/os-release \ && rpm -e util-linux --nodeps \ && zypper "${ZYPPER_OPTIONS[@]}" --non-interactive install --download-in-advance --no-recommends \ bash procps grep gawk sed coreutils busybox ldns libidn2-0 socat openssl curl \ - && ln -s /usr/bin/busybox /usr/bin/hexdump \ && zypper up -y \ && zypper "${ZYPPER_OPTIONS[@]}" clean --all ## Cleanup (reclaim approx 13 MiB): @@ -36,6 +35,7 @@ ARG INSTALL_ROOT COPY --link --from=builder ${INSTALL_ROOT} / # Link busybox to tar, see #2403. Create user + (home with SGID set): RUN ln -s /usr/bin/busybox /usr/bin/tar \ + && ln -s /usr/bin/busybox /usr/bin/hexdump \ && echo 'testssl:x:1000:1000::/home/testssl:/bin/bash' >> /etc/passwd \ && echo 'testssl:x:1000:' >> /etc/group \ && echo 'testssl:!::0:::::' >> /etc/shadow \ From 0abca6f06754b2d7aac30003bde1f3c3d1951079 Mon Sep 17 00:00:00 2001 From: Dirk Date: Tue, 15 Oct 2024 10:56:29 +0200 Subject: [PATCH 15/41] Mute socat killing & improve STARTTLS grading explanation Fixes #2582 . --- testssl.sh | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/testssl.sh b/testssl.sh index 93ec230..ac6e27a 100755 --- a/testssl.sh +++ b/testssl.sh @@ -19322,7 +19322,7 @@ run_starttls_injection() { esac uds="$TEMPDIR/uds" - $SOCAT FD:5 UNIX-LISTEN:$uds & + $SOCAT FD:5 UNIX-LISTEN:$uds 2>/dev/null & socat_pid=$! if "$HAS_UDS"; then @@ -22934,11 +22934,11 @@ run_rating() { pr_headlineln " Rating (experimental) " outln - [[ -n "$STARTTLS_PROTOCOL" ]] && set_grade_cap "T" "STARTTLS is prone to MITM downgrade attacks. A secure TLS upgrade can only be ensured client-side. You should use TLS only (=implicit TLS) rather than STARTTLS as per RFC 8314, for other than SMTP and SIEVE" + [[ -n "$STARTTLS_PROTOCOL" ]] && set_grade_cap "T" "STARTTLS is prone to MITM downgrade attacks. A secure TLS upgrade can only be ensured client-side. As per RFC 8314 you should use implicit TLS rather than STARTTLS. For SMTP (port 25) and SIEVE this is not possible." # TL;DR: STARTTLS connections are inherently insecure. A MITM can always intercept the connection, unless the client checks e.g. the - # certificate accordingly. A secure STARTTLS client is the key but we can't test for it. For other than SMTP and SIEVE (there's no implicit TLS port) - # you should use implicit TLS as per RFC 8314. Especially e-mail transfer via port 25 is broken and amendments so far are duct tape. + # certificate accordingly. A secure STARTTLS client is the key but we can't test for it. Especially e-mail transfer via port 25 is broken + # as message delivery is still more important than security. Amendments like DANE and MTA-STS are duct tape and depend on the client. # Explanation: There are active MitM attacks possible when using STARTTLS like https://github.com/tintinweb/striptls or # https://github.com/libcrack/starttlsstrip. It depends on the client only whether it can detect such downgrade attack. @@ -22946,6 +22946,9 @@ run_rating() { # accept those wrong certificates -- delivering e-mails is more important. There is an e-mail submission port 587 but a mail server # cannot just switch to it and continue to receive mail from everyone. Even if you advertise this via SRV record (RFC 6186). # TLSA Records/DANE and MTA-STS (RFC-8461) on the server side can help too, + # + # For other than SMTP on port 25 and port 587 and SIEVE (there's no implicit TLS port) you should use implicit TLS as per RFC 8314. + # Instead of port 587 (STARTTLS) implicit TLS on port 465 should be considered. pr_bold " Rating specs"; out " (not complete) "; outln "SSL Labs's 'SSL Server Rating Guide' (version 2009q from 2020-01-30)" pr_bold " Specification documentation "; pr_url "https://github.com/ssllabs/research/wiki/SSL-Server-Rating-Guide" From 1f37a8406f1144d62b4f803719a008c278d63b9a Mon Sep 17 00:00:00 2001 From: David Cooper Date: Tue, 8 Oct 2024 12:49:39 -0700 Subject: [PATCH 16/41] Accept stapled OCSP responses that use SHA-256 in CertID This commit modifies check_revocation_ocsp() to check the revocation status of a certificate in a stapled OCSP response whether the response uses SHA-1 or SHA-256 in CertID. --- testssl.sh | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/testssl.sh b/testssl.sh index ac6e27a..e4e972b 100755 --- a/testssl.sh +++ b/testssl.sh @@ -2035,7 +2035,7 @@ check_revocation_ocsp() { local stapled_response="$2" local jsonID="$3" local tmpfile="" - local -i success + local -i success=1 local response="" local host_header="" @@ -2052,9 +2052,20 @@ check_revocation_ocsp() { tmpfile=$TEMPDIR/${NODE}-${NODEIP}.${uri##*\/} || exit $ERR_FCREATE if [[ -n "$stapled_response" ]]; then hex2binary "$stapled_response" > "$TEMPDIR/stapled_ocsp_response.dd" - $OPENSSL ocsp -no_nonce -respin "$TEMPDIR/stapled_ocsp_response.dd" \ - -issuer $TEMPDIR/hostcert_issuer.pem -verify_other $TEMPDIR/intermediatecerts.pem \ - -CAfile <(cat $ADDTL_CA_FILES "$GOOD_CA_BUNDLE") -cert $HOSTCERT -text &> "$tmpfile" + if [[ "$stapled_response" =~ 06052[bB]0[eE]03021[aA] ]]; then + # Response appears to use SHA-1 in CertID + $OPENSSL ocsp -no_nonce -respin "$TEMPDIR/stapled_ocsp_response.dd" \ + -issuer $TEMPDIR/hostcert_issuer.pem -verify_other $TEMPDIR/intermediatecerts.pem \ + -CAfile <(cat $ADDTL_CA_FILES "$GOOD_CA_BUNDLE") -cert $HOSTCERT -text &> "$tmpfile" + success=$? + fi + if [[ $success -ne 0 ]] && [[ "$stapled_response" =~ 0609608648016503040201 ]]; then + # Response appears to use SHA-256 in CertID + $OPENSSL ocsp -sha256 -no_nonce -respin "$TEMPDIR/stapled_ocsp_response.dd" \ + -issuer $TEMPDIR/hostcert_issuer.pem -verify_other $TEMPDIR/intermediatecerts.pem \ + -CAfile <(cat $ADDTL_CA_FILES "$GOOD_CA_BUNDLE") -cert $HOSTCERT -text &> "$tmpfile" + success=$? + fi else host_header=${uri##http://} host_header=${host_header%%/*} @@ -2069,8 +2080,9 @@ check_revocation_ocsp() { $OPENSSL ocsp -no_nonce ${host_header} -url "$uri" \ -issuer $TEMPDIR/hostcert_issuer.pem -verify_other $TEMPDIR/intermediatecerts.pem \ -CAfile <(cat $ADDTL_CA_FILES "$GOOD_CA_BUNDLE") -cert $HOSTCERT -text &> "$tmpfile" + success=$? fi - if [[ $? -eq 0 ]] && grep -Fq "Response verify OK" "$tmpfile"; then + if [[ $success -eq 0 ]] && grep -Fq "Response verify OK" "$tmpfile"; then response="$(grep -F "$HOSTCERT: " "$tmpfile")" response="${response#$HOSTCERT: }" response="${response%\.}" From 3c544740610551e36325527a3b2ddf2aee3a4b5d Mon Sep 17 00:00:00 2001 From: David Cooper Date: Fri, 25 Oct 2024 12:24:06 -0700 Subject: [PATCH 17/41] Support LibreSSL 4.0.0 LibreSSL 4.0.0 was recently released. This commit modified the version check in determine_trust() so that there isn't an incorrect warning suggesting that LibreSSL 4.0.0 "<= 1.0.2 might be too unreliable to determine trust." --- testssl.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testssl.sh b/testssl.sh index e4e972b..0bf9e01 100755 --- a/testssl.sh +++ b/testssl.sh @@ -7637,7 +7637,7 @@ determine_trust() { [[ -n $json_postfix ]] && spaces=" " case $OSSL_VER_MAJOR.$OSSL_VER_MINOR in - 1.0.2|1.1.0|1.1.1|2.[1-9].*|3.*) # 2.x is LibreSSL. 2.1.1 was tested to work, below is not sure + 1.0.2|1.1.0|1.1.1|2.[1-9].*|3.*|4.*) # 2.x is LibreSSL. 2.1.1 was tested to work, below is not sure : ;; *) addtl_warning="Your $OPENSSL <= 1.0.2 might be too unreliable to determine trust" From e17b1c17bbc6d96dd94f1907807cfb6e5648ae30 Mon Sep 17 00:00:00 2001 From: David Cooper Date: Thu, 24 Oct 2024 08:11:21 -0700 Subject: [PATCH 18/41] Support RFC 9150 cipher suites This commit adds support for the two cipher suites in RFC 9150, TLS_SHA256_SHA256 and TLS_SHA384_SHA384. These are authentication and integrity-only cipher suites. --- etc/cipher-mapping.txt | 2 + etc/tls_data.txt | 4 +- openssl-iana.mapping.html | 4 + testssl.sh | 200 +++++++++++++++++++++++--------- utils/update_client_sim_data.pl | 4 + 5 files changed, 158 insertions(+), 56 deletions(-) diff --git a/etc/cipher-mapping.txt b/etc/cipher-mapping.txt index e0b542f..1125f87 100644 --- a/etc/cipher-mapping.txt +++ b/etc/cipher-mapping.txt @@ -342,6 +342,8 @@ 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 0x00,0x28 - EXP-KRB5-RC4-SHA TLS_KRB5_EXPORT_WITH_RC4_40_SHA SSLv3 Kx=KRB5 Au=KRB5 Enc=RC4(40) Mac=SHA1 export 0x00,0x2B - EXP-KRB5-RC4-MD5 TLS_KRB5_EXPORT_WITH_RC4_40_MD5 SSLv3 Kx=KRB5 Au=KRB5 Enc=RC4(40) Mac=MD5 export + 0xC0,0xB4 - TLS_SHA256_SHA256 TLS_SHA256_SHA256 TLSv1.3 Kx=any Au=any Enc=None Mac=SHA256 + 0xC0,0xB5 - TLS_SHA384_SHA384 TLS_SHA384_SHA384 TLSv1.3 Kx=any Au=any Enc=None Mac=SHA384 0xC0,0x10 - ECDHE-RSA-NULL-SHA TLS_ECDHE_RSA_WITH_NULL_SHA SSLv3 Kx=ECDH Au=RSA Enc=None Mac=SHA1 0xC0,0x06 - ECDHE-ECDSA-NULL-SHA TLS_ECDHE_ECDSA_WITH_NULL_SHA SSLv3 Kx=ECDH Au=ECDSA Enc=None Mac=SHA1 0xC0,0x15 - AECDH-NULL-SHA TLS_ECDH_anon_WITH_NULL_SHA SSLv3 Kx=ECDH Au=None Enc=None Mac=SHA1 diff --git a/etc/tls_data.txt b/etc/tls_data.txt index 5fc5b7c..cf84b65 100644 --- a/etc/tls_data.txt +++ b/etc/tls_data.txt @@ -3,9 +3,9 @@ # see #807 and #806 (especially # https://github.com/drwetter/testssl.sh/issues/806#issuecomment-318686374) -# All 5 ciphers defined for TLS 1.3 +# 7 ciphers defined for TLS 1.3 in RFCs 8446 and 9150 readonly TLS13_CIPHER=" -13,01, 13,02, 13,03, 13,04, 13,05" +13,01, 13,02, 13,03, 13,04, 13,05, c0,b4, c0,b5" # 123 standard cipher + 4x GOST for TLS 1.2 and SPDY/NPN HTTP2/ALPN declare TLS12_CIPHER=" diff --git a/openssl-iana.mapping.html b/openssl-iana.mapping.html index 8b6363d..9e90ce2 100644 --- a/openssl-iana.mapping.html +++ b/openssl-iana.mapping.html @@ -425,6 +425,10 @@ xB9 TLS_RSA_PSK_WITH_NULL_SHA384 [0xc0ae] ECDHE-ECDSA-AES128-CCM8 ECDH AESCCM 128 TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 [0xc0af] ECDHE-ECDSA-AES256-CCM8 ECDH AESCCM 256 TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8 + + [0xc0b4] TLS_SHA256_SHA256 ECDH Null 0 TLS_SHA256_SHA256 + [0xc0b5] TLS_SHA384_SHA384 ECDH Null 0 TLS_SHA384_SHA384 + [0xcc13] ECDHE-RSA-CHACHA20-POLY1305-OLD ECDH ChaCha20-Poly1305 TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256_OLD [0xcc14] ECDHE-ECDSA-CHACHA20-POLY1305-OLD ECDH ChaCha20-Poly1305 TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256_OLD diff --git a/testssl.sh b/testssl.sh index e4e972b..1698805 100755 --- a/testssl.sh +++ b/testssl.sh @@ -454,7 +454,7 @@ declare TLS_CIPHER_AUTH=() declare TLS_CIPHER_ENC=() declare TLS_CIPHER_EXPORT=() declare TLS_CIPHER_OSSL_SUPPORTED=() -declare TLS13_OSSL_CIPHERS="TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_CCM_SHA256:TLS_AES_128_CCM_8_SHA256" +declare TLS13_OSSL_CIPHERS="TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_CCM_SHA256:TLS_AES_128_CCM_8_SHA256:TLS_SHA256_SHA256:TLS_SHA384_SHA384" ########### Some predefinitions: date, sed (we always use tests for binaries and NOT try to determine @@ -972,9 +972,14 @@ join_by() { actually_supported_osslciphers() { local ciphers="$1" local tls13_ciphers="$TLS13_OSSL_CIPHERS" + local cipher tls13_supported_ciphers="" local options="$3 " [[ "$2" != ALL ]] && tls13_ciphers="$2" + for cipher in ${tls13_ciphers//:/ }; do + [[ "$TLS13_OSSL_CIPHERS" =~ $cipher ]] && tls13_supported_ciphers+=":$cipher" + done + tls13_ciphers="${tls13_supported_ciphers:1}" "$HAS_SECLEVEL" && [[ -n "$ciphers" ]] && ciphers="@SECLEVEL=0:$1" # With OpenSSL 1.0.2 the only way to exclude SSLv2 ciphers is to use the -tls1 option. # However, with newer versions of OpenSSL, the -tls1 option excludes TLSv1.2 ciphers. @@ -1001,7 +1006,10 @@ strip_inconsistent_ciphers() { local -i proto=0x$1 local cipherlist="$2" - [[ $proto -lt 4 ]] && cipherlist="${cipherlist//, 13,0[0-9a-fA-F]/}" + if [[ $proto -lt 4 ]]; then + cipherlist="${cipherlist//, 13,0[0-9a-fA-F]/}" + cipherlist="${cipherlist//, [cC]0,[bB][45]/}" + fi if [[ $proto -lt 3 ]]; then cipherlist="${cipherlist//, 00,3[b-fB-F]/}" cipherlist="${cipherlist//, 00,40/}" @@ -2232,6 +2240,7 @@ string_to_asciihex() { s_client_options() { local options=" $1" local ciphers="notpresent" tls13_ciphers="notpresent" + local cipher tls13_supported_ciphers="" # Extract the TLSv1.3 ciphers and the non-TLSv1.3 ciphers if [[ " $options " =~ \ -cipher\ ]]; then @@ -2248,6 +2257,10 @@ s_client_options() { tls13_ciphers="${tls13_ciphers##\'}" tls13_ciphers="${tls13_ciphers%%\'}" [[ "$tls13_ciphers" == ALL ]] && tls13_ciphers="$TLS13_OSSL_CIPHERS" + for cipher in ${tls13_ciphers//:/ }; do + [[ "$TLS13_OSSL_CIPHERS" =~ $cipher ]] && tls13_supported_ciphers+=":$cipher" + done + tls13_ciphers="${tls13_supported_ciphers:1}" fi # Don't include the -servername option for an SSLv2 or SSLv3 ClientHello. @@ -2300,6 +2313,13 @@ s_client_options() { if "$HAS_SECLEVEL"; then if [[ "$ciphers" == notpresent ]]; then [[ ! " $options " =~ \ -tls1_3\ ]] && ciphers="@SECLEVEL=0:ALL:COMPLEMENTOFALL" + if "$HAS_CIPHERSUITES" && [[ "$tls13_ciphers" == notpresent ]] && \ + [[ ! " $options " =~ \ -ssl[2|3]\ ]] && \ + [[ ! " $options " =~ \ -tls1\ ]] && \ + [[ ! " $options " =~ \ -tls1_[1|2]\ ]] && \ + [[ ! " $options " =~ \ -no_tls1_3\ ]]; then + tls13_ciphers="$TLS13_OSSL_CIPHERS" + fi elif [[ -n "$ciphers" ]]; then ciphers="@SECLEVEL=0:$ciphers" fi @@ -4001,7 +4021,7 @@ run_cipher_match(){ ! "${ciphers_found2[i]}" && ciphers_to_test+=", ${hexcode2[i]}" done [[ -z "$ciphers_to_test" ]] && break - [[ "$proto" == 04 ]] && [[ ! "$ciphers_to_test" =~ ,\ 13,[0-9a-f][0-9a-f] ]] && break + [[ "$proto" == 04 ]] && [[ ! "$ciphers_to_test" =~ ,\ 13,[0-9a-f][0-9a-f] ]] && [[ ! "$ciphers_to_test" =~ ,\ [cC]0,[bB][45] ]] && break ciphers_to_test="$(strip_inconsistent_ciphers "$proto" "$ciphers_to_test")" [[ -z "$ciphers_to_test" ]] && break if "$SHOW_SIGALGO"; then @@ -4276,7 +4296,7 @@ run_allciphers() { ! "${ciphers_found2[i]}" && ciphers_to_test+=", ${hexcode2[i]}" done [[ -z "$ciphers_to_test" ]] && break - [[ "$proto" == 04 ]] && [[ ! "$ciphers_to_test" =~ ,\ 13,[0-9a-f][0-9a-f] ]] && break + [[ "$proto" == 04 ]] && [[ ! "$ciphers_to_test" =~ ,\ 13,[0-9a-f][0-9a-f] ]] && [[ ! "$ciphers_to_test" =~ ,\ [cC]0,[bB][45] ]] && break ciphers_to_test="$(strip_inconsistent_ciphers "$proto" "$ciphers_to_test")" [[ -z "$ciphers_to_test" ]] && break if "$SHOW_SIGALGO"; then @@ -4392,9 +4412,9 @@ ciphers_by_strength() { if { "$using_sockets" || "${TLS_CIPHER_OSSL_SUPPORTED[i]}"; }; then if [[ ${#hexc} -eq 9 ]] && [[ "$proto" != -ssl2 ]]; then if [[ "$proto" == -tls1_3 ]]; then - [[ "${hexc:2:2}" == 13 ]] && nr_ciphers+=1 + [[ "${TLS_CIPHER_SSLVERS[i]}" == TLSv1.3 ]] && nr_ciphers+=1 elif [[ "$proto" == -tls1_2 ]]; then - [[ "${hexc:2:2}" != 13 ]] && nr_ciphers+=1 + [[ "${TLS_CIPHER_SSLVERS[i]}" != TLSv1.3 ]] && 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 @@ -6079,10 +6099,15 @@ listciphers() { local -i ret local debugname="" local ciphers="$1" - local tls13_ciphers="$TLS13_OSSL_CIPHERS" + local tls13_ciphers="$TLS13_OSSL_CIPHERS" cipher tls13_supported_ciphers="" local options="$3 " [[ "$2" != ALL ]] && tls13_ciphers="$2" + for cipher in ${tls13_ciphers//:/ }; do + [[ "$TLS13_OSSL_CIPHERS" =~ $cipher ]] && tls13_supported_ciphers+=":$cipher" + done + tls13_ciphers="${tls13_supported_ciphers:1}" + "$HAS_SECLEVEL" && [[ -n "$ciphers" ]] && ciphers="@SECLEVEL=0:$1" ! "$HAS_TLS1" && options="${options//-tls1 /}" if "$HAS_CIPHERSUITES"; then @@ -6151,7 +6176,7 @@ sub_cipherlists() { for proto in 04 03 02 01 00; do # If $cipherlist doesn't contain any TLSv1.3 ciphers, then there is # no reason to try a TLSv1.3 ClientHello. - [[ "$proto" == 04 ]] && [[ ! "$6" =~ 13,0 ]] && continue + [[ "$proto" == 04 ]] && [[ ! "$6" =~ 13,0 ]] && [[ ! "$6" =~ [cC]0,[bB][45] ]] && continue [[ $(has_server_protocol "$proto") -eq 1 ]] && continue cipherlist="$(strip_inconsistent_ciphers "$proto" ", $6")" cipherlist="${cipherlist:2}" @@ -6290,13 +6315,14 @@ run_cipherlists() { local hexc hexcode strength local -i i local -i ret=0 - local ossl_null_ciphers null_ciphers sslv2_null_ciphers + local ossl_null_ciphers ossl_null_ciphersuites null_ciphers sslv2_null_ciphers local ossl_anon_ciphers anon_ciphers sslv2_anon_ciphers local ossl_exp_ciphers exp_ciphers sslv2_exp_ciphers local ossl_low_ciphers low_ciphers sslv2_low_ciphers local ossl_tdes_ciphers tdes_ciphers sslv2_tdes_ciphers local ossl_obsoleted_ciphers obsoleted_ciphers - local strong_ciphers + local ossl_good_ciphers good_ciphers + local ossl_strong_ciphers ossl_strong_ciphersuites strong_ciphers local cwe="CWE-327" local cwe2="CWE-310" local cve="" @@ -6310,7 +6336,8 @@ run_cipherlists() { # conversion 2 byte ciphers via: echo "$@" | sed -e 's/[[:xdigit:]]\{2\},/0x&/g' -e 's/, /\n/g' | while read ci; do grep -wi $ci etc/cipher-mapping.txt; done ossl_null_ciphers='NULL:eNULL' - 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" + ossl_null_ciphersuites="TLS_SHA256_SHA256:TLS_SHA384_SHA384" + 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, c0,b4, c0,b5, ff,87, 00,ff" sslv2_null_ciphers="FF,80,10, 00,00,00" ossl_anon_ciphers='aNULL:ADH' @@ -6346,6 +6373,7 @@ run_cipherlists() { good_ciphers="00,9C, 00,9D, 00,A0, 00,A1, 00,A4, 00,A5, 00,A8, 00,A9, 00,AC, 00,AD, C0,2D, C0,2E, C0,31, C0,32, C0,50, C0,51, C0,54, C0,55, C0,58, C0,59, C0,5E, C0,5F, C0,62, C0,63, C0,6A, C0,6B, C0,6E, C0,6F, C0,7A, C0,7B, C0,7E, C0,7F, C0,82, C0,83, C0,88, C0,89, C0,8C, C0,8D, C0,8E, C0,8F, C0,92, C0,93, C0,9C, C0,9D, C0,A0, C0,A1, C0,A4, C0,A5, C0,A8, C0,A9, CC,AB, CC,AE, 00,FF" ossl_strong_ciphers='AESGCM:CHACHA20:CamelliaGCM:AESCCM:ARIAGCM:!kPSK:!kRSAPSK:!kRSA:!kDH:!kECDH:!aNULL' + ossl_strong_ciphersuites="TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_CCM_SHA256:TLS_AES_128_CCM_8_SHA256" # grep AEAD etc/cipher-mapping.txt | grep -E 'TLS_ECDHE|TLS_DHE|TLS_PSK_DHE|TLSv1.3' strong_ciphers="00,9E, 00,9F, 00,A2, 00,A3, 00,AA, 00,AB, 13,01, 13,02, 13,03, 13,04, 13,05, 16,B7, 16,B8, 16,B9, 16,BA, C0,2B, C0,2C, C0,2F, C0,30, C0,52, C0,53, C0,56, C0,57, C0,5C, C0,5D, C0,60, C0,61, C0,6C, C0,6D, C0,7C, C0,7D, C0,80, C0,81, C0,86, C0,87, C0,8A, C0,8B, C0,90, C0,91, C0,9E, C0,9F, C0,A2, C0,A3, C0,A6, C0,A7, C0,AA, C0,AB, C0,AC, C0,AD, C0,AE, C0,AF, CC,13, CC,14, CC,15, CC,A8, CC,A9, CC,AA, CC,AC, CC,AD, 00,FF" @@ -6360,7 +6388,7 @@ run_cipherlists() { # argv[9]: CVE # argv[10]: CWE - sub_cipherlists "$ossl_null_ciphers" "" " NULL ciphers (no encryption) " 1 "NULL" "$null_ciphers" "$sslv2_null_ciphers" "$using_sockets" "$cve" "$cwe" + sub_cipherlists "$ossl_null_ciphers" "$ossl_null_ciphersuites" " NULL ciphers (no encryption) " 1 "NULL" "$null_ciphers" "$sslv2_null_ciphers" "$using_sockets" "$cve" "$cwe" ret=$? sub_cipherlists "$ossl_anon_ciphers" "" " Anonymous NULL Ciphers (no authentication) " 1 "aNULL" "$anon_ciphers" "$sslv2_anon_ciphers" "$using_sockets" "$cve" "$cwe" ret=$((ret + $?)) @@ -6374,7 +6402,7 @@ run_cipherlists() { ret=$((ret + $?)) sub_cipherlists "$ossl_good_ciphers" "" " Strong encryption (AEAD ciphers) with no FS " 6 "STRONG_NOFS" "$good_ciphers" "" "$using_sockets" "" "" ret=$((ret + $?)) - sub_cipherlists "$ossl_strong_ciphers" 'ALL' " Forward Secrecy strong encryption (AEAD ciphers)" 7 "STRONG_FS" "$strong_ciphers" "" "$using_sockets" "" "" + sub_cipherlists "$ossl_strong_ciphers" "$ossl_strong_ciphersuites" " Forward Secrecy strong encryption (AEAD ciphers)" 7 "STRONG_FS" "$strong_ciphers" "" "$using_sockets" "" "" ret=$((ret + $?)) outln @@ -6515,7 +6543,7 @@ get_cipher_quality() { # We have an OpenSSL name and can't convert it to the RFC name which is rarely # the case, see "prepare_arrays()" and "./etc/cipher-mapping.txt" case "$cipher" in - *NULL*|EXP*|ADH*|AECDH*|*anon*) + *NULL*|EXP*|ADH*|AECDH*|*anon*|TLS_SHA*) return 1 ;; *RC4*|*RC2*|*MD5|*M1) @@ -6557,7 +6585,7 @@ get_cipher_quality() { # Now we look at the RFC cipher names. The sequence matters - as above. case "$cipher" in - *NULL*|*EXP*|*_DES40_*|*anon*) + *NULL*|*EXP*|*_DES40_*|*anon*|TLS_SHA*) return 1 ;; *RC4*|*RC2*|*MD5|*MD5_1) @@ -6882,7 +6910,7 @@ run_server_preference() { "c0,2c, c0,30, 00,9f, cc,a9, cc,a8, cc,aa, c0,2b, c0,2f, 00,9a, 00,96, 00,9e, c0,24, c0,28, 00,6b, c0,23, c0,27, 00,67, c0,0a, c0,14, 00,39, c0,09, c0,13, 00,33, 00,9d, 00,9c, 13,02, - 13,03, 13,01, 13,04, 13,05, 00,3d, 00,3c, 00,35, 00,2f, 00,ff" \ + 13,03, 13,01, 13,04, 13,05, c0,b4, c0,b5, 00,3d, 00,3c, 00,35, 00,2f, 00,ff" \ "ephemeralkey" sclient_success=$? if [[ $sclient_success -eq 0 ]]; then @@ -6924,12 +6952,12 @@ run_server_preference() { # Some servers don't have a TLS 1.3 cipher order, see #1163 if [[ "$default_proto" == TLSv1.3 ]]; then - tls_sockets "04" "13,05, 13,04, 13,03, 13,02, 13,01, 00,ff" + tls_sockets "04" "c0,b5, c0,b4, 13,05, 13,04, 13,03, 13,02, 13,01, 00,ff" [[ $? -ne 0 ]] && ret=1 && prln_fixme "something weird happened around line $((LINENO - 1))" cp "$TEMPDIR/$NODEIP.parse_tls_serverhello.txt" $TMPFILE tls13_cipher1=$(get_cipher $TMPFILE) debugme tm_out "TLS 1.3: --> $tls13_cipher1\n" - tls_sockets "04" "13,01, 13,02, 13,03, 13,04, 13,05, 00,ff" + tls_sockets "04" "13,01, 13,02, 13,03, 13,04, 13,05, c0,b4, c0,b5, 00,ff" [[ $? -ne 0 ]] && ret=1 && prln_fixme "something weird happened around line $((LINENO - 1))" cp "$TEMPDIR/$NODEIP.parse_tls_serverhello.txt" $TMPFILE tls13_cipher2=$(get_cipher $TMPFILE) @@ -7316,9 +7344,9 @@ cipher_pref_check() { index[nr_nonossl_ciphers]=$i # Only test ciphers that are relevant to the protocol. if [[ $proto == tls1_3 ]]; then - [[ "${hexc:2:2}" == 13 ]] && nr_nonossl_ciphers+=1 + [[ "${TLS_CIPHER_SSLVERS[i]}" == TLSv1.3 ]] && nr_nonossl_ciphers+=1 elif [[ $proto == tls1_2 ]]; then - [[ "${hexc:2:2}" != 13 ]] && nr_nonossl_ciphers+=1 + [[ "${TLS_CIPHER_SSLVERS[i]}" != TLSv1.3 ]] && nr_nonossl_ciphers+=1 elif [[ ! "${TLS_CIPHER_RFC_NAME[i]}" =~ SHA256 ]] && \ [[ ! "${TLS_CIPHER_RFC_NAME[i]}" =~ SHA384 ]] && \ [[ "${TLS_CIPHER_RFC_NAME[i]}" != *_CCM ]] && \ @@ -7390,9 +7418,9 @@ cipher_pref_check() { hexcode[nr_ciphers]="${hexc:2:2},${hexc:7:2}" rfc_ciph[nr_ciphers]="${TLS_CIPHER_RFC_NAME[i]}" if [[ $proto == tls1_3 ]]; then - [[ "${hexc:2:2}" == 13 ]] && nr_ciphers+=1 + [[ "${TLS_CIPHER_SSLVERS[i]}" == TLSv1.3 ]] && nr_ciphers+=1 elif [[ $proto == tls1_2 ]]; then - [[ "${hexc:2:2}" != 13 ]] && nr_ciphers+=1 + [[ "${TLS_CIPHER_SSLVERS[i]}" != TLSv1.3 ]] && nr_ciphers+=1 elif [[ ! "${TLS_CIPHER_RFC_NAME[i]}" =~ SHA256 ]] && \ [[ ! "${TLS_CIPHER_RFC_NAME[i]}" =~ SHA384 ]] && \ [[ "${TLS_CIPHER_RFC_NAME[i]}" != *_CCM ]] && \ @@ -7409,9 +7437,9 @@ cipher_pref_check() { hexcode[nr_ciphers]="${hexc:2:2},${hexc:7:2}" rfc_ciph[nr_ciphers]="${TLS_CIPHER_RFC_NAME[i]}" if [[ $proto == tls1_3 ]]; then - [[ "${hexc:2:2}" == 13 ]] && nr_ciphers+=1 + [[ "${TLS_CIPHER_SSLVERS[i]}" == TLSv1.3 ]] && nr_ciphers+=1 elif [[ $proto == tls1_2 ]]; then - [[ "${hexc:2:2}" != 13 ]] && nr_ciphers+=1 + [[ "${TLS_CIPHER_SSLVERS[i]}" != TLSv1.3 ]] && nr_ciphers+=1 elif [[ ! "${TLS_CIPHER_RFC_NAME[i]}" =~ SHA256 ]] && \ [[ ! "${TLS_CIPHER_RFC_NAME[i]}" =~ SHA384 ]] && \ [[ "${TLS_CIPHER_RFC_NAME[i]}" != *_CCM ]] && \ @@ -8787,7 +8815,7 @@ certificate_transparency() { if [[ $number_of_certificates -gt 1 ]] && ! "$SSL_NATIVE"; then if [[ "$tls_version" == 0304 ]]; then - ciphers=", 13,01, 13,02, 13,03, 13,04, 13,05" + ciphers=", 13,01, 13,02, 13,03, 13,04, 13,05, c0,b4, c0,b5" if [[ "$cipher" == tls1_3_RSA ]]; then extra_extns=", 00,0d,00,10,00,0e,08,04,08,05,08,06,04,01,05,01,06,01,02,01" elif [[ "$cipher" == tls1_3_ECDSA ]]; then @@ -10542,13 +10570,10 @@ run_fs() { sigalg[nr_supported_ciphers]="" ossl_supported[nr_supported_ciphers]=true nr_supported_ciphers+=1 - done < <(actually_supported_osslciphers "$fs_cipher_list" "ALL" "-V") + done < <(actually_supported_osslciphers "$fs_cipher_list" "TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_CCM_SHA256:TLS_AES_128_CCM_8_SHA256" "-V") fi - if [[ $(has_server_protocol "tls1_3") -eq 0 ]]; then - # All TLSv1.3 cipher suites offer robust FS. - sclient_success=0 - elif "$using_sockets"; then + if "$using_sockets"; then tls_sockets "04" "${fs_hex_cipher_list:2}, 00,ff" sclient_success=$? [[ $sclient_success -eq 2 ]] && sclient_success=0 @@ -10560,7 +10585,7 @@ run_fs() { fi else debugme echo $nr_supported_ciphers - debugme echo $(actually_supported_osslciphers $fs_cipher_list "ALL") + debugme echo $(actually_supported_osslciphers $fs_cipher_list "TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_CCM_SHA256:TLS_AES_128_CCM_8_SHA256") if [[ "$nr_supported_ciphers" -le "$CLIENT_MIN_FS" ]]; then outln prln_local_problem "You only have $nr_supported_ciphers FS ciphers on the client side " @@ -10581,7 +10606,7 @@ run_fs() { curves_list2="${curves_list2// /:}" fi curves_list1="${curves_list1// /:}" - $OPENSSL s_client $(s_client_options "-cipher $fs_cipher_list -ciphersuites ALL $STARTTLS $BUGS -connect $NODEIP:$PORT $PROXY $SNI") >$TMPFILE 2>$ERRFILE $TMPFILE 2>$ERRFILE Date: Mon, 4 Nov 2024 11:38:18 +0100 Subject: [PATCH 19/41] Quick fix for #2590 Proper fix need another refactoring/cleanup of the renego test. --- testssl.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testssl.sh b/testssl.sh index c2e43e3..6465cee 100755 --- a/testssl.sh +++ b/testssl.sh @@ -17189,7 +17189,7 @@ run_renego() { sec_client_renego=1 else # second try in the foreground as we are sure now it won't hang - echo R | $OPENSSL s_client $(s_client_options "$proto $legacycmd $STARTTLS $BUGS -connect $NODEIP:$PORT $PROXY $SNI") >$TMPFILE 2>>$ERRFILE + (echo R; sleep 1) | $OPENSSL s_client $(s_client_options "$proto $legacycmd $STARTTLS $BUGS -connect $NODEIP:$PORT $PROXY $SNI") >$TMPFILE 2>>$ERRFILE sec_client_renego=$? # 0 means client is renegotiating & doesn't return an error --> vuln! # 1 means client tried to renegotiating but the server side errored then. You still see RENEGOTIATING in the output From d4fa5df47508e6cff13add581704cd07ec34d475 Mon Sep 17 00:00:00 2001 From: Jan Brasna <1784648+janbrasna@users.noreply.github.com> Date: Tue, 19 Nov 2024 20:42:08 +0100 Subject: [PATCH 20/41] Fix CI badge --- Readme.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Readme.md b/Readme.md index da26026..b335205 100644 --- a/Readme.md +++ b/Readme.md @@ -1,8 +1,7 @@ ## Intro - -[![Build Status](https://github.com/drwetter/testssl.sh/actions/workflows/test.yml/badge.svg)](https://github.com/drwetter/testssl.sh/actions/workflows/test.yml) +[![CI tests](https://github.com/drwetter/testssl.sh/actions/workflows/unit_tests.yml/badge.svg)](https://github.com/drwetter/testssl.sh/actions/workflows/unit_tests.yml) [![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/drwetter/testssl.sh?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![License](https://img.shields.io/github/license/drwetter/testssl.sh)](https://github.com/drwetter/testssl.sh/LICENSE) [![Docker](https://img.shields.io/docker/pulls/drwetter/testssl.sh)](https://github.com/drwetter/testssl.sh/blob/3.2/Dockerfile.md) From 26a3a8fd51d724cb24c9d61fda4e5dfc8ce10449 Mon Sep 17 00:00:00 2001 From: David Cooper Date: Tue, 26 Nov 2024 09:13:11 -0800 Subject: [PATCH 21/41] Fix #2599 This commit fixes #2599 by not wrapping fileout() messages in a "clientProblem" wrapper if TLS13_ONLY is set. The TLS13_ONLY flag being set is an indicator that fileout_banner() has already been called. --- testssl.sh | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/testssl.sh b/testssl.sh index c2e43e3..e4a7823 100755 --- a/testssl.sh +++ b/testssl.sh @@ -1371,13 +1371,17 @@ fileout_insert_warning() { [[ "$CMDLINE=" =~ -iL ]] && return 0 # Note we still have the message on screen + in HTML which is not as optimal as it could be - if "$do_pretty_json" && "$JSONHEADER"; then + # See #2599. The "clientProblem" wrapper should only be added if fileout_insert_warning() + # is called before fileout_banner(). The only instance in which this function is called + # after fileout_banner() is in the case of a TLS 1.3 only server when $OPENSSL does not + # support TLS 1.3. + if "$do_pretty_json" && "$JSONHEADER" && ! "$TLS13_ONLY"; then echo -e " \"clientProblem${CLIENT_PROB_NO}\" : [" >>"$JSONFILE" CLIENT_PROB_NO=$((CLIENT_PROB_NO + 1)) FIRST_FINDING=true # make sure we don't have a comma here fi fileout "$1" "$2" "$3" - if "$do_pretty_json"; then + if "$do_pretty_json" && ! "$TLS13_ONLY"; then if "$JSONHEADER"; then echo -e "\n ]," >>"$JSONFILE" else From 3e7efb7dd69ca4abe7552780caa335e4deb68b34 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 28 Nov 2024 00:10:10 +0000 Subject: [PATCH 22/41] Bump docker/build-push-action from 6.9.0 to 6.10.0 Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 6.9.0 to 6.10.0. - [Release notes](https://github.com/docker/build-push-action/releases) - [Commits](https://github.com/docker/build-push-action/compare/v6.9.0...v6.10.0) --- updated-dependencies: - dependency-name: docker/build-push-action dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- .github/workflows/docker-3.2.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docker-3.2.yml b/.github/workflows/docker-3.2.yml index b08b9eb..8da89f8 100644 --- a/.github/workflows/docker-3.2.yml +++ b/.github/workflows/docker-3.2.yml @@ -48,7 +48,7 @@ jobs: password: ${{ secrets.GITHUB_TOKEN }} - name: Build and push - uses: docker/build-push-action@v6.9.0 + uses: docker/build-push-action@v6.10.0 with: push: ${{ github.event_name != 'pull_request' }} context: . From b708026151bba8d3bb06c35b5117eb9a50419929 Mon Sep 17 00:00:00 2001 From: Dirk Date: Mon, 6 Jan 2025 15:22:20 +0100 Subject: [PATCH 23/41] Change orga from drwetter --> testssl ... to avoid redirects on the client side and to make repo migration better visible. Also amend 'Status' and 'Contributing' in Readme.md. bluesky added, albeit mastodon seems more interactive. Clarify twitter account is not in use anymore. --- CHANGELOG.md | 8 ++++---- CONTRIBUTING.md | 2 +- Dockerfile.git | 4 ++-- Readme.md | 37 ++++++++++++++++++++----------------- testssl.sh | 48 ++++++++++++++++++++++++------------------------ 5 files changed, 51 insertions(+), 48 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index dca42a3..2942f07 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -137,7 +137,7 @@ * Trust chain check against certificate stores from Apple (OS), Linux (OS), Microsoft (OS), Mozilla (Firefox Browser), works for openssl >=1.0.1 * IPv6 (status: 80% working, details see - https://github.com/drwetter/testssl.sh/issues/11 + https://github.com/testssl/testssl.sh/issues/11 * works now on servers requiring a x509 certificate for authentication * extensive CN <--> hostname check * SSL Session ID check @@ -183,7 +183,7 @@ * quite some LibreSSL fixes, still not recommended to use though (see https://testssl.sh/) * lots of fixes, code improvements, even more robust -Full log @ https://github.com/drwetter/testssl.sh/commits/2.6/testssl.sh +Full log @ https://github.com/testssl/testssl.sh/commits/2.6/testssl.sh ### New in 2.4 * "only one cmd line option at a time" is completely gone @@ -198,7 +198,7 @@ Full log @ https://github.com/drwetter/testssl.sh/commits/2.6/testssl.sh * lots of cosmetic and maintainability code cleanups * bugfixing -Full changelog: https://github.com/drwetter/testssl.sh/commits/2.4/testssl.sh +Full changelog: https://github.com/testssl/testssl.sh/commits/2.4/testssl.sh ### 2.2. new features: * Works fully under FreeBSD (openssl >=1.0) @@ -214,7 +214,7 @@ Full changelog: https://github.com/drwetter/testssl.sh/commits/2.4/testssl.sh * RFC <---> OpenSSL name space mapping of ciphers everywhere * includes a lot of fixes -Full changelog @ https://github.com/drwetter/testssl.sh/commits/2.2/testssl.sh +Full changelog @ https://github.com/testssl/testssl.sh/commits/2.2/testssl.sh ### 2.0 major release, new features: * SNI diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 5953205..bd8dfcb 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -5,7 +5,7 @@ is always welcome, here @ github or via e-mail. Note please the following -* Please read at least the [coding convention](https://github.com/drwetter/testssl.sh/Coding_Convention.md). +* Please read at least the [coding convention](https://github.com/testssl/testssl.sh/Coding_Convention.md). * One PR per feature or bug fix or improvement. Please do not mix issues. * Document your PR, both in the PR and/or commit message and in the code. * Please test your changes thoroughly as reliability is important for this project. You may want to check different servers with different settings. diff --git a/Dockerfile.git b/Dockerfile.git index e822163..8e69382 100644 --- a/Dockerfile.git +++ b/Dockerfile.git @@ -5,8 +5,8 @@ FROM alpine:3.20 WORKDIR /home/testssl ARG BUILD_VERSION -ARG ARCHIVE_URL=https://github.com/drwetter/testssl.sh/archive/ -ARG URL=https://github.com/drwetter/testssl.sh.git +ARG ARCHIVE_URL=https://github.com/testssl/testssl.sh/archive/ +ARG URL=https://github.com/testssl/testssl.sh.git RUN test -n "${BUILD_VERSION}" \ && apk update \ diff --git a/Readme.md b/Readme.md index da26026..e41e775 100644 --- a/Readme.md +++ b/Readme.md @@ -1,11 +1,11 @@ ## Intro - -[![Build Status](https://github.com/drwetter/testssl.sh/actions/workflows/test.yml/badge.svg)](https://github.com/drwetter/testssl.sh/actions/workflows/test.yml) -[![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/drwetter/testssl.sh?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) -[![License](https://img.shields.io/github/license/drwetter/testssl.sh)](https://github.com/drwetter/testssl.sh/LICENSE) -[![Docker](https://img.shields.io/docker/pulls/drwetter/testssl.sh)](https://github.com/drwetter/testssl.sh/blob/3.2/Dockerfile.md) + +[![Build Status](https://github.com/testssl/testssl.sh/actions/workflows/test.yml/badge.svg)](https://github.com/testssl/testssl.sh/actions/workflows/test.yml) +[![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/testssl/testssl.sh?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) +[![License](https://img.shields.io/github/license/testssl/testssl.sh)](https://github.com/testssl/testssl.sh/LICENSE) +[![Docker](https://img.shields.io/docker/pulls/testssl/testssl.sh)](https://github.com/testssl/testssl.sh/blob/3.2/Dockerfile.md) `testssl.sh` is a free command line tool which checks a server's service on any port for the support of TLS/SSL ciphers, protocols as well as some @@ -45,16 +45,16 @@ due to bash-socket-based checks. As a result you can also use e.g. LibreSSL or O (silent) check for binaries is done when you start testssl.sh . System V needs probably to have GNU grep installed. MacOS X and Windows (using MSYS2, Cygwin or WSL) work too. -Update notification here or @ [mastodon](https://infosec.exchange/@testssl) (old: [twitter](https://twitter.com/drwetter)) +Update notification here or @ [mastodon](https://infosec.exchange/@testssl or [bluesky](https://bsky.app/profile/testssl.bsky.social). Please note the [twitter](https://twitter.com/drwetter) account is not being used anymore. ### Installation You can download testssl.sh branch 3.2 just by cloning this git repository: - git clone --depth 1 https://github.com/drwetter/testssl.sh.git + git clone --depth 1 https://github.com/testssl/testssl.sh.git -3.2 is now the latest branch which evolved from 3.1dev. It's in the release candidate phase. -For the former stable version help yourself by downloading the [ZIP](https://codeload.github.com/drwetter/testssl.sh/zip/v3.0.8) or [tar.gz](https://codeload.github.com/drwetter/testssl.sh/tar.gz/v3.0.8) archive. Just ``cd`` to the directory created (=INSTALLDIR) and run it off there. +3.2 is now the latest branch which evolved from 3.1dev. It's in the release candidate phase and considered as stable. +For the former stable version named oldstable please help yourself by downloading the [ZIP](https://codeload.github.com/testssl/testssl.sh/zip/v3.0.9) or [tar.gz](https://codeload.github.com/testssl/testssl.sh/tar.gz/v3.0.9) archive. Just ``cd`` to the directory created (=INSTALLDIR) and run it off there. #### Docker @@ -69,19 +69,19 @@ Or if you have cloned this repo you also can just ``cd`` to the INSTALLDIR and r docker build . -t imagefoo && docker run --rm -t imagefoo example.com ``` -For more please consult [Dockerfile.md](https://github.com/drwetter/testssl.sh/blob/3.2/Dockerfile.md). +For more please consult [Dockerfile.md](https://github.com/testssl/testssl.sh/blob/3.2/Dockerfile.md). ### No Warranty -Usage of the program is without any warranty. Use it at your own risk. +Usage of the program is without any warranty. Use it at your own risk. Testssl.sh is intended to be used as a standalone CLI tool. While we tried to apply best practise security measures, we can't guarantee that the program is without any vulnerabilities. Running as a service may pose security risks and you're recommended to apply additional security measures. ### Status -We're currently in the release candidate phase for version 3.2. Bigger features will be developed in a separate branch before merged into a 3.3dev to avoid hiccups or inconsistencies. +We're currently in the release candidate phase for version 3.2. You should use it despite the label "RC". Bigger features will be developed in a separate branch before merged into a 3.3dev to avoid hiccups or inconsistencies. -Version 3.0.X receives bugfixes, labeled as 3.0.1, 3.0.2 and so on. This will happen until 3.2 is released. +Version 3.0.X receives bugfixes, labeled as 3.0.1, 3.0.2 and so on. This will happen until 3.2 is finally released. Support for 2.9.5 has been dropped. Supported is >= 3.0.x only. @@ -93,16 +93,19 @@ Support for 2.9.5 has been dropped. Supported is >= 3.0.x only. ### Contributing -Contributions are welcome! See [CONTRIBUTING.md](https://github.com/drwetter/testssl.sh/blob/3.2/CONTRIBUTING.md) for details. Please also have a look at the [Coding Convention](https://github.com/drwetter/testssl.sh/blob/3.2/Coding_Convention.md). +Contributions are welcome! See [CONTRIBUTING.md](https://github.com/testssl/testssl.sh/blob/3.2/CONTRIBUTING.md) for details. Please also have a look at the [Coding Convention](https://github.com/testssl/testssl.sh/blob/3.2/Coding_Convention.md). A lot of contributors already helped to push the project where it currently is, see [CREDITS.md](https://github.com/testssl/testssl.sh/blob/3.2/CREDITS.md). We still you use your help now. A start would be look for issues which are labeled as [good first issue](https://github.com/testssl/testssl.sh/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22), [for grabs](https://github.com/testssl/testssl.sh/issues?q=is%3Aissue+is%3Aopen+label%3A%22for+grabs%22) or [help wanted](https://github.com/testssl/testssl.sh/issues?q=is%3Aissue+is%3Aopen+label%3A%22help+wanted%22). The latter is more advanced. + +In general there's some maintenance burden, like maintaining handshakes and CA stores, writing unit tests, improving github actions. If you believe you can contribute, speak up. + ### Bug reports Bug reports are important. It makes this project more robust. Please file bugs in the issue tracker @ GitHub. Do not forget to provide detailed information, see template for issue, and further details @ -https://github.com/drwetter/testssl.sh/wiki/Bug-reporting. Nobody can read your thoughts -- yet. And only agencies your screen ;-) +https://github.com/testssl/testssl.sh/wiki/Bug-reporting. Nobody can read your thoughts -- yet. And only agencies your screen ;-) -You can also debug yourself, see [here](https://github.com/drwetter/testssl.sh/wiki/Findings-and-HowTo-Fix-them). +You can also debug yourself, see [here](https://github.com/testssl/testssl.sh/wiki/Findings-and-HowTo-Fix-them). ---- @@ -129,7 +132,7 @@ Please address questions not specifically to the code of testssl.sh to the respe #### Brew package -* see [#233](https://github.com/drwetter/testssl.sh/issues/233) and +* see [#233](https://github.com/testssl/testssl.sh/issues/233) and [https://github.com/Homebrew/homebrew](https://github.com/Homebrew/homebrew) #### Daemon for batch execution of testssl.sh command files diff --git a/testssl.sh b/testssl.sh index c2e43e3..761d040 100755 --- a/testssl.sh +++ b/testssl.sh @@ -7,9 +7,9 @@ # vulnerabilities or features. It may or may be not distributed by your distribution. # The upstream versions are available (please leave the links intact): # -# Development version https://github.com/drwetter/testssl.sh +# Development version https://github.com/testssl/testssl.sh # Stable version https://testssl.sh -# File bugs at GitHub https://github.com/drwetter/testssl.sh/issues +# File bugs at GitHub https://github.com/testssl/testssl.sh/issues # # Project lead and initiator: Dirk Wetter, copyleft: 2007-today, contributions so far see CREDITS.md # Main contributions from David Cooper @@ -399,7 +399,7 @@ RSA_CERT_FINGERPRINT_SHA2="" STARTTLS_PROTOCOL="" OPTIMAL_PROTO="" # Need this for IIS6 (sigh) + OpenSSL 1.0.2, otherwise some handshakes will fail see # https://github.com/PeterMosmans/openssl/issues/19#issuecomment-100897892 -STARTTLS_OPTIMAL_PROTO="" # Same for STARTTLS, see https://github.com/drwetter/testssl.sh/issues/188 +STARTTLS_OPTIMAL_PROTO="" # Same for STARTTLS, see https://github.com/testssl/testssl.sh/issues/188 OPTIMAL_SOCKETS_PROTO="" # Same for tls_sockets(). -- not yet used ALL_FAILED_SOCKETS=true # Set to true if all attempts to connect to server using tls_sockets/sslv2_sockets failed TLS_TIME="" # To keep the value of TLS server timestamp @@ -617,7 +617,7 @@ tmln_cyan() { tm_cyan "$1"; tmln_out; } pr_cyan() { tm_cyan "$1"; [[ "$COLOR" -ge 2 ]] && html_out "$(html_reserved "$1")" || html_out "$(html_reserved "$1")"; } prln_cyan() { pr_cyan "$1"; outln; } -tm_litegrey() { [[ "$COLOR" -ne 0 ]] && tm_out "\033[0;37m$1" || tm_out "$1"; tm_off; } # ... https://github.com/drwetter/testssl.sh/pull/600#issuecomment-276129876 +tm_litegrey() { [[ "$COLOR" -ne 0 ]] && tm_out "\033[0;37m$1" || tm_out "$1"; tm_off; } # ... https://github.com/testssl/testssl.sh/pull/600#issuecomment-276129876 tmln_litegrey() { tm_litegrey "$1"; tmln_out; } # not really usable on a black background, see .. prln_litegrey() { pr_litegrey "$1"; outln; } pr_litegrey() { tm_litegrey "$1"; [[ "$COLOR" -ne 0 ]] && html_out "$(html_reserved "$1")" || html_out "$(html_reserved "$1")"; } @@ -1037,7 +1037,7 @@ get_cipher() { # However there seem to be cases where the preferred $(< "$1") logic has a problem. # Especially with bash 3.2 (Mac OS X) and when on the server side binary chars # are returned, see https://stackoverflow.com/questions/7427262/how-to-read-a-file-into-a-variable-in-shell#22607352 - # and https://github.com/drwetter/testssl.sh/issues/1292 + # and https://github.com/testssl/testssl.sh/issues/1292 # Performance measurements showed no to barely measurable penalty (1s displayed in 9 tries). if [[ "$server_hello" =~ Cipher\ *:\ ([A-Z0-9]+-[A-Za-z0-9\-]+|TLS_[A-Za-z0-9_]+|SSL_[A-Za-z0-9_]+) ]]; then @@ -4922,9 +4922,9 @@ client_simulation_sockets() { data+=", ${clienthello:i:2}" done # same as above. If a CIPHER_SUITES string was provided, then check that it is in the ServerHello - # this appeared 1st in yassl + MySQL (https://github.com/drwetter/testssl.sh/pull/784) but adds + # this appeared 1st in yassl + MySQL (https://github.com/testssl/testssl.sh/pull/784) but adds # robustness to the implementation - # see also https://github.com/drwetter/testssl.sh/pull/797 + # see also https://github.com/testssl/testssl.sh/pull/797 if [[ "${1:0:4}" == 1603 ]]; then # Extract list of cipher suites from SSLv3 or later ClientHello sid_len=4*$(hex2dec "${data:174:2}") @@ -6471,7 +6471,7 @@ pr_ecdh_quality() { elif [[ "$bits" -le 163 ]]; then pr_svrty_medium "$string" elif [[ "$bits" -le 193 ]]; then # hmm, according to https://wiki.openssl.org/index.php/Elliptic_Curve_Cryptography it should ok - pr_svrty_low "$string" # but openssl removed it https://github.com/drwetter/testssl.sh/issues/299#issuecomment-220905416 + pr_svrty_low "$string" # but openssl removed it https://github.com/testssl/testssl.sh/issues/299#issuecomment-220905416 elif [[ "$bits" -le 224 ]]; then out "$string" elif [[ "$bits" -gt 224 ]]; then @@ -14857,7 +14857,7 @@ parse_tls_serverhello() { fi # If a CIPHER_SUITES string was provided, then check that $tls_cipher_suite is in the string. - # this appeared in yassl + MySQL (https://github.com/drwetter/testssl.sh/pull/784) but adds robustness + # this appeared in yassl + MySQL (https://github.com/testssl/testssl.sh/pull/784) but adds robustness # to the implementation if [[ -n "$cipherlist" ]]; then tls_cipher_suite="$(tolower "$tls_cipher_suite")" @@ -15722,7 +15722,7 @@ prepare_tls_clienthello() { # There does not seem to be any reason to include this extension. However, it appears that # OpenSSL, Firefox, and Chrome include it in TLS 1.3 ClientHello messages, and there is at # least one server that will fail the connection if it is absent - # (see https://github.com/drwetter/testssl.sh/issues/990). + # (see https://github.com/testssl/testssl.sh/issues/990). if [[ "0x$tls_low_byte" -ge 0x04 ]] && [[ ! "$extra_extensions_list" =~ \ 002d\ ]]; then [[ -n "$all_extensions" ]] && all_extensions+="," all_extensions+="$extn_psk_mode" @@ -17195,7 +17195,7 @@ run_renego() { # 1 means client tried to renegotiating but the server side errored then. You still see RENEGOTIATING in the output if tail -5 $TMPFILE| grep -qa '^closed'; then # Exemption from above: server closed the connection but return value was zero - # See https://github.com/drwetter/testssl.sh/issues/1725 and referenced issue @haproxy + # See https://github.com/testssl/testssl.sh/issues/1725 and referenced issue @haproxy sec_client_renego=1 fi case "$sec_client_renego" in @@ -18004,7 +18004,7 @@ run_tls_fallback_scsv() { elif grep -qa "alert handshake failure" "$TMPFILE"; then pr_svrty_good "Probably OK. " fileout "$jsonID" "OK" "Probably oK" - # see RFC 7507, https://github.com/drwetter/testssl.sh/issues/121 + # see RFC 7507, https://github.com/testssl/testssl.sh/issues/121 # other case reported by Nicolas was F5 and at customer of mine: the same pr_svrty_medium "But received non-RFC-compliant \"handshake failure\" instead of \"inappropriate fallback\"" fileout "$jsonID" "MEDIUM" "received non-RFC-compliant \"handshake failure\" instead of \"inappropriate fallback\"" @@ -21281,7 +21281,7 @@ get_local_a() { check_resolver_bins() { local saved_openssl_conf="$OPENSSL_CONF" - OPENSSL_CONF="" # see https://github.com/drwetter/testssl.sh/issues/134 + OPENSSL_CONF="" # see https://github.com/testssl/testssl.sh/issues/134 type -p dig &> /dev/null && HAS_DIG=true type -p host &> /dev/null && HAS_HOST=true type -p drill &> /dev/null && HAS_DRILL=true @@ -21303,7 +21303,7 @@ check_resolver_bins() { HAS_DIG_NOIDNOUT=true fi fi - OPENSSL_CONF="$saved_openssl_conf" # see https://github.com/drwetter/testssl.sh/issues/134 + OPENSSL_CONF="$saved_openssl_conf" # see https://github.com/testssl/testssl.sh/issues/134 return 0 } @@ -21326,7 +21326,7 @@ get_a_record() { echo $1 return 0 fi - OPENSSL_CONF="" # see https://github.com/drwetter/testssl.sh/issues/134 + OPENSSL_CONF="" # see https://github.com/testssl/testssl.sh/issues/134 if [[ "$NODE" == *.local ]]; then if "$HAS_AVAHIRESOLVE"; then ip4=$(filter_ip4_address $(avahi-resolve -4 -n "$1" 2>/dev/null | awk '{ print $2 }')) @@ -21351,7 +21351,7 @@ get_a_record() { if [[ -z "$ip4" ]] && "$HAS_NSLOOKUP"; then ip4=$(filter_ip4_address $(strip_lf "$(nslookup -querytype=a "$1" 2>/dev/null | awk '/^Name/ { getline; print $NF }')")) fi - OPENSSL_CONF="$saved_openssl_conf" # see https://github.com/drwetter/testssl.sh/issues/134 + OPENSSL_CONF="$saved_openssl_conf" # see https://github.com/testssl/testssl.sh/issues/134 echo "$ip4" } @@ -21364,7 +21364,7 @@ get_aaaa_record() { "$HAS_DIG_NOIDNOUT" && noidnout="+noidnout" [[ "$NODNS" == none ]] && return 0 # if no DNS lookup was instructed, leave here - OPENSSL_CONF="" # see https://github.com/drwetter/testssl.sh/issues/134 + OPENSSL_CONF="" # see https://github.com/testssl/testssl.sh/issues/134 if is_ipv6addr "$1"; then # This saves walking through this. Also it avoids hangs e.g. if you run docker locally without reachable DNS echo "$1" @@ -21398,7 +21398,7 @@ get_aaaa_record() { ip6=$(filter_ip6_address $(strip_lf "$(nslookup -type=aaaa "$1" 2>/dev/null | awk '/'"^${a}"'.*AAAA/ { print $NF }')")) fi fi - OPENSSL_CONF="$saved_openssl_conf" # see https://github.com/drwetter/testssl.sh/issues/134 + OPENSSL_CONF="$saved_openssl_conf" # see https://github.com/testssl/testssl.sh/issues/134 echo "$ip6" } @@ -21444,7 +21444,7 @@ get_caa_rr_record() { return 1 # No dig, drill, host, or nslookup --> complaint was elsewhere already fi - OPENSSL_CONF="$saved_openssl_conf" # see https://github.com/drwetter/testssl.sh/issues/134 + OPENSSL_CONF="$saved_openssl_conf" # see https://github.com/testssl/testssl.sh/issues/134 debugme echo $raw_caa if [[ "$raw_caa" =~ \#\ [0-9][0-9] ]]; then @@ -21492,7 +21492,7 @@ get_mx_record() { local noidnout="" "$HAS_DIG_NOIDNOUT" && noidnout="+noidnout" - OPENSSL_CONF="" # see https://github.com/drwetter/testssl.sh/issues/134 + OPENSSL_CONF="" # see https://github.com/testssl/testssl.sh/issues/134 # we need the last two columns here if "$HAS_HOST"; then mx="$(host -t MX "$1" 2>/dev/null | awk '/is handled by/ { print $(NF-1), $NF }')" @@ -21519,7 +21519,7 @@ get_txt_record() { local noidnout="" "$HAS_DIG_NOIDNOUT" && noidnout="+noidnout" - OPENSSL_CONF="" # see https://github.com/drwetter/testssl.sh/issues/134 + OPENSSL_CONF="" # see https://github.com/testssl/testssl.sh/issues/134 # we need the last two columns here and strip any remaining double quotes later if "$HAS_HOST"; then record="$(host -t TXT "$1" 2>/dev/null | awk -F\" '/descriptive text/ { print $(NF-1) }')" @@ -21620,7 +21620,7 @@ determine_rdns() { [[ "$NODNS" == none ]] && rDNS="(instructed to skip DNS queries)" && return 0 # No DNS lookups at all [[ "$NODNS" == min ]] && rDNS="(instructed to minimize DNS queries)" && return 0 # PTR records were not asked for local nodeip="$(tr -d '[]' <<< $NODEIP)" # for DNS we do not need the square brackets of IPv6 addresses - OPENSSL_CONF="" # see https://github.com/drwetter/testssl.sh/issues/134 + OPENSSL_CONF="" # see https://github.com/testssl/testssl.sh/issues/134 if [[ "$NODE" == *.local ]]; then if "$HAS_AVAHIRESOLVE"; then rDNS=$(avahi-resolve -a $nodeip 2>/dev/null | awk '{ print $2 }') @@ -21637,7 +21637,7 @@ determine_rdns() { elif "$HAS_NSLOOKUP"; then rDNS=$(strip_lf "$(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 + OPENSSL_CONF="$saved_openssl_conf" # see https://github.com/testssl/testssl.sh/issues/134 # First, rDNS can contain multilines due to multiple PTR DNS records, though this is not recommended. # So we use a loop to check for each FQDN returned. There we remove chars which under weird # circumstances (see #1506) can show up here. The blacklist is taken from RFC 1912 ("Allowable characters in a @@ -22033,7 +22033,7 @@ determine_optimal_proto() { >$ERRFILE if [[ -n "$1" ]]; then - # STARTTLS workaround needed see https://github.com/drwetter/testssl.sh/issues/188 -- kind of odd + # STARTTLS workaround needed see https://github.com/testssl/testssl.sh/issues/188 -- kind of odd for STARTTLS_OPTIMAL_PROTO in -tls1_2 -tls1 -ssl3 -tls1_1 -tls1_3 -ssl2; do sclient_supported "$STARTTLS_OPTIMAL_PROTO" || continue $OPENSSL s_client $(s_client_options "$STARTTLS_OPTIMAL_PROTO $BUGS -connect "$NODEIP:$PORT" $PROXY -msg $STARTTLS $SNI") $TMPFILE 2>>$ERRFILE From b6aa4c32144949724200190cd22d81a32e76df1b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 9 Jan 2025 00:23:29 +0000 Subject: [PATCH 24/41] Bump docker/setup-qemu-action from 3.2.0 to 3.3.0 Bumps [docker/setup-qemu-action](https://github.com/docker/setup-qemu-action) from 3.2.0 to 3.3.0. - [Release notes](https://github.com/docker/setup-qemu-action/releases) - [Commits](https://github.com/docker/setup-qemu-action/compare/v3.2.0...v3.3.0) --- updated-dependencies: - dependency-name: docker/setup-qemu-action dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- .github/workflows/docker-3.2.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docker-3.2.yml b/.github/workflows/docker-3.2.yml index 8da89f8..78adc01 100644 --- a/.github/workflows/docker-3.2.yml +++ b/.github/workflows/docker-3.2.yml @@ -23,7 +23,7 @@ jobs: - name: Setup QEMU id: qemu - uses: docker/setup-qemu-action@v3.2.0 + uses: docker/setup-qemu-action@v3.3.0 - name: Setup Buildx id: buildx From 9c74fe8f317b2c8caf3af3fc625712728266bcde Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 9 Jan 2025 00:23:31 +0000 Subject: [PATCH 25/41] Bump docker/build-push-action from 6.10.0 to 6.11.0 Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 6.10.0 to 6.11.0. - [Release notes](https://github.com/docker/build-push-action/releases) - [Commits](https://github.com/docker/build-push-action/compare/v6.10.0...v6.11.0) --- updated-dependencies: - dependency-name: docker/build-push-action dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- .github/workflows/docker-3.2.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docker-3.2.yml b/.github/workflows/docker-3.2.yml index 8da89f8..9627ce1 100644 --- a/.github/workflows/docker-3.2.yml +++ b/.github/workflows/docker-3.2.yml @@ -48,7 +48,7 @@ jobs: password: ${{ secrets.GITHUB_TOKEN }} - name: Build and push - uses: docker/build-push-action@v6.10.0 + uses: docker/build-push-action@v6.11.0 with: push: ${{ github.event_name != 'pull_request' }} context: . From 582d4658ae9767ab0573d40e567cbad0b17a8b7c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 16 Jan 2025 00:29:43 +0000 Subject: [PATCH 26/41] Bump docker/build-push-action from 6.11.0 to 6.12.0 Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 6.11.0 to 6.12.0. - [Release notes](https://github.com/docker/build-push-action/releases) - [Commits](https://github.com/docker/build-push-action/compare/v6.11.0...v6.12.0) --- updated-dependencies: - dependency-name: docker/build-push-action dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- .github/workflows/docker-3.2.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docker-3.2.yml b/.github/workflows/docker-3.2.yml index bb0980b..0335c0f 100644 --- a/.github/workflows/docker-3.2.yml +++ b/.github/workflows/docker-3.2.yml @@ -48,7 +48,7 @@ jobs: password: ${{ secrets.GITHUB_TOKEN }} - name: Build and push - uses: docker/build-push-action@v6.11.0 + uses: docker/build-push-action@v6.12.0 with: push: ${{ github.event_name != 'pull_request' }} context: . From 8e184b886e52ceeea38025247c105b6aebf3034a Mon Sep 17 00:00:00 2001 From: David Cooper Date: Wed, 15 Jan 2025 08:42:50 -0800 Subject: [PATCH 27/41] Fix #2615 The server mentioned in #2615 has a bug, which results in it sending a handshake_failure alert rather than a successful connection if the signature_algorithms extension lists RSA+MD5 before one of the signature algorithms that it supports. This commit works around this issue by reversing the order in which it lists the signature algorithms in the signature_algorithms extension, thus (generally) listing stronger options first. This change should not affect the testing, except that it will result in the order of the supported signature algorithms being reversed in the output, if the server respects the client's preferences. --- testssl.sh | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/testssl.sh b/testssl.sh index 7976e1d..59cfcfd 100755 --- a/testssl.sh +++ b/testssl.sh @@ -11079,25 +11079,27 @@ run_fs() { # A few servers get confused if the signature_algorithms extension contains too many entries. So: # * For TLS 1.3, break the list into two and test each half separately. # * For TLS 1.2, generally limit the signature_algorithms extension to algorithms that are consistent with the key type. + # At least one server gets confused if RSA+MD5 is offered first. So, the ordering is reversed so that the strongest + # options appear in $sigalgs_to_test first. for hexc in "${sigalgs_hex[@]}"; do if [[ "$proto" == 04* ]]; then if ! "${tls13_supported_sigalgs[i]}"; then if [[ "${proto##*-}" == 01 ]]; then - [[ $i -le 16 ]] && sigalgs_to_test+=", $hexc" + [[ $i -le 16 ]] && sigalgs_to_test=", $hexc$sigalgs_to_test" else - [[ $i -gt 16 ]] && sigalgs_to_test+=", $hexc" + [[ $i -gt 16 ]] && sigalgs_to_test=", $hexc$sigalgs_to_test" fi fi elif ! "${tls12_supported_sigalgs[i]}"; then if [[ "$proto" =~ rsa ]]; then if [[ "${hexc:3:2}" == 01 ]] || [[ "${hexc:0:2}" == 08 ]]; then - sigalgs_to_test+=", $hexc" + sigalgs_to_test=", $hexc$sigalgs_to_test" fi elif [[ "$proto" =~ dss ]]; then - [[ "${hexc:3:2}" == 02 ]] && sigalgs_to_test+=", $hexc" + [[ "${hexc:3:2}" == 02 ]] && sigalgs_to_test=", $hexc$sigalgs_to_test" else if [[ "${hexc:3:2}" == 03 ]] || [[ "${hexc:0:2}" == 08 ]]; then - sigalgs_to_test+=", $hexc" + sigalgs_to_test=", $hexc$sigalgs_to_test" fi fi fi From 2e8d4a112858fc739bbe00bf8c829f6fd4fe8823 Mon Sep 17 00:00:00 2001 From: Hyeonho Kang Date: Fri, 17 Jan 2025 00:36:37 +0900 Subject: [PATCH 28/41] Edit CONTRIBUTING.md --- CONTRIBUTING.md | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index bd8dfcb..eb9098e 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,21 +1,21 @@ -### Contributions / participation +### Contribution -is always welcome, here @ github or via e-mail. +Contribution is always welcome, submit here (GitHub) or via e-mail. -Note please the following +Please note the following: -* Please read at least the [coding convention](https://github.com/testssl/testssl.sh/Coding_Convention.md). -* One PR per feature or bug fix or improvement. Please do not mix issues. -* Document your PR, both in the PR and/or commit message and in the code. +* Please read at least the [coding convention](https://github.com/testssl/testssl.sh/blob/3.2/Coding_Convention.md). +* One Pull Request per feature or bug fix or improvement. Please do not mix issues. +* Document your Pull Request, both in the Pull Request and/or commit message and in the code. * Please test your changes thoroughly as reliability is important for this project. You may want to check different servers with different settings. -* Travis runs automatically when anything is committed/PR'd. You should check any complains from Travis. Beforehand you can check with `prove -v`. -* If it's a new feature please consider writing a unit test for it. You can use e.g. `t/20_baseline_ipv4_http.t` as a template. The general documentation for [Test::More](https://perldoc.perl.org/Test/More.html) is a good start. -* If it's a new feature it would need to be documented in the appropriate section in `help()` and in `~/doc/testssl.1.md` +* Travis runs automatically when anything is committed/pull requested. You should check any complains from Travis. Beforehand you can check with `prove -v`. +* If it's a new feature, please consider writing a unit test for it. You can use e.g. `t/20_baseline_ipv4_http.t` as a template. The general documentation for [Test::More](https://perldoc.perl.org/Test/More.html) is a good start. +* If it's a new feature, it would need to be documented in the appropriate section in `help()` and in `~/doc/testssl.1.md` -For questions just open an issue or feel free to send me an e-mail. +For the questions, just open an issue or feel free to send us an e-mail. -#### Patches via e-mail +#### Contribute via e-mail -Of course it is fine when you want to send in patches to use e-mail. For the address please grep for SWCONTACT in testssl.sh . +Of course it is fine when you want to send in patches to use e-mail. For the address, please grep for SWCONTACT in testssl.sh. Let me know how you like them to be attributed. From 80008853714b7f3ce52e888f33e5dbcb2fb5d3b3 Mon Sep 17 00:00:00 2001 From: Dirk Wetter Date: Thu, 16 Jan 2025 21:18:47 +0100 Subject: [PATCH 29/41] Add more security headers ... and deprecate "X-Content-Security-Policy" and "X-WebKit-CSP" --- testssl.sh | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/testssl.sh b/testssl.sh index 1dd94c6..188de3b 100755 --- a/testssl.sh +++ b/testssl.sh @@ -3438,13 +3438,17 @@ run_security_headers() { for header_and_svrty in "X-Frame-Options OK" \ "X-Content-Type-Options OK" \ "Content-Security-Policy OK" \ - "X-Content-Security-Policy OK" \ - "X-WebKit-CSP OK" \ + "X-Content-Security-Policy INFO" \ + "X-WebKit-CSP INFO" \ "Content-Security-Policy-Report-Only OK" \ "Expect-CT OK" \ "Permissions-Policy OK" \ + "Cross-Origin-Opener-Policy INFO" \ + "Cross-Origin-Resource-Policy INFO" \ + "Cross-Origin-Embedder-Policy INFO" \ "X-XSS-Protection INFO" \ "Access-Control-Allow-Origin INFO" \ + "Access-Control-Allow-Credentials INFO" \ "Upgrade INFO" \ "X-Served-By INFO" \ "Referrer-Policy INFO" \ From 95b6258f820efd4eb4454e8fc2155987fa93d1f1 Mon Sep 17 00:00:00 2001 From: David Cooper Date: Thu, 16 Jan 2025 14:51:16 -0800 Subject: [PATCH 30/41] Fix #2614 Currently `compare_server_name_to_cert()` only indicates whether the server's host name matches a wildcard name in the certificate. So, it does not indicate if the certificate includes a wildcard name that does not match the server's host name. As a result, if a certificate includes the names "api.sub.example.tld" and "*.api.sub.example.tld," then a wildcard certificate warning will be issued for host names such as www.api.sub.example.tld, but not for api.sub.example.tld. This commit changes `compare_server_name_to_cert()` to indicate whether the certificate is a wildcard certificate in addition to providing information about how the certificate matches the server's host name. Functions that use this function's response are then changed to extract the information they need (matching or wildcard) from the return value. --- testssl.sh | 47 +++++++++++++++++++++++++++++++---------------- 1 file changed, 31 insertions(+), 16 deletions(-) diff --git a/testssl.sh b/testssl.sh index 59cfcfd..1a79340 100755 --- a/testssl.sh +++ b/testssl.sh @@ -8386,12 +8386,14 @@ wildcard_match() # 8, if the server name provided is a wildcard match against the CN # 9, if the server name provided matches a name in the SAN AND is a wildcard match against the CN # 10, if the server name provided is a wildcard match against the CN AND a name in the SAN +# +# Add 128 to the return value if the CN or a DNS name in the SAN is a wildcard. compare_server_name_to_cert() { local cert="$1" local servername cns cn dns_sans ip_sans san dercert tag local srv_id="" xmppaddr="" - local -i i len len1 cn_match=0 + local -i i len len1 cn_match=0 wildcard_cert=0 local -i subret=0 # no error condition, passing results HAS_DNS_SANS=false @@ -8536,10 +8538,16 @@ compare_server_name_to_cert() { fi # Check whether any of the DNS names in the certificate are wildcard names - # that match the servername + # and if they match the servername if [[ $subret -eq 0 ]]; then while read san; do [[ -n "$san" ]] || continue + is_wildcard "$san" + if [[ $? -eq 0 ]]; then + wildcard_cert=128 + else + continue + fi wildcard_match "$servername" "$san" [[ $? -eq 0 ]] && subret=2 && break done <<< "$dns_sans" @@ -8555,13 +8563,20 @@ compare_server_name_to_cert() { # Check whether the CN matches the servername [[ $(toupper "$cn") == "$servername" ]] && cn_match=4 && break - # Check whether the CN is a wildcard name that matches the servername + # Check whether the CN is a wildcard name and if it matches the servername # NOTE: Don't stop loop on a wildcard match in case there is another CN # that is an exact match. + is_wildcard "$cn" + if [[ $? -eq 0 ]]; then + wildcard_cert=128 + else + continue + fi wildcard_match "$servername" "$cn" [[ $? -eq 0 ]] && cn_match=8 done <<< "$cns" subret+=$cn_match + subret+=$wildcard_cert return $subret } @@ -9456,7 +9471,7 @@ certificate_info() { # supported by the client. has_dns_sans=$HAS_DNS_SANS - case $trust_sni in + case $((trust_sni%128)) in 0) trustfinding="certificate does not match supplied URI" set_grade_cap "M" "Domain name mismatch" ;; @@ -9483,10 +9498,10 @@ certificate_info() { ;; esac - if [[ $trust_sni -eq 0 ]]; then + if [[ $((trust_sni%128)) -eq 0 ]]; then pr_svrty_high "$trustfinding" trust_sni_finding="HIGH" - elif [[ $trust_sni -eq 4 ]] || [[ $trust_sni -eq 8 ]]; then + elif [[ $((trust_sni%128)) -eq 4 ]] || [[ $((trust_sni%128)) -eq 8 ]]; then if [[ $SERVICE == HTTP ]] || "$ASSUME_HTTP"; then # https://bugs.chromium.org/p/chromium/issues/detail?id=308330 # https://bugzilla.mozilla.org/show_bug.cgi?id=1245280 @@ -9513,17 +9528,17 @@ certificate_info() { # See issue #733. if [[ -z "$sni_used" ]]; then trustfinding_nosni="" - elif [[ $trust_sni -eq $trust_nosni && "$has_dns_sans" == "$has_dns_sans_nosni" ]] || \ - [[ $trust_sni -eq 0 && $trust_nosni -eq 0 ]]; then + elif [[ $((trust_sni%128)) -eq $((trust_nosni%128)) && "$has_dns_sans" == "$has_dns_sans_nosni" ]] || \ + [[ $((trust_sni%128)) -eq 0 && $((trust_nosni%128)) -eq 0 ]]; then trustfinding_nosni=" (same w/o SNI)" - elif [[ $trust_nosni -eq 0 ]]; then - if [[ $trust_sni -eq 4 ]] || [[ $trust_sni -eq 8 ]]; then + elif [[ $((trust_nosni%128)) -eq 0 ]]; then + if [[ $((trust_sni%128)) -eq 4 ]] || [[ $((trust_sni%128)) -eq 8 ]]; then trustfinding_nosni=" (w/o SNI: certificate does not match supplied URI)" else trustfinding_nosni=" (SNI mandatory)" fi - elif [[ $trust_nosni -eq 4 ]] || [[ $trust_nosni -eq 8 ]] || [[ $trust_sni -eq 4 ]] || [[ $trust_sni -eq 8 ]]; then - case $trust_nosni in + elif [[ $((trust_nosni%128)) -eq 4 ]] || [[ $((trust_nosni%128)) -eq 8 ]] || [[ $((trust_sni%128)) -eq 4 ]] || [[ $((trust_sni%128)) -eq 8 ]]; then + case $((trust_nosni%128)) in 1) trustfinding_nosni=" (w/o SNI: Ok via SAN)" ;; 2) trustfinding_nosni=" (w/o SNI: Ok via SAN wildcard)" ;; 4) if "$has_dns_sans_nosni"; then @@ -9543,12 +9558,12 @@ certificate_info() { 9) trustfinding_nosni=" (w/o SNI: Ok via CN wildcard and SAN)" ;; 10) trustfinding_nosni=" (w/o SNI: Ok via SAN wildcard and CN wildcard)" ;; esac - elif [[ $trust_sni -ne 0 ]]; then + elif [[ $((trust_sni%128)) -ne 0 ]]; then trustfinding_nosni=" (works w/o SNI)" else trustfinding_nosni=" (however, works w/o SNI)" fi - if [[ -n "$sni_used" ]] || [[ $trust_nosni -eq 0 ]] || [[ $trust_nosni -ne 4 && $trust_nosni -ne 8 ]]; then + if [[ -n "$sni_used" ]] || [[ $((trust_nosni%128)) -eq 0 ]] || [[ $((trust_nosni%128)) -ne 4 && $((trust_nosni%128)) -ne 8 ]]; then outln "$trustfinding_nosni" elif [[ $SERVICE == HTTP ]] || "$ASSUME_HTTP"; then prln_svrty_high "$trustfinding_nosni" @@ -9558,7 +9573,7 @@ certificate_info() { fileout "cert_trust${json_postfix}" "$trust_sni_finding" "${trustfinding}${trustfinding_nosni}" - if [[ "$trust_sni" =~ ^(2|6|8|9|10)$ ]] || [[ "$trust_nosni" =~ ^(2|6|8|9|10)$ ]]; then + if [[ $((trust_sni&128)) -eq 128 ]] || [[ $((trust_nosni&128)) -eq 128 ]]; then out "${spaces}" pr_svrty_low "wildcard certificate" ; outln " could be problematic, see other hosts at" outln "${spaces}https://search.censys.io/search?resource=hosts&virtual_hosts=INCLUDE&q=$cert_fingerprint_sha2" @@ -10164,7 +10179,7 @@ run_server_defaults() { # $NODE being tested or if it has the same subject # (CN and SAN) as other certificates for this host. compare_server_name_to_cert "$HOSTCERT" - [[ $? -ne 0 ]] && success[n]=0 || success[n]=1 + [[ $(($?%128)) -ne 0 ]] && success[n]=0 || success[n]=1 if [[ ${success[n]} -ne 0 ]]; then cn_nosni="$(toupper "$(get_cn_from_cert $HOSTCERT)")" From 11d7979f41d4af2e5f1ce0e1046c4d4602dfb7c4 Mon Sep 17 00:00:00 2001 From: David Cooper Date: Wed, 11 Sep 2024 11:21:13 -0700 Subject: [PATCH 31/41] Support draft-kwiatkowski-tls-ecdhe-mlkem and draft-tls-westerbaan-xyber768d00 This commit adds support for the three code points in draft-kwiatkowski-tls-ecdhe-mlkem and the code point 0x6399 from draft-tls-westerbaan-xyber768d00. The group 0x6399 uses a pre-standard version of Kyber and is considered obsolete. --- etc/curves-mapping.txt | 4 ++ etc/tls_data.txt | 5 ++- testssl.sh | 93 +++++++++++++++++++++++++++++++++--------- 3 files changed, 82 insertions(+), 20 deletions(-) diff --git a/etc/curves-mapping.txt b/etc/curves-mapping.txt index 444f92d..2120f0a 100644 --- a/etc/curves-mapping.txt +++ b/etc/curves-mapping.txt @@ -45,3 +45,7 @@ 0x01,0x02 - ffdhe4096 ffdhe4096 0x01,0x03 - ffdhe6144 ffdhe6144 0x01,0x04 - ffdhe8192 ffdhe8192 + 0x11,0xeb - SecP256r1MLKEM768 SecP256r1MLKEM768 + 0x11,0xec - X25519MLKEM768 X25519MLKEM768 + 0x11,0xed - SecP384r1MLKEM1024 SecP384r1MLKEM1024 + 0x63,0x99 - X25519Kyber768Draft00 X25519Kyber768Draft00 diff --git a/etc/tls_data.txt b/etc/tls_data.txt index cf84b65..42483d9 100644 --- a/etc/tls_data.txt +++ b/etc/tls_data.txt @@ -339,5 +339,8 @@ readonly -a TLS13_PUBLIC_KEY_SHARES=( "01,02,02,00,8f,b3,b5,3f,0b,de,23,e1,5c,4a,77,ed,b2,4d,1c,4b,76,91,12,c4,fe,5b,15,23,13,a4,f3,b6,5b,23,8d,88,d5,77,0e,e4,1d,60,0b,58,1b,af,67,ee,31,fb,b6,ce,f5,1b,36,10,c1,f2,f0,83,e6,b9,23,13,1e,b2,9f,ae,e0,9e,42,64,4c,bd,1e,87,18,bd,a6,9b,ae,59,20,e8,9f,52,78,e6,f7,35,56,b6,3a,e6,82,8e,87,b5,c8,23,07,e1,f5,6e,95,8d,c6,83,83,88,b8,41,d8,63,58,33,fe,39,20,d4,9c,37,0e,68,5b,e9,1f,48,0e,85,d6,36,70,a2,06,a8,dc,5c,62,75,4d,bd,bd,3a,6f,03,b0,25,33,11,20,67,0f,76,23,d9,ab,5b,e9,c4,bc,ff,a8,1f,49,c0,e1,42,c7,3c,cb,25,7a,d3,c8,39,e2,f7,b1,22,ca,14,b2,3a,2e,7a,a0,80,a9,e0,dc,96,53,ca,d7,48,be,6d,bc,68,a9,38,b0,be,b0,1b,8c,85,9e,51,42,69,24,f0,28,c8,7c,f1,bc,e3,0f,1f,9c,f3,8b,3a,96,3b,52,ed,36,b1,88,10,9f,c8,02,89,2b,5a,eb,d5,fc,af,03,46,fa,cf,8a,ba,80,ae,8f,89,f7,fd,0f,77,f3,4e,24,35,32,35,e9,c4,82,97,25,51,ab,2b,01,dd,ca,53,5f,7c,3b,25,89,d2,54,69,30,48,6b,4a,03,25,dd,be,c6,ea,33,c2,86,7f,e9,d0,9b,31,fd,70,37,54,c2,8c,dc,96,6d,5a,2e,b6,c2,6d,85,ee,f2,32,b8,95,b0,66,40,44,1e,a2,bf,25,ed,1f,41,9d,37,5b,56,e0,1d,95,1d,ec,d8,f6,24,68,d4,06,17,16,7e,8c,31,7e,40,c2,88,29,d1,f9,8e,eb,4d,4e,5a,9d,65,c8,a2,43,83,4c,04,8b,93,eb,40,23,5f,80,8f,2f,29,ff,c3,13,47,ad,b0,c1,5a,28,08,dc,1e,83,e7,ed,26,4e,30,2c,6e,5a,0e,f1,db,68,ab,89,bb,61,63,6d,55,97,b2,94,16,cd,6f,d5,60,92,e8,71,ef,a3,b2,ae,0c,40,26,d5,35,1d,c8,ed,12,94,86,8c,1c,97,bd,cc,1d,53,0f,4c,99,21,fc,34,5a,79,8c,ca,ea,ae,99,bc,8b,a9,52,fe,f9,63,75,6f,7d,51,79,e6,ca,92,6c,b8,7e,7b,20,a9,c0,2a,15,1d,bb,c0,c2,b1,52,42,7f,dd,1c,8d,e5,a7,7f,26,f5,29,cb,4b,91,5b,80,c2,3a,94,e8,c5,2f,6d,7a,0d" "01,03,03,00,13,37,f3,03,0c,1f,cf,3d,2f,9c,e1,aa,a2,d5,90,ab,4a,e0,e6,b3,87,d2,a2,16,1e,26,7b,21,17,7d,82,39,ce,d4,50,94,17,b4,d0,5a,37,6e,ba,82,2b,fa,0f,7c,b6,e2,1d,01,7d,40,ca,a9,c3,fb,0d,4e,ef,ce,8a,b8,f8,61,54,14,02,6c,50,f9,dd,86,a8,2c,a8,5b,06,ff,60,4d,19,a9,ff,77,77,ba,6d,96,72,b4,d2,46,71,e2,2b,45,d8,5e,1f,84,64,07,ef,56,f9,64,1b,11,ff,ad,05,19,f9,2b,5d,af,50,91,24,c1,ca,ff,c8,78,92,32,13,fc,90,f3,12,24,62,c6,97,7f,5d,73,90,70,72,43,e2,bc,90,3f,3b,a4,85,3e,53,2e,43,a2,4f,c6,c6,38,88,0b,07,52,3d,98,b7,e3,4d,24,86,02,86,36,b8,2c,fa,49,28,e2,b9,a8,8c,75,16,32,8b,c8,e4,90,47,ba,d8,da,a6,ae,2e,af,4c,1e,ae,a1,99,70,c9,cf,1d,a8,e1,5c,fc,1f,61,25,f8,e5,5c,d2,27,8c,32,a6,28,51,42,91,91,08,e5,8f,48,d0,33,ad,7f,45,1a,5f,ee,30,f7,29,2c,23,88,b0,5c,6e,76,2d,56,7c,bc,63,73,a0,d6,13,71,58,82,91,79,4c,9b,aa,22,05,61,48,b5,51,af,d0,0e,9c,7d,94,a7,f5,6a,b9,cb,57,97,55,ca,d1,cc,b8,f5,3e,f7,bc,93,05,1a,af,c4,57,54,4c,a3,83,80,53,90,ac,16,5b,ec,6d,5f,82,83,e5,ca,fa,12,c2,8d,2b,a6,36,a8,b2,38,50,fc,f0,a5,fb,52,2d,eb,68,95,4d,f7,94,6d,75,f7,41,1f,46,db,86,71,d0,37,16,91,34,df,2f,89,78,4c,88,27,7d,2a,46,39,f0,8b,ec,75,e1,f3,5c,3f,98,b4,03,f3,c4,ea,70,af,67,0d,ee,97,d0,31,cd,3e,c1,c9,6e,4c,97,a0,64,19,44,9f,ad,16,4c,be,10,b6,e4,cc,9c,9d,2d,4f,79,02,a4,ea,09,2c,1d,2e,fd,c2,12,1a,de,ba,c9,a1,98,77,41,1c,14,56,ca,d9,19,02,46,87,7c,8d,a1,c4,3f,90,99,ca,2e,99,18,40,7e,ae,93,91,c3,4a,5f,68,f8,62,f9,34,83,ae,2e,64,c6,cf,a7,6d,80,eb,28,8b,ac,90,3b,1a,a2,a2,13,26,f3,91,40,bb,3a,44,2b,d2,0c,58,74,fc,9d,60,a9,d2,a6,34,c4,21,65,f6,00,c2,73,e1,e4,29,9d,c8,a9,88,33,38,c7,dd,83,23,d8,4b,66,d5,7c,78,7f,c3,62,23,34,12,1a,ee,a1,62,84,fe,62,3a,09,6b,72,69,58,d8,1b,fd,b0,89,e9,e1,da,fa,35,db,83,5f,93,a5,62,ad,c7,f7,e2,a7,6d,db,00,9e,7e,ea,9f,53,ef,d4,bd,32,e7,9e,2a,d1,90,a4,37,1b,b2,cd,cc,21,28,4a,96,3f,35,54,78,88,90,3b,e5,22,94,e4,2a,9f,d2,ef,7f,75,3d,b2,83,34,fe,66,45,4c,c2,ca,06,f3,fd,46,29,6b,40,32,66,a2,64,30,16,ee,04,cb,3d,28,bd,bf,a7,f1,84,9d,23,bf,61,e1,59,c7,36,b5,60,b5,39,39,eb,fd,ff,06,9e,52,99,69,97,d4,8b,bb,8f,84,90,fd,e2,0d,fd,7b,85,49,cc,81,3c,1d,c1,37,1e,5f,34,cd,52,4f,61,9a,85,c5,29,1d,b4,42,8c,c4,8d,94,43,cb,6a,e2,af,90,a6,ec,09,89,07,ae,62,9d,66,bd,fe,87,4d,76,0c,ce,e4,70,87,74,89,02,00,6c,54,4b,86,45,b5,f2,d6,fe,6e,f1,74,ae,c5,1f,67,f0,19,44,44,32,5d,d1,8a,a4,71,17,b0,9c,a4,5d,90,d4,29,b6,24" "01,04,04,00,67,47,f0,4b,9c,5b,75,a3,4d,9b,1f,b2,b4,32,56,a4,dd,23,69,70,4c,c3,ee,f2,0f,82,51,bc,54,8c,0d,a3,21,bf,94,88,82,7c,69,e8,55,d3,1d,8d,80,be,71,4d,4c,48,f8,ce,1e,f8,72,ac,a5,4c,74,aa,8f,a7,e0,51,99,ad,51,35,14,e7,98,02,1b,9d,07,e5,d1,07,d0,15,d2,9b,33,81,62,b7,7e,52,d5,b1,37,ea,55,f7,80,74,4c,25,cb,61,e9,75,c0,c9,7b,4e,19,4d,d1,69,46,ca,01,c9,14,06,a8,17,e0,f4,e5,c4,5d,e9,f6,2a,d5,02,b8,8b,6e,4a,26,ec,8c,a4,c0,bd,17,a6,48,5c,46,4f,bf,6f,c9,f1,4a,27,fa,4c,d1,93,e7,22,8c,2b,32,55,0c,2b,c6,ea,73,19,7d,e8,b7,fc,64,0d,f0,f9,bf,0d,3a,8b,3c,a9,30,a1,03,1b,e3,1b,d6,94,a8,39,4b,23,ce,ea,7b,2a,3a,af,4f,6c,15,cd,13,ca,67,84,05,9c,a7,d0,f6,7f,97,0b,e0,b3,bb,fd,ca,10,f6,35,57,5f,9b,e7,c2,5f,5c,16,f8,31,0c,23,34,7b,0b,f0,d1,b0,e4,e6,6a,45,db,32,be,fa,fc,92,df,01,3d,ca,bc,c8,d2,c9,57,8e,6b,eb,7b,f4,8c,23,b4,cf,16,73,a3,20,50,e7,f6,98,7a,19,f8,be,e4,72,3f,45,e7,e9,df,69,10,dd,72,24,94,d4,ce,c9,70,13,49,9d,af,bd,61,7a,a8,ee,82,9f,ce,2e,0f,4f,cf,c0,26,9b,98,a6,9e,a7,06,ed,b6,d7,f0,db,c6,c4,f0,db,55,94,87,92,af,11,dc,07,47,eb,e4,b5,3b,c8,5a,24,31,f2,d7,06,c5,a5,19,80,75,88,5e,45,f1,0f,e0,94,ea,9f,1b,65,4d,1a,ec,18,db,b0,c8,05,ca,25,46,6a,85,8a,49,d1,e7,06,9d,84,1f,ca,7e,48,02,34,b2,0d,4c,5e,61,d5,5d,b5,51,8c,19,18,2c,87,9e,69,b2,81,c1,4c,62,09,25,1f,e9,8d,0b,23,81,d3,36,a1,c5,41,f8,db,c6,8c,cf,1c,55,54,41,d0,5b,92,a8,3f,a5,ae,dd,69,98,c4,f3,8f,7b,26,70,43,f6,62,e5,89,4f,e4,cb,c7,de,63,13,f7,a9,6b,51,e4,41,dc,fe,9e,50,32,32,32,04,bd,d2,d7,8b,4d,29,9a,78,91,28,6e,56,30,5e,89,ba,1e,62,c5,8a,27,05,bc,ad,1e,2c,d1,cf,d4,bc,c0,69,a7,2d,3f,07,3c,77,f9,69,ca,16,1f,a7,14,4e,c8,0b,fa,e7,3a,9e,38,a6,c0,aa,b6,1e,66,30,a8,18,51,8f,76,27,fa,5c,c2,07,e8,e6,f0,98,6e,bb,b0,d7,53,d3,db,d4,2e,d6,1f,83,49,23,a3,1f,c4,0c,12,8c,67,ed,1c,01,a6,40,a8,ad,68,9a,6e,af,ee,ad,5f,d0,78,5f,15,5d,09,8e,e6,80,a4,f0,f3,c8,55,27,f1,44,6f,58,07,16,ed,87,1f,8e,26,d6,3c,a0,17,2e,79,d0,72,12,dc,81,d5,ae,a0,ad,86,31,8e,6d,45,d7,d1,3a,94,e7,e5,7b,3d,b7,5f,50,3c,af,e8,ea,2b,f0,e2,3c,eb,14,b6,16,31,0c,70,3b,92,e8,a2,f9,84,d1,aa,ba,73,80,89,ec,54,3c,23,a9,d5,87,87,b9,27,9a,87,bb,c5,06,96,9a,37,2b,d8,d9,af,32,e8,fd,8d,b0,49,c1,cb,81,bc,0d,0b,fe,dc,40,fb,b1,50,41,ed,71,3b,87,cc,95,6d,df,80,85,92,c6,66,cb,4c,75,16,46,f1,b1,08,ed,be,91,21,c5,b0,e8,83,58,96,24,16,28,15,e2,fe,94,e4,42,99,84,77,43,7b,1f,ac,a7,55,ff,33,09,6a,6e,b4,66,21,d6,c0,6f,88,35,94,6f,ab,1d,c6,74,7b,4c,30,a9,e0,70,36,7f,94,aa,c0,c7,98,71,ec,10,c9,96,86,32,08,83,37,16,60,cf,19,f0,19,11,4c,f4,65,87,d8,5f,16,ad,c6,80,89,1d,37,d6,26,91,bf,ef,de,47,62,c5,05,b8,b9,c1,a8,6c,19,ec,80,af,ec,dd,d8,ee,d3,c4,b5,13,77,88,20,fe,68,64,b3,bd,f1,90,67,c4,d7,29,e5,b9,4e,7c,29,34,a8,14,4f,09,60,9b,5f,87,c5,23,d2,49,da,e6,da,2a,cf,c4,c6,3d,c8,9a,5f,37,ca,fb,08,d0,28,1e,88,f0,30,37,74,b0,c3,8f,3f,2c,b3,bc,39,3a,96,27,d6,c0,c7,91,bb,d1,fc,f0,28,be,82,3b,ac,2b,28,72,9d,31,2d,42,5d,d8,36,d8,a8,c9,ca,58,b9,f9,4a,14,b8,38,52,c9,ea,aa,8d,05,52,d5,4b,22,87,8f,09,d3,0d,c9,16,f1,d3,26,61,e5,5c,bd,84,64,88,7d,32,8d,ea,6d,8a,00,dc,54,a5,75,50,a4,3b,99,33,b1,e2,ef,8d,e5,f6,78,d8,dd,71,1a,64,02,6f,ac,37,a5,2a,fc,5d,c8,af,f9,87,3b,77,f3,1c,2c,cc,db,a6" - "105" "106" "107" "108" "109" "10a" "10b" "10c" "10d" "10e" "10f" ) + [4587]="11,eb,04,e1,04,4e,42,eb,6e,46,64,d1,91,3e,88,28,08,ee,82,61,a2,2b,db,42,50,96,ff,0c,ae,4b,c7,1f,5b,b1,50,99,5f,37,77,b3,70,53,3f,96,2f,23,6a,83,07,eb,b2,91,ce,c0,ea,0e,aa,33,42,80,ce,cf,3b,ce,02,58,46,4f,58,ba,e1,68,65,e7,ba,7b,79,2b,05,03,89,dd,48,91,d4,d2,be,bc,ba,0e,9d,86,1f,fe,42,a6,91,f4,43,5a,33,34,59,f6,6e,26,c3,11,1b,08,0d,7f,a1,5b,fd,75,2f,61,f6,5e,f9,91,24,94,d9,97,d8,f5,43,f9,6a,c8,20,da,84,b9,35,7a,04,45,1c,d2,10,4b,e2,2b,05,28,30,be,85,1a,75,4a,d8,25,91,6c,6a,47,12,95,7d,f6,aa,8d,57,55,b1,24,c1,7c,13,9d,bf,f0,06,9a,56,5c,fc,d5,2c,af,39,0d,12,59,17,91,02,3f,39,c8,28,a3,24,2b,8d,fb,57,c1,02,94,23,94,0c,a4,9a,31,8d,08,87,d6,01,15,d1,dc,b6,12,93,03,3a,57,3f,1b,bb,94,30,3a,71,20,72,54,b1,50,12,13,03,0e,61,da,85,7e,f3,12,fe,08,a5,ef,9c,3c,6d,30,af,03,c6,62,02,41,55,46,ba,8c,59,a6,48,2e,4a,92,a4,d5,ae,61,97,16,1b,f0,4a,58,48,45,d7,9c,1b,63,b6,b8,b8,46,0f,c8,7b,be,f0,91,57,8f,20,7e,93,1a,97,10,bc,a3,6f,23,92,ce,c5,59,8b,b1,94,a6,95,85,08,41,62,8e,8b,2c,b4,f7,af,9c,e6,17,70,58,24,90,bb,0e,09,a1,a1,1f,b2,03,98,7a,61,a7,a3,5a,89,37,b5,eb,97,18,9a,17,22,43,53,bf,88,ab,6b,0f,a0,57,b5,74,71,f6,41,28,0b,84,85,31,b2,2f,c7,08,0e,b8,40,12,8f,87,c4,38,99,b0,80,43,13,ba,eb,54,ab,b6,6e,b7,43,9c,64,69,7b,3f,66,5f,35,5b,03,c1,bb,78,54,47,8b,9e,c8,70,68,42,75,c9,e1,47,2d,39,38,a0,9c,66,f3,bc,b4,75,b1,98,b8,77,85,bf,01,70,6e,81,49,c5,8b,59,5b,6a,b3,f9,cc,0c,4f,1b,2c,2c,d3,50,ef,b1,89,1d,54,2c,5d,22,2a,a0,fa,53,60,02,05,e0,b0,13,fe,e9,85,cc,57,5a,88,97,38,63,45,56,d3,2b,69,c4,00,1e,e3,92,22,2f,e4,55,8e,86,13,c8,a4,16,98,d3,3d,51,53,77,ea,d8,37,ca,41,0e,16,94,68,66,b5,c9,ca,06,28,de,78,02,94,d0,8e,67,5c,9b,57,ac,74,a4,73,66,10,d4,4c,74,14,68,01,db,1a,a9,b8,aa,56,91,71,3c,f6,75,23,bb,99,e5,5c,89,47,a3,7c,9f,d6,a4,82,a1,39,a9,35,42,49,94,29,0c,a5,22,e6,03,5d,fd,59,28,63,8c,05,b3,1a,84,8a,99,86,1a,02,10,c1,ec,c5,4f,58,0a,50,67,c0,c3,a5,7d,22,01,b5,57,c6,68,63,37,cb,74,e8,44,18,17,1f,ce,54,59,2a,4c,5f,e1,bb,96,85,77,81,d6,d9,88,54,02,69,51,1c,41,e4,03,3f,6c,62,94,e2,68,2e,9c,03,cb,b3,5b,73,a3,9c,36,ab,c4,29,0c,b5,c1,e6,b6,5a,bd,f4,89,3b,93,97,0c,33,59,a5,71,71,fc,2c,7a,d9,46,b3,11,1c,10,fe,55,9e,01,82,42,60,ec,3d,e5,83,c7,84,eb,8e,10,f9,8d,eb,7b,b3,82,0a,88,2f,50,53,20,1c,7b,de,27,39,1a,68,86,be,db,80,b6,4c,29,11,68,4f,3d,f0,76,eb,b5,4e,e1,65,7c,a4,82,2b,30,23,15,1d,65,7b,a8,06,24,3f,77,65,ab,80,84,d1,7b,a4,10,1b,08,c3,f6,a7,9d,c5,bb,e9,c5,02,2d,47,c0,22,47,6b,32,8b,2f,a4,5c,02,6d,7c,38,72,23,6d,a7,09,ba,7f,45,b1,04,76,cd,0e,12,0b,61,75,81,1a,94,68,88,c9,c5,1c,d5,7a,42,a4,c4,f3,dc,51,ed,6a,78,e6,45,a6,1f,31,74,de,9c,9c,61,32,51,67,e3,a5,bb,19,88,77,77,76,52,59,27,49,82,8c,c2,59,00,df,80,67,8c,82,ad,13,f0,13,17,21,43,3c,40,76,71,96,72,40,57,38,d9,e0,80,56,d7,bc,40,fb,9a,a4,8a,a1,a6,bb,99,94,31,96,38,b8,57,8b,68,08,27,d7,9e,18,1b,1b,3f,a1,9a,92,5b,6b,b8,73,72,8e,d7,3d,86,c7,24,73,98,ba,6e,07,17,0e,11,36,44,69,b8,7d,aa,b7,de,e6,71,5f,13,1a,55,c9,bb,e9,06,bd,4e,d7,04,df,e5,29,9f,c6,59,cf,77,4c,11,b1,41,ef,5c,68,2d,22,9d,8f,13,80,2c,cc,a9,35,8b,b3,1e,73,2c,0f,61,13,0f,2b,8f,a2,69,b4,bf,22,2e,23,4c,b5,24,66,39,a9,a3,19,12,56,44,3a,f4,15,e2,f4,cb,b7,36,08,bf,79,c1,fa,90,71,e8,84,4c,ec,95,73,e7,41,62,7f,f2,57,95,ca,13,3c,f3,ba,36,03,cd,e1,37,6f,31,b0,9f,17,8b,b8,a6,85,44,e3,26,71,8b,b1,05,b1,91,73,96,7b,bb,04,35,19,a5,44,a0,d8,17,c8,73,5b,58,d5,e9,b1,dc,9a,71,3d,16,84,a4,10,37,67,cc,0c,d4,77,94,e4,f2,5e,f1,e9,36,b0,61,93,68,59,bb,e0,24,c0,4c,e8,58,1e,83,2d,a9,88,7a,15,52,16,6b,94,18,2e,2b,2d,60,93,78,b1,32,98,4f,a7,5c,4d,2a,7e,4d,b5,27,04,79,20,d5,83,bf,37,1a,68,11,0a,b5,1b,45,31,3a,31,b9,4f,a7,ba,e5,49,20,2d,d1,19,ab,38,3c,7d,f1,cd,bf,db,1e,13,8c,70,0c,ab,bd,23,24,53,3b,39,bb,01,b2,56,e2,3c,96,94,22,92,f6,89,86,31,fb,ad,59,ea,07,64,e3,d7,68,35,6f,33,41,b7,c9,38,2e,08,b7,3a,01,10,9a,96,9d,e0,d1,92,24,e5,d6,26,af,45" + [4588]="11,ec,04,c0,15,45,8a,33,c6,16,72,fb,44,02,c9,c1,42,63,5d,2e,d0,30,a8,9b,a8,84,19,33,bf,23,10,ec,05,67,68,d9,12,0e,88,07,0a,39,85,85,6c,52,6e,24,70,69,38,aa,a1,a7,10,41,b5,4f,5a,99,2f,38,dc,07,0e,ab,a8,a2,44,40,49,7c,47,5d,3a,bd,7c,ea,af,63,11,47,5f,d2,8c,ef,81,b1,4d,e1,57,40,e6,32,0c,49,5d,43,63,62,7e,a8,49,71,7a,85,ea,00,9f,42,54,85,71,97,16,0e,43,35,4b,d1,26,2c,73,c8,cc,f2,43,63,c3,66,17,b4,7c,a7,d2,66,98,b4,60,e8,0b,a7,94,49,75,03,e3,4f,bf,69,ba,e7,67,68,89,c2,8a,4b,24,a2,42,f4,74,92,e3,44,85,bc,9e,da,e3,40,e9,e4,bd,4c,02,20,88,dc,67,2d,25,ba,4f,0a,4b,7c,dc,1f,96,d3,6a,01,86,5b,ad,75,b2,23,c5,c7,39,10,35,34,59,6e,23,fc,c9,cd,c0,17,e0,16,79,4b,04,82,70,d9,1f,62,a4,36,67,d3,00,a9,db,a4,25,09,21,38,f0,0b,d1,17,6a,3d,d5,22,51,1a,a6,0b,97,23,c7,67,32,0b,7c,a0,b3,a7,0d,06,49,01,52,69,9c,4f,f5,37,dd,0c,a7,bc,d0,c2,72,d5,6f,9c,26,aa,c3,ca,0d,84,6b,27,40,f8,1b,e3,55,bb,e4,f0,9a,15,52,2f,a3,da,06,45,c2,10,6e,a3,2a,07,87,61,89,1c,39,b1,52,26,2a,80,a5,a6,4b,2c,b3,3c,40,d7,42,0d,8b,67,90,d6,c6,49,09,a7,6e,d3,f2,c2,ac,b5,46,75,2c,8c,0d,03,0a,d8,f2,b7,19,a7,a4,84,f4,90,48,34,29,aa,00,28,e8,01,bf,2b,02,94,57,e2,62,36,59,61,d2,c0,0e,1c,69,04,57,b0,ba,c3,2c,a4,aa,e7,46,03,45,c9,a1,b6,58,13,ba,3f,ea,80,b3,ef,dc,5c,7f,28,8b,c6,92,18,db,81,0b,43,e1,07,65,b4,be,96,33,58,f0,31,c0,8c,29,9c,4c,d9,a8,95,91,58,e1,e7,61,b5,b5,23,0e,fa,39,62,63,38,3e,d4,3c,df,c1,09,81,ea,4f,0b,a2,7c,e3,08,1f,e6,e1,0f,5e,e0,5f,f1,02,c3,99,fa,6a,6f,45,96,87,31,18,f6,d8,48,13,15,6b,ed,7a,02,1e,da,a5,ec,da,67,07,67,ab,c2,ab,94,a5,07,01,17,54,8e,9c,35,12,55,60,53,02,8b,48,46,06,79,9f,da,6c,f3,51,86,a6,34,16,af,ba,45,ac,77,68,10,0b,c1,ce,f0,0a,c5,20,98,37,42,22,f8,e8,2e,9b,80,52,23,e4,90,f3,01,6e,f9,40,a7,19,c1,9d,59,97,9d,2e,57,06,d2,2a,75,28,c5,5b,aa,0c,a8,94,62,7b,ff,80,c4,6c,01,67,7f,c5,98,61,06,a3,bf,2c,19,32,77,86,7c,1c,42,36,0c,8c,7b,6b,62,01,d7,5a,2c,62,6f,a5,18,1b,19,c3,47,f7,e9,c9,ff,a9,c1,89,31,1d,46,79,2c,35,51,63,4a,f7,66,91,4a,b8,93,f9,40,b9,28,71,29,85,9a,0d,c5,16,c7,7b,ae,b9,4a,cc,50,d3,39,37,54,5f,31,fc,1b,fc,5a,76,23,e5,49,6b,c0,bd,11,1b,a2,b0,ca,36,55,07,54,40,0a,08,c8,49,ca,09,ea,29,73,02,80,d5,30,4c,e6,00,ae,0a,a4,2f,b8,57,4c,2d,75,58,05,8b,b6,c5,55,be,22,e6,48,63,75,c5,aa,f9,8d,e9,4c,8a,51,84,b7,96,b0,2e,14,58,18,99,48,29,de,36,7d,be,e5,8e,01,7c,9d,0f,71,2f,f8,84,7d,6e,d2,88,d0,67,b2,5b,e3,bb,63,bc,53,fa,80,88,29,26,c5,22,54,42,d8,21,82,5d,6a,4a,b1,b7,a2,8f,48,68,c2,c7,2f,79,fa,8d,25,f4,85,7b,47,a5,46,a5,af,3e,88,37,06,f5,41,40,71,02,89,f9,3e,1d,46,43,3e,34,5e,7e,39,4b,f2,25,c8,30,33,59,45,8a,c2,95,4b,94,37,53,b3,f0,03,73,21,d5,36,51,fc,6f,e9,1c,69,dd,a6,47,2b,39,5e,fc,35,c4,a8,84,7e,34,32,b3,76,f5,23,1b,67,07,e7,c8,b3,99,82,36,ec,9b,c7,a3,2c,80,de,09,46,c9,c9,22,cd,19,b9,a7,e0,c8,cb,a3,20,f7,f4,3a,7c,48,44,86,db,96,a4,b0,9d,bd,63,84,54,d9,c6,09,16,03,1e,45,89,65,da,57,2d,b3,33,0a,7b,1a,98,5a,cc,e5,08,ba,8c,35,7e,fe,4a,36,fa,f4,58,c3,fb,c8,e1,66,14,9e,91,b6,02,88,6f,fe,a9,6e,41,cb,63,6d,92,cc,65,c4,a9,9e,69,38,75,ec,6f,0f,89,c7,65,aa,2a,a1,8b,90,ad,e5,83,4b,b2,3e,68,60,84,be,a0,98,32,e6,47,53,41,c4,35,49,ca,10,16,c5,52,53,47,2b,ac,4f,44,1b,6a,04,7a,ab,95,7b,ae,20,b6,cc,be,21,9d,66,0a,c9,b0,a4,0b,2c,36,48,f2,6c,70,1d,56,11,b5,54,0a,7a,75,41,f1,fc,94,97,fc,5f,1c,53,c2,80,d5,64,6e,f9,c4,32,a1,69,fb,f6,b4,d7,63,a9,86,b8,7a,70,30,2f,45,22,47,19,1a,0e,54,b6,c4,58,81,b8,36,c1,2f,b5,67,6e,07,05,7b,68,37,aa,a8,73,46,c7,1b,1c,d8,34,44,83,83,b8,d7,07,76,5a,e9,32,38,30,9f,17,78,b0,c0,11,73,43,f2,c9,10,b1,cc,59,e9,59,f8,44,60,a0,1b,9c,98,f2,43,2e,5b,5a,b1,6a,07,e7,9a,73,79,56,cf,73,05,9a,a6,6a,79,a5,49,1f,c0,97,22,fe,89,e2,e4,66,6d,9a,18,ac,5e,d1,41,ba,dc,99,b4,01,0d,b0,43,11,3e,be,a0,50,d6,39,8a,4f,58,7d,cc,30,ba,c0,e6,41,51,ab,4e" + [4589]="11,ed,06,81,04,28,4e,85,ac,80,07,2c,4d,65,e1,21,0b,bb,ef,c5,1b,a6,0e,34,8b,9f,4b,c7,2a,3a,7b,dd,46,85,32,47,c4,00,dd,17,4b,7b,e6,18,fd,b5,77,bd,0e,90,8d,fe,4c,75,e0,b1,ca,68,d1,6b,cd,ce,7c,06,91,c2,f5,97,9d,3c,3c,46,e4,07,64,96,3a,8b,fd,dc,92,cb,f1,b8,56,7d,76,1f,bd,db,c7,af,3b,de,b9,74,75,13,3c,10,6f,ee,12,c4,68,60,39,4b,6b,cd,4d,5b,6f,55,03,5a,bc,70,40,78,15,9e,74,81,9a,68,b2,4c,4c,40,ce,02,32,5a,d7,89,10,48,e4,63,f9,f2,bc,e8,d6,0c,80,db,24,2f,27,2a,9d,29,22,55,a2,b7,c1,bb,92,a4,b9,a5,32,42,cf,41,e1,09,55,0b,68,21,c1,07,50,6c,0a,8b,cc,18,db,bb,7a,9f,91,4c,de,72,53,c4,5a,7e,17,10,c8,ed,34,16,11,9b,2b,a0,10,84,1b,48,60,bf,17,42,3f,84,56,0b,d1,19,55,3c,56,ea,83,26,f4,e8,a6,82,6a,7d,c0,49,c3,5b,b6,36,89,d0,8f,1f,b5,3b,d1,52,34,cd,c3,3f,8a,f8,04,b7,68,84,df,e8,75,f8,9b,23,65,c7,2f,05,aa,cd,ea,48,28,6e,54,57,44,99,76,c1,68,6a,c8,3b,6c,18,1c,50,54,c5,ba,96,71,ac,d8,0a,00,8d,41,0e,f3,41,c2,9f,8b,21,4a,ec,af,d7,64,5a,29,37,54,5a,a2,11,f7,ba,60,04,b6,b7,77,0c,bf,6f,30,ac,dd,00,3f,de,53,23,f3,a9,9e,de,c1,6e,ad,4a,00,9f,da,6d,a4,73,4d,57,83,a3,2d,5a,32,d2,76,3b,85,b2,5a,b8,89,5e,93,79,8b,aa,24,8e,a3,5c,16,d6,21,0f,15,08,c9,19,0c,6f,6d,fa,b9,00,4d,69,43,43,29,34,3c,99,77,2a,29,ef,d7,1c,fb,02,a2,4c,41,90,07,d5,78,03,0c,74,e4,03,7f,bc,d2,61,f4,da,aa,b2,89,5f,23,0a,9f,73,a4,ac,a3,e2,bf,1c,23,4c,c4,95,42,8e,44,18,4a,92,0f,f5,13,89,07,12,a7,8d,11,4b,43,07,7a,62,eb,cf,25,49,ce,73,11,c1,b0,f3,c2,4d,24,1e,94,69,30,19,c1,ba,57,66,72,d9,52,b5,1a,35,4e,af,f6,9c,85,26,80,73,92,22,1c,54,90,3d,67,01,11,01,2f,4c,7c,57,06,c8,6f,bb,87,14,88,d1,2f,4b,a9,92,4b,57,ce,59,c3,76,db,b6,71,6e,27,9c,d8,60,52,07,77,0c,10,c9,6e,32,74,bc,d6,75,c7,77,80,81,5f,6a,a9,f0,c2,42,8c,79,83,db,75,15,68,1c,1d,78,59,96,7b,82,98,0f,74,49,ef,c0,b4,82,d7,c0,cd,a3,27,4d,ac,18,cd,bb,38,43,ac,04,70,73,6c,f3,d1,80,d1,88,28,c2,83,0e,54,89,61,01,8b,81,b0,27,45,46,1c,b8,11,81,23,45,b9,12,4c,a4,06,85,00,3e,75,0c,0c,1a,d6,99,d0,79,cf,2d,a0,00,94,09,34,e5,d9,1c,80,08,ca,71,3c,03,df,12,02,c8,77,92,9f,4b,7d,cf,3c,75,08,c2,16,39,73,b8,d1,ab,6a,bb,05,32,35,2a,70,b4,d7,03,4c,74,76,3e,eb,ac,f7,c5,70,4f,18,62,3a,55,86,0b,6c,13,82,45,c0,33,b5,2c,57,36,5a,1b,a7,7b,32,b3,4b,89,78,c2,d9,04,ca,66,f5,2b,32,26,c1,c0,76,a5,87,93,2f,0d,b9,6f,1a,c2,a4,48,32,c9,b4,98,98,b4,c2,4a,cf,74,ae,b6,fb,9f,ff,5c,c2,c7,66,47,35,89,9d,32,02,79,34,aa,c7,f7,44,a3,cb,f8,7a,dc,b6,66,21,51,93,d4,e4,c0,3f,f7,0f,e9,56,57,84,b9,81,3b,d3,8d,ea,73,40,45,22,34,e2,cc,c5,8b,b3,b3,b6,4b,cf,71,14,61,a5,31,36,5f,c6,64,de,19,0a,67,7c,0c,df,90,16,b0,78,0b,b3,88,54,80,ea,5e,6b,eb,44,c5,bb,4d,ea,11,1c,52,b6,39,8d,72,1b,ac,02,cf,bc,36,6b,9d,a9,5b,db,87,3d,72,66,20,20,5c,6f,43,86,1f,aa,3c,95,90,0c,60,e2,86,c4,57,57,21,b6,47,33,40,a2,4d,c5,70,50,8d,11,0a,ce,77,2b,f3,70,39,64,42,81,49,18,c1,ae,79,0d,43,55,01,99,bb,55,7a,5a,19,20,a7,a6,6c,75,6a,39,cc,87,4b,73,61,a4,9c,13,c3,d1,25,a3,51,39,b9,8b,a0,82,2c,2f,67,db,b9,de,65,34,eb,8a,3d,56,6a,7e,23,32,91,d4,86,70,30,11,03,e9,54,3b,87,bc,47,7d,eb,17,b1,b5,84,c0,10,59,50,f5,24,08,e6,59,0b,28,b9,c8,7c,3a,ad,e1,b8,28,cc,28,52,a6,b2,1f,1b,17,30,28,10,aa,b9,06,13,55,86,41,35,7b,98,20,10,94,65,2e,7a,42,09,d2,f4,62,b2,b5,39,6c,c8,88,99,f4,0f,bf,69,03,5a,63,79,05,b4,19,4b,72,43,ba,26,14,44,6a,70,dc,82,2f,32,47,68,28,91,87,30,87,70,4b,93,1c,75,9a,28,fb,a8,ac,cf,95,2e,5e,89,4f,1b,0b,31,72,77,0a,6b,f0,0b,41,a1,45,fb,65,5a,09,6c,54,7a,c7,00,ef,e9,97,6f,2c,a1,82,47,50,7e,3a,1b,41,56,99,15,97,a0,71,50,c1,77,9b,bc,d8,bb,9c,3a,43,90,c1,ea,4e,10,88,41,61,31,33,60,01,30,44,f1,37,e0,ca,88,fa,14,45,d5,d5,8e,20,a5,6e,53,62,77,93,13,8b,ea,cb,63,f7,05,25,cd,2c,a0,81,33,a3,6e,d0,7e,07,c1,98,fc,19,87,47,5a,a5,6e,cb,7b,47,f1,ae,ac,f4,bc,e4,30,a1,0e,36,4c,0e,04,76,5b,08,a9,10,d7,c7,ac,67,0b,0b,88,a5,09,03,54,ef,e7,18,ab,47,69,18,74,af,06,11,43,4b,a1,73,bd,66,7b,e7,15,8c,16,d6,43,cb,6a,2c,a0,32,c2,e0,46,95,81,f0,cb,49,b4,1e,4b,5a,0a,6f,c8,4e,d7,3b,47,93,08,8e,c2,78,3b,95,d6,02,b4,5c,8d,ac,b9,a6,ac,16,50,1a,8b,63,34,20,4d,bc,2b,23,9f,cb,a1,de,8c,15,95,98,cf,50,e7,30,f4,1b,3f,2f,a8,1d,cf,c5,5c,19,84,35,9e,1b,21,ef,95,4d,58,49,6a,5a,50,1b,c6,20,47,b6,78,3e,1e,59,3d,df,91,63,75,4b,c6,dd,58,b4,1e,12,2a,58,16,8d,44,68,8f,40,db,1d,c7,34,02,aa,3a,43,c4,f1,44,a7,47,c7,37,82,0b,05,31,c7,a8,a6,71,74,58,89,1e,f9,b9,78,67,c5,ef,b2,b8,fb,14,22,f2,ac,8e,c3,73,a2,f8,c2,5a,42,e3,33,8f,fc,9d,33,6a,ac,d2,67,43,8e,a2,44,5b,30,0d,74,f2,8a,d1,82,84,c5,11,a7,80,ca,b3,ab,5c,11,97,b9,92,68,82,46,3b,34,53,15,62,bb,b2,86,14,1b,68,90,a0,0a,c5,a4,e7,34,38,95,4d,66,61,3e,6c,6a,91,d8,44,a6,9a,85,b9,9f,d3,82,65,c1,8a,4d,11,75,3c,86,0b,b5,1b,25,ab,e0,7f,9c,7c,cd,ff,1b,29,8e,dc,15,63,25,ba,be,40,84,ae,11,b9,fa,09,17,36,f0,21,47,11,9d,fc,3c,8b,6e,08,22,eb,c5,a7,25,c3,86,9d,c1,a3,a0,4c,00,d5,66,3f,d5,d0,be,8b,59,09,d8,3c,1b,a8,a0,b0,8a,c1,16,5c,94,1d,50,42,b9,b0,95,3e,22,26,b2,45,89,b1,b9,b6,bd,b3,33,75,e9,69,6b,d6,11,28,cd,61,47,cc,c8,28,60,99,42,a1,c7,b7,f9,2a,61,f7,fb,12,91,99,71,94,1b,8c,69,c5,67,25,b6,50,12,e1,6d,ed,f9,3b,bb,f0,57,e9,e5,13,8d,d8,46,9f,4e,dc,8c,06,fd,b1,67,f4,66,fe,e8,06,79,97,ee,fd,07,aa,26,90,86,f2,1a,c4,9d,c5,f5,33,6a,ca,59" +[25497]="63,99,04,c0,15,45,8a,33,c6,16,72,fb,44,02,c9,c1,42,63,5d,2e,d0,30,a8,9b,a8,84,19,33,bf,23,10,ec,05,67,68,d9,12,0e,88,07,0a,39,85,85,6c,52,6e,24,70,69,38,aa,a1,a7,10,41,b5,4f,5a,99,2f,38,dc,07,0e,ab,a8,a2,44,40,49,7c,47,5d,3a,bd,7c,ea,af,63,11,47,5f,d2,8c,ef,81,b1,4d,e1,57,40,e6,32,0c,49,5d,43,63,62,7e,a8,49,71,7a,85,ea,00,9f,42,54,85,71,97,16,0e,43,35,4b,d1,26,2c,73,c8,cc,f2,43,63,c3,66,17,b4,7c,a7,d2,66,98,b4,60,e8,0b,a7,94,49,75,03,e3,4f,bf,69,ba,e7,67,68,89,c2,8a,4b,24,a2,42,f4,74,92,e3,44,85,bc,9e,da,e3,40,e9,e4,bd,4c,02,20,88,dc,67,2d,25,ba,4f,0a,4b,7c,dc,1f,96,d3,6a,01,86,5b,ad,75,b2,23,c5,c7,39,10,35,34,59,6e,23,fc,c9,cd,c0,17,e0,16,79,4b,04,82,70,d9,1f,62,a4,36,67,d3,00,a9,db,a4,25,09,21,38,f0,0b,d1,17,6a,3d,d5,22,51,1a,a6,0b,97,23,c7,67,32,0b,7c,a0,b3,a7,0d,06,49,01,52,69,9c,4f,f5,37,dd,0c,a7,bc,d0,c2,72,d5,6f,9c,26,aa,c3,ca,0d,84,6b,27,40,f8,1b,e3,55,bb,e4,f0,9a,15,52,2f,a3,da,06,45,c2,10,6e,a3,2a,07,87,61,89,1c,39,b1,52,26,2a,80,a5,a6,4b,2c,b3,3c,40,d7,42,0d,8b,67,90,d6,c6,49,09,a7,6e,d3,f2,c2,ac,b5,46,75,2c,8c,0d,03,0a,d8,f2,b7,19,a7,a4,84,f4,90,48,34,29,aa,00,28,e8,01,bf,2b,02,94,57,e2,62,36,59,61,d2,c0,0e,1c,69,04,57,b0,ba,c3,2c,a4,aa,e7,46,03,45,c9,a1,b6,58,13,ba,3f,ea,80,b3,ef,dc,5c,7f,28,8b,c6,92,18,db,81,0b,43,e1,07,65,b4,be,96,33,58,f0,31,c0,8c,29,9c,4c,d9,a8,95,91,58,e1,e7,61,b5,b5,23,0e,fa,39,62,63,38,3e,d4,3c,df,c1,09,81,ea,4f,0b,a2,7c,e3,08,1f,e6,e1,0f,5e,e0,5f,f1,02,c3,99,fa,6a,6f,45,96,87,31,18,f6,d8,48,13,15,6b,ed,7a,02,1e,da,a5,ec,da,67,07,67,ab,c2,ab,94,a5,07,01,17,54,8e,9c,35,12,55,60,53,02,8b,48,46,06,79,9f,da,6c,f3,51,86,a6,34,16,af,ba,45,ac,77,68,10,0b,c1,ce,f0,0a,c5,20,98,37,42,22,f8,e8,2e,9b,80,52,23,e4,90,f3,01,6e,f9,40,a7,19,c1,9d,59,97,9d,2e,57,06,d2,2a,75,28,c5,5b,aa,0c,a8,94,62,7b,ff,80,c4,6c,01,67,7f,c5,98,61,06,a3,bf,2c,19,32,77,86,7c,1c,42,36,0c,8c,7b,6b,62,01,d7,5a,2c,62,6f,a5,18,1b,19,c3,47,f7,e9,c9,ff,a9,c1,89,31,1d,46,79,2c,35,51,63,4a,f7,66,91,4a,b8,93,f9,40,b9,28,71,29,85,9a,0d,c5,16,c7,7b,ae,b9,4a,cc,50,d3,39,37,54,5f,31,fc,1b,fc,5a,76,23,e5,49,6b,c0,bd,11,1b,a2,b0,ca,36,55,07,54,40,0a,08,c8,49,ca,09,ea,29,73,02,80,d5,30,4c,e6,00,ae,0a,a4,2f,b8,57,4c,2d,75,58,05,8b,b6,c5,55,be,22,e6,48,63,75,c5,aa,f9,8d,e9,4c,8a,51,84,b7,96,b0,2e,14,58,18,99,48,29,de,36,7d,be,e5,8e,01,7c,9d,0f,71,2f,f8,84,7d,6e,d2,88,d0,67,b2,5b,e3,bb,63,bc,53,fa,80,88,29,26,c5,22,54,42,d8,21,82,5d,6a,4a,b1,b7,a2,8f,48,68,c2,c7,2f,79,fa,8d,25,f4,85,7b,47,a5,46,a5,af,3e,88,37,06,f5,41,40,71,02,89,f9,3e,1d,46,43,3e,34,5e,7e,39,4b,f2,25,c8,30,33,59,45,8a,c2,95,4b,94,37,53,b3,f0,03,73,21,d5,36,51,fc,6f,e9,1c,69,dd,a6,47,2b,39,5e,fc,35,c4,a8,84,7e,34,32,b3,76,f5,23,1b,67,07,e7,c8,b3,99,82,36,ec,9b,c7,a3,2c,80,de,09,46,c9,c9,22,cd,19,b9,a7,e0,c8,cb,a3,20,f7,f4,3a,7c,48,44,86,db,96,a4,b0,9d,bd,63,84,54,d9,c6,09,16,03,1e,45,89,65,da,57,2d,b3,33,0a,7b,1a,98,5a,cc,e5,08,ba,8c,35,7e,fe,4a,36,fa,f4,58,c3,fb,c8,e1,66,14,9e,91,b6,02,88,6f,fe,a9,6e,41,cb,63,6d,92,cc,65,c4,a9,9e,69,38,75,ec,6f,0f,89,c7,65,aa,2a,a1,8b,90,ad,e5,83,4b,b2,3e,68,60,84,be,a0,98,32,e6,47,53,41,c4,35,49,ca,10,16,c5,52,53,47,2b,ac,4f,44,1b,6a,04,7a,ab,95,7b,ae,20,b6,cc,be,21,9d,66,0a,c9,b0,a4,0b,2c,36,48,f2,6c,70,1d,56,11,b5,54,0a,7a,75,41,f1,fc,94,97,fc,5f,1c,53,c2,80,d5,64,6e,f9,c4,32,a1,69,fb,f6,b4,d7,63,a9,86,b8,7a,70,30,2f,45,22,47,19,1a,0e,54,b6,c4,58,81,b8,36,c1,2f,b5,67,6e,07,05,7b,68,37,aa,a8,73,46,c7,1b,1c,d8,34,44,83,83,b8,d7,07,76,5a,e9,32,38,30,9f,17,78,b0,c0,11,73,43,f2,c9,10,b1,cc,59,e9,59,f8,44,60,a0,1b,9c,98,f2,43,2e,5b,5a,b1,6a,07,e7,9a,73,79,56,cf,73,05,9a,a6,6a,79,a5,49,1f,c0,97,22,fe,89,e2,e4,66,6d,9a,18,ac,5e,d1,41,ba,dc,99,b4,01,0d,b0,43,11,3e,be,a0,50,d6,39,8a,4f,58,7d,cc,30,ba,c0,e6,41,51,ab,4e" ) diff --git a/testssl.sh b/testssl.sh index 1a79340..23b6eb5 100755 --- a/testssl.sh +++ b/testssl.sh @@ -5286,7 +5286,9 @@ run_client_simulation() { fi if [[ -n "$what_dh" ]]; then [[ -n "$curve" ]] && curve="($curve)" - if [[ "$what_dh" == ECDH ]]; then + if [[ "$what_dh" =~ MLKEM ]] || [[ "$what_dh" =~ Kyber ]]; then + pr_kem_quality "$bits" "$(printf -- "%-12s" "$what_dh")" + elif [[ "$what_dh" == ECDH ]]; then pr_ecdh_quality "$bits" "$(printf -- "%-12s" "$bits bit $what_dh") $curve" else pr_dh_quality "$bits" "$(printf -- "%-12s" "$bits bit $what_dh") $curve" @@ -6524,6 +6526,30 @@ pr_ecdh_curve_quality() { pr_ecdh_quality "$bits" "$curve" } +pr_kem_quality() { + local bits="$1" + local string="$2" + + # At the moment all KEMs offer at least 128 bits of security strength + # (comparable to 256-bit elliptic curve key). So, all KEMs should be + # considered good. + pr_svrty_good "$string" +} + + +pr_kem_param_set_quality() { + kem="$1" + local -i bits=0 + + case "$kem" in + "SecP256r1MLKEM768") bits=192 ;; + "X25519MLKEM768") bits=192 ;; + "SecP384r1MLKEM1024") bits=256 ;; + "X25519Kyber768Draft00") bits=128 ;; + esac + pr_kem_quality "$bits" "$kem" +} + # Return a value that is an indicator of the quality of the cipher in $1: # 0 = $1 is empty # 1 = pr_svrty_critical, 2 = pr_svrty_high, 3 = pr_svrty_medium, 4 = pr_svrty_low @@ -6676,6 +6702,10 @@ read_dhtype_from_file() { kx="Kx=${temp%%,*}" [[ "$kx" == "Kx=X25519" ]] && kx="Kx=ECDH" [[ "$kx" == "Kx=X448" ]] && kx="Kx=ECDH" + [[ "$kx" == "Kx=SecP256r1MLKEM768" ]] && kx="Kx=ECDH/MLKEM" + [[ "$kx" == "Kx=X25519MLKEM768" ]] && kx="Kx=ECDH/MLKEM" + [[ "$kx" == "Kx=SecP384r1MLKEM1024" ]] && kx="Kx=ECDH/MLKEM" + [[ "$kx" == "Kx=X25519Kyber768Draft00" ]] && kx="Kx=ECDH/Kyber" tm_out "$kx" return 0 } @@ -10512,13 +10542,13 @@ run_fs() { local fs_cipher_list="DHE-DSS-AES128-GCM-SHA256:DHE-DSS-AES128-SHA256:DHE-DSS-AES128-SHA:DHE-DSS-AES256-GCM-SHA384:DHE-DSS-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-DSS-CAMELLIA128-SHA256:DHE-DSS-CAMELLIA128-SHA:DHE-DSS-CAMELLIA256-SHA256:DHE-DSS-CAMELLIA256-SHA:DHE-DSS-SEED-SHA:DHE-RSA-AES128-CCM8:DHE-RSA-AES128-CCM:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-CCM8:DHE-RSA-AES256-CCM:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-CAMELLIA128-SHA256:DHE-RSA-CAMELLIA128-SHA:DHE-RSA-CAMELLIA256-SHA256:DHE-RSA-CAMELLIA256-SHA:DHE-RSA-CHACHA20-POLY1305-OLD:DHE-RSA-CHACHA20-POLY1305:DHE-RSA-SEED-SHA:ECDHE-ECDSA-AES128-CCM8:ECDHE-ECDSA-AES128-CCM:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-ECDSA-AES256-CCM8:ECDHE-ECDSA-AES256-CCM:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-ECDSA-CAMELLIA128-SHA256:ECDHE-ECDSA-CAMELLIA256-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305-OLD:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-RSA-CAMELLIA128-SHA256:ECDHE-RSA-CAMELLIA256-SHA384:ECDHE-RSA-CHACHA20-POLY1305-OLD:ECDHE-RSA-CHACHA20-POLY1305" local fs_hex_cipher_list="" ciphers_to_test tls13_ciphers_to_test local ecdhe_cipher_list="" tls13_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" "00,1f" "00,20" "00,21") - 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" "brainpoolP256r1tls13" "brainpoolP384r1tls13" "brainpoolP512r1tls13") - 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" "brainpoolP256r1tls13" "brainpoolP384r1tls13" "brainpoolP512r1tls13") - local -ai curves_bits=(163 162 163 193 193 232 233 238 281 282 407 409 570 570 161 161 161 192 192 225 224 256 256 384 521 256 384 512 253 448 256 384 512) + 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" "00,1f" "00,20" "00,21" "11,eb" "11,ec" "11,ed" "63,99") + 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" "brainpoolP256r1tls13" "brainpoolP384r1tls13" "brainpoolP512r1tls13" "SecP256r1MLKEM768" "X25519MLKEM768" "SecP384r1MLKEM1024" "X25519Kyber768Draft00") + 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" "brainpoolP256r1tls13" "brainpoolP384r1tls13" "brainpoolP512r1tls13" "SecP256r1MLKEM768" "X25519MLKEM768" "SecP384r1MLKEM1024" "X25519Kyber768Draft00") + local -ai curves_bits=(163 162 163 193 193 232 233 238 281 282 407 409 570 570 161 161 161 192 192 225 224 256 256 384 521 256 384 512 253 448 256 384 512 192 192 256 128) # Many curves have been deprecated, and RFC 8446, Appendix B.3.1.4, states # that these curves MUST NOT be offered in a TLS 1.3 ClientHello. - local -a curves_deprecated=("true" "true" "true" "true" "true" "true" "true" "true" "true" "true" "true" "true" "true" "true" "true" "true" "true" "true" "true" "true" "true" "true" "false" "false" "false" "true" "true" "true" "false" "false" "false" "false" "false") + local -a curves_deprecated=("true" "true" "true" "true" "true" "true" "true" "true" "true" "true" "true" "true" "true" "true" "true" "true" "true" "true" "true" "true" "true" "true" "false" "false" "false" "true" "true" "true" "false" "false" "false" "false" "false" "false" "false" "false" "false") 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 @@ -10529,7 +10559,7 @@ run_fs() { local rsa_cipher="" ecdsa_cipher="" dss_cipher="" local sigalgs_to_test tls12_supported_sigalg_list="" tls13_supported_sigalg_list="" local -i nr_supported_ciphers=0 nr_curves=0 nr_ossl_curves=0 i j low high - local fs_ciphers curves_offered="" curves_to_test temp + local fs_ciphers curves_offered="" kems_offered="" curves_to_test temp local curves_option="" curves_list1="" curves_list2="" local len1 len2 curve_found sigalg_found local key_bitstring quality_str @@ -10719,7 +10749,7 @@ run_fs() { else ! "$fs_tls12_offered" && [[ "$(get_protocol "$TMPFILE")" == TLSv1.2 ]] && fs_tls12_offered=true fi - if "$WIDE"; then + if "$WIDE" && [[ ${kx[i]} == Kx=ECDH || ${kx[i]} == Kx=DH || ${kx[i]} == Kx=EDH ]]; then dhlen=$(read_dhbits_from_file "$TMPFILE" quiet) kx[i]="${kx[i]} $dhlen" fi @@ -10755,7 +10785,7 @@ run_fs() { fs_tls13_offered=true "$WIDE" && kx[i]="$(read_dhtype_from_file "$TEMPDIR/$NODEIP.parse_tls_serverhello.txt")" fi - if "$WIDE"; then + if "$WIDE" && [[ ${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 @@ -10819,7 +10849,7 @@ run_fs() { fi fi debugme echo $fs_offered - "$WIDE" || outln + outln fileout "${jsonID}_ciphers" "INFO" "$fs_ciphers" fi @@ -10930,12 +10960,21 @@ run_fs() { low=1000 for (( i=0; i < nr_curves; i++ )); do if "${supported_curve[i]}"; then - curves_offered+="${curves_ossl[i]} " - [[ ${curves_bits[i]} -lt $low ]] && low=${curves_bits[i]} + if [[ "${curves_ossl[i]}" =~ KEM ]] || [[ "${curves_ossl[i]}" =~ Kyber ]]; then + kems_offered+="${curves_ossl[i]} " + else + curves_offered+="${curves_ossl[i]} " + [[ ${curves_bits[i]} -lt $low ]] && low=${curves_bits[i]} + fi fi done + if [[ -n "$kems_offered" ]]; then + pr_bold " KEMs offered " + out_row_aligned_max_width_by_entry "$kems_offered" " " $TERM_WIDTH pr_kem_param_set_quality + outln + fileout "${jsonID}_KEMs" "OK" "$kems_offered" + fi if [[ -n "$curves_offered" ]]; then - "$WIDE" && outln pr_bold " Elliptic curves offered: " out_row_aligned_max_width_by_entry "$curves_offered" " " $TERM_WIDTH pr_ecdh_curve_quality outln @@ -14513,6 +14552,10 @@ parse_tls_serverhello() { "0102") echo -n "ffdhe4096" >> $TMPFILE ;; "0103") echo -n "ffdhe6144" >> $TMPFILE ;; "0104") echo -n "ffdhe8192" >> $TMPFILE ;; + "11EB") echo -n "SecP256r1MLKEM768" >> $TMPFILE ;; + "11EC") echo -n "X25519MLKEM768" >> $TMPFILE ;; + "11ED") echo -n "SecP384r1MLKEM1024" >> $TMPFILE ;; + "6399") echo -n "X25519Kyber768Draft00" >> $TMPFILE ;; *) echo -n "unknown (${tls_serverhello_ascii:offset:4})" >> $TMPFILE ;; esac offset=$((offset+4)) @@ -14608,6 +14651,10 @@ parse_tls_serverhello() { 258) dh_bits=4096 ; named_curve_str="ffdhe4096" ;; 259) dh_bits=6144 ; named_curve_str="ffdhe6144" ;; 260) dh_bits=8192 ; named_curve_str="ffdhe8192" ;; + 4587) dh_bits=192 ; named_curve_str="SecP256r1MLKEM768" ;; + 4588) dh_bits=192 ; named_curve_str="X25519MLKEM768" ;; + 4589) dh_bits=256 ; named_curve_str="SecP384r1MLKEM1024" ;; + 25497) dh_bits=128 ; named_curve_str="X25519Kyber768Draft00" ;; *) named_curve_str="" ; named_curve_oid="" ;; esac offset=$((extns_offset+20+i)) @@ -14795,9 +14842,9 @@ parse_tls_serverhello() { fi echo "Cipher : $rfc_cipher_suite" >> $TMPFILE if [[ $dh_bits -ne 0 ]]; then - if [[ "$named_curve_str" =~ "ffdhe" ]]; then + if [[ "$named_curve_str" =~ ffdhe ]]; then echo "Server Temp Key: DH, $named_curve_str, $dh_bits bits" >> $TMPFILE - elif [[ "$named_curve_str" == "X25519" ]] || [[ "$named_curve_str" == "X448" ]]; then + elif [[ "$named_curve_str" == X25519 ]] || [[ "$named_curve_str" == X448 ]] || [[ "$named_curve_str" =~ KEM ]] || [[ "$named_curve_str" =~ Kyber ]]; then echo "Server Temp Key: $named_curve_str, $dh_bits bits" >> $TMPFILE else echo "Server Temp Key: ECDH, $named_curve_str, $dh_bits bits" >> $TMPFILE @@ -14840,9 +14887,9 @@ parse_tls_serverhello() { echo "" fi if [[ $dh_bits -ne 0 ]]; then - if [[ "$named_curve_str" =~ "ffdhe" ]]; then + if [[ "$named_curve_str" =~ ffdhe ]]; then echo " dh_bits: DH, $named_curve_str, $dh_bits bits" - elif [[ "$named_curve_str" == "X25519" ]] || [[ "$named_curve_str" == "X448" ]]; then + elif [[ "$named_curve_str" == X25519 ]] || [[ "$named_curve_str" == X448 ]] || [[ "$named_curve_str" =~ KEM ]] || [[ "$named_curve_str" =~ Kyber ]]; then echo " dh_bits: $named_curve_str, $dh_bits bits" else echo " dh_bits: ECDH, $named_curve_str, $dh_bits bits" @@ -15631,7 +15678,15 @@ prepare_tls_clienthello() { 00, 01, 00, 02, 00, 03, 00, 0f, 00, 10, 00, 11, 01, 00, 01, 01" elif [[ 0x$tls_low_byte -gt 0x03 ]]; then # Supported Groups Extension - if [[ ! "$process_full" =~ all ]] || { "$HAS_X25519" && "$HAS_X448"; }; then + if [[ ! "$process_full" =~ all ]]; then + extension_supported_groups=" + 00,0a, # Type: Supported Groups, see RFC 8446 + 00,1e, 00,1c, # lengths + 00,1d, 00,17, 00,1e, 00,18, 00,19, 00,1f, 00,20, 00,21, + 01,00, 01,01, 11,eb, 11,ec, 11,ed, 63,99" + # Only include ML-KEM and Kyber hybrids as options if the response does + # not need to be decrypted. + elif [[ ! "$process_full" =~ all ]] || { "$HAS_X25519" && "$HAS_X448"; }; then extension_supported_groups=" 00,0a, # Type: Supported Groups, see RFC 8446 00,16, 00,14, # lengths @@ -15653,7 +15708,7 @@ prepare_tls_clienthello() { 00,1d, 00,17, 00,18, 00,19, 00,1f, 00,20, 00,21, 01,00, 01,01, 00,1e" # OpenSSL prior to 1.1.0 does not support either X25519 or X448, - # so list them as the least referred options if the response + # so list them as the least preferred options if the response # needs to be decrypted, and do not list them at all if the # response MUST be decrypted. elif [[ "$process_full" == all+ ]]; then From a85073bf0d5d98583697d5a83d1cc5958909e043 Mon Sep 17 00:00:00 2001 From: David Cooper Date: Tue, 21 Jan 2025 09:10:33 -0800 Subject: [PATCH 32/41] Fix checks for whether X25519 and X448 are supported In some cases OpenSSL returns an "unsupported" message rather than a "not found" message if X25519 and X448 are not supported. This commit changes the check for whether X5519 and X448 are supported for checking for either response. --- testssl.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/testssl.sh b/testssl.sh index 1a79340..5c4ddc9 100755 --- a/testssl.sh +++ b/testssl.sh @@ -20354,8 +20354,8 @@ find_openssl_binary() { $OPENSSL s_client -tls1_3 &1 | grep -aiq "unknown option" || HAS_TLS13=true $OPENSSL s_client -no_ssl2 &1 | grep -aiq "unknown option" || HAS_NO_SSL2=true - $OPENSSL genpkey -algorithm X448 2>&1 | grep -aq "not found" || HAS_X448=true - $OPENSSL genpkey -algorithm X25519 2>&1 | grep -aq "not found" || HAS_X25519=true + $OPENSSL genpkey -algorithm X448 2>&1 | grep -Eaq "not found|unsupported" || HAS_X448=true + $OPENSSL genpkey -algorithm X25519 2>&1 | grep -Eaq "not found|unsupported" || HAS_X25519=true $OPENSSL pkey -help 2>&1 | grep -q Error || HAS_PKEY=true $OPENSSL pkeyutl 2>&1 | grep -q Error || HAS_PKUTIL=true From a1c2dc7c72e60ef58afc376fff063d10bde77596 Mon Sep 17 00:00:00 2001 From: Dirk Date: Wed, 22 Jan 2025 19:19:16 +0100 Subject: [PATCH 33/41] Remove --nsa in help() and add --forward-secrecy instead Both are possible to use --- testssl.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testssl.sh b/testssl.sh index a80d13a..5b398d5 100755 --- a/testssl.sh +++ b/testssl.sh @@ -20685,7 +20685,7 @@ single check as ("$PROG_NAME URI" does everything except -E and -g): -e, --each-cipher checks each local cipher remotely -E, --cipher-per-proto checks those per protocol -s, --std, --categories tests standard cipher categories by strength - -f, --fs, --nsa checks forward secrecy settings + -f, --fs, --forward-secrecy checks forward secrecy settings -p, --protocols checks TLS/SSL protocols (including SPDY/HTTP2) -g, --grease tests several server implementation bugs like GREASE and size limitations -S, --server-defaults displays the server's default picks and certificate info From 12036fb6c8b4aa38ac3472464bc3c673f41d6d0f Mon Sep 17 00:00:00 2001 From: Dirk Date: Wed, 22 Jan 2025 19:54:34 +0100 Subject: [PATCH 34/41] Update baseline scan + add/deprecate security headers --- t/baseline_data/default_testssl.csvfile | 6 ++++-- testssl.sh | 10 ++++++++-- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/t/baseline_data/default_testssl.csvfile b/t/baseline_data/default_testssl.csvfile index 28118ba..bb91a05 100644 --- a/t/baseline_data/default_testssl.csvfile +++ b/t/baseline_data/default_testssl.csvfile @@ -70,7 +70,7 @@ "FS_TLS13_sig_algs","testssl.sh/81.169.166.184","443","INFO","RSA-PSS-RSAE+SHA256 RSA-PSS-RSAE+SHA384 RSA-PSS-RSAE+SHA512","","" "HTTP_status_code","testssl.sh/81.169.166.184","443","INFO","200 OK ('/')","","" "HTTP_clock_skew","testssl.sh/81.169.166.184","443","INFO","0 seconds from localtime","","" -"HTTP_headerTime","testssl.sh/81.169.166.184","443","INFO","1654006271","","" +"HTTP_headerTime","testssl.sh/81.169.166.184","443","INFO","1737570310","","" "HSTS_time","testssl.sh/81.169.166.184","443","OK","362 days (=31337000 seconds) > 15552000 seconds","","" "HSTS_subdomains","testssl.sh/81.169.166.184","443","INFO","only for this domain","","" "HSTS_preload","testssl.sh/81.169.166.184","443","INFO","domain is NOT marked for preloading","","" @@ -81,6 +81,8 @@ "X-Frame-Options","testssl.sh/81.169.166.184","443","OK","DENY","","" "X-Content-Type-Options","testssl.sh/81.169.166.184","443","OK","nosniff","","" "Content-Security-Policy","testssl.sh/81.169.166.184","443","OK","script-src 'unsafe-inline'; style-src 'unsafe-inline' 'self'; object-src 'self'; base-uri 'none'; form-action 'none'; img-src 'self' ; default-src 'self'; frame-ancestors 'self'; upgrade-insecure-requests;","","" +"Cross-Origin-Opener-Policy","testssl.sh/81.169.166.184","443","INFO","same-origin-allow-popups","","" +"Cross-Origin-Resource-Policy","testssl.sh/81.169.166.184","443","INFO","same-site","","" "banner_reverseproxy","testssl.sh/81.169.166.184","443","INFO","--","","CWE-200" "heartbleed","testssl.sh/81.169.166.184","443","OK","not vulnerable, no heartbeat extension","CVE-2014-0160","CWE-119" "CCS","testssl.sh/81.169.166.184","443","OK","not vulnerable","CVE-2014-0224","CWE-310" @@ -95,7 +97,7 @@ "SWEET32","testssl.sh/81.169.166.184","443","OK","not vulnerable","CVE-2016-2183 CVE-2016-6329","CWE-327" "FREAK","testssl.sh/81.169.166.184","443","OK","not vulnerable","CVE-2015-0204","CWE-310" "DROWN","testssl.sh/81.169.166.184","443","OK","not vulnerable on this host and port","CVE-2016-0800 CVE-2016-0703","CWE-310" -"DROWN_hint","testssl.sh/81.169.166.184","443","INFO","Make sure you don't use this certificate elsewhere with SSLv2 enabled services, see https://search.censys.io/search?resource=hosts&virtual_hosts=INCLUDE&q=31B44391529821C6A77F3C78B02D716A07F99B8FDB342BF5A78F263C25375968","CVE-2016-0800 CVE-2016-0703","CWE-310" +"DROWN_hint","testssl.sh/81.169.166.184","443","INFO","Make sure you don't use this certificate elsewhere with SSLv2 enabled services, see https://search.censys.io/search?resource=hosts&virtual_hosts=INCLUDE&q=5B4BC205947AED96ECB1879F2668F7F69D696C143BA8D1C69DBB4DC873C92AE9","CVE-2016-0800 CVE-2016-0703","CWE-310" "LOGJAM","testssl.sh/81.169.166.184","443","OK","not vulnerable, no DH EXPORT ciphers,","CVE-2015-4000","CWE-310" "LOGJAM-common_primes","testssl.sh/81.169.166.184","443","OK","--","CVE-2015-4000","CWE-310" "BEAST_CBC_TLS1","testssl.sh/81.169.166.184","443","MEDIUM","ECDHE-RSA-AES256-SHA ECDHE-RSA-AES128-SHA DHE-RSA-CAMELLIA256-SHA DHE-RSA-CAMELLIA128-SHA DHE-RSA-AES256-SHA DHE-RSA-AES128-SHA AES256-SHA","CVE-2011-3389","CWE-20" diff --git a/testssl.sh b/testssl.sh index 188de3b..6474414 100755 --- a/testssl.sh +++ b/testssl.sh @@ -3127,11 +3127,13 @@ emphasize_stuff_in_headers(){ -e "s/X-Powered-By/${yellow}X-Powered-By${off}/g" \ -e "s/X-UA-Compatible/${yellow}X-UA-Compatible${off}/g" \ -e "s/Link/${yellow}Link${off}/g" \ + -e "s/X-DNS-Prefetch-Control/${html_yellow}X-DNS-Prefetch-Control${html_off}/g" \ -e "s/X-Rack-Cache/${yellow}X-Rack-Cache${off}/g" \ -e "s/X-Runtime/${yellow}X-Runtime${off}/g" \ -e "s/X-Pingback/${yellow}X-Pingback${off}/g" \ -e "s/X-Permitted-Cross-Domain-Policies/${yellow}X-Permitted-Cross-Domain-Policies${off}/g" \ -e "s/X-AspNet-Version/${yellow}X-AspNet-Version${off}/g" \ + -e "s/X-AspNetMvc-Version/${yellow}X-AspNetMvc-Version${off}/g" \ -e "s/x-note/${yellow}x-note${off}/g" \ -e "s/x-global-transaction-id/${yellow}x-global-transaction-id${off}/g" \ -e "s/X-Global-Transaction-ID/${yellow}X-Global-Transaction-ID${off}/g" \ @@ -3177,9 +3179,11 @@ emphasize_stuff_in_headers(){ -e "s/Link/${html_yellow}Link${html_off}/g" \ -e "s/X-Runtime/${html_yellow}X-Runtime${html_off}/g" \ -e "s/X-Rack-Cache/${html_yellow}X-Rack-Cache${html_off}/g" \ + -e "s/X-DNS-Prefetch-Control/${html_yellow}X-DNS-Prefetch-Control${html_off}/g" \ -e "s/X-Pingback/${html_yellow}X-Pingback${html_off}/g" \ -e "s/X-Permitted-Cross-Domain-Policies/${html_yellow}X-Permitted-Cross-Domain-Policies${html_off}/g" \ - -e "s/X-AspNet-Version/${html_yellow}X-AspNet-Version${html_off}/g")" \ + -e "s/X-AspNet-Version/${html_yellow}X-AspNet-Version${html_off}/g" \ + -e "s/X-AspNetMvc-Version/${yellow}X-AspNetMvc-Version${off}/g" \ -e "s/x-note/${html_yellow}x-note${html_off}/g" \ -e "s/X-Global-Transaction-ID/${html_yellow}X-Global-Transaction-ID${html_off}/g" \ -e "s/x-global-transaction-id/${html_yellow}x-global-transaction-id${html_off}/g" \ @@ -3435,13 +3439,14 @@ run_security_headers() { pr_bold " Security headers " # X-XSS-Protection is useless and at worst harmful, see https://news.ycombinator.com/item?id=20472947 + # Expect-CT is depecated, see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Expect-CT for header_and_svrty in "X-Frame-Options OK" \ "X-Content-Type-Options OK" \ "Content-Security-Policy OK" \ "X-Content-Security-Policy INFO" \ "X-WebKit-CSP INFO" \ "Content-Security-Policy-Report-Only OK" \ - "Expect-CT OK" \ + "Expect-CT INFO" \ "Permissions-Policy OK" \ "Cross-Origin-Opener-Policy INFO" \ "Cross-Origin-Resource-Policy INFO" \ @@ -3449,6 +3454,7 @@ run_security_headers() { "X-XSS-Protection INFO" \ "Access-Control-Allow-Origin INFO" \ "Access-Control-Allow-Credentials INFO" \ + "Permissions-Policy INFO" \ "Upgrade INFO" \ "X-Served-By INFO" \ "Referrer-Policy INFO" \ From ad912ea332943630bc8912382cc8afbe44010918 Mon Sep 17 00:00:00 2001 From: Dirk Date: Wed, 22 Jan 2025 20:05:19 +0100 Subject: [PATCH 35/41] Fix typo + tags --- testssl.sh | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/testssl.sh b/testssl.sh index 6474414..02a2ac8 100755 --- a/testssl.sh +++ b/testssl.sh @@ -3127,7 +3127,7 @@ emphasize_stuff_in_headers(){ -e "s/X-Powered-By/${yellow}X-Powered-By${off}/g" \ -e "s/X-UA-Compatible/${yellow}X-UA-Compatible${off}/g" \ -e "s/Link/${yellow}Link${off}/g" \ - -e "s/X-DNS-Prefetch-Control/${html_yellow}X-DNS-Prefetch-Control${html_off}/g" \ + -e "s/X-DNS-Prefetch-Control/${yellow}X-DNS-Prefetch-Control${off}/g" \ -e "s/X-Rack-Cache/${yellow}X-Rack-Cache${off}/g" \ -e "s/X-Runtime/${yellow}X-Runtime${off}/g" \ -e "s/X-Pingback/${yellow}X-Pingback${off}/g" \ @@ -3183,14 +3183,13 @@ emphasize_stuff_in_headers(){ -e "s/X-Pingback/${html_yellow}X-Pingback${html_off}/g" \ -e "s/X-Permitted-Cross-Domain-Policies/${html_yellow}X-Permitted-Cross-Domain-Policies${html_off}/g" \ -e "s/X-AspNet-Version/${html_yellow}X-AspNet-Version${html_off}/g" \ - -e "s/X-AspNetMvc-Version/${yellow}X-AspNetMvc-Version${off}/g" \ + -e "s/X-AspNetMvc-Version/${html_yellow}X-AspNetMvc-Version${html_off}/g" \ -e "s/x-note/${html_yellow}x-note${html_off}/g" \ -e "s/X-Global-Transaction-ID/${html_yellow}X-Global-Transaction-ID${html_off}/g" \ -e "s/x-global-transaction-id/${html_yellow}x-global-transaction-id${html_off}/g" \ -e "s/Alt-Svc/${html_yellow}Alt-Svc${html_off}/g" \ -e "s/system-wsgw-management-loopback/${html_yellow}system-wsgw-management-loopback${html_off}/g" -#FIXME: this is double code. The pattern to emphasize would fit better into -# one function. +#FIXME: this is double code. The pattern to emphasize would fit better into one function. # Also we need another function like run_other_header as otherwise "Link" "Alt-Svc" will never be found. # And: I matches case sensitive only which might not detect all banners. (sed ignorecase is not possible w/ BSD sed) else @@ -3439,7 +3438,7 @@ run_security_headers() { pr_bold " Security headers " # X-XSS-Protection is useless and at worst harmful, see https://news.ycombinator.com/item?id=20472947 - # Expect-CT is depecated, see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Expect-CT + # Expect-CT is deprecated, see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Expect-CT for header_and_svrty in "X-Frame-Options OK" \ "X-Content-Type-Options OK" \ "Content-Security-Policy OK" \ From 4df0d9e4c343a673cce01d40f413fb92e1af1068 Mon Sep 17 00:00:00 2001 From: Dirk Date: Wed, 22 Jan 2025 23:32:39 +0100 Subject: [PATCH 36/41] Re-added the ) to make the action word (why??) --- testssl.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testssl.sh b/testssl.sh index 6bb8c26..0672297 100755 --- a/testssl.sh +++ b/testssl.sh @@ -3182,7 +3182,7 @@ emphasize_stuff_in_headers(){ -e "s/X-DNS-Prefetch-Control/${html_yellow}X-DNS-Prefetch-Control${html_off}/g" \ -e "s/X-Pingback/${html_yellow}X-Pingback${html_off}/g" \ -e "s/X-Permitted-Cross-Domain-Policies/${html_yellow}X-Permitted-Cross-Domain-Policies${html_off}/g" \ - -e "s/X-AspNet-Version/${html_yellow}X-AspNet-Version${html_off}/g" \ + -e "s/X-AspNet-Version/${html_yellow}X-AspNet-Version${html_off}/g")" \ -e "s/X-AspNetMvc-Version/${html_yellow}X-AspNetMvc-Version${html_off}/g" \ -e "s/x-note/${html_yellow}x-note${html_off}/g" \ -e "s/X-Global-Transaction-ID/${html_yellow}X-Global-Transaction-ID${html_off}/g" \ From d7da22d598084b66546bf8ff32ff2471c94c8b1f Mon Sep 17 00:00:00 2001 From: Dirk Date: Wed, 22 Jan 2025 23:33:35 +0100 Subject: [PATCH 37/41] Finalize check * use system with @args so that we can query the return value * code style improved for readability * diff shows the filtered difference * ok instead of cmp_ok to show not the whole content of vars --- t/61_diff_testsslsh.t | 56 +++++++++++++++++++++---------------------- 1 file changed, 27 insertions(+), 29 deletions(-) diff --git a/t/61_diff_testsslsh.t b/t/61_diff_testsslsh.t index f4070b1..18c3bfb 100755 --- a/t/61_diff_testsslsh.t +++ b/t/61_diff_testsslsh.t @@ -3,11 +3,10 @@ # Baseline diff test against testssl.sh (csv output) # # We don't use a full run yet and only the certificate section. -# There we would need to blacklist at least: +# There we would need to blacklist more, like: # cert_serialNumber, cert_fingerprintSHA1, cert_fingerprintSHA256, cert # cert_expirationStatus, cert_notBefore, cert_notAfter, cert_caIssuers, intermediate_cert # -# help is appreciated here use strict; use Test::More; @@ -16,55 +15,54 @@ use Text::Diff; my $tests = 0; my $prg="./testssl.sh"; -my $master_socket_csv="./t/baseline_data/default_testssl.csvfile"; -my $socket_csv="tmp.csv"; -my $check2run="-p -s -P --fs -h -U -c -q --ip=one --color 0 --csvfile $socket_csv"; -#my $check2run="-p --color 0 --csvfile $socket_csv"; +my $baseline_csv="./t/baseline_data/default_testssl.csvfile"; +my $cat_csv="tmp.csv"; +my $check2run="-p -s -P --fs -h -U -c -q --ip=one --color 0 --csvfile $cat_csv"; my $uri="testssl.sh"; my $diff=""; die "Unable to open $prg" unless -f $prg; -die "Unable to open $master_socket_csv" unless -f $master_socket_csv; - +die "Unable to open $baseline_csv" unless -f $baseline_csv; # Provide proper start conditions -unlink "tmp.csv"; +unlink $cat_csv; -# Title -printf "\n%s\n", "Diff unit test IPv4 against \"$uri\""; +my @args=("$prg", "$check2run", "$uri", "2>&1"); #1 run -`$prg $check2run $uri 2>&1`; +printf "\n%s\n", "Diff unit test (IPv4) against \"$uri\""; +printf "@args\n"; +system("@args") == 0 + or die ("FAILED: \"@args\" "); -$diff = diff $socket_csv, $master_socket_csv; - -$socket_csv=`cat tmp.csv`; -$master_socket_csv=`cat $master_socket_csv`; +$cat_csv=`cat $cat_csv`; +$baseline_csv=`cat $baseline_csv`; # Filter for changes that are allowed to occur -$socket_csv=~ s/HTTP_clock_skew.*\n//g; -$master_socket_csv=~ s/HTTP_clock_skew.*\n//g; - -# DROWN -$socket_csv=~ s/censys.io.*\n//g; -$master_socket_csv=~ s/censys.io.*\n//g; +$cat_csv =~ s/HTTP_clock_skew.*\n//g; +$baseline_csv =~ s/HTTP_clock_skew.*\n//g; # HTTP time -$socket_csv=~ s/HTTP_headerTime.*\n//g; -$master_socket_csv=~ s/HTTP_headerTime.*\n//g; +$cat_csv =~ s/HTTP_headerTime.*\n//g; +$baseline_csv =~ s/HTTP_headerTime.*\n//g; -# Compare the differences to the master file -- and print differences if there were detected. +# DROWN +$cat_csv =~ s/censys.io.*\n//g; +$baseline_csv =~ s/censys.io.*\n//g; + +$diff = diff \$cat_csv, \$baseline_csv; + +# Compare the differences to the baseline file -- and print differences if there were detected. # -cmp_ok($socket_csv, "eq", $master_socket_csv, "Check whether CSV output matches master file from $uri") or +ok($cat_csv eq $baseline_csv, "Check whether CSV output matches baseline file from $uri") or diag ("\n%s\n", "$diff"); -$tests++; - unlink "tmp.csv"; +$tests++; done_testing($tests); printf "\n"; -# vim:ts=5:sw=5:expandtab +# vim:ts=5:sw=5:expandtab From fb3921cd1b2c9e392e9ff76ae349d05042624c04 Mon Sep 17 00:00:00 2001 From: Hyeonho Kang Date: Thu, 23 Jan 2025 13:10:12 +0900 Subject: [PATCH 38/41] Edit CONTRIBUTING.md --- CONTRIBUTING.md | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index eb9098e..5301665 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,21 +1,16 @@ -### Contribution +### Contributing / participating -Contribution is always welcome, submit here (GitHub) or via e-mail. +Contributing / participating is always welcome! Please note the following: * Please read at least the [coding convention](https://github.com/testssl/testssl.sh/blob/3.2/Coding_Convention.md). -* One Pull Request per feature or bug fix or improvement. Please do not mix issues. -* Document your Pull Request, both in the Pull Request and/or commit message and in the code. +* One pull request per feature or bug fix or improvement. Please do not mix issues. +* Document your pull request, both in the pull request and/or commit message and in the code. * Please test your changes thoroughly as reliability is important for this project. You may want to check different servers with different settings. -* Travis runs automatically when anything is committed/pull requested. You should check any complains from Travis. Beforehand you can check with `prove -v`. +* GitHub Actions runs automatically when anything is committed. You should check any complains from GitHub Actions. Beforehand you can check with `prove -v`. * If it's a new feature, please consider writing a unit test for it. You can use e.g. `t/20_baseline_ipv4_http.t` as a template. The general documentation for [Test::More](https://perldoc.perl.org/Test/More.html) is a good start. * If it's a new feature, it would need to be documented in the appropriate section in `help()` and in `~/doc/testssl.1.md` -For the questions, just open an issue or feel free to send us an e-mail. - -#### Contribute via e-mail - -Of course it is fine when you want to send in patches to use e-mail. For the address, please grep for SWCONTACT in testssl.sh. -Let me know how you like them to be attributed. +For the questions, just open an issue. From 4efe324ef7ac4b5d72e05035da4e95b385ec794e Mon Sep 17 00:00:00 2001 From: Dirk Wetter Date: Thu, 23 Jan 2025 10:45:15 +0100 Subject: [PATCH 39/41] Fix round bracket and remove obsolete comment --- testssl.sh | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/testssl.sh b/testssl.sh index 0672297..5655670 100755 --- a/testssl.sh +++ b/testssl.sh @@ -582,8 +582,6 @@ tmln_out() { printf -- "%b" "$1\n"; } out() { printf -- "%b" "$1"; html_out "$(html_reserved "$1")"; } outln() { printf -- "%b" "$1\n"; html_out "$(html_reserved "$1")\n"; } -#TODO: Still no shell injection safe but if just run it from the cmd line: that's fine - # Color print functions, see also https://www.tldp.org/HOWTO/Bash-Prompt-HOWTO/x329.html tm_liteblue() { [[ "$COLOR" -ge 2 ]] && { "$COLORBLIND" && tm_out "\033[0;32m$1" || tm_out "\033[0;34m$1"; } || tm_out "$1"; tm_off; } # not yet used pr_liteblue() { tm_liteblue "$1"; [[ "$COLOR" -ge 2 ]] && { "$COLORBLIND" && html_out "$(html_reserved "$1")" || html_out "$(html_reserved "$1")"; } || html_out "$(html_reserved "$1")"; } @@ -3143,7 +3141,7 @@ emphasize_stuff_in_headers(){ if "$do_html"; then if [[ $COLOR -ge 2 ]]; then html_out "$(tm_out "$1" | sed -e 's/\&/\&/g' \ - -e 's//\>/g' -e 's/"/\"/g' -e "s/'/\'/g" \ + -e 's//\>/g' -e 's/\"/\"/g' -e "s/\'/\'/g" \ -e "s/\([0-9]\)/${html_brown}\1${html_off}/g" \ -e "s/Unix/${html_yellow}Unix${html_off}/g" \ -e "s/Debian/${html_yellow}Debian${html_off}/g" \ @@ -3182,16 +3180,16 @@ emphasize_stuff_in_headers(){ -e "s/X-DNS-Prefetch-Control/${html_yellow}X-DNS-Prefetch-Control${html_off}/g" \ -e "s/X-Pingback/${html_yellow}X-Pingback${html_off}/g" \ -e "s/X-Permitted-Cross-Domain-Policies/${html_yellow}X-Permitted-Cross-Domain-Policies${html_off}/g" \ - -e "s/X-AspNet-Version/${html_yellow}X-AspNet-Version${html_off}/g")" \ + -e "s/X-AspNet-Version/${html_yellow}X-AspNet-Version${html_off}/g" \ -e "s/X-AspNetMvc-Version/${html_yellow}X-AspNetMvc-Version${html_off}/g" \ -e "s/x-note/${html_yellow}x-note${html_off}/g" \ -e "s/X-Global-Transaction-ID/${html_yellow}X-Global-Transaction-ID${html_off}/g" \ -e "s/x-global-transaction-id/${html_yellow}x-global-transaction-id${html_off}/g" \ -e "s/Alt-Svc/${html_yellow}Alt-Svc${html_off}/g" \ - -e "s/system-wsgw-management-loopback/${html_yellow}system-wsgw-management-loopback${html_off}/g" -#FIXME: this is double code. The pattern to emphasize would fit better into one function. -# Also we need another function like run_other_header as otherwise "Link" "Alt-Svc" will never be found. -# And: I matches case sensitive only which might not detect all banners. (sed ignorecase is not possible w/ BSD sed) + -e "s/system-wsgw-management-loopback/${html_yellow}system-wsgw-management-loopback${html_off}/g" \ + )" +#FIXME: this is double code. The pattern to emphasize headers should be better in one single function +# And: It matches case sensitive headers only which won't detect all banners. (sed ignorecase is not a/v for OpenBSD sed) else html_out "$(html_reserved "$1")" fi From 90f1e59e9f021b5bc687cb6cfb0ac2bbdff721f7 Mon Sep 17 00:00:00 2001 From: Dirk Date: Thu, 23 Jan 2025 17:37:32 +0100 Subject: [PATCH 40/41] Merge #2618 and doing some overdue amendments --- CONTRIBUTING.md | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 5301665..9fd3cbe 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -5,12 +5,21 @@ Contributing / participating is always welcome! Please note the following: -* Please read at least the [coding convention](https://github.com/testssl/testssl.sh/blob/3.2/Coding_Convention.md). -* One pull request per feature or bug fix or improvement. Please do not mix issues. -* Document your pull request, both in the pull request and/or commit message and in the code. +* Please read the [coding convention](https://github.com/testssl/testssl.sh/blob/3.2/Coding_Convention.md). +* If you have something new and/or bigger which you like to contribute, better open an issue first before you get frustrated. +* Please one pull request per feature or bug fix or improvement. Please do not mix issues. +* Documention pays off in the long run. So please your document your code and the pull request and/or commit message. * Please test your changes thoroughly as reliability is important for this project. You may want to check different servers with different settings. -* GitHub Actions runs automatically when anything is committed. You should check any complains from GitHub Actions. Beforehand you can check with `prove -v`. -* If it's a new feature, please consider writing a unit test for it. You can use e.g. `t/20_baseline_ipv4_http.t` as a template. The general documentation for [Test::More](https://perldoc.perl.org/Test/More.html) is a good start. +* GitHub actions are running automatically when anything is committed. You should see any complains. Beforehand you can check with `prove -v` from the "root dir"of tjhis project +* If it's a new feature, please consider writing a unit test for it. You can use e.g. `t/10_baseline_ipv4_http.t` or `t/61_diff_testsslsh.t` as a template. The general documentation for [Test::More](https://perldoc.perl.org/Test/More.html) is a good start. * If it's a new feature, it would need to be documented in the appropriate section in `help()` and in `~/doc/testssl.1.md` -For the questions, just open an issue. +If you're interested in contributing and wonder how you can help, you can search for different tags in the issues (somehwat increasing degree of difficulty): +* [documentation](https://github.com/testssl/testssl.sh/issues?q=is:issue%20state:open%20label:documentation) +* [good first issue](https://github.com/testssl/testssl.sh/issues?q=is:issue%20state:open%20label:%22good%20first%20issue%22) +* [help wanted](https://github.com/testssl/testssl.sh/issues?q=is:issue%20state:open%20label:%22help%20wanted%22) +* [for grabs](https://github.com/testssl/testssl.sh/issues?q=is:issue%20state:open%20label:%22good%20first%20issue%22) + +For questions just open an issue. Thanks for reading this! + + From b185b1bea96aec23d922beff84cf00b0e352309d Mon Sep 17 00:00:00 2001 From: Dirk Date: Thu, 23 Jan 2025 17:41:36 +0100 Subject: [PATCH 41/41] Fix typo --- CONTRIBUTING.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 9fd3cbe..1029fbe 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -8,13 +8,13 @@ Please note the following: * Please read the [coding convention](https://github.com/testssl/testssl.sh/blob/3.2/Coding_Convention.md). * If you have something new and/or bigger which you like to contribute, better open an issue first before you get frustrated. * Please one pull request per feature or bug fix or improvement. Please do not mix issues. -* Documention pays off in the long run. So please your document your code and the pull request and/or commit message. +* Documentation pays off in the long run. So please your document your code and the pull request and/or commit message. * Please test your changes thoroughly as reliability is important for this project. You may want to check different servers with different settings. -* GitHub actions are running automatically when anything is committed. You should see any complains. Beforehand you can check with `prove -v` from the "root dir"of tjhis project +* GitHub actions are running automatically when anything is committed. You should see any complains. Beforehand you can check with `prove -v` from the "root dir" of this project. * If it's a new feature, please consider writing a unit test for it. You can use e.g. `t/10_baseline_ipv4_http.t` or `t/61_diff_testsslsh.t` as a template. The general documentation for [Test::More](https://perldoc.perl.org/Test/More.html) is a good start. * If it's a new feature, it would need to be documented in the appropriate section in `help()` and in `~/doc/testssl.1.md` -If you're interested in contributing and wonder how you can help, you can search for different tags in the issues (somehwat increasing degree of difficulty): +If you're interested in contributing and wonder how you can help, you can search for different tags in the issues (somewhat increasing degree of difficulty): * [documentation](https://github.com/testssl/testssl.sh/issues?q=is:issue%20state:open%20label:documentation) * [good first issue](https://github.com/testssl/testssl.sh/issues?q=is:issue%20state:open%20label:%22good%20first%20issue%22) * [help wanted](https://github.com/testssl/testssl.sh/issues?q=is:issue%20state:open%20label:%22help%20wanted%22)