Commit 5a75801a authored by ChangZhuo Chen's avatar ChangZhuo Chen

New upstream version 2.9.5-5+dfsg1

parent 242e94c3
FROM alpine:latest
RUN apk update && apk upgrade
RUN apk add bash procps drill git coreutils
RUN addgroup testssl
RUN adduser -G testssl -g "testssl user" -s /bin/bash -D testssl
RUN ln -s /home/testssl/testssl.sh /usr/local/bin/
USER testssl
WORKDIR /home/testssl/
RUN git clone --depth=1 https://github.com/drwetter/testssl.sh.git .
ENTRYPOINT ["testssl.sh"]
CMD ["--help"]
## Usage:
(in git directory):
```
docker build -t mytestssl .
docker run -t mytestssl example.com
```
You can also supply command line options like:
``docker run -t mytestssl -p --header example.com``
Please keep in mind that any output file (--log, --html, --json etc.) will be created
in the container.
You can also pull the image from docker hub, then run:
```
docker run -t drwetter/testssl.sh --pfs example.com
```
Also if you don't provide a user, this docker container uses
a non-root user.
This is an experimental version with Alpine Linux. Don\'t rely on it!
Besides the "latest" branch supported tags are currently "2.9dev" (equal to "latest"), and
"2.9.5" = "stable": ``docker run -t drwetter/testssl.sh:stable example.com``.
......@@ -30,11 +30,10 @@ cryptographic flaws.
You can download testssl.sh by cloning this git repository:
git clone --depth 1 https://github.com/drwetter/testssl.sh.git
git clone --depth 1 --branch 2.9.5 https://github.com/drwetter/testssl.sh.git
Or help yourself downloading the ZIP archive
https://github.com/drwetter/testssl.sh/archive/2.9.5.zip. Then ``testssl.sh
--help`` will give you some help upfront. More help: see doc directory. Older
Or help yourself downloading the ZIP archive https://github.com/drwetter/testssl.sh/archive/v2.9.5-1.zip.
Then ``testssl.sh --help`` will give you some help upfront. More help: see doc directory. Older
sample runs are at https://testssl.sh/.
#### Compatibility
......@@ -59,10 +58,10 @@ usage before taking the next step in the development of this project.
#### Features implemented in 2.9.5
* TLS 1.2 protocol check via socket in production
* Way better coverage of ciphers as most checks are done via sockets, using bash sockets where ever possible
* Further tests via TLS sockets and improvements (handshake parsing, completeness, robustness)
* Testing 359 default ciphers (``testssl.sh -e/-E``) with a mixture of sockets and openssl. Same speed as with openssl only but addtional ciphers such as post-quantum ciphers, new CHAHA20/POLY1305, CamelliaGCM etc.
* TLS 1.2 protocol check via sockets in production
* Finding more TLS extensions via sockets
* TLS Supported Groups Registry (RFC 7919), key shares extension
* Non-flat JSON output support
......@@ -72,13 +71,13 @@ usage before taking the next step in the development of this project.
* Ticketbleed check
* LOGJAM: now checking also for known DH parameters
* Support of supplying timeout value for ``openssl connect`` -- useful for batch/mass scanning
* Parallel mass testing
* Check for CAA RR
* Check for OCSP must staple
* Check for Certificate Transparency
* Check for session resumption (Ticket, ID)
* Better formatting of output (indentation)
* Choice showing the RFC naming scheme only
* Parallel mass testing
* File input for mass testing can be also in nmap grep(p)able (-oG) format
* Postgres und MySQL STARTTLS support
* Man page
......
.\" generated with Ronn/v0.7.3
.\" http://github.com/rtomayko/ronn/tree/0.7.3
.
.TH "TESTSSL" "1" "August 2017" "" ""
.TH "TESTSSL" "1" "April 2018" "" ""
.
.SH "NAME"
\fBtestssl\fR
......@@ -296,7 +296,7 @@ Security headers (X\-Frame\-Options, X\-XSS\-Protection, \.\.\., CSP headers)
\fB\-4, \-\-rc4, \-\-appelbaum\fR Checks which RC4 stream ciphers are being offered\.
.
.SS "OUTPUT OPTIONS"
\fB\-\-warnings <batch|off>\fR The warnings parameter determines how testssl\.sh will deal with situations where user input will normally be necessary\. There are a couple of options here\. \fBbatch\fR doesn\'t wait for a confirming keypress\. This is automatically being chosen for mass testing (\fB\-\-file\fR)\. \fB\-false\fR just skips the warning AND the confirmation\. Please note that there are conflicts where testssl\.sh will still ask for confirmation\. Those are ones which would have a drastic impact on the results\. The same can be achived by setting the environment variable \fBWARNINGS\fR\.
\fB\-\-warnings <batch|off>\fR The warnings parameter determines how testssl\.sh will deal with situations where user input normally will be necessary\. There are a couple of options here\. \fBbatch\fR doesn\'t wait for a confirming keypress\. This is automatically being chosen for mass testing (\fB\-\-file\fR)\. \fB\-false\fR just skips the warning AND the confirmation\. Please note that there are conflicts where testssl\.sh will still ask for a confirmation which are the ones which would have a drastic impact on the results\. Almost any other decision will be made as a best guess by testssl\.sh\. The same can be achived by setting the environment variable \fBWARNINGS\fR\.
.
.P
\fB\-\-openssl\-timeout <seconds>\fR This is especially useful for all connects using openssl and practically useful for mass testing\. It avoids the openssl connect to hang for ~2 minutes\. The expected parameter \fB<seconds>\fR instructs testssl\.sh to wait before the openssl connect will be terminated\. The option is only available if your OS has a timeout binary installed\. As there are different implementations of \fBtimeout\fR: It automatically calls the binary with the right parameters\.
......
......@@ -204,7 +204,7 @@ If the server provides no matching record in Subject Alternative Name (SAN) but
### OUTPUT OPTIONS
`--warnings <batch|off>` The warnings parameter determines how testssl.sh will deal with situations where user input will normally be necessary. There are a couple of options here. `batch` doesn't wait for a confirming keypress. This is automatically being chosen for mass testing (`--file`). `-false` just skips the warning AND the confirmation. Please note that there are conflicts where testssl.sh will still ask for confirmation. Those are ones which would have a drastic impact on the results.
`--warnings <batch|off>` The warnings parameter determines how testssl.sh will deal with situations where user input normally will be necessary. There are a couple of options here. `batch` doesn't wait for a confirming keypress. This is automatically being chosen for mass testing (`--file`). `-false` just skips the warning AND the confirmation. Please note that there are conflicts where testssl.sh will still ask for a confirmation which are the ones which would have a drastic impact on the results. Almost any other decision will be made as a best guess by testssl.sh.
The same can be achived by setting the environment variable `WARNINGS`.
`--openssl-timeout <seconds>` This is especially useful for all connects using openssl and practically useful for mass testing. It avoids the openssl connect to hang for ~2 minutes. The expected parameter `<seconds>` instructs testssl.sh to wait before the openssl connect will be terminated. The option is only available if your OS has a timeout binary installed. As there are different implementations of `timeout`: It automatically calls the binary with the right parameters.
......
......@@ -5,6 +5,7 @@
[ -z "$BASH_VERSINFO" ] && printf "\n\033[1;35m Please make sure you're using \"bash\"! Bye...\033[m\n\n" >&2 && exit 245
[ $(kill -l | grep -c SIG) -eq 0 ] && printf "\n\033[1;35m Please make sure you're calling me without leading \"sh\"! Bye...\033[m\n\n" >&2 && exit 245
[ ${BASH_VERSINFO[0]} -le 3 -a ${BASH_VERSINFO[1]} -le 1 ] && printf "\n\033[1;35m Minimum requirement is bash 3.2. You have $BASH_VERSION \033[m\n\n" >&2 && exit 245
# testssl.sh is a program for spotting weak SSL encryption, ciphers, version and some
# vulnerabilities or features
......@@ -104,7 +105,7 @@ fi
trap "cleanup" QUIT EXIT
trap "child_error" USR1
readonly VERSION="2.9.5"
readonly VERSION="2.9.5-4"
readonly SWCONTACT="dirk aet testssl dot sh"
egrep -q "dev|rc" <<< "$VERSION" && \
SWURL="https://testssl.sh/dev/" ||
......@@ -137,13 +138,23 @@ else
fi
readonly SYSTEM=$(uname -s)
SYSTEM2="" # currently only being used for WSL = bash on windows
date -d @735275209 >/dev/null 2>&1 && \
readonly HAS_GNUDATE=true || \
readonly HAS_GNUDATE=false
HAS_GNUDATE=false
HAS_FREEBSDDATE=false
HAS_OPENBSDDATE=false
if date -d @735275209 >/dev/null 2>&1; then
if date -r @735275209 >/dev/null 2>&1; then
# it can't do any conversion from a plain date output
HAS_OPENBSDDATE=true
else
HAS_GNUDATE=true
fi
fi
# FreeBSD and OS X date(1) accept "-f inputformat"
date -j -f '%s' 1234567 >/dev/null 2>&1 && \
readonly HAS_FREEBSDDATE=true || \
readonly HAS_FREEBSDDATE=false
HAS_FREEBSDDATE=true
echo A | sed -E 's/A//' >/dev/null 2>&1 && \
readonly HAS_SED_E=true || \
readonly HAS_SED_E=false
......@@ -201,7 +212,7 @@ HEADER_MAXSLEEP=${HEADER_MAXSLEEP:-5} # we wait this long before killing the p
MAX_WAITSOCK=${MAX_WAITSOCK:-10} # waiting at max 10 seconds for socket reply. There shouldn't be any reason to change this.
CCS_MAX_WAITSOCK=${CCS_MAX_WAITSOCK:-5} # for the two CCS payload (each). There shouldn't be any reason to change this.
HEARTBLEED_MAX_WAITSOCK=${HEARTBLEED_MAX_WAITSOCK:-8} # for the heartbleed payload. There shouldn't be any reason to change this.
STARTTLS_SLEEP=${STARTTLS_SLEEP:-1} # max time to wait on a socket replay for STARTTLS
STARTTLS_SLEEP=${STARTTLS_SLEEP:-10} # max time to wait on a socket replay for STARTTLS
FAST_STARTTLS=${FAST_STARTTLS:-true} # at the cost of reliabilty decrease the handshakes for STARTTLS
USLEEP_SND=${USLEEP_SND:-0.1} # sleep time for general socket send
USLEEP_REC=${USLEEP_REC:-0.2} # sleep time for general socket receive
......@@ -671,6 +682,10 @@ fileout_json_print_parameter() {
fileout_json_finding() {
local target
local finding="$3"
local cve="$4"
local cwe="$5"
local hint="$6"
if "$do_json"; then
"$FIRST_FINDING" || echo -n "," >> "$JSONFILE"
......@@ -793,6 +808,7 @@ fileout_insert_warning() {
# ID, SEVERITY, FINDING, CVE, CWE, HINT
fileout() {
local severity="$2"
local cve="$4"
local cwe="$5"
local hint="$6"
......@@ -1240,6 +1256,11 @@ elif "$HAS_FREEBSDDATE"; then # FreeBSD and OS X
parse_date() {
LC_ALL=C date -j -f "$3" "$2" "$1"
}
elif "$HAS_OPENBSDDATE"; then
parse_date() {
# we just echo it as a conversion is not possible
echo "$1"
}
else
parse_date() {
LC_ALL=C date -j "$2" "$1"
......@@ -1356,7 +1377,7 @@ service_detection() {
*) if "$CLIENT_AUTH"; then
out "certificate based authentication => skipping all HTTP checks"
echo "certificate based authentication => skipping all HTTP checks" >$TMPFILE
fileout "client_auth" "INFO" "certificate based authentication => skipping all HTTP checks"
fileout "service" "INFO" "certificate based authentication => skipping all HTTP checks"
else
out " Couldn't determine what's running on port $PORT"
if "$ASSUME_HTTP"; then
......@@ -1514,6 +1535,7 @@ detect_ipv4() {
run_http_date() {
local now difftime
local spaces=" "
if [[ ! -s $HEADERFILE ]]; then
run_http_header "$1" || return 3 # this is just for the line "Testing HTTP header response"
......@@ -1523,14 +1545,21 @@ run_http_date() {
out "not tested as we're not targeting HTTP"
else
if [[ -n "$HTTP_TIME" ]]; then
HTTP_TIME=$(parse_date "$HTTP_TIME" "+%s" "%a, %d %b %Y %T %Z" 2>>$ERRFILE) # the trailing \r confuses BSD flavors otherwise
difftime=$((HTTP_TIME - NOW_TIME))
[[ $difftime != "-"* ]] && [[ $difftime != "0" ]] && difftime="+$difftime"
# process was killed, so we need to add an error:
[[ $HAD_SLEPT -ne 0 ]] && difftime="$difftime (± 1.5)"
out "$difftime sec from localtime";
fileout "http_clock_skew" "INFO" "HTTP clock skew $difftime sec from localtime"
HTTP_TIME="$(strip_lf "$HTTP_TIME")"
if "$HAS_OPENBSDDATE"; then
# we can't normalize the date under OpenBSD thus no substraction is possible
outln "remote: $HTTP_TIME"
out "${spaces}local: $(date)"
fileout "$jsonID" "INFO" "$HTTP_TIME - $(date)"
else
HTTP_TIME=$(parse_date "$HTTP_TIME" "+%s" "%a, %d %b %Y %T %Z" 2>>$ERRFILE)
difftime=$((HTTP_TIME - NOW_TIME))
[[ $difftime != "-"* ]] && [[ $difftime != "0" ]] && difftime="+$difftime"
# process was killed, so we need to add an error:
[[ $HAD_SLEPT -ne 0 ]] && difftime="$difftime (± 1.5)"
out "$difftime sec from localtime";
fileout "http_clock_skew" "INFO" "HTTP clock skew $difftime sec from localtime"
fi
else
out "Got no HTTP time, maybe try different URL?";
fileout "http_clock_skew" "INFO" "HTTP clock skew not measured. Got no HTTP time, maybe try different URL?"
......@@ -1554,12 +1583,12 @@ detect_header() {
local spaces="$3"
local -i nr=0
nr=$(grep -Faciw "$key:" $HEADERFILE)
nr=$(grep -Eaicw "^ *$key:" $HEADERFILE)
if [[ $nr -eq 0 ]]; then
HEADERVALUE=""
return 0
elif [[ $nr -eq 1 ]]; then
HEADERVALUE=$(grep -Faiw "$key:" $HEADERFILE)
HEADERVALUE=$(grep -Eiaw "^ *$key:" $HEADERFILE)
HEADERVALUE=${HEADERVALUE#*:} # remove leading part=key to colon
HEADERVALUE="$(strip_leading_space "$HEADERVALUE")"
return 1
......@@ -1618,17 +1647,17 @@ run_hsts() {
hsts_age_days=-1
fi
if [[ $hsts_age_days -eq -1 ]]; then
pr_svrty_medium "HSTS max-age is required but missing. Setting 15552000 s (180 days) or more is recommended"
fileout "hsts_time" "MEDIUM" "HSTS max-age missing. 15552000 s (180 days) or more recommnded"
pr_svrty_medium "HSTS max-age is required but missing. Setting 15552000 seconds (180 days) or more is recommended"
fileout "hsts_time" "MEDIUM" "HSTS max-age missing. 15552000 seconds (180 days) or more recommnded"
elif [[ $hsts_age_sec -eq 0 ]]; then
pr_svrty_medium "HSTS max-age is set to 0. HSTS is disabled"
fileout "hsts_time" "MEDIUM" "HSTS max-age set to 0. HSTS is disabled"
elif [[ $hsts_age_sec -gt $HSTS_MIN ]]; then
pr_done_good "$hsts_age_days days" ; out "=$hsts_age_sec s"
fileout "hsts_time" "OK" "HSTS timeout $hsts_age_days days (=$hsts_age_sec seconds) > $HSTS_MIN days"
fileout "hsts_time" "OK" "HSTS timeout $hsts_age_days days (=$hsts_age_sec seconds) > $HSTS_MIN seconds"
else
pr_svrty_medium "$hsts_age_sec s = $hsts_age_days days is too short ( >=$HSTS_MIN s recommended)"
fileout "hsts_time" "MEDIUM" "HSTS timeout too short. $hsts_age_days days (=$hsts_age_sec seconds) < $HSTS_MIN days"
pr_svrty_medium "$hsts_age_sec s = $hsts_age_days days is too short ( >=$HSTS_MIN seconds recommended)"
fileout "hsts_time" "MEDIUM" "HSTS timeout too short. $hsts_age_days days (=$hsts_age_sec seconds) < $HSTS_MIN seconds"
fi
if includeSubDomains "$TMPFILE"; then
fileout "hsts_subdomains" "OK" "HSTS includes subdomains"
......@@ -1645,7 +1674,7 @@ run_hsts() {
fi
else
out "--"
fileout "hsts" "HIGH" "No support for HTTP Strict Transport Security"
fileout "hsts" "INFO" "No support for HTTP Strict Transport Security"
fi
outln
......@@ -1693,12 +1722,9 @@ run_hpkp() {
fileout "hpkp_multiple" "WARN" "Multiple HPKP headers $hpkp_headers. Using first header: $first_hpkp_header"
fi
# remove leading Public-Key-Pins*, any colons, double quotes and trailing spaces and taking the first -- whatever that is
sed -e 's/Public-Key-Pins://g' -e s'/Public-Key-Pins-Report-Only://' $TMPFILE | \
sed -e 's/;//g' -e 's/\"//g' -e 's/^ //' | head -1 > $TMPFILE.2
# BSD lacks -i, otherwise we would have done it inline
# now separate key value and other stuff per line:
tr ' ' '\n' < $TMPFILE.2 >$TMPFILE
# remove leading Public-Key-Pins* and convert it to mulitline arg
sed -e 's/Public-Key-Pins://g' -e s'/Public-Key-Pins-Report-Only://' $TMPFILE | tr ';' '\n' | sed -e 's/\"//g' -e 's/^ //' >$TMPFILE.2
mv $TMPFILE.2 $TMPFILE
hpkp_nr_keys=$(grep -ac pin-sha $TMPFILE)
if [[ $hpkp_nr_keys -eq 1 ]]; then
......@@ -1995,7 +2021,7 @@ run_server_banner() {
grep -ai '^Server' $HEADERFILE >$TMPFILE
if [[ $? -eq 0 ]]; then
serverbanner=$(sed -e 's/^Server: //' -e 's/^server: //' $TMPFILE)
if [[ x"$serverbanner" == "x\n" ]] || [[ x"$serverbanner" == "x\n\r" ]] || [[ -z "$serverbanner" ]]; then
if [[ "$serverbanner" == $'\n' ]] || [[ "$serverbanner" == $'\r' ]] || [[ "$serverbanner" == $'\n\r' ]] || [[ -z "$serverbanner" ]]; then
outln "banner exists but empty string"
fileout "serverbanner" "INFO" "Server banner exists but empty string"
else
......@@ -2150,7 +2176,7 @@ run_cookie_flags() { # ARG1: Path
run_more_flags() {
local good_flags2test="X-Frame-Options X-XSS-Protection X-Content-Type-Options Content-Security-Policy X-Content-Security-Policy X-WebKit-CSP Content-Security-Policy-Report-Only"
local other_flags2test="Access-Control-Allow-Origin Upgrade X-Served-By X-UA-Compatible Referrer-Policy X-UA-Compatible"
local other_flags2test="Access-Control-Allow-Origin Upgrade X-Served-By Referrer-Policy X-UA-Compatible"
local f2t line
local first=true
local spaces=" "
......@@ -4537,6 +4563,7 @@ run_server_preference() {
# workaround is to connect with a protocol
debugme tm_out "(workaround #188) "
determine_optimal_proto $STARTTLS_PROTOCOL
[[ ! "$STARTTLS_OPTIMAL_PROTO" =~ ssl ]] && addcmd2="$SNI"
$OPENSSL s_client $STARTTLS $STARTTLS_OPTIMAL_PROTO -cipher $list_fwd $BUGS -connect $NODEIP:$PORT $PROXY $addcmd2 </dev/null 2>$ERRFILE >$TMPFILE
if ! sclient_connect_successful $? $TMPFILE; then
pr_warning "no matching cipher in this list found (pls report this): "
......@@ -5093,12 +5120,14 @@ determine_trust() {
# and the output should should be indented by two more spaces.
[[ -n $json_prefix ]] && spaces=" "
if [[ $OSSL_VER_MAJOR.$OSSL_VER_MINOR != "1.0.2" ]] && \
[[ $OSSL_VER_MAJOR.$OSSL_VER_MINOR != "1.1.0" ]] && \
[[ $OSSL_VER_MAJOR.$OSSL_VER_MINOR != "1.1.1" ]]; then
addtl_warning="(Your $OPENSSL <= 1.0.2 might be too unreliable to determine trust)"
fileout "${json_prefix}chain_of_trust_Problem" "WARN" "$addtl_warning"
fi
case $OSSL_VER_MAJOR.$OSSL_VER_MINOR in
1.0.2|1.1.0|1.1.1|2.[1-9].*)
: # 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)"
fileout "${json_prefix}chain_of_trust_Problem" "WARN" "$addtl_warning"
;;
esac
debugme tmln_out
# if you run testssl.sh from a different path /you can set either TESTSSL_INSTALL_DIR or CA_BUNDLES_PATH to find the CA BUNDLES
......@@ -5546,26 +5575,27 @@ compare_server_name_to_cert()
# Check whether any of the DNS names in the certificate match the servername
dns_sans="$(get_san_dns_from_cert "$cert")"
for san in $dns_sans; do
[[ $(toupper "$san") == "$servername" ]] && ret=1 && break
done
while read san; do
[[ -n "$san" ]] && [[ $(toupper "$san") == "$servername" ]] && ret=1 && break
done <<< "$dns_sans"
if [[ $ret -eq 0 ]]; then
# Check whether any of the IP addresses in the certificate match the servername
ip_sans=$($OPENSSL x509 -in "$cert" -noout -text 2>>$ERRFILE | grep -A2 "Subject Alternative Name" | \
tr ',' '\n' | grep "IP Address:" | sed -e 's/IP Address://g' -e 's/ //g')
for san in $ip_sans; do
[[ "$san" == "$servername" ]] && ret=1 && break
done
while read san; do
[[ -n "$san" ]] && [[ "$san" == "$servername" ]] && ret=1 && break
done <<< "$ip_sans"
fi
# Check whether any of the DNS names in the certificate are wildcard names
# that match the servername
if [[ $ret -eq 0 ]]; then
for san in $dns_sans; do
while read san; do
[[ -n "$san" ]] || continue
wildcard_match "$servername" "$san"
[[ $? -eq 0 ]] && ret=2 && break
done
done <<< "$dns_sans"
fi
cn="$(get_cn_from_cert "$cert")"
......@@ -6195,16 +6225,21 @@ certificate_info() {
out "$indent"; pr_bold " Certificate Expiration "
enddate=$(parse_date "$($OPENSSL x509 -in $HOSTCERT -noout -enddate 2>>$ERRFILE | cut -d= -f 2)" +"%F %H:%M %z" "%b %d %T %Y %Z")
enddate=$(parse_date "$($OPENSSL x509 -in $HOSTCERT -noout -enddate 2>>$ERRFILE | cut -d= -f 2)" +"%F %H:%M" "%b %d %T %Y %Z")
startdate=$(parse_date "$($OPENSSL x509 -in $HOSTCERT -noout -startdate 2>>$ERRFILE | cut -d= -f 2)" +"%F %H:%M" "%b %d %T %Y %Z")
days2expire=$(( $(parse_date "$enddate" "+%s" "%F %H:%M %z") - $(LC_ALL=C date "+%s") )) # in seconds
days2expire=$((days2expire / 3600 / 24 ))
if grep -q "^Let's Encrypt Authority" <<< "$issuer_CN"; then # we take the half of the thresholds for LE certificates
days2warn2=$((days2warn2 / 2))
days2warn1=$((days2warn1 / 2))
fi
if "$HAS_OPENBSDDATE"; then
# best we are able to do under OpenBSD
days2expire=""
else
days2expire=$(( $(parse_date "$enddate" "+%s" "%F %H:%M") - $(LC_ALL=C date "+%s") )) # in seconds
days2expire=$((days2expire / 3600 / 24 ))
if grep -q "^Let's Encrypt Authority" <<< "$issuer_CN"; then # we take the half of the thresholds for LE certificates
days2warn2=$((days2warn2 / 2))
days2warn1=$((days2warn1 / 2))
fi
fi
expire=$($OPENSSL x509 -in $HOSTCERT -checkend 1 2>>$ERRFILE)
if ! grep -qw not <<< "$expire" ; then
pr_svrty_critical "expired!"
......@@ -6230,8 +6265,8 @@ certificate_info() {
expok="HIGH"
fi
fi
outln " ($startdate --> $enddate)"
fileout "${json_prefix}expiration" "$expok" "Certificate Expiration : $expfinding ($startdate --> $enddate)"
outln " (UTC: $startdate --> $enddate)"
fileout "${json_prefix}expiration" "$expok" "Certificate Expiration : $expfinding (UTC: $startdate --> $enddate)"
certificates_provided=1+$(grep -c "\-\-\-\-\-BEGIN CERTIFICATE\-\-\-\-\-" $TEMPDIR/intermediatecerts.pem)
out "$indent"; pr_bold " # of certificates provided"; outln " $certificates_provided"
......@@ -6435,9 +6470,9 @@ run_server_defaults() {
if [[ "$sans_nosni" == "$sans_sni" ]]; then
success[n]=0
else
for san in $sans_nosni; do
[[ " $sans_sni " =~ " $san " ]] && success[n]=0 && break
done
while read san; do
[[ -n "$san" ]] && [[ " $sans_sni " =~ " $san " ]] && success[n]=0 && break
done <<< "$sans_nosni"
fi
fi
fi
......@@ -6596,7 +6631,7 @@ get_session_ticket_lifetime_from_serverhello() {
get_san_dns_from_cert() {
echo "$($OPENSSL x509 -in "$1" -noout -text 2>>$ERRFILE | \
grep -A2 "Subject Alternative Name" | tr ',' '\n' | grep "DNS:" | \
sed -e 's/DNS://g' -e 's/ //g' | tr '\n' ' ')"
sed -e 's/DNS://g' -e 's/ //g')"
}
......@@ -7137,7 +7172,7 @@ starttls_just_read(){
}
starttls_full_read(){
starttls_read_data=()
local starttls_read_data=()
local one_line=""
local ret=0
local cont_pattern="$1"
......@@ -7160,6 +7195,11 @@ starttls_full_read(){
fi
fi
starttls_read_data+=("${one_line}")
if [[ $DEBUG -ge 4 ]]; then
echo "one_line: ${one_line}"
echo "end_pattern: ${end_pattern}"
echo "cont_pattern: ${cont_pattern}"
fi
if [[ ${one_line} =~ ${end_pattern} ]]; then
debugme echo "=== full read finished ==="
IFS="${oldIFS}"
......@@ -7204,9 +7244,9 @@ starttls_smtp_dialog(){
starttls_pop3_dialog() {
debugme echo "=== starting pop3 STARTTLS dialog ==="
starttls_full_read '$^' '^+OK' && debugme echo "received server greeting" &&
starttls_full_read '^\+OK' '^\+OK' && debugme echo "received server greeting" &&
starttls_just_send 'STLS' && debugme echo "initiated STARTTLS" &&
starttls_full_read '$^' '^+OK' && debugme echo "received ack for STARTTLS"
starttls_full_read '^\+OK' '^\+OK' && debugme echo "received ack for STARTTLS"
local ret=$?
debugme echo "=== finished pop3 STARTTLS dialog with ${ret} ==="
return $ret
......@@ -7356,8 +7396,9 @@ EOF
fatal "FIXME: STARTTLS protocol $STARTTLS_PROTOCOL is not yet supported" -4
esac
fi
return 0
[[ $? -eq 0 ]] && return 0
prln_warning "STARTTLS handshake failed"
return 1
}
......@@ -7663,12 +7704,21 @@ get_dh_ephemeralkey() {
# arg1: name of file with socket reply
# arg2: true if entire server hello should be parsed
# return values: 0=no SSLv2 (reset)
# 1=no SSLv2 (plaintext reply like it happens with OLS webservers)
# 3=SSLv2 supported (in $TEMPDIR/$NODEIP.sslv2_sockets.dd is reply for further processing
# --> there could be checked whether ciphers e.g have been returned at all (or anything else)
# 4=looks like an STARTTLS 5xx message
# 6=socket coudln't be opened
# 7=strange reply we can't deal with
parse_sslv2_serverhello() {
local ret v2_hello_ascii v2_hello_initbyte v2_hello_length
local v2_hello_handshake v2_cert_type v2_hello_cert_length
local v2_hello_cipherspec_length tmp_der_certfile
local -i certificate_len nr_ciphers_detected offset i
# server hello: in hex representation, see below
local ret=3
local parse_complete="false"
# SSLv2 server hello: in hex representation, see below
# byte 1+2: length of server hello 0123
# 3: 04=Handshake message, server hello 45
# 4: session id hit or not (boolean: 00=false, this 67
......@@ -7681,8 +7731,8 @@ parse_sslv2_serverhello() {
# [certificate length] ==> certificate
# [cipher spec length] ==> ciphers GOOD: HERE ARE ALL CIPHERS ALREADY!
local ret=3
local parse_complete="false"
# Note: recent SSL/TLS stacks reply with a TLS alert on a SSLv2 client hello.
# The TLS error message is different and could be used for fingerprinting.
if [[ "$2" == "true" ]]; then
parse_complete=true
......@@ -7707,7 +7757,17 @@ parse_sslv2_serverhello() {
V2_HELLO_CIPHERSPEC_LENGTH=$(printf "%d\n" "0x$v2_hello_cipherspec_length" 2>/dev/null)
[[ $? -ne 0 ]] && ret=7
if [[ $v2_hello_initbyte != "8" ]] || [[ $v2_hello_handshake != "04" ]]; then
if [[ "${v2_hello_ascii:0:4}" == "1503" ]]; then
# Cloudflare does this, OpenSSL 1.1.1 and picoTLS. With different alert messages
# Just in case somebody's interested in the exact error, we deliver it ;-)
debugme echo -n ">TLS< alert message discovered: ${v2_hello_ascii} "
case "${v2_hello_ascii:10:2}" in
01) debugme echo "(01/warning: 0x"${v2_hello_ascii:12:2}"/$(tls_alert "${v2_hello_ascii:12:2}"))" ;;
02) debugme echo "(02/fatal: 0x"${v2_hello_ascii:12:2}"/$(tls_alert "${v2_hello_ascii:12:2}"))" ;;
*) debugme echo "("${v2_hello_ascii:10:2}" : "${v2_hello_ascii:12:2}"))" ;;
esac
ret=0
elif [[ $v2_hello_initbyte != "8" ]] || [[ $v2_hello_handshake != "04" ]]; then
ret=1
if [[ $DEBUG -ge 2 ]]; then
echo "no correct server hello"
......@@ -7850,6 +7910,52 @@ check_tls_serverhellodone() {
return 1
}
# arg1: tls alert error/warning code
# returns: description
tls_alert() {
local tls_alert_text=""
case "$1" in
00) tls_alert_text="close notify" ;;
0A) tls_alert_text="unexpected message" ;;
14) tls_alert_text="bad record mac" ;;
15) tls_alert_text="decryption failed" ;;
16) tls_alert_text="record overflow" ;;
1E) tls_alert_text="decompression failure" ;;
28) tls_alert_text="handshake failure" ;;
29) tls_alert_text="no certificate RESERVED" ;;
2A) tls_alert_text="bad certificate" ;;
2B) tls_alert_text="unsupported certificate" ;;
2C) tls_alert_text="certificate revoked" ;;
2D) tls_alert_text="certificate expired" ;;
2E) tls_alert_text="certificate unknown" ;;
2F) tls_alert_text="illegal parameter" ;;
30) tls_alert_text="unknown ca" ;;
31) tls_alert_text="access denied" ;;
32) tls_alert_text="decode error" ;;
33) tls_alert_text="decrypt error" ;;
3C) tls_alert_text="export restriction RESERVED" ;;
46) tls_alert_text="protocol version" ;;
47) tls_alert_text="insufficient security" ;;
50) tls_alert_text="internal error" ;;
56) tls_alert_text="inappropriate fallback" ;;
5A) tls_alert_text="user canceled" ;;
64) tls_alert_text="no renegotiation" ;;
6D) tls_alert_text="missing extension" ;;
6E) tls_alert_text="unsupported extension" ;;
6F) tls_alert_text="certificate unobtainable" ;;
70) tls_alert_text="unrecognized name" ;;
71) tls_alert_text="bad certificate status response" ;;
72) tls_alert_text="bad certificate hash value" ;;
73) tls_alert_text="unknown psk identity" ;;
74) tls_alert_text="certificate required" ;;
78) tls_alert_text="no application protocol" ;;
*) tls_alert_text="$(hex2dec "$1")";;
esac
echo "$tls_alert_text"
return 0
}
# arg1: ASCII-HEX encoded reply
# arg2: (optional): "all" - process full response (including Certificate and certificate_status handshake messages)
# "ephemeralkey" - extract the server's ephemeral key (if any)
......@@ -7869,7 +7975,7 @@ parse_tls_serverhello() {
local tls_alert_descrip tls_sid_len_hex issuerDN subjectDN CAissuerDN CAsubjectDN
local -i tls_sid_len offset extns_offset nr_certs=0
local tls_msg_type tls_content_type tls_protocol tls_protocol2 tls_hello_time
local tls_err_level tls_err_descr tls_cipher_suite rfc_cipher_suite tls_compression_method
local tls_err_level tls_err_descr_no tls_cipher_suite rfc_cipher_suite tls_compression_method
local tls_extensions="" extension_type named_curve_str=""
local -i i j extension_len tls_extensions_len ocsp_response_len ocsp_response_list_len
local -i certificate_list_len certificate_len cipherlist_len
......@@ -7967,46 +8073,9 @@ parse_tls_serverhello() {
for (( i=0; i+3 < tls_alert_ascii_len; i=i+4 )); do
tls_err_level=${tls_alert_ascii:i:2} # 1: warning, 2: fatal
j=$i+2
tls_err_descr=${tls_alert_ascii:j:2}
debugme tm_out " tls_err_descr: 0x${tls_err_descr} / = $(hex2dec ${tls_err_descr})"
case $tls_err_descr in
00) tls_alert_descrip="close notify" ;;
01) tls_alert_descrip="end of early data" ;;
0A) tls_alert_descrip="unexpected message" ;;
14) tls_alert_descrip="bad record mac" ;;
15) tls_alert_descrip="decryption failed" ;;
16) tls_alert_descrip="record overflow" ;;
1E) tls_alert_descrip="decompression failure" ;;
28) tls_alert_descrip="handshake failure" ;;
29) tls_alert_descrip="no certificate RESERVED" ;;
2A) tls_alert_descrip="bad certificate" ;;
2B) tls_alert_descrip="unsupported certificate" ;;
2C) tls_alert_descrip="certificate revoked" ;;
2D) tls_alert_descrip="certificate expired" ;;
2E) tls_alert_descrip="certificate unknown" ;;
2F) tls_alert_descrip="illegal parameter" ;;
30) tls_alert_descrip="unknown ca" ;;
31) tls_alert_descrip="access denied" ;;
32) tls_alert_descrip="decode error" ;;
33) tls_alert_descrip="decrypt error" ;;
3C) tls_alert_descrip="export restriction RESERVED" ;;
46) tls_alert_descrip="protocol version" ;;
47) tls_alert_descrip="insufficient security" ;;
50) tls_alert_descrip="internal error" ;;
56) tls_alert_descrip="inappropriate fallback" ;;
5A) tls_alert_descrip="user canceled" ;;
64) tls_alert_descrip="no renegotiation" ;;
6D) tls_alert_descrip="missing extension" ;;
6E) tls_alert_descrip="unsupported extension" ;;
6F) tls_alert_descrip="certificate unobtainable" ;;
70) tls_alert_descrip="unrecognized name" ;;
71) tls_alert_descrip="bad certificate status response" ;;
72) tls_alert_descrip="bad certificate hash value" ;;
73) tls_alert_descrip="unknown psk identity" ;;
74) tls_alert_descrip="certificate required" ;;
78) tls_alert_descrip="no application protocol" ;;
*) tls_alert_descrip="$(hex2dec "$tls_err_descr")";;
esac
tls_err_descr_no=${tls_alert_ascii:j:2}
debugme tm_out " tls_err_descr_no: 0x${tls_err_descr_no} / = $(hex2dec ${tls_err_descr_no})"
tls_alert_descrip="$(tls_alert "$tls_err_descr_no")"
if [[ $DEBUG -ge 2 ]]; then
tmln_out " ($tls_alert_descrip)"
tm_out " tls_err_level: ${tls_err_level}"
......@@ -11518,7 +11587,7 @@ tuning / connect options (most also can be preset via environment variables):
--sneaky leave less traces in target logs: user agent, referer
output options (can also be preset via environment variables):
--warnings <batch|off|false> "batch" doesn't wait for keypress, "off" or "false" skips connection warning
--warnings <batch|off|false> "batch" doesn't ask for a confirmation, "off" or "false" skips connection warnings
--openssl-timeout <seconds> useful to avoid hangers. <seconds> to wait before openssl connect will be terminated
--quiet don't output the banner. By doing this you acknowledge usage terms normally appearing in the banner
--wide wide output for tests like RC4, BEAST. PFS also with hexcode, kx, strength, RFC name
......@@ -11623,6 +11692,7 @@ TERM_WIDTH: $TERM_WIDTH
INTERACTIVE: $INTERACTIVE
HAS_GNUDATE: $HAS_GNUDATE
HAS_FREEBSDDATE: $HAS_FREEBSDDATE
HAS_OPENBSDDATE: $HAS_OPENBSDDATE
HAS_SED_E: $HAS_SED_E
SHOW_EACH_C: $SHOW_EACH_C
......@@ -13024,6 +13094,7 @@ initialize_globals() {
do_tls_sockets=false
do_client_simulation=false
do_display_only=false
do_starttls=true
}
......@@ -13643,7 +13714,7 @@ lets_roll() {
SCAN_TIME=$(( END_TIME - START_TIME ))
datebanner " Done"
"$MEASURE_TIME" && printf "%${COLUMNS}s\n" "$SCAN_TIME"
"$MEASURE_TIME" && printf "$1: %${COLUMNS}s\n" "$SCAN_TIME"
[[ -e "$MEASURE_TIME_FILE" ]] && echo "Total : $SCAN_TIME " >> "$MEASURE_TIME_FILE"
return $ret
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment