From becd310390ea23cca414f5b7e7bb88cf7e2a7afd Mon Sep 17 00:00:00 2001 From: Dirk Date: Fri, 6 Sep 2024 12:47:03 +0200 Subject: [PATCH 01/78] Address open UI problems for TLS 1.3 only hosts While in 3.2 there was only a hint how to deal with TLS 1.3 only hosts, a restart with --openssl=/usr/bin/openssl or setting of OSSL_SHORTCUT-true was required. This PR changes the behavior: if an openssl version can be found in /usr/bin/openssl (or SUPPLIED via OPENSSL2=/home/version/ofopenssl testssl ) which supports TLS 1.3 it switches automatically and informs the user that it has done so. This message is asynchonous and is implemented with a new function check_msg() and a global OPEN_MSG, so that we maintain the formatting. Otherwise it would have appeared between rDNS and service detection. Now it's nicely after service detection. --- testssl.sh | 62 ++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 42 insertions(+), 20 deletions(-) diff --git a/testssl.sh b/testssl.sh index cc824a8..e7e6bd8 100755 --- a/testssl.sh +++ b/testssl.sh @@ -243,9 +243,10 @@ SYSTEM2="" # currently only being used for WSL = ba PRINTF="" # which external printf to use. Empty presets the internal one, see #1130 CIPHERS_BY_STRENGTH_FILE="" TLS_DATA_FILE="" # mandatory file for socket-based handshakes -OPENSSL="" # If you run this from GitHub it's ~/bin/openssl.$(uname).$(uname -m) otherwise /usr/bin/openssl -OPENSSL2="" # When running from GitHub, this will be openssl version >=1.1.1 (auto determined) -OPENSSL2_HAS_TLS_1_3=false # If we run with supplied binary AND /usr/bin/openssl supports TLS 1.3 this is set to true +OPENSSL="" # ~/bin/openssl.$(uname).$(uname -m) if you run this from GitHub. Linux otherwise probably /usr/bin/openssl +OPENSSL2=${OPENSSL2:-/usr/bin/openssl} # This will be openssl version >=1.1.1 (auto determined) as opposed to openssl-bad (OPENSSL) +OPENSSL2_HAS_TLS_1_3=false # If we run with supplied binary AND $OPENSSL2 supports TLS 1.3 this wil be set to true +OSSL_SHORTCUT=${OSSL_SHORTCUT:-true} # Hack: if during the scan turns out the OpenSSL binary supports TLS 1.3 would be a better choice OPENSSL_LOCATION="" IKNOW_FNAME=false FIRST_FINDING=true # is this the first finding we are outputting to file? @@ -275,7 +276,6 @@ KNOWN_OSSL_PROB=false # We need OpenSSL a few times. This vari DETECTED_TLS_VERSION="" # .. as hex string, e.g. 0300 or 0303 APP_TRAF_KEY_INFO="" # Information about the application traffic keys for a TLS 1.3 connection. TLS13_ONLY=false # Does the server support TLS 1.3 ONLY? -OSSL_SHORTCUT=${OSSL_SHORTCUT:-false} # Hack: if during the scan turns out the OpenSSL binary supports TLS 1.3 would be a better choice, this enables it. TLS_EXTENSIONS="" TLS13_CERT_COMPRESS_METHODS="" CERTIFICATE_TRANSPARENCY_SOURCE="" @@ -415,6 +415,7 @@ END_TIME=0 # .. ended SCAN_TIME=0 # diff of both: total scan time LAST_TIME=0 # only used for performance measurements (MEASURE_TIME=true) SERVER_COUNTER=0 # Counter for multiple servers +OPEN_MSG="" # Null the poor man's implementation of a message stack TLS_LOW_BYTE="" # For "secret" development stuff, see -q below HEX_CIPHER="" # -- " -- @@ -20297,7 +20298,7 @@ find_openssl_binary() { # not check /usr/bin/openssl -- if available. This is more a kludge which we shouldn't use for # every openssl feature. At some point we need to decide which with openssl version we go. # We also check, whether there's /usr/bin/openssl which has TLS 1.3 - OPENSSL2=/usr/bin/openssl + OPENSSL2=${OPENSSL2:-/usr/bin/openssl} if [[ ! "$OSSL_NAME" =~ LibreSSL ]] && [[ ! $OSSL_VER =~ 1.1.1 ]] && [[ ! $OSSL_VER_MAJOR =~ 3 ]]; then if [[ -x $OPENSSL2 ]]; then $OPENSSL2 s_client -help 2>$s_client_has2 @@ -21015,6 +21016,9 @@ EOF # arg1: text to display before "-->" # arg2: arg needed to accept to continue +# ret=0 : arg was acceppted to continue (batch mode doesn't do this,or warnings are turned off) +# 1 : arg was not acceppted by user or we're in bacth mode + ignore_no_or_lame() { local a @@ -22033,21 +22037,26 @@ determine_optimal_proto() { [[ $? -ne 0 ]] && exit $ERR_CLUELESS elif "$all_failed" && ! "$ALL_FAILED_SOCKETS"; then if ! "$HAS_TLS13" && "$TLS13_ONLY"; then - pr_magenta " $NODE:$PORT appears to support TLS 1.3 ONLY. You better use --openssl=" - if ! "$OSSL_SHORTCUT" || [[ ! -x /usr/bin/openssl ]] || /usr/bin/openssl s_client -tls1_3 2>&1 | grep -aiq "unknown option"; then - outln - fileout "$jsonID" "WARN" "$NODE:$PORT appears to support TLS 1.3 ONLY, but $OPENSSL does not support TLS 1.3" - ignore_no_or_lame " Type \"yes\" to proceed with $OPENSSL and accept all scan problems" "yes" - [[ $? -ne 0 ]] && exit $ERR_CLUELESS - MAX_OSSL_FAIL=10 - else - # dirty hack but an idea for the future to be implemented upfront: Now we know, we'll better off - # with the OS supplied openssl binary. We need to initialize variables / arrays again though. - # And the service detection can't be made up for now - outln ", \n proceeding with /usr/bin/openssl" - OPENSSL=/usr/bin/openssl - find_openssl_binary - prepare_arrays + if "$OPENSSL2_HAS_TLS_1_3"; then + if "$OSSL_SHORTCUT" || [[ "$WARNINGS" == batch ]]; then + # switch w/o asking + OPEN_MSG=" $NODE:$PORT appeared to support TLS 1.3 ONLY. Thus switched implictly from\n \"$OPENSSL\" to \"$OPENSSL2\"." + fileout "$jsonID" "INFO" "$NODE:$PORT appears to support TLS 1.3 ONLY, switching from $OPENSSL to $OPENSSL2 was implictly enforced" + OPENSSL="$OPENSSL2" + find_openssl_binary + prepare_arrays + else + # now we need to ask the user + ignore_no_or_lame " Type \"yes\" to proceed with \"$OPENSSL2\" OR accept all scan problems" "yes" + if [[ $? -eq 0 ]]; then + fileout "$jsonID" "INFO" "$NODE:$PORT appears to support TLS 1.3 ONLY, switching from $OPENSSL to $OPENSSL2 by the user" + OPENSSL="$OPENSSL2" + find_openssl_binary + prepare_arrays + else + fileout "$jsonID" "WARN" "$NODE:$PORT appears to support TLS 1.3 ONLY, switching from $OPENSSL to $OPENSSL2 was denied by user" + fi + fi fi elif ! "$HAS_SSL3" && [[ "$(has_server_protocol "ssl3")" -eq 0 ]] && [[ "$(has_server_protocol "tls1_3")" -ne 0 ]] && \ [[ "$(has_server_protocol "tls1_2")" -ne 0 ]] && [[ "$(has_server_protocol "tls1_1")" -ne 0 ]] && @@ -22092,6 +22101,18 @@ determine_optimal_proto() { } +# Check messages which needed to be processed. I.e. those which would have destroyed the nice +# screen output and thus havve been postponed. This is just an idea and is only used once +# but can be extended in the future. An array migh be more handy +# +check_msg() { + if [[ -n "$OPEN_MSG" ]]; then + outln "$OPEN_MSG" + OPEN_MSG="" + fi +} + + # arg1 (optional): ftp smtp, lmtp, pop3, imap, sieve, xmpp, xmpp-server, telnet, ldap, postgres, mysql, irc, nntp (maybe with trailing s) # determine_service() { @@ -22132,6 +22153,7 @@ determine_service() { determine_optimal_proto # returns always 0: service_detection $OPTIMAL_PROTO + check_msg else # STARTTLS if [[ "$1" == postgres ]] || [[ "$1" == sieve ]]; then protocol="$1" From 12bc15adc39fa20243c013d2523098c597770bd9 Mon Sep 17 00:00:00 2001 From: Dirk Date: Fri, 6 Sep 2024 12:53:00 +0200 Subject: [PATCH 02/78] misc - remove 1xLF in UI - fix obsolete statment for OPENSSL2 --- testssl.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/testssl.sh b/testssl.sh index e7e6bd8..d0200a2 100755 --- a/testssl.sh +++ b/testssl.sh @@ -2406,7 +2406,7 @@ service_detection() { ;; esac - outln "\n" + outln tmpfile_handle ${FUNCNAME[0]}.txt return 0 } @@ -20298,7 +20298,6 @@ find_openssl_binary() { # not check /usr/bin/openssl -- if available. This is more a kludge which we shouldn't use for # every openssl feature. At some point we need to decide which with openssl version we go. # We also check, whether there's /usr/bin/openssl which has TLS 1.3 - OPENSSL2=${OPENSSL2:-/usr/bin/openssl} if [[ ! "$OSSL_NAME" =~ LibreSSL ]] && [[ ! $OSSL_VER =~ 1.1.1 ]] && [[ ! $OSSL_VER_MAJOR =~ 3 ]]; then if [[ -x $OPENSSL2 ]]; then $OPENSSL2 s_client -help 2>$s_client_has2 From 3d2bd5020cd49d280fcb960fc95cef5cb20d2e1a Mon Sep 17 00:00:00 2001 From: Dirk Date: Fri, 6 Sep 2024 13:00:27 +0200 Subject: [PATCH 03/78] fix spellcheck --- testssl.sh | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/testssl.sh b/testssl.sh index d0200a2..f25f30f 100755 --- a/testssl.sh +++ b/testssl.sh @@ -245,7 +245,7 @@ CIPHERS_BY_STRENGTH_FILE="" TLS_DATA_FILE="" # mandatory file for socket-based handshakes OPENSSL="" # ~/bin/openssl.$(uname).$(uname -m) if you run this from GitHub. Linux otherwise probably /usr/bin/openssl OPENSSL2=${OPENSSL2:-/usr/bin/openssl} # This will be openssl version >=1.1.1 (auto determined) as opposed to openssl-bad (OPENSSL) -OPENSSL2_HAS_TLS_1_3=false # If we run with supplied binary AND $OPENSSL2 supports TLS 1.3 this wil be set to true +OPENSSL2_HAS_TLS_1_3=false # If we run with supplied binary AND $OPENSSL2 supports TLS 1.3 this will be set to true OSSL_SHORTCUT=${OSSL_SHORTCUT:-true} # Hack: if during the scan turns out the OpenSSL binary supports TLS 1.3 would be a better choice OPENSSL_LOCATION="" IKNOW_FNAME=false @@ -21015,8 +21015,8 @@ EOF # arg1: text to display before "-->" # arg2: arg needed to accept to continue -# ret=0 : arg was acceppted to continue (batch mode doesn't do this,or warnings are turned off) -# 1 : arg was not acceppted by user or we're in bacth mode +# ret=0 : arg was accepted to continue (batch mode doesn't do this,or warnings are turned off) +# 1 : arg was not accepted by user or we're in bacth mode ignore_no_or_lame() { local a @@ -22039,8 +22039,8 @@ determine_optimal_proto() { if "$OPENSSL2_HAS_TLS_1_3"; then if "$OSSL_SHORTCUT" || [[ "$WARNINGS" == batch ]]; then # switch w/o asking - OPEN_MSG=" $NODE:$PORT appeared to support TLS 1.3 ONLY. Thus switched implictly from\n \"$OPENSSL\" to \"$OPENSSL2\"." - fileout "$jsonID" "INFO" "$NODE:$PORT appears to support TLS 1.3 ONLY, switching from $OPENSSL to $OPENSSL2 was implictly enforced" + OPEN_MSG=" $NODE:$PORT appeared to support TLS 1.3 ONLY. Thus switched implicitly from\n \"$OPENSSL\" to \"$OPENSSL2\"." + fileout "$jsonID" "INFO" "$NODE:$PORT appears to support TLS 1.3 ONLY, switching from $OPENSSL to $OPENSSL2 was implicitly enforced" OPENSSL="$OPENSSL2" find_openssl_binary prepare_arrays @@ -22102,7 +22102,7 @@ determine_optimal_proto() { # Check messages which needed to be processed. I.e. those which would have destroyed the nice # screen output and thus havve been postponed. This is just an idea and is only used once -# but can be extended in the future. An array migh be more handy +# but can be extended in the future. An array might be more handy # check_msg() { if [[ -n "$OPEN_MSG" ]]; then From 52213d3072923b4b884f529abee648f34fddf33f Mon Sep 17 00:00:00 2001 From: Dirk Date: Fri, 6 Sep 2024 17:32:53 +0200 Subject: [PATCH 04/78] Suppy documenation for TLS 1.3 only hosts and the automagic wrt /usr/bin/openssl OPENSSL2 and OSSL_SHORTCUT --- doc/testssl.1 | 6 +++++- doc/testssl.1.html | 4 +++- doc/testssl.1.md | 5 ++++- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/doc/testssl.1 b/doc/testssl.1 index c192cb3..bbabf4b 100644 --- a/doc/testssl.1 +++ b/doc/testssl.1 @@ -141,7 +141,7 @@ Any single check switch supplied as an argument prevents testssl\.sh from doing .P \fB\-f, \-\-fs, \-\-nsa, \-\-forward\-secrecy\fR Checks robust forward secrecy key exchange\. "Robust" means that ciphers having intrinsic severe weaknesses like Null Authentication or Encryption, 3DES and RC4 won't be considered here\. There shouldn't be the wrong impression that a secure key exchange has been taking place and everything is fine when in reality the encryption sucks\. Also this section lists the available elliptical curves and Diffie Hellman groups, as well as FFDHE groups (TLS 1\.2 and TLS 1\.3)\. .P -\fB\-p, \-\-protocols\fR checks TLS/SSL protocols SSLv2, SSLv3, TLS 1\.0 through TLS 1\.3 and for HTTP: SPDY (NPN) and ALPN, a\.k\.a\. HTTP/2\. For TLS 1\.3 several drafts (from 18 on) and final are supported and being tested for\. +\fB\-p, \-\-protocols\fR checks TLS/SSL protocols SSLv2, SSLv3, TLS 1\.0 through TLS 1\.3 and for HTTP: SPDY (NPN) and ALPN, a\.k\.a\. HTTP/2\. For TLS 1\.3 several drafts (from 18 on) and final are supported and being tested for\. Note the supplied openssl\-bad version doesn't support TLS 1\.3 \. As the check for TLS 1\.3 will be done in sockets this normally does not pose a problem\. However if a TLS\-1\.3\-only host is encountered and to have a complete test coverage (e.g. header checks) \fB/usr/bin/openssl\fR (or the content of \fBOPENSSL2\fR) is checked for existence and support of TLS 1\.3 and if those tests succeeded it will be switched to this binary\. A message will notify you\. .P \fB\-P, \-\-server\-preference, \-\-preference\fR displays the servers preferences: cipher order, with used openssl client: negotiated protocol and cipher\. If there's a cipher order enforced by the server it displays it for each protocol (openssl+sockets)\. If there's not, it displays instead which ciphers from the server were picked with each protocol\. .P @@ -418,6 +418,10 @@ MAX_SOCKET_FAIL: A number which tells testssl\.sh how often a TCP socket connect MAX_OSSL_FAIL: A number which tells testssl\.sh how often an OpenSSL s_client connect may fail before the program gives up and terminates\. The default is 2\. You can increase it to a higher value if you frequently see a message like \fIFatal error: repeated TCP connect problems, giving up\fR\. .IP "\[ci]" 4 MAX_HEADER_FAIL: A number which tells testssl\.sh how often a HTTP GET request over OpenSSL may return an empty file before the program gives up and terminates\. The default is 3\. Also here you can increase the threshold when you spot messages like \fIFatal error: repeated HTTP header connect problems, doesn't make sense to continue\fR\. +.IP "\[ci]" 4 +OPENSSL2 can be used to supply an alternative openssl version\. This only makes sense if you want to amend the supplied version in \fBbin/\fR which lacks TLS 1\.3 support with a version which does not and is not in \fB/usr/bin/openssl\fR. +.IP "\[ci]" 4 +OSSL_SHORTCUT can be set to true when you run interactively and don't want to switch automatically to \fB/usr/bin/openssl\fR (\fBOPENSSL2\fR) if you encounter a TLS 1\.3-only host\. .IP "" 0 .SS "RATING" This program has a near\-complete implementation of SSL Labs's 'SSL Server Rating Guide \fIhttps://github\.com/ssllabs/research/wiki/SSL\-Server\-Rating\-Guide\fR'\. diff --git a/doc/testssl.1.html b/doc/testssl.1.html index 17a8ddf..e704a3d 100644 --- a/doc/testssl.1.html +++ b/doc/testssl.1.html @@ -262,7 +262,7 @@ in /etc/hosts. The use of the switch is only useful if you either

