Merge branch '2.9dev' of github.com:drwetter/testssl.sh into 2.9dev

This commit is contained in:
Dirk 2017-02-21 08:50:46 +01:00
commit 34053e27cd
1 changed files with 164 additions and 32 deletions

View File

@ -4660,6 +4660,80 @@ pr_ecdh_curve_quality() {
fi
}
# Print $2 based on the quality of the cipher in $1. If $2 is empty, print $1.
# The return value 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
# 5 = neither good nor bad, 6 = pr_done_good, 7 = pr_done_best
pr_cipher_quality() {
local cipher="$1"
local text="$2"
[[ -z "$1" ]] && return 0
[[ -z "$text" ]] && text="$cipher"
if [[ "$cipher" != TLS_* ]] && [[ "$cipher" != SSL_* ]]; then
# This must be the OpenSSL name for a cipher
if [[ $TLS_NR_CIPHERS -eq 0 ]]; then
# We have the OpenSSL name and can't convert it to the RFC name
case "$cipher" in
*NULL*|*EXP*)
pr_svrty_critical "$text"
return 1
;;
*RC4*)
pr_svrty_high "$text"
return 2
;;
*CBC*)
pr_svrty_medium "$text"
return 3
;; # FIXME BEAST: We miss some CBC ciphers here, need to work w/ a list
*GCM*|*CHACHA20*)
pr_done_best "$text"
return 7
;; #best ones
ECDHE*AES*)
pr_svrty_low "$text"
return 4
;; # it's CBC. --> lucky13
*)
out "$text"
return 5
;;
esac
fi
cipher="$(openssl2rfc "$cipher")"
fi
case "$cipher" in
*NULL*|*EXP*|*RC2*|*_DES_*|*_DES40_*)
pr_svrty_critical "$text"
return 1
;;
*RC4*)
pr_svrty_high "$text"
return 2
;;
*ECDHE*AES*CBC*)
pr_svrty_low "$text"
return 4
;;
*CBC*)
pr_svrty_medium "$text"
return 3
;;
*GCM*|*CHACHA20*)
pr_done_best "$text"
return 7
;;
*)
out "$text"
return 5
;;
esac
}
# arg1: file with input for grepping the bit length for ECDH/DHE
# arg2: whether to print warning "old fart" or not (empty: no)
read_dhbits_from_file() {
@ -4876,28 +4950,24 @@ run_server_preference() {
default_cipher="$(openssl2rfc "$default_cipher_ossl")"
[[ -z "$default_cipher" ]] && default_cipher="$default_cipher_ossl"
fi
case "$default_cipher_ossl" in
*NULL*|*EXP*)
pr_svrty_critical "$default_cipher"
pr_cipher_quality "$default_cipher"
case $? in
1)
fileout "order_cipher" "CRITICAL" "Default cipher: $default_cipher$(read_dhbits_from_file "$TMPFILE") $remark4default_cipher"
;;
*RC4*)
pr_svrty_high "$default_cipher"
2)
fileout "order_cipher" "HIGH" "Default cipher: $default_cipher$(read_dhbits_from_file "$TMPFILE") $remark4default_cipher"
;;
*CBC*)
pr_svrty_medium "$default_cipher"
3)
fileout "order_cipher" "MEDIUM" "Default cipher: $default_cipher$(read_dhbits_from_file "$TMPFILE") $remark4default_cipher"
;; # FIXME BEAST: We miss some CBC ciphers here, need to work w/ a list
*GCM*|*CHACHA20*)
pr_done_best "$default_cipher"
;;
6|7)
fileout "order_cipher" "OK" "Default cipher: $default_cipher$(read_dhbits_from_file "$TMPFILE") $remark4default_cipher"
;; # best ones
ECDHE*AES*)
pr_svrty_low "$default_cipher"
4)
fileout "order_cipher" "LOW" "Default cipher: $default_cipher$(read_dhbits_from_file "$TMPFILE") (cbc) $remark4default_cipher"
;; # it's CBC. --> lucky13
"")
0)
pr_warning "default cipher empty" ;
if [[ $OSSL_VER == 1.0.2* ]]; then
out " (Hint: if IIS6 give OpenSSL 1.0.1 a try)"
@ -4907,7 +4977,6 @@ run_server_preference() {
fi
;;
*)
out "$default_cipher"
fileout "order_cipher" "INFO" "Default cipher: $default_cipher$(read_dhbits_from_file "$TMPFILE") $remark4default_cipher"
;;
esac
@ -5894,6 +5963,50 @@ compare_server_name_to_cert()
return $ret
}
must_staple() {
local json_prefix="$2"
local cert extn
local -i extn_len
local supported=false
# Note this function is only looking for status_request (5) and not
# status_request_v2 (17), since OpenSSL seems to only include status_request (5)
# in its ClientHello when the "-status" option is used.
# OpenSSL 1.1.0 supports pretty-printing the "TLS Feature extension." For any
# previous versions of OpenSSL, OpenSSL can only show if the extension OID is present.
if $OPENSSL x509 -in "$HOSTCERT" -noout -text 2>>$ERRFILE | grep -A 1 "TLS Feature:" | grep -q "status_request"; then
# FIXME: This will indicate that must staple is supported if the
# certificate indicates status_request or status_request_v2. This is
# probably okay, since it seems likely that any TLS Feature extension
# that includes status_request_v2 will also include status_request.
supported=true
elif $OPENSSL x509 -in "$HOSTCERT" -noout -text 2>>$ERRFILE | grep -q "1.3.6.1.5.5.7.1.24:"; then
cert="$($OPENSSL x509 -in "$HOSTCERT" -outform DER 2>>$ERRFILE | hexdump -v -e '16/1 "%02X"')"
extn="${cert##*06082B06010505070118}"
# Check for critical bit, and skip over it if present.
[[ "${extn:0:6}" == "0101FF" ]] && extn="${extn:6}"
# Next is tag and length of extnValue OCTET STRING. Assume it is less than 128 bytes.
extn="${extn:4}"
# The TLS Feature is a SEQUENCE of INTEGER. Get the length of the SEQUENCE
extn_len=2*$(hex2dec "${extn:2:2}")
# If the extension include the status_request (5), then it supports must staple.
if [[ "${extn:4:extn_len}" =~ "020105" ]]; then
supported=true
fi
fi
if "$supported"; then
pr_done_bestln "Supported"
fileout "${json_prefix}ocsp_must_staple" "OK" "OCSP must staple : supported"
return 0
else
outln "No"
fileout "${json_prefix}ocsp_must_staple" "INFO" "OCSP must staple : no"
return 1
fi
}
certificate_info() {
local proto
local -i certificate_number=$1
@ -5904,7 +6017,8 @@ certificate_info() {
local ocsp_response_status=$6
local sni_used=$7
local cert_sig_algo cert_sig_hash_algo cert_key_algo
local expire days2expire secs2warn ocsp_uri crl startdate enddate issuer_CN issuer_C issuer_O issuer sans san all_san="" cn
local expire days2expire secs2warn ocsp_uri ocsp_must_staple crl
local startdate enddate issuer_CN issuer_C issuer_O issuer sans san all_san="" cn
local issuer_DC issuerfinding cn_nosni=""
local cert_fingerprint_sha1 cert_fingerprint_sha2 cert_fingerprint_serial
local policy_oid
@ -6423,10 +6537,22 @@ certificate_info() {
fileout "${json_prefix}ocsp_uri" "INFO" "OCSP URI : $ocsp_uri"
fi
out "$indent"; pr_bold " OCSP must staple ";
must_staple "$json_prefix"
[[ $? -eq 0 ]] && ocsp_must_staple=true || ocsp_must_staple=false
out "$indent"; pr_bold " OCSP stapling "
if grep -a "OCSP response" <<<"$ocsp_response" | grep -q "no response sent" ; then
pr_svrty_low "--"
fileout "${json_prefix}ocsp_stapling" "LOW" "OCSP stapling : not offered"
if "$ocsp_must_staple"; then
pr_svrty_critical "--"
fileout "${json_prefix}ocsp_stapling" "CRITICAL" "OCSP stapling : not offered"
elif [[ -n "$ocsp_uri" ]]; then
pr_svrty_low "--"
fileout "${json_prefix}ocsp_stapling" "LOW" "OCSP stapling : not offered"
else
out "--"
fileout "${json_prefix}ocsp_stapling" "INFO" "OCSP stapling : not offered"
fi
else
if grep -a "OCSP Response Status" <<<"$ocsp_response_status" | grep -q successful; then
pr_done_good "offered"
@ -9350,9 +9476,6 @@ run_ccs_injection(){
if [[ $DEBUG -ge 3 ]]; then
outln "\n1st reply: "
hexdump -C "$SOCK_REPLY_FILE" | head -20
# ok: 15 | 0301 | 02 | 02 | 0a
# ALERT | TLS 1.0 | Length=2 | Unexpected Message (0a)
# or just timed out
outln
out "sending payload #2 with TLS version $tls_hexcode: "
fi
@ -9372,29 +9495,38 @@ run_ccs_injection(){
outln
fi
# not ok: 15 | 0301 | 02 | 02 | 15
# ALERT | TLS 1.0 | Length=2 | Decryption failed (21)
# in general, see https://en.wikipedia.org/wiki/Transport_Layer_Security#Alert_protocol
# https://tools.ietf.org/html/rfc5246#section-7.2
#
# ok: 0a or nothing: ==> RST
# not ok fo CCSI: 15 | 0301 | 00 02 | 02 15
# ALERT | TLS 1.0 | Length=2 | Decryption failed (21)
#
# ok: nothing: ==> RST
#
# 0A: Unexpected message
# 28: Handshake failure
if [[ -z "${tls_hello_ascii:0:12}" ]]; then
# empty reply
pr_done_best "not vulnerable (OK)"
if [[ $retval -eq 3 ]]; then
### what?
fileout "ccs" "OK" "CCS: not vulnerable (timed out)" "$cve" "$cwe"
else
fileout "ccs" "OK" "CCS: not vulnerable" "$cve" "$cwe"
fi
ret=0
elif [[ "$byte6" == "15" ]] && [[ "${tls_hello_ascii:0:4}" == "1503" ]]; then
# decyption failed received
pr_svrty_critical "VULNERABLE (NOT ok)"
if [[ $retval -eq 3 ]]; then
fileout "ccs" "CRITICAL" "CCS: VULNERABLE (timed out)" "$cve" "$cwe" "$hint"
else
fileout "ccs" "CRITICAL" "CCS: VULNERABLE" "$cve" "$cwe" "$hint"
fi
fileout "ccs" "CRITICAL" "CCS: VULNERABLE" "$cve" "$cwe" "$hint"
ret=1
elif [[ "${tls_hello_ascii:0:4}" == "1503" ]]; then
if [[ "$byte6" == "0A" ]] || [[ "$byte6" == "28" ]]; then
# Unexpected message / Handshake failure received
pr_warning "likely "
out "not vulnerable (OK)"
out " - alert description type: $byte6"
fileout "ccs" "WARN" "CCS: probably not vulnerable but received 0x${byte6} instead of 0x15" "$cve" "$cwe" "$hint"
fi
elif [[ "$byte6" == [0-9a-f][0-9a-f] ]] && [[ "${tls_hello_ascii:2:2}" != "03" ]]; then
pr_warning "test failed"
out ", probably read buffer too small (${tls_hello_ascii:0:14})"
@ -9402,8 +9534,8 @@ run_ccs_injection(){
ret=7
else
pr_warning "test failed "
out "around line $LINENO (debug info: ${tls_hello_ascii:0:14})"
fileout "ccs" "WARN" "CCS: test failed, around line $LINENO, debug info (${tls_hello_ascii:0:14})" "$cve" "$cwe" "$hint"
out "around line $LINENO (debug info: ${tls_hello_ascii:0:12},$byte6)"
fileout "ccs" "WARN" "CCS: test failed, around line $LINENO, debug info (${tls_hello_ascii:0:12},$byte6)" "$cve" "$cwe" "$hint"
ret=7
fi
outln