From af5cad91837221abd67988b77c45416519d24dda Mon Sep 17 00:00:00 2001 From: Dirk Wetter Date: Mon, 24 Aug 2020 16:22:04 +0200 Subject: [PATCH] Additions to find_openssl_binary() for a new openssl version / cleanup() This is a small cleanup of find_openssl_binary(). It tries also to find a newer openssl version which we could need for any new features. As stated in the comment at some point we should decide whether we stick with our old version or rather supply a new one. (xmpp-server is also not builtin for our 1.0.2) or maybe find a good way (code) how to use both. Also it looks for socat and if found it populates the according global var. It does a minor resort of global vars in the beginning. --- Dockerfile | 2 +- testssl.sh | 152 ++++++++++++++++++++++++++++------------------------- 2 files changed, 82 insertions(+), 72 deletions(-) diff --git a/Dockerfile b/Dockerfile index 42a6941..4bb321f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -2,7 +2,7 @@ FROM alpine:3.11 RUN apk update && \ apk upgrade && \ - apk add --no-cache bash procps drill git coreutils libidn curl && \ + apk add --no-cache bash procps drill git coreutils libidn curl socat && \ addgroup testssl && \ adduser -G testssl -g "testssl user" -s /bin/bash -D testssl && \ ln -s /home/testssl/testssl.sh /usr/local/bin/ && \ diff --git a/testssl.sh b/testssl.sh index ed93ca8..997204d 100755 --- a/testssl.sh +++ b/testssl.sh @@ -217,11 +217,8 @@ UNBRACKTD_IPV6=${UNBRACKTD_IPV6:-false} # some versions of OpenSSL (like Gentoo) NO_ENGINE=${NO_ENGINE:-false} # if there are problems finding the (external) openssl engine set this to true declare -r CLIENT_MIN_FS=5 # number of ciphers needed to run a test for FS CAPATH="${CAPATH:-/etc/ssl/certs/}" # Does nothing yet (FC has only a CA bundle per default, ==> openssl version -d) -GOOD_CA_BUNDLE="" # A bundle of CA certificates that can be used to validate the server's certificate -CERTIFICATE_LIST_ORDERING_PROBLEM=false # Set to true if server sends a certificate list that contains a certificate - # that does not certify the one immediately preceding it. (See RFC 8446, Section 4.4.2) -STAPLED_OCSP_RESPONSE="" -HAS_DNS_SANS=false # Whether the certificate includes a subjectAltName extension with a DNS name or an application-specific identifier type. +SOCAT="${SOCAT:-}" # For now we would need this for STARTTLS injection + MEASURE_TIME_FILE=${MEASURE_TIME_FILE:-""} if [[ -n "$MEASURE_TIME_FILE" ]] && [[ -z "$MEASURE_TIME" ]]; then MEASURE_TIME=true @@ -238,6 +235,8 @@ 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) OPENSSL_LOCATION="" IKNOW_FNAME=false FIRST_FINDING=true # is this the first finding we are outputting to file? @@ -294,13 +293,21 @@ NW_STR="" LEN_STR="" SNI="" POODLE="" # keep vulnerability status for TLS_FALLBACK_SCSV + +# Initialize OpenSSL variables (and others) OSSL_NAME="" # openssl name, in case of LibreSSL it's LibreSSL OSSL_VER="" # openssl version, will be auto-determined OSSL_VER_MAJOR=0 OSSL_VER_MINOR=0 OSSL_VER_APPENDIX="none" CLIENT_PROB_NO=1 -HAS_DH_BITS=${HAS_DH_BITS:-false} # initialize openssl variables + +GOOD_CA_BUNDLE="" # A bundle of CA certificates that can be used to validate the server's certificate +CERTIFICATE_LIST_ORDERING_PROBLEM=false # Set to true if server sends a certificate list that contains a certificate + # that does not certify the one immediately preceding it. (See RFC 8446, Section 4.4.2) +STAPLED_OCSP_RESPONSE="" +HAS_DNS_SANS=false # Whether the certificate includes a subjectAltName extension with a DNS name or an application-specific identifier type. +HAS_DH_BITS=${HAS_DH_BITS:-false} # These are variables which are set by find_openssl_binary() HAS_CURVES=false OSSL_SUPPORTED_CURVES="" HAS_SSL2=false @@ -332,6 +339,8 @@ HAS_CHACHA20=false HAS_AES128_GCM=false HAS_AES256_GCM=false HAS_ZLIB=false +HAS_UDS=false +HAS_UDS2=false HAS_DIG=false HAS_HOST=false HAS_DRILL=false @@ -18491,7 +18500,9 @@ test_openssl_suffix() { find_openssl_binary() { local s_client_has=$TEMPDIR/s_client_has.txt + local s_client_has2=$TEMPDIR/s_client_has2.txt local s_client_starttls_has=$TEMPDIR/s_client_starttls_has.txt + local s_client_starttls_has2=$TEMPDIR/s_client_starttls_has2 local openssl_location cwd="" local ossl_wo_dev_info local curve @@ -18581,6 +18592,7 @@ find_openssl_binary() { HAS_PROXY=false HAS_XMPP=false HAS_XMPP_SERVER=false + HAS_XMPP_SERVER2=false HAS_POSTGRES=false HAS_MYSQL=false HAS_LMTP=false @@ -18590,48 +18602,34 @@ find_openssl_binary() { HAS_AES128_GCM=false HAS_AES256_GCM=false HAS_ZLIB=false + HAS_UDS=false + HAS_UDS2=false - $OPENSSL ciphers -s 2>&1 | grep -aiq "unknown option" || \ - OSSL_CIPHERS_S="-s" + $OPENSSL ciphers -s 2>&1 | grep -aiq "unknown option" || OSSL_CIPHERS_S="-s" # This and all other occurences we do a little trick using "invalid." to avoid plain and # link level DNS lookups. See issue #1418 and https://tools.ietf.org/html/rfc6761#section-6.4 - $OPENSSL s_client -ssl2 -connect invalid. 2>&1 | grep -aiq "unknown option" || \ - HAS_SSL2=true + $OPENSSL s_client -ssl2 -connect invalid. 2>&1 | grep -aiq "unknown option" || HAS_SSL2=true + $OPENSSL s_client -ssl3 -connect invalid. 2>&1 | grep -aiq "unknown option" || HAS_SSL3=true + $OPENSSL s_client -tls1_3 -connect invalid. 2>&1 | grep -aiq "unknown option" || HAS_TLS13=true + $OPENSSL s_client -no_ssl2 -connect invalid. 2>&1 | grep -aiq "unknown option" || HAS_NO_SSL2=true - $OPENSSL s_client -ssl3 -connect invalid. 2>&1 | grep -aiq "unknown option" || \ - HAS_SSL3=true - - $OPENSSL s_client -tls1_3 -connect invalid. 2>&1 | grep -aiq "unknown option" || \ - HAS_TLS13=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 -aq "not found" || HAS_X448=true + $OPENSSL genpkey -algorithm X25519 2>&1 | grep -aq "not found" || HAS_X25519=true + $OPENSSL pkey -help 2>&1 | grep -q Error || HAS_PKEY=true + $OPENSSL pkeyutl 2>&1 | grep -q Error || HAS_PKUTIL=true if "$HAS_TLS13"; then - $OPENSSL s_client -tls1_3 -sigalgs PSS+SHA256:PSS+SHA384 -connect invalid. 2>&1 | grep -aiq "unknown option" || \ - HAS_SIGALGS=true + $OPENSSL s_client -tls1_3 -sigalgs PSS+SHA256:PSS+SHA384 -connect invalid. 2>&1 | grep -aiq "unknown option" || HAS_SIGALGS=true fi - $OPENSSL s_client -no_ssl2 -connect invalid. 2>&1 | grep -aiq "unknown option" || \ - HAS_NO_SSL2=true - $OPENSSL s_client -noservername -connect invalid. 2>&1 | grep -aiq "unknown option" || \ - HAS_NOSERVERNAME=true + $OPENSSL s_client -noservername -connect invalid. 2>&1 | grep -aiq "unknown option" || HAS_NOSERVERNAME=true + $OPENSSL s_client -ciphersuites -connect invalid. 2>&1 | grep -aiq "unknown option" || HAS_CIPHERSUITES=true - $OPENSSL s_client -ciphersuites -connect invalid. 2>&1 | grep -aiq "unknown option" || \ - HAS_CIPHERSUITES=true + $OPENSSL ciphers @SECLEVEL=0:ALL > /dev/null 2> /dev/null && HAS_SECLEVEL=true - $OPENSSL ciphers @SECLEVEL=0:ALL > /dev/null 2> /dev/null - [[ $? -eq 0 ]] && HAS_SECLEVEL=true - - $OPENSSL s_client -comp -connect invalid. 2>&1 | grep -aiq "unknown option" || \ - HAS_COMP=true - - $OPENSSL s_client -no_comp -connect invalid. 2>&1 | grep -aiq "unknown option" || \ - HAS_NO_COMP=true + $OPENSSL s_client -comp -connect invalid. 2>&1 | grep -aiq "unknown option" || HAS_COMP=true + $OPENSSL s_client -no_comp -connect invalid. 2>&1 | grep -aiq "unknown option" || HAS_NO_COMP=true OPENSSL_NR_CIPHERS=$(count_ciphers "$(actually_supported_osslciphers 'ALL:COMPLEMENTOFALL' 'ALL')") @@ -18648,50 +18646,40 @@ find_openssl_binary() { done fi - $OPENSSL pkey -help 2>&1 | grep -q Error || \ - HAS_PKEY=true - - $OPENSSL pkeyutl 2>&1 | grep -q Error || \ - HAS_PKUTIL=true - # For the following we feel safe enough to query the s_client help functions. # That was not good enough for the previous lookups $OPENSSL s_client -help 2>$s_client_has - $OPENSSL s_client -starttls foo 2>$s_client_starttls_has - grep -qw '\-alpn' $s_client_has && \ - HAS_ALPN=true + grep -q '\-proxy' $s_client_has && HAS_PROXY=true + grep -qw '\-alpn' $s_client_has && HAS_ALPN=true + grep -qw '\-nextprotoneg' $s_client_has && HAS_NPN=true - grep -qw '\-nextprotoneg' $s_client_has && \ - HAS_NPN=true + grep -qw '\-fallback_scsv' $s_client_has && HAS_FALLBACK_SCSV=true - grep -qw '\-fallback_scsv' $s_client_has && \ - HAS_FALLBACK_SCSV=true + grep -q 'xmpp' $s_client_starttls_has && HAS_XMPP=true + grep -q 'xmpp-server' $s_client_starttls_has && HAS_XMPP_SERVER=true - grep -q '\-proxy' $s_client_has && \ - HAS_PROXY=true + grep -q 'postgres' $s_client_starttls_has && HAS_POSTGRES=true + grep -q 'mysql' $s_client_starttls_has && HAS_MYSQL=true + grep -q 'lmtp' $s_client_starttls_has && HAS_LMTP=true + grep -q 'nntp' $s_client_starttls_has && HAS_NNTP=true + grep -q 'irc' $s_client_starttls_has && HAS_IRC=true - grep -q 'xmpp' $s_client_starttls_has && \ - HAS_XMPP=true + grep -q 'Unix-domain socket' $s_client_has && HAS_UDS=true - grep -q 'xmpp-server' $s_client_starttls_has && \ - HAS_XMPP_SERVER=true - - grep -q 'postgres' $s_client_starttls_has && \ - HAS_POSTGRES=true - - grep -q 'mysql' $s_client_starttls_has && \ - HAS_MYSQL=true - - grep -q 'lmtp' $s_client_starttls_has && \ - HAS_LMTP=true - - grep -q 'nntp' $s_client_starttls_has && \ - HAS_NNTP=true - - grep -q 'irc' $s_client_starttls_has && \ - HAS_IRC=true + # Now check whether the standard $OPENSSL has Unix-domain socket and xmpp-server support. If + # 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. + OPENSSL2=/usr/bin/openssl + if [[ ! $OSSL_VER =~ 1.1.1 ]] && [[ ! $OSSL_VER_MAJOR =~ 3 ]]; then + if [[ -x $OPENSSL2 ]]; then + $OPENSSL2 s_client -help 2>$s_client_has2 + $OPENSSL2 s_client -starttls foo 2>$s_client_starttls_has2 + grep -q 'Unix-domain socket' $s_client_has2 && HAS_UDS2=true + grep -q 'xmpp-server' $s_client_starttls_has2 && HAS_XMPP_SERVER2=true + fi + fi $OPENSSL enc -chacha20 -K 12345678901234567890123456789012 -iv 01000000123456789012345678901234 > /dev/null 2> /dev/null <<< "test" [[ $? -eq 0 ]] && HAS_CHACHA20=true @@ -18732,6 +18720,21 @@ find_openssl_binary() { } +find_socat() { + local result"" + + result=$(type -p socat) + if [[ $? -ne 0 ]]; then + return 1 + else + if [[ -x $result ]] && $result -V | grep -iaq 'socat version' ; then + SOCAT=$result + return 0 + fi + fi +} + + check4openssl_oldfarts() { case "$OSSL_VER" in 0.9.7*|0.9.6*|0.9.5*) @@ -19000,11 +19003,14 @@ HAS_PKUTIL: $HAS_PKUTIL HAS_PROXY: $HAS_PROXY HAS_XMPP: $HAS_XMPP HAS_XMPP_SERVER: $HAS_XMPP_SERVER +HAS_XMPP_SERVER2: $HAS_XMPP_SERVER2 HAS_POSTGRES: $HAS_POSTGRES HAS_MYSQL: $HAS_MYSQL HAS_LMTP: $HAS_LMTP HAS_NNTP: $HAS_NNTP HAS_IRC: $HAS_IRC +HAS_UDS: $HAS_UDS +HAS_UDS2: $HAS_UDS2 HAS_DIG: $HAS_DIG HAS_HOST: $HAS_HOST @@ -19054,6 +19060,8 @@ CCS_MAX_WAITSOCK: $CCS_MAX_WAITSOCK USLEEP_SND $USLEEP_SND USLEEP_REC $USLEEP_REC +SOCAT: $SOCAT + EOF type -p locale &>/dev/null && locale >>$TEMPDIR/environment.txt || echo "locale doesn't exist" >>$TEMPDIR/environment.txt actually_supported_osslciphers 'ALL:COMPLEMENTOFALL' 'ALL' "-V" &>$TEMPDIR/all_local_ciphers.txt @@ -20216,6 +20224,7 @@ determine_service() { fi fi if [[ "$protocol" == xmpp-server ]] && ! "$HAS_XMPP_SERVER"; then + #FIXME: make use of HAS_XMPP_SERVER2 fatal "Your $OPENSSL does not support the \"-starttls xmpp-server\" option" $ERR_OSSLBIN fi elif [[ "$protocol" == postgres ]]; then @@ -22076,6 +22085,7 @@ lets_roll() { set_color_functions maketempf find_openssl_binary + find_socat choose_printf check_resolver_bins prepare_debug ; stopwatch parse