-f, --fs, --nsa, --forward-secrecy Checks robust forward secrecy key exchange. "Robust" means that ciphers having intrinsic severe weaknesses like Null Authentication or Encryption, 3DES and RC4 won't be considered here. There shouldn't be the wrong impression that a secure key exchange has been taking place and everything is fine when in reality the encryption sucks. Also this section lists the available elliptical curves and Diffie Hellman groups, as well as FFDHE groups (TLS 1.2 and TLS 1.3).

-

-p, --protocols checks TLS/SSL protocols SSLv2, SSLv3, TLS 1.0 through TLS 1.3 and for HTTP: SPDY (NPN) and ALPN, a.k.a. HTTP/2. For TLS 1.3 several drafts (from 18 on) and final are supported and being tested for.

+

-p, --protocols checks TLS/SSL protocols SSLv2, SSLv3, TLS 1.0 through TLS 1.3 and for HTTP: SPDY (NPN) and ALPN, a.k.a. HTTP/2. For TLS 1.3 several drafts (from 18 on) and final are supported and being tested for. Note the supplied openssl-bad version doesn't support TLS 1.3 . As the check for TLS 1.3 will be done in sockets this normally does not pose a problem. However if a TLS-1.3-only host is encountered and to have a complete test coverage (e.g. header checks) `/usr/bin/openssl` (or the content of `OPENSSL2`) is checked for existence and support of TLS 1.3 and if those tests succeeded it will be switched to this binary. A message will notify you.

-P, --server-preference, --preference displays the servers preferences: cipher order, with used openssl client: negotiated protocol and cipher. If there's a cipher order enforced by the server it displays it for each protocol (openssl+sockets). If there's not, it displays instead which ciphers from the server were picked with each protocol.

@@ -501,6 +501,8 @@ Rating automatically gets disabled, to not give a wrong or misleading grade, whe
  • MAX_SOCKET_FAIL: A number which tells testssl.sh how often a TCP socket connection may fail before the program gives up and terminates. The default is 2. You can increase it to a higher value if you frequently see a message like Fatal error: repeated openssl s_client connect problem, doesn't make sense to continue.
  • MAX_OSSL_FAIL: A number which tells testssl.sh how often an OpenSSL s_client connect may fail before the program gives up and terminates. The default is 2. You can increase it to a higher value if you frequently see a message like Fatal error: repeated TCP connect problems, giving up.
  • MAX_HEADER_FAIL: A number which tells testssl.sh how often a HTTP GET request over OpenSSL may return an empty file before the program gives up and terminates. The default is 3. Also here you can increase the threshold when you spot messages like Fatal error: repeated HTTP header connect problems, doesn't make sense to continue.
  • +
  • OPENSSL2 can be used to supply an alternative openssl version. This only makes sense if you want to amend the supplied version in bin/ which lacks TLS 1.3 support with a version which does not and is not in /usr/bin/openssl.
  • +
  • OSSL_SHORTCUT can be set to true when you run interactively and don't want to switch automatically to /usr/bin/openssl (OPENSSL2) if you encounter a TLS 1.3-only host.

    RATING

    diff --git a/doc/testssl.1.md b/doc/testssl.1.md index 65c1df9..81d7527 100644 --- a/doc/testssl.1.md +++ b/doc/testssl.1.md @@ -175,7 +175,7 @@ Any single check switch supplied as an argument prevents testssl.sh from doing a `-f, --fs, --nsa, --forward-secrecy` Checks robust forward secrecy key exchange. "Robust" means that ciphers having intrinsic severe weaknesses like Null Authentication or Encryption, 3DES and RC4 won't be considered here. There shouldn't be the wrong impression that a secure key exchange has been taking place and everything is fine when in reality the encryption sucks. Also this section lists the available elliptical curves and Diffie Hellman groups, as well as FFDHE groups (TLS 1.2 and TLS 1.3). -`-p, --protocols` checks TLS/SSL protocols SSLv2, SSLv3, TLS 1.0 through TLS 1.3 and for HTTP: SPDY (NPN) and ALPN, a.k.a. HTTP/2. For TLS 1.3 several drafts (from 18 on) and final are supported and being tested for. +`-p, --protocols` checks TLS/SSL protocols SSLv2, SSLv3, TLS 1.0 through TLS 1.3 and for HTTP: SPDY (NPN) and ALPN, a.k.a. HTTP/2. For TLS 1.3 several drafts (from 18 on) and final are supported and being tested for. Note the supplied openssl-bad version doesn't support TLS 1.3 . As the check for TLS 1.3 will be done in sockets this normally does not pose a problem. However if a TLS-1.3-only host is encountered and to have a complete test coverage (e.g. header checks) `/usr/bin/openssl` (or the content of `OPENSSL2`) is checked for existence and support of TLS 1.3 and if those tests succeeded it will be switched to this binary. A message will notify you. `-P, --server-preference, --preference` displays the servers preferences: cipher order, with used openssl client: negotiated protocol and cipher. If there's a cipher order enforced by the server it displays it for each protocol (openssl+sockets). If there's not, it displays instead which ciphers from the server were picked with each protocol. @@ -403,6 +403,9 @@ Except the environment variables mentioned above which can replace command line * MAX_SOCKET_FAIL: A number which tells testssl.sh how often a TCP socket connection may fail before the program gives up and terminates. The default is 2. You can increase it to a higher value if you frequently see a message like *Fatal error: repeated openssl s_client connect problem, doesn't make sense to continue*. * MAX_OSSL_FAIL: A number which tells testssl.sh how often an OpenSSL s_client connect may fail before the program gives up and terminates. The default is 2. You can increase it to a higher value if you frequently see a message like *Fatal error: repeated TCP connect problems, giving up*. * MAX_HEADER_FAIL: A number which tells testssl.sh how often a HTTP GET request over OpenSSL may return an empty file before the program gives up and terminates. The default is 3. Also here you can increase the threshold when you spot messages like *Fatal error: repeated HTTP header connect problems, doesn't make sense to continue*. +* OPENSSL2 can be used to supply an alternative openssl version. This only makes sense if you want to amend the supplied version in `bin/` which lacks TLS 1.3 support with a version which doesn not and is not in `/usr/bin/openssl`. +* OSSL_SHORTCUT can be set to true when you run interactively and don't want to switch automatically to `/usr/bin/openssl` (`OPENSSL2`) if you encounter a TLS 1.3-only host. + ### RATING From 733c2d31b798fc17d3e91d62bf7ff4826dab5fd2 Mon Sep 17 00:00:00 2001 From: Dirk Date: Fri, 6 Sep 2024 17:37:42 +0200 Subject: [PATCH 05/78] Automagic with openssl and TLS 1.3-only host --- CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3aed6cd..dca42a3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -46,7 +46,8 @@ * Compatible to GNU grep 3.8 * Don't use external pwd command anymore * Doesn't hang anymore when there's no local resolver -* Added --mtls feature to support client authentication +* Added --mtls feature to support client authentication +* If a TLS 1.3 host is tested and e.g. /usr/bin/openssl supports it, it'll automagically will switch to it ### Features implemented / improvements in 3.0 From bb7d9f4ac56a7fa49bc208bbaa245cc7cde4f855 Mon Sep 17 00:00:00 2001 From: Dirk Wetter Date: Fri, 6 Sep 2024 17:53:58 +0200 Subject: [PATCH 06/78] Revert "Update Dockerfile to leap 15.6" --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index fc58f57..3767781 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,6 +1,6 @@ # syntax=docker.io/docker/dockerfile:1 -ARG LEAP_VERSION=15.6 +ARG LEAP_VERSION=15.5 ARG INSTALL_ROOT=/rootfs FROM opensuse/leap:${LEAP_VERSION} as builder From f9edaa7fe1465d0fd099d28f7fe17bdeb82c37e0 Mon Sep 17 00:00:00 2001 From: Dirk Date: Sat, 7 Sep 2024 15:51:12 +0200 Subject: [PATCH 07/78] Phrasing of STARTTLS grading improved ... a a comment added in the desciption. Unfortunately I couldn't get the line wrapping working. --- testssl.sh | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/testssl.sh b/testssl.sh index cc824a8..35a45de 100755 --- a/testssl.sh +++ b/testssl.sh @@ -22912,7 +22912,15 @@ run_rating() { pr_headlineln " Rating (experimental) " outln - [[ -n "$STARTTLS_PROTOCOL" ]] && set_grade_cap "T" "Encryption via STARTTLS is not mandatory (opportunistic)." + [[ -n "$STARTTLS_PROTOCOL" ]] && set_grade_cap "T" "STARTTLS encryption is not mandatory for clients. STARTTLS can only be secured clientside" + + # 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. 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" @@ -22965,7 +22973,7 @@ run_rating() { c1_worst=80 elif [[ $(has_server_protocol "tls1") -eq 0 ]]; then c1_worst=90 - elif [[ $(has_server_protocol "tls1_1") -eq 0 ]]; then + elif [[ $(as_server_protocol "tls1_1") -eq 0 ]]; then c1_worst=95 else # TLS1.2 and TLS1.3 both give 100 points c1_worst=100 From a1c67c0794d74d6891b08e54c955658c06679f08 Mon Sep 17 00:00:00 2001 From: Dirk Date: Sat, 7 Sep 2024 16:03:53 +0200 Subject: [PATCH 08/78] proper English --- testssl.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testssl.sh b/testssl.sh index 35a45de..c9c66b4 100755 --- a/testssl.sh +++ b/testssl.sh @@ -22912,7 +22912,7 @@ 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 clientside" + [[ -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. From 3b85f53d52e4fbd7aa12d438cdf850cb34117298 Mon Sep 17 00:00:00 2001 From: Dirk Date: Sat, 7 Sep 2024 16:15:03 +0200 Subject: [PATCH 09/78] added an accidently erased char --- testssl.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testssl.sh b/testssl.sh index c9c66b4..f35949d 100755 --- a/testssl.sh +++ b/testssl.sh @@ -22973,7 +22973,7 @@ run_rating() { c1_worst=80 elif [[ $(has_server_protocol "tls1") -eq 0 ]]; then c1_worst=90 - elif [[ $(as_server_protocol "tls1_1") -eq 0 ]]; then + elif [[ $(has_server_protocol "tls1_1") -eq 0 ]]; then c1_worst=95 else # TLS1.2 and TLS1.3 both give 100 points c1_worst=100 From c5b07e7d991b7a4094407e9ac90b05ab6f708749 Mon Sep 17 00:00:00 2001 From: Dirk Wetter Date: Sun, 8 Sep 2024 12:22:52 +0200 Subject: [PATCH 10/78] Make the client side security clearer for STARTTLS ... also in the man pages. See also #2564. --- doc/testssl.1 | 2 +- doc/testssl.1.html | 4 ++-- doc/testssl.1.md | 5 ++--- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/doc/testssl.1 b/doc/testssl.1 index bbabf4b..e57bc0e 100644 --- a/doc/testssl.1 +++ b/doc/testssl.1 @@ -428,7 +428,7 @@ This program has a near\-complete implementation of SSL Labs's 'SSL Server Ratin .P This is \fInot\fR a 100% reimplementation of the SSL Lab's SSL Server Test \fIhttps://www\.ssllabs\.com/ssltest/analyze\.html\fR, but an implementation of the above rating specification, slight discrepancies may occur\. Please note that for now we stick to the SSL Labs rating as good as possible\. We are not responsible for their rating\. Before filing issues please inspect their Rating Guide\. .P -Disclaimer: Having a good grade is \fBNOT\fR necessarily equal to having good security! Don't start a competition for the best grade, at least not without monitoring the client handshakes and not without adding a portion of good sense to it\. Please note STARTTLS always results in a grade cap to T\. Anything else would lead to a false sense of security \- at least until we test for DANE or MTA\-STS\. +Disclaimer: Having a good grade is \fBNOT\fR necessarily equal to having good security! Don't start a competition for the best grade, at least not without monitoring the client handshakes and not without adding a portion of good sense to it\. Please note STARTTLS always results in a grade cap to T\. Anything else would lead to a false sense of security\. Use TLS, see also RFC 8314\. The security of STARTTLS is always client determined, i'\.e\. checking the certificate which for SMTP port 25 is often enough not the case\. Also with DANE or MTA\-STS no one can test on the server side whether a client makes use if it\. .P As of writing, these checks are missing: * GOLDENDOODLE \- should be graded \fBF\fR if vulnerable * Insecure renegotiation \- should be graded \fBF\fR if vulnerable * Padding oracle in AES\-NI CBC MAC check (CVE\-2016\-2107) \- should be graded \fBF\fR if vulnerable * Sleeping POODLE \- should be graded \fBF\fR if vulnerable * Zero Length Padding Oracle (CVE\-2019\-1559) \- should be graded \fBF\fR if vulnerable * Zombie POODLE \- should be graded \fBF\fR if vulnerable * All remaining old Symantec PKI certificates are distrusted \- should be graded \fBT\fR * Symantec certificates issued before June 2016 are distrusted \- should be graded \fBT\fR * Anonymous key exchange \- should give \fB0\fR points in \fBset_key_str_score()\fR * Exportable key exchange \- should give \fB40\fR points in \fBset_key_str_score()\fR * Weak key (Debian OpenSSL Flaw) \- should give \fB0\fR points in \fBset_key_str_score()\fR .P diff --git a/doc/testssl.1.html b/doc/testssl.1.html index e704a3d..dbcbba5 100644 --- a/doc/testssl.1.html +++ b/doc/testssl.1.html @@ -502,7 +502,7 @@ Rating automatically gets disabled, to not give a wrong or misleading grade, whe
  • MAX_OSSL_FAIL: A number which tells testssl.sh how often an OpenSSL s_client connect may fail before the program gives up and terminates. The default is 2. You can increase it to a higher value if you frequently see a message like Fatal error: repeated TCP connect problems, giving up.
  • MAX_HEADER_FAIL: A number which tells testssl.sh how often a HTTP GET request over OpenSSL may return an empty file before the program gives up and terminates. The default is 3. Also here you can increase the threshold when you spot messages like Fatal error: repeated HTTP header connect problems, doesn't make sense to continue.
  • OPENSSL2 can be used to supply an alternative openssl version. This only makes sense if you want to amend the supplied version in bin/ which lacks TLS 1.3 support with a version which does not and is not in /usr/bin/openssl.
  • -
  • OSSL_SHORTCUT can be set to true when you run interactively and don't want to switch automatically to /usr/bin/openssl (OPENSSL2) if you encounter a TLS 1.3-only host. +
  • OSSL_SHORTCUT should be set to false when you run interactively and don't want to switch automatically to /usr/bin/openssl (OPENSSL2) if you encounter a TLS 1.3-only host.
  • RATING

    @@ -511,7 +511,7 @@ Rating automatically gets disabled, to not give a wrong or misleading grade, whe

    This is not a 100% reimplementation of the SSL Lab's SSL Server Test, but an implementation of the above rating specification, slight discrepancies may occur. Please note that for now we stick to the SSL Labs rating as good as possible. We are not responsible for their rating. Before filing issues please inspect their Rating Guide.

    Disclaimer: Having a good grade is NOT necessarily equal to having good security! Don't start a competition for the best grade, at least not without monitoring the client handshakes and not without adding a portion of good sense to it. Please note STARTTLS always results in a grade cap to T. Anything else -would lead to a false sense of security - at least until we test for DANE or MTA-STS.

    +would lead to a false sense of security. Use TLS, see also RFC 8314. The security of STARTTLS is always client determined, i.e. checking the certificate which for SMTP port 25 is often enough not the case. Also with DANE or MTA-STS no one can test on the server side whether a client makes use if it.

    As of writing, these checks are missing: * GOLDENDOODLE - should be graded F if vulnerable diff --git a/doc/testssl.1.md b/doc/testssl.1.md index 81d7527..42ac9c6 100644 --- a/doc/testssl.1.md +++ b/doc/testssl.1.md @@ -404,7 +404,7 @@ Except the environment variables mentioned above which can replace command line * MAX_OSSL_FAIL: A number which tells testssl.sh how often an OpenSSL s_client connect may fail before the program gives up and terminates. The default is 2. You can increase it to a higher value if you frequently see a message like *Fatal error: repeated TCP connect problems, giving up*. * MAX_HEADER_FAIL: A number which tells testssl.sh how often a HTTP GET request over OpenSSL may return an empty file before the program gives up and terminates. The default is 3. Also here you can increase the threshold when you spot messages like *Fatal error: repeated HTTP header connect problems, doesn't make sense to continue*. * OPENSSL2 can be used to supply an alternative openssl version. This only makes sense if you want to amend the supplied version in `bin/` which lacks TLS 1.3 support with a version which doesn not and is not in `/usr/bin/openssl`. -* OSSL_SHORTCUT can be set to true when you run interactively and don't want to switch automatically to `/usr/bin/openssl` (`OPENSSL2`) if you encounter a TLS 1.3-only host. +* OSSL_SHORTCUT should be set to false when you run interactively and don't want to switch automatically to `/usr/bin/openssl` (`OPENSSL2`) if you encounter a TLS 1.3-only host. ### RATING @@ -413,8 +413,7 @@ This program has a near-complete implementation of SSL Labs's '[SSL Server Ratin This is *not* a 100% reimplementation of the [SSL Lab's SSL Server Test](https://www.ssllabs.com/ssltest/analyze.html), but an implementation of the above rating specification, slight discrepancies may occur. Please note that for now we stick to the SSL Labs rating as good as possible. We are not responsible for their rating. Before filing issues please inspect their Rating Guide. -Disclaimer: Having a good grade is **NOT** necessarily equal to having good security! Don't start a competition for the best grade, at least not without monitoring the client handshakes and not without adding a portion of good sense to it. Please note STARTTLS always results in a grade cap to T. Anything else -would lead to a false sense of security - at least until we test for DANE or MTA-STS. +Disclaimer: Having a good grade is **NOT** necessarily equal to having good security! Don't start a competition for the best grade, at least not without monitoring the client handshakes and not without adding a portion of good sense to it. Please note STARTTLS always results in a grade cap to T. Anything else would lead to a false sense of security. Use TLS, see also RFC 8314. The security of STARTTLS is always client determined, i.e. checking the certificate which for SMTP port 25 is often enough not the case. Also with DANE or MTA-STS no one can test on the server side whether a client makes use if it. As of writing, these checks are missing: From 4ce91d7d6175e16e73f3ba3f8cf58c9c6079164c Mon Sep 17 00:00:00 2001 From: Dirk Wetter Date: Sun, 8 Sep 2024 12:27:51 +0200 Subject: [PATCH 11/78] Explain OSSL_SHORTCUT better, "automagically" is the word we wanted to use --- testssl.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/testssl.sh b/testssl.sh index 06115b5..a1b4021 100755 --- a/testssl.sh +++ b/testssl.sh @@ -246,7 +246,7 @@ TLS_DATA_FILE="" # mandatory file for socket-based handsh OPENSSL="" # ~/bin/openssl.$(uname).$(uname -m) if you run this from GitHub. Linux otherwise probably /usr/bin/openssl OPENSSL2=${OPENSSL2:-/usr/bin/openssl} # This will be openssl version >=1.1.1 (auto determined) as opposed to openssl-bad (OPENSSL) OPENSSL2_HAS_TLS_1_3=false # If we run with supplied binary AND $OPENSSL2 supports TLS 1.3 this will be set to true -OSSL_SHORTCUT=${OSSL_SHORTCUT:-true} # Hack: if during the scan turns out the OpenSSL binary supports TLS 1.3 would be a better choice +OSSL_SHORTCUT=${OSSL_SHORTCUT:-true} # If you don't want automagically switch from $OPENSSL to $OPENSSL2 for TLS 1.3 hosts, set this to false OPENSSL_LOCATION="" IKNOW_FNAME=false FIRST_FINDING=true # is this the first finding we are outputting to file? @@ -22039,8 +22039,8 @@ determine_optimal_proto() { if "$OPENSSL2_HAS_TLS_1_3"; then if "$OSSL_SHORTCUT" || [[ "$WARNINGS" == batch ]]; then # switch w/o asking - OPEN_MSG=" $NODE:$PORT appeared to support TLS 1.3 ONLY. Thus switched implicitly from\n \"$OPENSSL\" to \"$OPENSSL2\"." - fileout "$jsonID" "INFO" "$NODE:$PORT appears to support TLS 1.3 ONLY, switching from $OPENSSL to $OPENSSL2 was implicitly enforced" + OPEN_MSG=" $NODE:$PORT appeared to support TLS 1.3 ONLY. Thus switched automagically from\n \"$OPENSSL\" to \"$OPENSSL2\"." + fileout "$jsonID" "INFO" "$NODE:$PORT appears to support TLS 1.3 ONLY, switching from $OPENSSL to $OPENSSL2 automagically" OPENSSL="$OPENSSL2" find_openssl_binary prepare_arrays From 04c5ee391d9c0099bcdc145c8cc2904fd47cb3e4 Mon Sep 17 00:00:00 2001 From: Dirk Wetter Date: Sun, 8 Sep 2024 13:19:16 +0200 Subject: [PATCH 12/78] "only" was important here --- testssl.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testssl.sh b/testssl.sh index a1b4021..4068440 100755 --- a/testssl.sh +++ b/testssl.sh @@ -246,7 +246,7 @@ TLS_DATA_FILE="" # mandatory file for socket-based handsh OPENSSL="" # ~/bin/openssl.$(uname).$(uname -m) if you run this from GitHub. Linux otherwise probably /usr/bin/openssl OPENSSL2=${OPENSSL2:-/usr/bin/openssl} # This will be openssl version >=1.1.1 (auto determined) as opposed to openssl-bad (OPENSSL) OPENSSL2_HAS_TLS_1_3=false # If we run with supplied binary AND $OPENSSL2 supports TLS 1.3 this will be set to true -OSSL_SHORTCUT=${OSSL_SHORTCUT:-true} # If you don't want automagically switch from $OPENSSL to $OPENSSL2 for TLS 1.3 hosts, set this to false +OSSL_SHORTCUT=${OSSL_SHORTCUT:-true} # If you don't want automagically switch from $OPENSSL to $OPENSSL2 for TLS 1.3-only hosts, set this to false OPENSSL_LOCATION="" IKNOW_FNAME=false FIRST_FINDING=true # is this the first finding we are outputting to file? From b5427e3006d0bdb39e3c25e681a90736241710d2 Mon Sep 17 00:00:00 2001 From: Dirk Date: Sun, 8 Sep 2024 16:32:19 +0200 Subject: [PATCH 13/78] Bump version to 3.2rc4 --- testssl.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testssl.sh b/testssl.sh index 4068440..cf02a8f 100755 --- a/testssl.sh +++ b/testssl.sh @@ -122,7 +122,7 @@ trap "child_error" USR1 ########### Internal definitions # -declare -r VERSION="3.2rc3" +declare -r VERSION="3.2rc4" declare -r SWCONTACT="dirk aet testssl dot sh" [[ "$VERSION" =~ dev|rc|beta ]] && \ SWURL="https://testssl.sh/dev/" || From 69bdbeb982c53c03b3bca4249b032f22ce26becd Mon Sep 17 00:00:00 2001 From: Magnus Larsen Date: Wed, 18 Sep 2024 09:08:07 +0200 Subject: [PATCH 14/78] 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 15/78] 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 16/78] 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 17/78] 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 18/78] 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 19/78] 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 20/78] 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 21/78] 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 22/78] 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 23/78] 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 24/78] 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 25/78] 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 26/78] 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 27/78] 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 28/78] 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 29/78] 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 30/78] 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 31/78] 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 32/78] 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 dab177fda96dce0d5bb21f3ae8fcde86c9b6f4fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emmanuel=20Fust=C3=A9?= Date: Mon, 4 Nov 2024 17:27:18 +0100 Subject: [PATCH 33/78] Big client renego cleanup / refactoring All cases could be handled by the single openssl s_client invocation loop: - dispatch and adjust comments to not loose them - remove the first s_client invocation: stuck connections are allready handled by the main loop - remove the second s_client invocation: normal case and server closed connections are allready handled by the main loop. The loop take care of the race between server connection close and s_client terminating too by doing another loop run, not closing STDIN. - special non HTTP case equivalent to ssl_reneg_attempts=2 - specialcase only the HTTP result printing to not change the output - openssl-timeout option clashe badly with the main loop logic: Introduce $OPENSSL_NOTIMEOUT --- testssl.sh | 181 +++++++++++++++++++++++++---------------------------- 1 file changed, 87 insertions(+), 94 deletions(-) diff --git a/testssl.sh b/testssl.sh index c2e43e3..c90581c 100755 --- a/testssl.sh +++ b/testssl.sh @@ -17076,7 +17076,7 @@ run_ticketbleed() { # run_renego() { local legacycmd="" proto="$OPTIMAL_PROTO" - local sec_renego sec_client_renego + local sec_renego local -i ret=0 local cve="" local cwe="CWE-310" @@ -17168,7 +17168,6 @@ run_renego() { elif [[ "$CLIENT_AUTH" == required ]] && [[ -z "$MTLS" ]]; then prln_warning "not having provided client certificate and private key file, the client x509-based authentication prevents this from being tested" fileout "$jsonID" "WARN" "not having provided client certificate and private key file, the client x509-based authentication prevents this from being tested" - sec_client_renego=1 else # We will need $ERRFILE for mitigation detection if [[ $ERRFILE =~ dev.null ]]; then @@ -17179,99 +17178,91 @@ run_renego() { else restore_errfile=0 fi - # We need up to two tries here, as some LiteSpeed servers don't answer on "R" and block. Thus first try in the background - # msg enables us to look deeper into it while debugging - echo R | $OPENSSL s_client $(s_client_options "$proto $BUGS $legacycmd $STARTTLS -connect $NODEIP:$PORT $PROXY $SNI") >$TMPFILE 2>>$ERRFILE & - wait_kill $! $HEADER_MAXSLEEP - if [[ $? -eq 3 ]]; then - pr_svrty_good "likely not vulnerable (OK)"; outln ", timed out" # it hung - fileout "$jsonID" "OK" "likely not vulnerable (timed out)" "$cve" "$cwe" - sec_client_renego=1 + if [[ $SERVICE != HTTP ]]; then + # Connection could be closed by the server after one try so we will try two iteration + # to not close the openssl s_client STDIN too early like on the HTTP case. + # See https://github.com/drwetter/testssl.sh/issues/2590 + ssl_reneg_attempts=2 + fi + # We try again if server is HTTP. This could be either a node.js server or something else. + # Mitigations (default values) for: + # - node.js allows 3x R and then blocks. So then 4x should be tested. + # - F5 BIG-IP ADS allows 5x R and then blocks. So then 6x should be tested. + # - Stormshield allows 9x and then blocks. So then 10x should be tested. + # This way we save a couple seconds as we weeded out the ones which are more robust + # Amount of times tested before breaking is set in SSL_RENEG_ATTEMPTS. + + # Clear the log to not get the content of previous run before the execution of the new one. + echo -n > $TMPFILE + # RENEGOTIATING wait loop watchdog file + touch $TEMPDIR/allowed_to_loop + # If we dont wait for the session to be established on slow server, we will try to re-negotiate + # too early losing all the attempts before the session establishment as OpenSSL will not buffer them + # (only the first will be till the establishement of the session). + (j=0; while [[ $(grep -ac '^SSL-Session:' $TMPFILE) -ne 1 ]] && [[ $j -lt 30 ]]; do sleep $ssl_reneg_wait; ((j++)); done; \ + for ((i=0; i < ssl_reneg_attempts; i++ )); do sleep $ssl_reneg_wait; echo R; k=0; \ + # 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 + # 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 + while [[ $(grep -ac '^RENEGOTIATING' $ERRFILE) -ne $((i+1)) ]] && [[ -f $TEMPDIR/allowed_to_loop ]] \ + && [[ $(tail -n1 $ERRFILE |grep -acE '^(RENEGOTIATING|depth|verify|notAfter)') -eq 1 ]] \ + && [[ $k -lt 120 ]]; \ + do sleep $ssl_reneg_wait; ((k++)); if (tail -5 $TMPFILE| grep -qa '^closed'); then sleep 1; break; fi; done; \ + done) | \ + $OPENSSL_NOTIMEOUT s_client $(s_client_options "$proto $legacycmd $STARTTLS $BUGS -connect $NODEIP:$PORT $PROXY $SNI") >$TMPFILE 2>>$ERRFILE & + pid=$! + ( sleep $((ssl_reneg_attempts*3)) && kill $pid && touch $TEMPDIR/was_killed ) >&2 2>/dev/null & + watcher=$! + # Trick to get the return value of the openssl command, output redirection and a timeout. + # Yes, some target hang/block after some tries (some LiteSpeed servers don't answer at all on "R" and block). + wait $pid + tmp_result=$? + pkill -HUP -P $watcher + wait $watcher + rm -f $TEMPDIR/allowed_to_loop + # If we are here, we have done the loop + loop_reneg=$(grep -ac '^RENEGOTIATING' $ERRFILE) + # As above, some servers close the connection and return value is zero + if (tail -5 $TMPFILE| grep -qa '^closed'); then + tmp_result=1 + fi + if [[ -f $TEMPDIR/was_killed ]]; then + tmp_result=2 + rm -f $TEMPDIR/was_killed + fi + if [[ $SERVICE != HTTP ]]; then + case $tmp_result in + 0) pr_svrty_medium "VULNERABLE (NOT ok)"; outln ", potential DoS threat" + fileout "$jsonID" "MEDIUM" "VULNERABLE, potential DoS threat" "$cve" "$cwe" "$hint" + ;; + 1) prln_svrty_good "not vulnerable (OK)" + fileout "$jsonID" "OK" "not vulnerable" "$cve" "$cwe" + ;; + 2) pr_svrty_good "likely not vulnerable (OK)"; outln ", timed out ($((${ssl_reneg_attempts}*3))s)" # it hung + fileout "$jsonID" "OK" "likely not vulnerable (timed out)" "$cve" "$cwe" + ;; + *) prln_warning "FIXME (bug): $sec_client_renego" + fileout "$jsonID" "DEBUG" "FIXME (bug) $sec_client_renego - Please report" "$cve" "$cwe" + ret=1 + ;; + esac 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 - 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 - 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 - sec_client_renego=1 - fi - case "$sec_client_renego" in - 0) # We try again if server is HTTP. This could be either a node.js server or something else. - # Mitigations (default values) for: - # - node.js allows 3x R and then blocks. So then 4x should be tested. - # - F5 BIG-IP ADS allows 5x R and then blocks. So then 6x should be tested. - # - Stormshield allows 9x and then blocks. So then 10x should be tested. - # This way we save a couple seconds as we weeded out the ones which are more robust - # Amount of times tested before breaking is set in SSL_RENEG_ATTEMPTS. - if [[ $SERVICE != HTTP ]]; then - pr_svrty_medium "VULNERABLE (NOT ok)"; outln ", potential DoS threat" - fileout "$jsonID" "MEDIUM" "VULNERABLE, potential DoS threat" "$cve" "$cwe" "$hint" - else - # Clear the log to not get the content of previous run before the execution of the new one. - echo -n > $TMPFILE - #RENEGOTIATING wait loop watchdog file - touch $TEMPDIR/allowed_to_loop - # If we dont wait for the session to be established on slow server, we will try to re-negotiate - # too early losing all the attempts before the session establishment as OpenSSL will not buffer them - # (only the first will be till the establishement of the session). - (j=0; while [[ $(grep -ac '^SSL-Session:' $TMPFILE) -ne 1 ]] && [[ $j -lt 30 ]]; do sleep $ssl_reneg_wait; ((j++)); done; \ - for ((i=0; i < ssl_reneg_attempts; i++ )); do sleep $ssl_reneg_wait; echo R; k=0; \ - while [[ $(grep -ac '^RENEGOTIATING' $ERRFILE) -ne $((i+3)) ]] && [[ -f $TEMPDIR/allowed_to_loop ]] \ - && [[ $(tail -n1 $ERRFILE |grep -acE '^(RENEGOTIATING|depth|verify|notAfter)') -eq 1 ]] \ - && [[ $k -lt 120 ]]; \ - do sleep $ssl_reneg_wait; ((k++)); if (tail -5 $TMPFILE| grep -qa '^closed'); then sleep 1; break; fi; done; \ - done) | \ - $OPENSSL s_client $(s_client_options "$proto $legacycmd $STARTTLS $BUGS -connect $NODEIP:$PORT $PROXY $SNI") >$TMPFILE 2>>$ERRFILE & - pid=$! - ( sleep $((ssl_reneg_attempts*3)) && kill $pid && touch $TEMPDIR/was_killed ) >&2 2>/dev/null & - watcher=$! - # Trick to get the return value of the openssl command, output redirection and a timeout. - # Yes, some target hang/block after some tries. - wait $pid - tmp_result=$? - pkill -HUP -P $watcher - wait $watcher - rm -f $TEMPDIR/allowed_to_loop - # If we are here, we have done two successful renegotiation (-2) and do the loop - loop_reneg=$(($(grep -ac '^RENEGOTIATING' $ERRFILE)-2)) - # As above, some servers close the connection and return value is zero - if (tail -5 $TMPFILE| grep -qa '^closed'); then - tmp_result=1 - fi - if [[ -f $TEMPDIR/was_killed ]]; then - tmp_result=2 - rm -f $TEMPDIR/was_killed - fi - case $tmp_result in - 0) pr_svrty_high "VULNERABLE (NOT ok)"; outln ", DoS threat ($ssl_reneg_attempts attempts)" - fileout "$jsonID" "HIGH" "VULNERABLE, DoS threat" "$cve" "$cwe" "$hint" - ;; - 1) pr_svrty_good "not vulnerable (OK)"; outln " -- mitigated (disconnect after $loop_reneg/$ssl_reneg_attempts attempts)" - fileout "$jsonID" "OK" "not vulnerable, mitigated" "$cve" "$cwe" - ;; - 2) pr_svrty_good "not vulnerable (OK)"; \ - outln " -- mitigated ($loop_reneg successful reneg within ${ssl_reneg_attempts} in $((${ssl_reneg_attempts}*3))s(timeout))" - fileout "$jsonID" "OK" "not vulnerable, mitigated" "$cve" "$cwe" - ;; - *) prln_warning "FIXME (bug): $sec_client_renego ($ssl_reneg_attempts tries)" - fileout "$jsonID" "DEBUG" "FIXME (bug $ssl_reneg_attempts tries) $sec_client_renego" "$cve" "$cwe" - ret=1 - ;; - esac - fi - ;; - 1) - prln_svrty_good "not vulnerable (OK)" - fileout "$jsonID" "OK" "not vulnerable" "$cve" "$cwe" - ;; - *) - prln_warning "FIXME (bug): $sec_client_renego" - fileout "$jsonID" "DEBUG" "FIXME (bug) $sec_client_renego - Please report" "$cve" "$cwe" - ret=1 - ;; + case $tmp_result in + 0) pr_svrty_high "VULNERABLE (NOT ok)"; outln ", DoS threat ($ssl_reneg_attempts attempts)" + fileout "$jsonID" "HIGH" "VULNERABLE, DoS threat" "$cve" "$cwe" "$hint" + ;; + 1) pr_svrty_good "not vulnerable (OK)"; outln " -- mitigated (disconnect after $loop_reneg/$ssl_reneg_attempts attempts)" + fileout "$jsonID" "OK" "not vulnerable, mitigated" "$cve" "$cwe" + ;; + 2) pr_svrty_good "not vulnerable (OK)"; \ + outln " -- mitigated ($loop_reneg successful reneg within ${ssl_reneg_attempts} in $((${ssl_reneg_attempts}*3))s(timeout))" + fileout "$jsonID" "OK" "not vulnerable, mitigated" "$cve" "$cwe" + ;; + *) prln_warning "FIXME (bug): $sec_client_renego ($ssl_reneg_attempts tries)" + fileout "$jsonID" "DEBUG" "FIXME (bug $ssl_reneg_attempts tries) $sec_client_renego" "$cve" "$cwe" + ret=1 + ;; esac fi fi @@ -20447,6 +20438,8 @@ find_openssl_binary() { fi fi + OPENSSL_NOTIMEOUT=$OPENSSL + if ! "$do_mass_testing"; then if [[ -n $OPENSSL_TIMEOUT ]]; then OPENSSL="$TIMEOUT_CMD $OPENSSL_TIMEOUT $OPENSSL" From 09719a322bc2ae7006a243a2fc01bc19b0485af4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emmanuel=20Fust=C3=A9?= Date: Mon, 4 Nov 2024 20:25:31 +0100 Subject: [PATCH 34/78] Remove the last 1s euristic In the wait loop, I was relying on a 1s sleep to eliminate a possible late zero return value server close on the last attempt. - do globaly one more harmless "for" iteration and remove the sleep 1 for faster and more robust result - correct the non HTTP case iteration value - adjust the timeout to the conservative 6s in the non HTTP case, for HTTP case it become 33s - improve comments --- testssl.sh | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/testssl.sh b/testssl.sh index c90581c..1391175 100755 --- a/testssl.sh +++ b/testssl.sh @@ -17179,10 +17179,7 @@ run_renego() { restore_errfile=0 fi if [[ $SERVICE != HTTP ]]; then - # Connection could be closed by the server after one try so we will try two iteration - # to not close the openssl s_client STDIN too early like on the HTTP case. - # See https://github.com/drwetter/testssl.sh/issues/2590 - ssl_reneg_attempts=2 + ssl_reneg_attempts=1 fi # We try again if server is HTTP. This could be either a node.js server or something else. # Mitigations (default values) for: @@ -17200,7 +17197,11 @@ run_renego() { # too early losing all the attempts before the session establishment as OpenSSL will not buffer them # (only the first will be till the establishement of the session). (j=0; while [[ $(grep -ac '^SSL-Session:' $TMPFILE) -ne 1 ]] && [[ $j -lt 30 ]]; do sleep $ssl_reneg_wait; ((j++)); done; \ - for ((i=0; i < ssl_reneg_attempts; i++ )); do sleep $ssl_reneg_wait; echo R; k=0; \ + # Connection could be closed by the server with 0 return value. We do one more iteration to not close + # s_client STDIN too early as the close could come at any time and race with the tear down of s_client. + # See https://github.com/drwetter/testssl.sh/issues/2590 + # In this case the added iteration is harmfull as it will just spin in backgroup + for ((i=0; i <= ssl_reneg_attempts; i++ )); do sleep $ssl_reneg_wait; echo R; k=0; \ # 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 # Exemption from above: server closed the connection but return value was zero @@ -17208,11 +17209,11 @@ run_renego() { while [[ $(grep -ac '^RENEGOTIATING' $ERRFILE) -ne $((i+1)) ]] && [[ -f $TEMPDIR/allowed_to_loop ]] \ && [[ $(tail -n1 $ERRFILE |grep -acE '^(RENEGOTIATING|depth|verify|notAfter)') -eq 1 ]] \ && [[ $k -lt 120 ]]; \ - do sleep $ssl_reneg_wait; ((k++)); if (tail -5 $TMPFILE| grep -qa '^closed'); then sleep 1; break; fi; done; \ + do sleep $ssl_reneg_wait; ((k++)); if (tail -5 $TMPFILE| grep -qa '^closed'); then break; fi; done; \ done) | \ $OPENSSL_NOTIMEOUT s_client $(s_client_options "$proto $legacycmd $STARTTLS $BUGS -connect $NODEIP:$PORT $PROXY $SNI") >$TMPFILE 2>>$ERRFILE & pid=$! - ( sleep $((ssl_reneg_attempts*3)) && kill $pid && touch $TEMPDIR/was_killed ) >&2 2>/dev/null & + ( sleep $((ssl_reneg_attempts*3+3)) && kill $pid && touch $TEMPDIR/was_killed ) >&2 2>/dev/null & watcher=$! # Trick to get the return value of the openssl command, output redirection and a timeout. # Yes, some target hang/block after some tries (some LiteSpeed servers don't answer at all on "R" and block). @@ -17220,8 +17221,10 @@ run_renego() { tmp_result=$? pkill -HUP -P $watcher wait $watcher + # Stop any backgroud wait loop rm -f $TEMPDIR/allowed_to_loop - # If we are here, we have done the loop + # If we are here, we have done the loop. Count the effective renego attempts. + # It could be less than the numbers of "for" itterations (minus one) in case of late server close. loop_reneg=$(grep -ac '^RENEGOTIATING' $ERRFILE) # As above, some servers close the connection and return value is zero if (tail -5 $TMPFILE| grep -qa '^closed'); then @@ -17239,7 +17242,7 @@ run_renego() { 1) prln_svrty_good "not vulnerable (OK)" fileout "$jsonID" "OK" "not vulnerable" "$cve" "$cwe" ;; - 2) pr_svrty_good "likely not vulnerable (OK)"; outln ", timed out ($((${ssl_reneg_attempts}*3))s)" # it hung + 2) pr_svrty_good "likely not vulnerable (OK)"; outln ", timed out ($((${ssl_reneg_attempts}*3+3))s)" # it hung fileout "$jsonID" "OK" "likely not vulnerable (timed out)" "$cve" "$cwe" ;; *) prln_warning "FIXME (bug): $sec_client_renego" @@ -17256,7 +17259,7 @@ run_renego() { fileout "$jsonID" "OK" "not vulnerable, mitigated" "$cve" "$cwe" ;; 2) pr_svrty_good "not vulnerable (OK)"; \ - outln " -- mitigated ($loop_reneg successful reneg within ${ssl_reneg_attempts} in $((${ssl_reneg_attempts}*3))s(timeout))" + outln " -- mitigated ($loop_reneg successful reneg within ${ssl_reneg_attempts} in $((${ssl_reneg_attempts}*3+3))s(timeout))" fileout "$jsonID" "OK" "not vulnerable, mitigated" "$cve" "$cwe" ;; *) prln_warning "FIXME (bug): $sec_client_renego ($ssl_reneg_attempts tries)" From d8b439e48c24b60855a92cb9dae5ea5455cccd74 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emmanuel=20Fust=C3=A9?= Date: Mon, 4 Nov 2024 20:53:07 +0100 Subject: [PATCH 35/78] Address a theorically still possible non HTTP case --- testssl.sh | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/testssl.sh b/testssl.sh index 1391175..6fc1069 100755 --- a/testssl.sh +++ b/testssl.sh @@ -17200,7 +17200,7 @@ run_renego() { # Connection could be closed by the server with 0 return value. We do one more iteration to not close # s_client STDIN too early as the close could come at any time and race with the tear down of s_client. # See https://github.com/drwetter/testssl.sh/issues/2590 - # In this case the added iteration is harmfull as it will just spin in backgroup + # In this case the added iteration is harmless as it will just spin in backgroup for ((i=0; i <= ssl_reneg_attempts; i++ )); do sleep $ssl_reneg_wait; echo R; k=0; \ # 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 @@ -17230,11 +17230,16 @@ run_renego() { if (tail -5 $TMPFILE| grep -qa '^closed'); then tmp_result=1 fi + # timeout reached ? if [[ -f $TEMPDIR/was_killed ]]; then tmp_result=2 rm -f $TEMPDIR/was_killed fi if [[ $SERVICE != HTTP ]]; then + # theoric possible case + if [[ $loop_reneg -eq 2 ]]; + $tmp_result=0 + fi case $tmp_result in 0) pr_svrty_medium "VULNERABLE (NOT ok)"; outln ", potential DoS threat" fileout "$jsonID" "MEDIUM" "VULNERABLE, potential DoS threat" "$cve" "$cwe" "$hint" From 5773303f239e3e7be412b61582bd81029ee58fe0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emmanuel=20Fust=C3=A9?= Date: Mon, 4 Nov 2024 20:59:45 +0100 Subject: [PATCH 36/78] Correct incomplete commit --- testssl.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/testssl.sh b/testssl.sh index 6fc1069..986f4b8 100755 --- a/testssl.sh +++ b/testssl.sh @@ -17237,8 +17237,8 @@ run_renego() { fi if [[ $SERVICE != HTTP ]]; then # theoric possible case - if [[ $loop_reneg -eq 2 ]]; - $tmp_result=0 + if [[ $loop_reneg -eq 2 ]]; then + tmp_result=0 fi case $tmp_result in 0) pr_svrty_medium "VULNERABLE (NOT ok)"; outln ", potential DoS threat" From 76254229761e9f224643ef58a7b719679903a62d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emmanuel=20Fust=C3=A9?= Date: Mon, 4 Nov 2024 21:02:03 +0100 Subject: [PATCH 37/78] Spell fix --- testssl.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/testssl.sh b/testssl.sh index 986f4b8..775b7a3 100755 --- a/testssl.sh +++ b/testssl.sh @@ -17221,10 +17221,10 @@ run_renego() { tmp_result=$? pkill -HUP -P $watcher wait $watcher - # Stop any backgroud wait loop + # Stop any background wait loop rm -f $TEMPDIR/allowed_to_loop # If we are here, we have done the loop. Count the effective renego attempts. - # It could be less than the numbers of "for" itterations (minus one) in case of late server close. + # It could be less than the numbers of "for" iterations (minus one) in case of late server close. loop_reneg=$(grep -ac '^RENEGOTIATING' $ERRFILE) # As above, some servers close the connection and return value is zero if (tail -5 $TMPFILE| grep -qa '^closed'); then From 1aaab67e81569cfbf0bf770cbbb65d571f9d5342 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emmanuel=20Fust=C3=A9?= Date: Tue, 5 Nov 2024 12:59:01 +0100 Subject: [PATCH 38/78] Multiple IP fix and simple not vulnerable printing case recover - Recover the "not vulnerable" case (no mitigation) printing, cosmetic fix. - With the removing of all s_client invocation other than the main loop one, fix the init of the ERRFILE and TMPFILE: no need to append, no need to remove, inconditionally zap the content before the loop. --- testssl.sh | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/testssl.sh b/testssl.sh index 775b7a3..e3c63c4 100755 --- a/testssl.sh +++ b/testssl.sh @@ -17172,8 +17172,6 @@ run_renego() { # We will need $ERRFILE for mitigation detection if [[ $ERRFILE =~ dev.null ]]; then ERRFILE=$TEMPDIR/errorfile.txt || exit $ERR_FCREATE - # cleanup previous run if any (multiple IP) - rm -f $ERRFILE restore_errfile=1 else restore_errfile=0 @@ -17190,7 +17188,9 @@ run_renego() { # Amount of times tested before breaking is set in SSL_RENEG_ATTEMPTS. # Clear the log to not get the content of previous run before the execution of the new one. + # (Used in the loop tests before s_client invocation) echo -n > $TMPFILE + echo -n > $ERRFILE # RENEGOTIATING wait loop watchdog file touch $TEMPDIR/allowed_to_loop # If we dont wait for the session to be established on slow server, we will try to re-negotiate @@ -17211,7 +17211,7 @@ run_renego() { && [[ $k -lt 120 ]]; \ do sleep $ssl_reneg_wait; ((k++)); if (tail -5 $TMPFILE| grep -qa '^closed'); then break; fi; done; \ done) | \ - $OPENSSL_NOTIMEOUT s_client $(s_client_options "$proto $legacycmd $STARTTLS $BUGS -connect $NODEIP:$PORT $PROXY $SNI") >$TMPFILE 2>>$ERRFILE & + $OPENSSL_NOTIMEOUT s_client $(s_client_options "$proto $legacycmd $STARTTLS $BUGS -connect $NODEIP:$PORT $PROXY $SNI") >$TMPFILE 2>$ERRFILE & pid=$! ( sleep $((ssl_reneg_attempts*3+3)) && kill $pid && touch $TEMPDIR/was_killed ) >&2 2>/dev/null & watcher=$! @@ -17235,6 +17235,9 @@ run_renego() { tmp_result=2 rm -f $TEMPDIR/was_killed fi + if [[ $tmp_result -eq 1 ]] && [[ loop_reneg -eq 1 ]]; then + tmp_result=3 + fi if [[ $SERVICE != HTTP ]]; then # theoric possible case if [[ $loop_reneg -eq 2 ]]; then @@ -17244,7 +17247,7 @@ run_renego() { 0) pr_svrty_medium "VULNERABLE (NOT ok)"; outln ", potential DoS threat" fileout "$jsonID" "MEDIUM" "VULNERABLE, potential DoS threat" "$cve" "$cwe" "$hint" ;; - 1) prln_svrty_good "not vulnerable (OK)" + 1|3) prln_svrty_good "not vulnerable (OK)" fileout "$jsonID" "OK" "not vulnerable" "$cve" "$cwe" ;; 2) pr_svrty_good "likely not vulnerable (OK)"; outln ", timed out ($((${ssl_reneg_attempts}*3+3))s)" # it hung @@ -17263,6 +17266,9 @@ run_renego() { 1) pr_svrty_good "not vulnerable (OK)"; outln " -- mitigated (disconnect after $loop_reneg/$ssl_reneg_attempts attempts)" fileout "$jsonID" "OK" "not vulnerable, mitigated" "$cve" "$cwe" ;; + 3) prln_svrty_good "not vulnerable (OK)" + fileout "$jsonID" "OK" "not vulnerable" "$cve" "$cwe" + ;; 2) pr_svrty_good "not vulnerable (OK)"; \ outln " -- mitigated ($loop_reneg successful reneg within ${ssl_reneg_attempts} in $((${ssl_reneg_attempts}*3+3))s(timeout))" fileout "$jsonID" "OK" "not vulnerable, mitigated" "$cve" "$cwe" From 991c1fefb228f62f0506a0d9aef05307da6599df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emmanuel=20Fust=C3=A9?= Date: Thu, 7 Nov 2024 12:25:50 +0100 Subject: [PATCH 39/78] One tab fix --- testssl.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testssl.sh b/testssl.sh index e3c63c4..fe0b2db 100755 --- a/testssl.sh +++ b/testssl.sh @@ -17188,7 +17188,7 @@ run_renego() { # Amount of times tested before breaking is set in SSL_RENEG_ATTEMPTS. # Clear the log to not get the content of previous run before the execution of the new one. - # (Used in the loop tests before s_client invocation) + # (Used in the loop tests before s_client invocation) echo -n > $TMPFILE echo -n > $ERRFILE # RENEGOTIATING wait loop watchdog file 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 40/78] 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 41/78] 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 42/78] 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 e4e3afbbe8ed721e28cb11037950d2990d1b7a01 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emmanuel=20Fust=C3=A9?= Date: Mon, 9 Dec 2024 10:46:45 +0100 Subject: [PATCH 43/78] Tentative to fix CI tests --- testssl.sh | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/testssl.sh b/testssl.sh index fe0b2db..0c6c668 100755 --- a/testssl.sh +++ b/testssl.sh @@ -17169,6 +17169,10 @@ run_renego() { prln_warning "not having provided client certificate and private key file, the client x509-based authentication prevents this from being tested" fileout "$jsonID" "WARN" "not having provided client certificate and private key file, the client x509-based authentication prevents this from being tested" else + # We will extensively use subshell and command pipe + # Do not let herited pipeline error control interfere + [[ $- == *e* ]] && restore_pipeerror=1 + [[ $restore_pipeerror == 1 ]] && set +e # We will need $ERRFILE for mitigation detection if [[ $ERRFILE =~ dev.null ]]; then ERRFILE=$TEMPDIR/errorfile.txt || exit $ERR_FCREATE @@ -17279,6 +17283,7 @@ run_renego() { ;; esac fi + [[ $restore_pipeerror == 1 ]] && set -e fi #pr_bold " Insecure Client-Initiated Renegotiation " # pre-RFC 5746, CVE-2009-3555 From 88856ecad5f6e83e127cf82675dd47e22150ba36 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emmanuel=20Fust=C3=A9?= Date: Mon, 9 Dec 2024 12:00:16 +0100 Subject: [PATCH 44/78] 2nd try --- testssl.sh | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/testssl.sh b/testssl.sh index 0616064..089abd1 100755 --- a/testssl.sh +++ b/testssl.sh @@ -17173,10 +17173,11 @@ run_renego() { prln_warning "not having provided client certificate and private key file, the client x509-based authentication prevents this from being tested" fileout "$jsonID" "WARN" "not having provided client certificate and private key file, the client x509-based authentication prevents this from being tested" else - # We will extensively use subshell and command pipe - # Do not let herited pipeline error control interfere - [[ $- == *e* ]] && restore_pipeerror=1 - [[ $restore_pipeerror == 1 ]] && set +e +# # We will extensively use subshell and command pipe +# # Do not let herited pipeline error control interfere +# [[ $- == *e* ]] && restore_pipeerror=1 +# [[ $restore_pipeerror == 1 ]] && set +e +# set +o pipefail # We will need $ERRFILE for mitigation detection if [[ $ERRFILE =~ dev.null ]]; then ERRFILE=$TEMPDIR/errorfile.txt || exit $ERR_FCREATE @@ -17209,7 +17210,7 @@ run_renego() { # s_client STDIN too early as the close could come at any time and race with the tear down of s_client. # See https://github.com/drwetter/testssl.sh/issues/2590 # In this case the added iteration is harmless as it will just spin in backgroup - for ((i=0; i <= ssl_reneg_attempts; i++ )); do sleep $ssl_reneg_wait; echo R; k=0; \ + for ((i=0; i <= ssl_reneg_attempts; i++ )); do sleep $ssl_reneg_wait; echo R 2>/dev/null; k=0; \ # 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 # Exemption from above: server closed the connection but return value was zero @@ -17287,7 +17288,7 @@ run_renego() { ;; esac fi - [[ $restore_pipeerror == 1 ]] && set -e +# [[ $restore_pipeerror == 1 ]] && set -e fi #pr_bold " Insecure Client-Initiated Renegotiation " # pre-RFC 5746, CVE-2009-3555 From 6c17b6641873636433ed15ab03b148b3307278e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emmanuel=20Fust=C3=A9?= Date: Mon, 9 Dec 2024 14:19:56 +0100 Subject: [PATCH 45/78] CI fix : Cleanup testssl.sh worked as expected. Under the hood, broken pipes are expected as part of the fast loop exit strategy that relies as little as possible on timeout detection. But under the CI, testssl.sh output is garbled by the subshells stderr outputs, catched for some reason by 'prove -v'. Simply redirecting the stderr output of the offending command to /dev/null fixes the problem. --- testssl.sh | 6 ------ 1 file changed, 6 deletions(-) diff --git a/testssl.sh b/testssl.sh index 089abd1..7983aae 100755 --- a/testssl.sh +++ b/testssl.sh @@ -17173,11 +17173,6 @@ run_renego() { prln_warning "not having provided client certificate and private key file, the client x509-based authentication prevents this from being tested" fileout "$jsonID" "WARN" "not having provided client certificate and private key file, the client x509-based authentication prevents this from being tested" else -# # We will extensively use subshell and command pipe -# # Do not let herited pipeline error control interfere -# [[ $- == *e* ]] && restore_pipeerror=1 -# [[ $restore_pipeerror == 1 ]] && set +e -# set +o pipefail # We will need $ERRFILE for mitigation detection if [[ $ERRFILE =~ dev.null ]]; then ERRFILE=$TEMPDIR/errorfile.txt || exit $ERR_FCREATE @@ -17288,7 +17283,6 @@ run_renego() { ;; esac fi -# [[ $restore_pipeerror == 1 ]] && set -e fi #pr_bold " Insecure Client-Initiated Renegotiation " # pre-RFC 5746, CVE-2009-3555 From b708026151bba8d3bb06c35b5117eb9a50419929 Mon Sep 17 00:00:00 2001 From: Dirk Date: Mon, 6 Jan 2025 15:22:20 +0100 Subject: [PATCH 46/78] 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 47/78] 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 48/78] 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 49/78] 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 50/78] 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 51/78] 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 52/78] 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 53/78] 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 54/78] 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 55/78] 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 a499233df23d35b45e0e29895d4e1925a38bacb1 Mon Sep 17 00:00:00 2001 From: Dirk Date: Wed, 22 Jan 2025 18:12:53 +0100 Subject: [PATCH 56/78] Add unittest for diffrent openssl versions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This adds a unit test to compare a run against google with the supplied openssl version vs /usr/bin/openssl . This would fix #2626. It looks like there are still points to clarify * NPN output is different (bug) * Newer openssl version claims it's ECDH 253 instead of ECDH 256. * Newer openssl version claims for 130x cipher it's ECDH 253, via sockets it´s ECDH/MLKEM. This seems a bug (@dcooper) A todo is also restricing the unit test to the one where openssl is being used. E.g. the ROBOT check and more aren't done with openssl. So there's no value checking this here. --- t/12_diff_opensslversions.t | 72 +++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100755 t/12_diff_opensslversions.t diff --git a/t/12_diff_opensslversions.t b/t/12_diff_opensslversions.t new file mode 100755 index 0000000..883ba17 --- /dev/null +++ b/t/12_diff_opensslversions.t @@ -0,0 +1,72 @@ +#!/usr/bin/env perl + +# Baseline diff test against testssl.sh (csv output) +# +# This runs a basic test with the supplied openssl vs /usr/bin/openssl + +use strict; +use Test::More; +use Data::Dumper; +use Text::Diff; + +my $tests = 0; +my $prg="./testssl.sh"; +my $check2run="-q --ip=one --color 0 --csvfile"; +my $csvfile="tmp.csv"; +my $csvfile2="tmp2.csv"; +my $cat_csvfile=""; +my $cat_csvfile2=""; +my $uri="google.com"; +my $diff=""; +my $distro_openssl="/usr/bin/openssl"; + +die "Unable to open $prg" unless -f $prg; +die "Unable to open $distro_openssl" unless -f $distro_openssl; + +# Provide proper start conditions +unlink "tmp.csv"; +unlink "tmp2.csv"; + +#1 run +printf "\n%s\n", "Diff test IPv4 with supplied openssl against \"$uri\""; +`$prg $check2run $csvfile $uri 2>&1`; + +# 2 +printf "\n%s\n", "Diff test IPv4 with $distro_openssl against \"$uri\""; +`$prg $check2run $csvfile2 --openssl=$distro_openssl $uri 2>&1`; + +$cat_csvfile = `cat $csvfile`; +$cat_csvfile2 = `cat $csvfile2`; + +# Filter for changes that are allowed to occur +$cat_csvfile =~ s/HTTP_clock_skew.*\n//g; +$cat_csvfile2 =~ s/HTTP_clock_skew.*\n//g; + +# HTTP time +$cat_csvfile =~ s/HTTP_headerTime.*\n//g; +$cat_csvfile2 =~ s/HTTP_headerTime.*\n//g; + +#engine_problem +$cat_csvfile =~ s/"engine_problem.*\n//g; +$cat_csvfile2 =~ s/"engine_problem.*\n//g; + +# Nonce in CSP +$cat_csvfile =~ s/.nonce-.* //g; +$cat_csvfile2 =~ s/.nonce-.* //g; + +$diff = diff \$cat_csvfile, \$cat_csvfile2; + +# Compare the differences -- and print them if there were any +ok( $cat_csvfile eq $cat_csvfile2, "Check whether CSV outputs match" ) or + diag ("\n%s\n", "$diff"); + +#unlink "tmp.csv"; +#unlink "tmp2.csv"; + +$tests++; +done_testing($tests); +printf "\n"; + + +# vim:ts=5:sw=5:expandtab + From 37d987684e7f9904abc5a78efba3000a24b16654 Mon Sep 17 00:00:00 2001 From: Dirk Date: Wed, 22 Jan 2025 18:25:54 +0100 Subject: [PATCH 57/78] remove comment sign from testing --- t/12_diff_opensslversions.t | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/t/12_diff_opensslversions.t b/t/12_diff_opensslversions.t index 883ba17..a74df6a 100755 --- a/t/12_diff_opensslversions.t +++ b/t/12_diff_opensslversions.t @@ -60,8 +60,8 @@ $diff = diff \$cat_csvfile, \$cat_csvfile2; ok( $cat_csvfile eq $cat_csvfile2, "Check whether CSV outputs match" ) or diag ("\n%s\n", "$diff"); -#unlink "tmp.csv"; -#unlink "tmp2.csv"; +unlink "tmp.csv"; +unlink "tmp2.csv"; $tests++; done_testing($tests); From ba58458909fe51d84c5ad2d87e130893b328429d Mon Sep 17 00:00:00 2001 From: Dirk Date: Wed, 22 Jan 2025 18:37:48 +0100 Subject: [PATCH 58/78] Restrict tests to those which use openssl --- t/12_diff_opensslversions.t | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/t/12_diff_opensslversions.t b/t/12_diff_opensslversions.t index a74df6a..9c3d803 100755 --- a/t/12_diff_opensslversions.t +++ b/t/12_diff_opensslversions.t @@ -11,7 +11,7 @@ use Text::Diff; my $tests = 0; my $prg="./testssl.sh"; -my $check2run="-q --ip=one --color 0 --csvfile"; +my $check2run="--protocols --std --server-preference --fs --header --renegotiation --crime --breach --poodle --tls-fallback --sweet32 --beast --lucky13 --freak --logjam --drown --rc4 --phone-out --client-simulation -q --ip=one --color 0 --csvfile"; my $csvfile="tmp.csv"; my $csvfile2="tmp2.csv"; my $cat_csvfile=""; From a1c2dc7c72e60ef58afc376fff063d10bde77596 Mon Sep 17 00:00:00 2001 From: Dirk Date: Wed, 22 Jan 2025 19:19:16 +0100 Subject: [PATCH 59/78] 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 60/78] 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 61/78] 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 62/78] 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 63/78] 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 64/78] 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 65/78] 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 66/78] 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 67/78] 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) From 0042b6313efdeda7af9740a0994c2e9f70599dda Mon Sep 17 00:00:00 2001 From: Dirk Wetter Date: Fri, 24 Jan 2025 11:15:55 +0100 Subject: [PATCH 68/78] s/drwetter/testssl For the remaining occurences. Except dockerhub which needs to be solved. --- bin/Readme.md | 6 +++--- doc/testssl.1 | 2 +- doc/testssl.1.html | 2 +- doc/testssl.1.md | 2 +- etc/tls_data.txt | 2 +- t/11_baseline_ipv6_http.t.DISABLED | 2 +- utils/make-openssl.sh | 2 +- 7 files changed, 9 insertions(+), 9 deletions(-) diff --git a/bin/Readme.md b/bin/Readme.md index 83d7094..2998804 100644 --- a/bin/Readme.md +++ b/bin/Readme.md @@ -10,7 +10,7 @@ for some new / advanced cipher suites and/or features which are not in the official branch like (old version of the) CHACHA20+POLY1305 and CAMELLIA 256 bit ciphers. The (stripped) binaries this directory are all compiled from my openssl snapshot -(https://github.com/drwetter/openssl-1.0.2.bad) which adds a few bits to Peter +(https://github.com/testssl/openssl-1.0.2.bad) which adds a few bits to Peter Mosman's openssl fork (https://github.com/PeterMosmans/openssl). Thx a bunch, Peter! The few bits are IPv6 support (except IPV6 proxy) and some STARTTLS backports. @@ -71,11 +71,11 @@ Compilation instructions If you want to compile OpenSSL yourself, here are the instructions: 1.) - git git clone https://github.com/drwetter/openssl-1.0.2-bad + git git clone https://github.com/testssl/openssl-1.0.2-bad cd openssl -2.) configure the damned thing. Options I used (see https://github.com/drwetter/testssl.sh/blob/master/utils/make-openssl.sh) +2.) configure the damned thing. Options I used (see https://github.com/testssl/testssl.sh/blob/master/utils/make-openssl.sh) **for 64Bit including Kerberos ciphers:** diff --git a/doc/testssl.1 b/doc/testssl.1 index e57bc0e..810d54a 100644 --- a/doc/testssl.1 +++ b/doc/testssl.1 @@ -607,4 +607,4 @@ All native Windows platforms emulating Linux are known to be slow\. .SH "BUGS" Probably\. Current known ones and interface for filing new ones: https://testssl\.sh/bugs/ \. .SH "SEE ALSO" -\fBciphers\fR(1), \fBopenssl\fR(1), \fBs_client\fR(1), \fBx509\fR(1), \fBverify\fR(1), \fBocsp\fR(1), \fBcrl\fR(1), \fBbash\fR(1) and the websites https://testssl\.sh/ and https://github\.com/drwetter/testssl\.sh/ \. +\fBciphers\fR(1), \fBopenssl\fR(1), \fBs_client\fR(1), \fBx509\fR(1), \fBverify\fR(1), \fBocsp\fR(1), \fBcrl\fR(1), \fBbash\fR(1) and the websites https://testssl\.sh/ and https://github\.com/testssl/testssl\.sh/ \. diff --git a/doc/testssl.1.html b/doc/testssl.1.html index dbcbba5..0336c4b 100644 --- a/doc/testssl.1.html +++ b/doc/testssl.1.html @@ -681,7 +681,7 @@ from. That helps us to get bugfixes, other feedback and more contributions.

    SEE ALSO

    -

    ciphers(1), openssl(1), s_client(1), x509(1), verify(1), ocsp(1), crl(1), bash(1) and the websites https://testssl.sh/ and https://github.com/drwetter/testssl.sh/ .

    +

    ciphers(1), openssl(1), s_client(1), x509(1), verify(1), ocsp(1), crl(1), bash(1) and the websites https://testssl.sh/ and https://github.com/testssl/testssl.sh/ .

    1. diff --git a/doc/testssl.1.md b/doc/testssl.1.md index 42ac9c6..edbc304 100644 --- a/doc/testssl.1.md +++ b/doc/testssl.1.md @@ -587,4 +587,4 @@ Probably. Current known ones and interface for filing new ones: https://testssl. ## SEE ALSO -`ciphers`(1), `openssl`(1), `s_client`(1), `x509`(1), `verify`(1), `ocsp`(1), `crl`(1), `bash`(1) and the websites https://testssl.sh/ and https://github.com/drwetter/testssl.sh/ . +`ciphers`(1), `openssl`(1), `s_client`(1), `x509`(1), `verify`(1), `ocsp`(1), `crl`(1), `bash`(1) and the websites https://testssl.sh/ and https://github.com/testssl/testssl.sh/ . diff --git a/etc/tls_data.txt b/etc/tls_data.txt index 42483d9..6b16b06 100644 --- a/etc/tls_data.txt +++ b/etc/tls_data.txt @@ -1,7 +1,7 @@ # data we need for socket based handshakes # see #807 and #806 (especially -# https://github.com/drwetter/testssl.sh/issues/806#issuecomment-318686374) +# https://github.com/testssl/testssl.sh/issues/806#issuecomment-318686374) # 7 ciphers defined for TLS 1.3 in RFCs 8446 and 9150 readonly TLS13_CIPHER=" diff --git a/t/11_baseline_ipv6_http.t.DISABLED b/t/11_baseline_ipv6_http.t.DISABLED index affa18a..028cbea 100755 --- a/t/11_baseline_ipv6_http.t.DISABLED +++ b/t/11_baseline_ipv6_http.t.DISABLED @@ -1,6 +1,6 @@ #!/usr/bin/env perl -# disabled as IPv6 is not supported by Travis, see https://github.com/drwetter/testssl.sh/issues/1177 +# disabled as IPv6 wasn't supported by Travis CI and isn't by GH action, see https://github.com/testssl/testssl.sh/issues/1177 # Just a functional test, whether there are any problems on the client side # Probably we could also inspect the JSON for any problems for diff --git a/utils/make-openssl.sh b/utils/make-openssl.sh index 931406a..f2a2bf3 100755 --- a/utils/make-openssl.sh +++ b/utils/make-openssl.sh @@ -69,7 +69,7 @@ testv6_patch() { else echo echo "no IPv6 patch (Fedora) detected!! -- Press ^C and dl & apply from" - echo "https://github.com/drwetter/testssl.sh/blob/master/bin/fedora-dirk-ipv6.diff" + echo "https://github.com/testssl/testssl.sh/blob/master/bin/fedora-dirk-ipv6.diff" echo "or press any key to ignore" echo read a From 163d744c1329ce5778313b3375aa143f35aeea9c Mon Sep 17 00:00:00 2001 From: Dirk Wetter Date: Fri, 24 Jan 2025 11:32:41 +0100 Subject: [PATCH 69/78] Add recent and bigger changes From today back to 1f37a8406f1144d62b4f803719a008c278d63b9a --- CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2942f07..1e1b5c1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ * Improved compatibility with Open/LibreSSL versions not supporting TLS 1.0-1.1 anymore * Renamed PFS/perfect forward secrecy --> FS/forward secrecy * Cipher list straightening +* Support RFC 9150 cipher suites * Improved mass testing * Better align colors of ciphers with standard cipherlists * Save a few cycles for ROBOT @@ -23,13 +24,16 @@ * Test for STARTTLS injection vulnerabilities (SMTP, POP3, IMAP) * STARTTLS: XMPP server support, plus new set of OpenSSL-bad binaries * Several code improvements to STARTTLS, also better detection when no STARTTLS is offered +* Renegotiation checks more reliable against different servers * STARTTLS on active directory service support * Security fixes: DNS and other input from servers * Don't penalize missing trust in rating when CA not in Java store * Added support for certificates with EdDSA signatures and public keys * Extract CA list shows supported certification authorities sent by the server +* Wildcard detction of certificate and warning * TLS 1.2 and TLS 1.3 sig algs added * Check for ffdhe groups +* Check for three KEMs in draft-kwiatkowski-tls-ecdhe-mlkem/draft-tls-westerbaan-xyber768d00 * Show server supported signature algorithms * --add-ca can also now be a directory with \*.pem files * Warning of 398 day limit for certificates issued after 2020/9/1 @@ -41,6 +45,7 @@ * DNS via proxy improvements * Client simulation runs in wide mode which is even better readable * Added --reqheader to support custom headers in HTTP requests +* Search for more HTTP security headers on the server * Test for support for RFC 8879 certificate compression * Deprecating --fast and --ssl-native (warning but still av) * Compatible to GNU grep 3.8 From 002b91192c630853f74f47a75126e1ec8dcc08d0 Mon Sep 17 00:00:00 2001 From: Dirk Date: Fri, 24 Jan 2025 13:50:35 +0100 Subject: [PATCH 70/78] fix spelling --- testssl.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testssl.sh b/testssl.sh index 3163425..2a37707 100755 --- a/testssl.sh +++ b/testssl.sh @@ -248,7 +248,7 @@ OPENSSL2=${OPENSSL2:-/usr/bin/openssl} # This will be openssl version >=1.1.1 ( OPENSSL2_HAS_TLS_1_3=false # If we run with supplied binary AND $OPENSSL2 supports TLS 1.3 this will be set to true OSSL_SHORTCUT=${OSSL_SHORTCUT:-true} # If you don't want automagically switch from $OPENSSL to $OPENSSL2 for TLS 1.3-only hosts, set this to false OPENSSL_LOCATION="" -OPENSSL_NOTIMEOUT="" # Needed for renogitiation tests +OPENSSL_NOTIMEOUT="" # Needed for renegotiation tests IKNOW_FNAME=false FIRST_FINDING=true # is this the first finding we are outputting to file? JSONHEADER=true # include JSON headers and footers in HTML file, if one is being created From 76cdf3166a8b9f4d24e28b1369b3e759bf0d48bc Mon Sep 17 00:00:00 2001 From: Dirk Date: Fri, 24 Jan 2025 14:53:52 +0100 Subject: [PATCH 71/78] fix typo --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1e1b5c1..4084521 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -30,7 +30,7 @@ * Don't penalize missing trust in rating when CA not in Java store * Added support for certificates with EdDSA signatures and public keys * Extract CA list shows supported certification authorities sent by the server -* Wildcard detction of certificate and warning +* Wildcard certificates: detection and warning * TLS 1.2 and TLS 1.3 sig algs added * Check for ffdhe groups * Check for three KEMs in draft-kwiatkowski-tls-ecdhe-mlkem/draft-tls-westerbaan-xyber768d00 From 43a0099fbc711453eebbdd0b939e6fcc7e5bbb8d Mon Sep 17 00:00:00 2001 From: Dirk Date: Fri, 24 Jan 2025 18:46:07 +0100 Subject: [PATCH 72/78] Fix bug when legacy NPN is tested against a TLS 1.3 host When testing a TLS 1.3 host s_client_options used TLS 1.3 ciphers to test for NPN. As that is not implemented we nee dto make sure any other version is used. This PR ensures that --after testing whether it's a TLS 1.3-only host where this test doesn't make any sense in the first place. Fix for #2633 --- testssl.sh | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/testssl.sh b/testssl.sh index d5115c4..441dc74 100755 --- a/testssl.sh +++ b/testssl.sh @@ -11258,6 +11258,12 @@ npn_pre(){ fileout "NPN" "WARN" "not tested $OPENSSL doesn't support NPN/SPDY" return 7 fi + if "$TLS13_ONLY"; then + # https://github.com/openssl/openssl/issues/3665 + pr_warning "There's no such thing as NPN on TLS 1.3-only hosts" + fileout "NPN" "WARN" "not possible for TLS 1.3-only hosts" + return 6 + fi return 0 } @@ -11281,16 +11287,24 @@ alpn_pre(){ run_npn() { local tmpstr local -i ret=0 + local proto="" local jsonID="NPN" [[ -n "$STARTTLS" ]] && return 0 "$FAST" && return 0 pr_bold " NPN/SPDY " + if ! npn_pre; then outln return 0 fi - $OPENSSL s_client $(s_client_options "-connect $NODEIP:$PORT $BUGS $SNI -nextprotoneg "$NPN_PROTOs"") $ERRFILE >$TMPFILE + + # TLS 1.3 s_client doesn't support -nextprotoneg when connecting with TLS 1.3. So we need to make sure it wont be used + # TLS13_ONLY is tested here again, just to be sure, see npn_pre + if "$HAS_TLS13" && ! $TLS13_ONLY ]] ; then + proto="-no_tls1_3" + fi + $OPENSSL s_client $(s_client_options "$proto -connect $NODEIP:$PORT $BUGS $SNI -nextprotoneg "$NPN_PROTOs"") $ERRFILE >$TMPFILE [[ $? -ne 0 ]] && ret=1 tmpstr="$(grep -a '^Protocols' $TMPFILE | sed 's/Protocols.*: //')" if [[ -z "$tmpstr" ]] || [[ "$tmpstr" == " " ]]; then From d9b293f6c79c8de285c587cdcafc43c36b03cefe Mon Sep 17 00:00:00 2001 From: Dirk Date: Fri, 24 Jan 2025 18:51:11 +0100 Subject: [PATCH 73/78] fix typo --- testssl.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testssl.sh b/testssl.sh index 441dc74..6d99b1a 100755 --- a/testssl.sh +++ b/testssl.sh @@ -11299,7 +11299,7 @@ run_npn() { return 0 fi - # TLS 1.3 s_client doesn't support -nextprotoneg when connecting with TLS 1.3. So we need to make sure it wont be used + # TLS 1.3 s_client doesn't support -nextprotoneg when connecting with TLS 1.3. So we need to make sure it won't be used # TLS13_ONLY is tested here again, just to be sure, see npn_pre if "$HAS_TLS13" && ! $TLS13_ONLY ]] ; then proto="-no_tls1_3" From ce8984706ec663c9e235755d31062222e4c1933d Mon Sep 17 00:00:00 2001 From: Dirk Date: Fri, 24 Jan 2025 20:36:59 +0100 Subject: [PATCH 74/78] Finalize unit test * pattern search + replace for tls_sockets() vs. openssl * better error handling for invocations with perl functions system + die --- t/12_diff_opensslversions.t | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/t/12_diff_opensslversions.t b/t/12_diff_opensslversions.t index 9c3d803..e88d33b 100755 --- a/t/12_diff_opensslversions.t +++ b/t/12_diff_opensslversions.t @@ -19,6 +19,7 @@ my $cat_csvfile2=""; my $uri="google.com"; my $diff=""; my $distro_openssl="/usr/bin/openssl"; +my @args=""; die "Unable to open $prg" unless -f $prg; die "Unable to open $distro_openssl" unless -f $distro_openssl; @@ -29,11 +30,15 @@ unlink "tmp2.csv"; #1 run printf "\n%s\n", "Diff test IPv4 with supplied openssl against \"$uri\""; -`$prg $check2run $csvfile $uri 2>&1`; +@args="$prg $check2run $csvfile $uri 2>&1"; +system("@args") == 0 + or die ("FAILED: \"@args\""); # 2 printf "\n%s\n", "Diff test IPv4 with $distro_openssl against \"$uri\""; -`$prg $check2run $csvfile2 --openssl=$distro_openssl $uri 2>&1`; +@args="$prg $check2run $csvfile2 --openssl=$distro_openssl $uri 2>&1"; +system("@args") == 0 + or die ("FAILED: \"@args\" "); $cat_csvfile = `cat $csvfile`; $cat_csvfile2 = `cat $csvfile2`; @@ -50,6 +55,10 @@ $cat_csvfile2 =~ s/HTTP_headerTime.*\n//g; $cat_csvfile =~ s/"engine_problem.*\n//g; $cat_csvfile2 =~ s/"engine_problem.*\n//g; +# PR #2628. TL:DR; make the kx between tls_sockets() and openssl the same for this CI run +$cat_csvfile =~ s/ECDH 256/ECDH 253/g; +$cat_csvfile =~ s/ECDH\/MLKEM/ECDH 253 /g; + # Nonce in CSP $cat_csvfile =~ s/.nonce-.* //g; $cat_csvfile2 =~ s/.nonce-.* //g; From 0640eb90043d2f8e48aed1e1162b30bb5e6e47f7 Mon Sep 17 00:00:00 2001 From: Dirk Wetter Date: Mon, 27 Jan 2025 16:33:58 +0100 Subject: [PATCH 75/78] Several CI fixes - don't output stdin on terminal - adapt to different google.com ip addresses - cleaner code --- t/12_diff_opensslversions.t | 12 ++++++++---- t/61_diff_testsslsh.t | 4 ++-- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/t/12_diff_opensslversions.t b/t/12_diff_opensslversions.t index e88d33b..7ad8d43 100755 --- a/t/12_diff_opensslversions.t +++ b/t/12_diff_opensslversions.t @@ -25,18 +25,18 @@ die "Unable to open $prg" unless -f $prg; die "Unable to open $distro_openssl" unless -f $distro_openssl; # Provide proper start conditions -unlink "tmp.csv"; -unlink "tmp2.csv"; +unlink $csvfile; +unlink $csvfile2; #1 run printf "\n%s\n", "Diff test IPv4 with supplied openssl against \"$uri\""; -@args="$prg $check2run $csvfile $uri 2>&1"; +@args="$prg $check2run $csvfile $uri >/dev/null"; system("@args") == 0 or die ("FAILED: \"@args\""); # 2 printf "\n%s\n", "Diff test IPv4 with $distro_openssl against \"$uri\""; -@args="$prg $check2run $csvfile2 --openssl=$distro_openssl $uri 2>&1"; +@args="$prg $check2run $csvfile2 --openssl=$distro_openssl $uri >/dev/null"; system("@args") == 0 or die ("FAILED: \"@args\" "); @@ -63,6 +63,10 @@ $cat_csvfile =~ s/ECDH\/MLKEM/ECDH 253 /g; $cat_csvfile =~ s/.nonce-.* //g; $cat_csvfile2 =~ s/.nonce-.* //g; ++# Fix IP adresses. needed when we don't hit the same IP address. We just remove them +$cat_csvfile =~ s/","google.com\/.*","443/","google.com","443/; +$cat_csvfile2 =~ s/","google.com\/.*","443/","google.com","443/; + $diff = diff \$cat_csvfile, \$cat_csvfile2; # Compare the differences -- and print them if there were any diff --git a/t/61_diff_testsslsh.t b/t/61_diff_testsslsh.t index 18c3bfb..8532e8f 100755 --- a/t/61_diff_testsslsh.t +++ b/t/61_diff_testsslsh.t @@ -20,6 +20,7 @@ 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=""; +my @args=""; die "Unable to open $prg" unless -f $prg; die "Unable to open $baseline_csv" unless -f $baseline_csv; @@ -27,11 +28,10 @@ die "Unable to open $baseline_csv" unless -f $baseline_csv; # Provide proper start conditions unlink $cat_csv; -my @args=("$prg", "$check2run", "$uri", "2>&1"); #1 run printf "\n%s\n", "Diff unit test (IPv4) against \"$uri\""; -printf "@args\n"; +@args="$prg $check2run $uri >/dev/null"; system("@args") == 0 or die ("FAILED: \"@args\" "); From 8e39d161a817bc909916871cb116ebe574b31918 Mon Sep 17 00:00:00 2001 From: Dirk Wetter Date: Mon, 27 Jan 2025 16:36:42 +0100 Subject: [PATCH 76/78] cleaner code --- t/10_baseline_ipv4_http.t | 43 +++++++++++++++++++++------------------ 1 file changed, 23 insertions(+), 20 deletions(-) diff --git a/t/10_baseline_ipv4_http.t b/t/10_baseline_ipv4_http.t index c98e6f2..90ededa 100755 --- a/t/10_baseline_ipv4_http.t +++ b/t/10_baseline_ipv4_http.t @@ -15,48 +15,51 @@ use JSON; my $tests = 0; my $prg="./testssl.sh"; -my $check2run="-p -s -P --fs -S -h -U -q --ip=one --color 0"; +my $tmp_json="tmp.json"; +my $check2run="-p -s -P --fs -S -h -U -q --ip=one --color 0 --jsonfile $tmp_json"; my $uri="google.com"; my $socket_out=""; my $openssl_out=""; -# Blacklists we use to trigger an error: -my $socket_regex_bl='(e|E)rror|\.\/testssl\.sh: line |(f|F)atal|(c|C)ommand not found'; -my $openssl_regex_bl='(e|E)rror|(f|F)atal|\.\/testssl\.sh: line |Oops|s_client connect problem|(c|C)ommand not found'; -my $json_regex_bl='(id".*:\s"scanProblem"|severity".*:\s"FATAL"|"Scan interrupted")'; - my $socket_json=""; my $openssl_json=""; -$check2run="--jsonfile tmp.json $check2run"; +#FIXME: Blacklists we use to trigger an error, but likely we can skip that and instead we should?/could use +# @args="$prg $check2run $uri >/dev/null"; +# system("@args") == 0 +# or die ("FAILED: \"@args\" "); +my $socket_errors='(e|E)rror|\.\/testssl\.sh: line |(f|F)atal|(c|C)ommand not found'; +my $openssl_errors='(e|E)rror|(f|F)atal|\.\/testssl\.sh: line |Oops|s_client connect problem|(c|C)ommand not found'; +my $json_errors='(id".*:\s"scanProblem"|severity".*:\s"FATAL"|"Scan interrupted")'; + die "Unable to open $prg" unless -f $prg; # Provide proper start conditions -unlink "tmp.json"; +unlink $tmp_json; # Title printf "\n%s\n", "Baseline unit test IPv4 against \"$uri\""; #1 $socket_out = `$prg $check2run $uri 2>&1`; -$socket_json = json('tmp.json'); -unlink "tmp.json"; -unlike($socket_out, qr/$socket_regex_bl/, "via sockets, terminal output"); +$socket_json = json($tmp_json); +unlike($socket_out, qr/$socket_errors≈/, "via sockets, checking terminal output"); $tests++; -unlike($socket_json, qr/$json_regex_bl/, "via sockets JSON output"); +unlike($socket_json, qr/$json_errors/, "via sockets checking JSON output"); $tests++; +unlink $tmp_json; + + #2 $openssl_out = `$prg --ssl-native $check2run $uri 2>&1`; -$openssl_json = json('tmp.json'); -unlink "tmp.json"; -# With Google only we sometimes encounter an error as they return a 0 char with openssl, so we white list this pattern here: -# It should be fixed in the code though so we comment this out -# $openssl_out =~ s/testssl.*warning: command substitution: ignored null byte in input\n//g; -unlike($openssl_out, qr/$openssl_regex_bl/, "via OpenSSL"); +$openssl_json = json($tmp_json); +unlike($openssl_out, qr/$openssl_errors/, "via (builtin) OpenSSL, checking terminal output"); $tests++; -unlike($openssl_json, qr/$json_regex_bl/, "via OpenSSL JSON output"); +unlike($openssl_json, qr/$json_errors/, "via OpenSSL (builtin) checking JSON output"); $tests++; +unlink $tmp_json; + done_testing($tests); printf "\n"; @@ -69,5 +72,5 @@ sub json($) { } -# vim:ts=5:sw=5:expandtab +# vim:ts=5:sw=5:expandtab From b984ae5ea285b6c5a4564600dc1b993cc4b6e107 Mon Sep 17 00:00:00 2001 From: Dirk Wetter Date: Mon, 27 Jan 2025 16:37:04 +0100 Subject: [PATCH 77/78] minor stuff --- t/Readme.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/t/Readme.md b/t/Readme.md index 272372b..bfdeac0 100644 --- a/t/Readme.md +++ b/t/Readme.md @@ -5,6 +5,6 @@ * 30-39: Does reporting work? * 50-69: Are the results what I expect (server side)? -Please help to write Travis/CI tests! Documentation can be found [here](https://perldoc.perl.org/Test/More.html). -You can consult the existing code here. Feel free to use `10_baseline_ipv4_http.t` or `23_client_simulation.t` as a -template. +Please help to write CI tests! Documentation can be found [here](https://perldoc.perl.org/Test/More.html). +You can consult the existing code here. Feel free to use `10_baseline_ipv4_http.t` or `12_diff_opensslversions.t` as a +template. The latter is newer and code is cleaner. From ef13122f4fd222e275f5b048001c9c25f8817b1a Mon Sep 17 00:00:00 2001 From: Dirk Wetter Date: Mon, 27 Jan 2025 16:39:02 +0100 Subject: [PATCH 78/78] fix typo --- t/12_diff_opensslversions.t | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/t/12_diff_opensslversions.t b/t/12_diff_opensslversions.t index 7ad8d43..c91e10c 100755 --- a/t/12_diff_opensslversions.t +++ b/t/12_diff_opensslversions.t @@ -63,7 +63,7 @@ $cat_csvfile =~ s/ECDH\/MLKEM/ECDH 253 /g; $cat_csvfile =~ s/.nonce-.* //g; $cat_csvfile2 =~ s/.nonce-.* //g; -+# Fix IP adresses. needed when we don't hit the same IP address. We just remove them ++# Fix IP addresses. needed when we don't hit the same IP address. We just remove them $cat_csvfile =~ s/","google.com\/.*","443/","google.com","443/; $cat_csvfile2 =~ s/","google.com\/.*","443/","google.com","443/;