Skip to content

Commit 6088edd

Browse files
author
David Cooper
committed
Show server supported signature algorithms
This commit modifies run_fs() to show the signature algorithms the server supports in the ServerKeyExchange message for TLS 1.2 and in the CertificateVerify message for TLS 1.3. Signature algorithms are not shown for TLS 1.1 and earlier, since for those protocol versions the signature algorithm to use is specified by the protocol. While the signature algorithm used in TLS 1.1 and earlier is weak, testssl.sh already warns if these protocol versions are supported.
1 parent 462a602 commit 6088edd

2 files changed

Lines changed: 136 additions & 3 deletions

File tree

t/baseline_data/default_testssl.csvfile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,8 @@
6666
"FS_ciphers","testssl.sh/81.169.166.184","443","INFO","TLS_AES_256_GCM_SHA384 TLS_CHACHA20_POLY1305_SHA256 ECDHE-RSA-AES256-GCM-SHA384 ECDHE-RSA-AES256-SHA384 ECDHE-RSA-AES256-SHA DHE-RSA-AES256-GCM-SHA384 DHE-RSA-AES256-SHA256 DHE-RSA-AES256-SHA DHE-RSA-CAMELLIA256-SHA TLS_AES_128_GCM_SHA256 ECDHE-RSA-AES128-GCM-SHA256 ECDHE-RSA-AES128-SHA DHE-RSA-AES128-GCM-SHA256 DHE-RSA-AES128-SHA256 DHE-RSA-AES128-SHA DHE-RSA-CAMELLIA128-SHA","",""
6767
"FS_ECDHE_curves","testssl.sh/81.169.166.184","443","OK","prime256v1 secp384r1 secp521r1 X25519 X448","",""
6868
"DH_groups","testssl.sh/81.169.166.184","443","OK","Unknown DH group (2048 bits)","",""
69+
"FS_TLS12_sig_algs","testssl.sh/81.169.166.184","443","INFO","RSA-PSS+SHA256 RSA-PSS+SHA384 RSA-PSS+SHA512 RSA+SHA256 RSA+SHA384 RSA+SHA512 RSA+SHA224","",""
70+
"FS_TLS13_sig_algs","testssl.sh/81.169.166.184","443","INFO","RSA-PSS+SHA256 RSA-PSS+SHA384 RSA-PSS+SHA512","",""
6971
"HTTP_status_code","testssl.sh/81.169.166.184","443","INFO","200 OK ('/')","",""
7072
"HTTP_clock_skew","testssl.sh/81.169.166.184","443","INFO","0 seconds from localtime","",""
7173
"HTTP_headerTime","testssl.sh/81.169.166.184","443","INFO","1654006271","",""

testssl.sh

Lines changed: 134 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6265,6 +6265,19 @@ run_cipherlists() {
62656265
return $ret
62666266
}
62676267

6268+
pr_sigalg_quality() {
6269+
local sigalg="$1"
6270+
6271+
if [[ "$sigalg" =~ MD5 ]]; then
6272+
pr_svrty_high "$sigalg"
6273+
elif [[ "$sigalg" =~ SHA1 ]]; then
6274+
pr_svrty_low "$sigalg"
6275+
else
6276+
out "$sigalg"
6277+
fi
6278+
}
6279+
6280+
62686281
# The return value is an indicator of the quality of the DH key length in $1:
62696282
# 1 = pr_svrty_critical, 2 = pr_svrty_high, 3 = pr_svrty_medium, 4 = pr_svrty_low
62706283
# 5 = neither good nor bad, 6 = pr_svrty_good, 7 = pr_svrty_best
@@ -10319,7 +10332,7 @@ get_san_dns_from_cert() {
1031910332
run_fs() {
1032010333
local -i sclient_success
1032110334
local fs_offered=false ecdhe_offered=false ffdhe_offered=false
10322-
local fs_tls13_offered=false
10335+
local fs_tls13_offered=false fs_tls12_offered=false
1032310336
local protos_to_try proto hexc dash fs_cipher sslvers auth mac export curve dhlen
1032410337
local -a hexcode normalized_hexcode ciph rfc_ciph kx enc ciphers_found sigalg ossl_supported
1032510338
# generated from 'kEECDH:kEDH:!aNULL:!eNULL:!DES:!3DES:!RC4' with openssl 1.0.2i and openssl 1.1.0
@@ -10336,10 +10349,16 @@ run_fs() {
1033610349
local -a ffdhe_groups_hex=("01,00" "01,01" "01,02" "01,03" "01,04")
1033710350
local -a ffdhe_groups_output=("ffdhe2048" "ffdhe3072" "ffdhe4096" "ffdhe6144" "ffdhe8192")
1033810351
local -a supported_curve
10352+
local -a sigalgs_hex=("01,01" "01,02" "01,03" "02,01" "02,02" "02,03" "03,01" "03,02" "03,03" "04,01" "04,02" "04,03" "04,20" "05,01" "05,02" "05,03" "05,20" "06,01" "06,02" "06,03" "06,20" "07,08" "08,04" "08,05" "08,06" "08,07" "08,08" "08,09" "08,0a" "08,0b" "08,1a" "08,1b" "08,1c")
10353+
local -a sigalgs_strings=("RSA+MD5" "DSA+MD5" "ECDSA+MD5" "RSA+SHA1" "DSA+SHA1" "ECDSA+SHA1" "RSA+SHA224" "DSA+SHA224" "ECDSA+SHA224" "RSA+SHA256" "DSA+SHA256" "ECDSA+SHA256" "RSA+SHA256" "RSA+SHA384" "DSA+SHA384" "ECDSA+SHA384" "RSA+SHA384" "RSA+SHA512" "DSA+SHA512" "ECDSA+SHA512" "RSA+SHA512" "SM2+SM3" "RSA-PSS+SHA256" "RSA-PSS+SHA384" "RSA-PSS+SHA512" "Ed25519" "Ed448" "RSA-PSS+SHA256" "RSA-PSS+SHA384" "RSA-PSS+SHA512" "ECDSA+SHA256" "ECDSA+SHA384" "ECDSA+SHA512")
10354+
local -a tls13_supported_sigalgs=("false" "false" "false" "false" "false" "false" "false" "false" "false" "false" "false" "false" "false" "false" "false" "false" "false" "false" "false" "false" "false" "false" "false" "false" "false" "false" "false" "false" "false" "false" "false" "false" "false")
10355+
local -a tls12_supported_sigalgs=("false" "false" "false" "false" "false" "false" "false" "false" "false" "false" "false" "false" "false" "false" "false" "false" "false" "false" "false" "false" "false" "false" "false" "false" "false" "false" "false" "false" "false" "false" "false" "false" "false")
10356+
local rsa_cipher="" ecdsa_cipher="" dss_cipher=""
10357+
local sigalgs_to_test tls12_supported_sigalg_list="" tls13_supported_sigalg_list=""
1033910358
local -i nr_supported_ciphers=0 nr_curves=0 nr_ossl_curves=0 i j low high
1034010359
local fs_ciphers curves_offered="" curves_to_test temp
1034110360
local curves_option="" curves_list1="" curves_list2=""
10342-
local len1 len2 curve_found
10361+
local len1 len2 curve_found sigalg_found
1034310362
local key_bitstring quality_str
1034410363
local -i len_dh_p quality
1034510364
local has_dh_bits="$HAS_DH_BITS"
@@ -10526,6 +10545,9 @@ run_fs() {
1052610545
"$WIDE" && kx[i]="$(read_dhtype_from_file $TMPFILE)"
1052710546
elif [[ "$fs_cipher" == ECDHE-* ]]; then
1052810547
ecdhe_offered=true
10548+
! "$fs_tls12_offered" && [[ "$(get_protocol "$TMPFILE")" == TLSv1.2 ]] && fs_tls12_offered=true
10549+
else
10550+
! "$fs_tls12_offered" && [[ "$(get_protocol "$TMPFILE")" == TLSv1.2 ]] && fs_tls12_offered=true
1052910551
fi
1053010552
if "$WIDE"; then
1053110553
dhlen=$(read_dhbits_from_file "$TMPFILE" quiet)
@@ -10569,6 +10591,12 @@ run_fs() {
1056910591
fi
1057010592
"$WIDE" && "$SHOW_SIGALGO" && [[ -r "$HOSTCERT" ]] && \
1057110593
sigalg[i]="$(read_sigalg_from_file "$HOSTCERT")"
10594+
if [[ "$proto" == 03 ]]; then
10595+
[[ $sclient_success -eq 0 ]] && fs_tls12_offered=true
10596+
elif ! "$fs_tls12_offered" && [[ $sclient_success -eq 2 ]] && \
10597+
[[ "$(get_protocol "$TEMPDIR/$NODEIP.parse_tls_serverhello.txt")" == TLSv1.2 ]]; then
10598+
fs_tls12_offered=true
10599+
fi
1057210600
done
1057310601
done
1057410602
fi
@@ -10861,9 +10889,112 @@ run_fs() {
1086110889
else
1086210890
fileout "DH_groups" "$quality_str" "$curves_offered"
1086310891
fi
10892+
outln
10893+
fi
10894+
fi
10895+
if "$using_sockets"; then
10896+
protos_to_try=""
10897+
"$fs_tls13_offered" && protos_to_try="04"
10898+
# For TLS 1.2, find a supported cipher suite corresponding to each of the key types (RSA, ECDSA, DSS).
10899+
# Need to try each key type separately, otherwise not all supported signature algorithms will be found.
10900+
if "$fs_tls12_offered"; then
10901+
for (( i=0; i < nr_supported_ciphers; i++ )); do
10902+
! "${ciphers_found[i]}" && continue
10903+
if [[ -z "$rsa_cipher" ]] && { [[ "${rfc_ciph[i]}" == TLS_DHE_RSA* ]] ||
10904+
[[ "${rfc_ciph[i]}" == TLS_ECDHE_RSA* ]] || [[ "${ciph[i]}" == DHE-RSA-* ]] ||
10905+
[[ "${ciph[i]}" == ECDHE-RSA-* ]]; }; then
10906+
rsa_cipher="${hexcode[i]}"
10907+
elif [[ -z "$ecdsa_cipher" ]] && { [[ "${rfc_ciph[i]}" == TLS_ECDHE_ECDSA* ]] || [[ "${ciph[i]}" == ECDHE-ECDSA-* ]]; }; then
10908+
ecdsa_cipher="${hexcode[i]}"
10909+
elif [[ -z "$dss_cipher" ]] && { [[ "${rfc_ciph[i]}" == TLS_DHE_DSS* ]] || [[ "${ciph[i]}" == DHE-DSS-* ]]; }; then
10910+
dss_cipher="${hexcode[i]}"
10911+
fi
10912+
done
10913+
[[ -n "$rsa_cipher" ]] && protos_to_try+=" 03-$rsa_cipher"
10914+
[[ -n "$ecdsa_cipher" ]] && protos_to_try+=" 03-$ecdsa_cipher"
10915+
[[ -n "$dss_cipher" ]] && protos_to_try+=" 03-$dss_cipher"
10916+
fi
10917+
for proto in $protos_to_try; do
10918+
while true; do
10919+
i=0
10920+
sigalgs_to_test=""
10921+
for hexc in "${sigalgs_hex[@]}"; do
10922+
if [[ "$proto" == 04 ]]; then
10923+
! "${tls13_supported_sigalgs[i]}" && sigalgs_to_test+=", $hexc"
10924+
else
10925+
! "${tls12_supported_sigalgs[i]}" && sigalgs_to_test+=", $hexc"
10926+
fi
10927+
i+=1
10928+
done
10929+
[[ -z "$sigalgs_to_test" ]] && break
10930+
len1=$(printf "%02x" "$((2*${#sigalgs_to_test}/7))")
10931+
len2=$(printf "%02x" "$((2*${#sigalgs_to_test}/7+2))")
10932+
if [[ "$proto" == 04 ]]; then
10933+
tls_sockets "$proto" "$TLS13_CIPHER" "all+" "00,0d, 00,$len2, 00,$len1, ${sigalgs_to_test:2}"
10934+
else
10935+
tls_sockets "${proto%-*}" "${proto#*-}, 00,ff" "ephemeralkey" "00,0d, 00,$len2, 00,$len1, ${sigalgs_to_test:2}"
10936+
fi
10937+
[[ $? -eq 0 ]] || break
10938+
sigalg_found="$(awk -F ': ' '/^Peer signing digest/ { print $2 } ' "$TEMPDIR/$NODEIP.parse_tls_serverhello.txt")"
10939+
[[ -n "$sigalg_found" ]] && sigalg_found="+$sigalg_found"
10940+
sigalg_found="$(awk -F ': ' '/^Peer signature type/ { print $2 } ' "$TEMPDIR/$NODEIP.parse_tls_serverhello.txt")$sigalg_found"
10941+
i=0
10942+
for hexc in "${sigalgs_hex[@]}"; do
10943+
[[ "${sigalgs_strings[i]}" == $sigalg_found ]] && break
10944+
i+=1
10945+
done
10946+
[[ -z "${sigalgs_hex[i]}" ]] && break
10947+
if [[ "$proto" == 04 ]]; then
10948+
"${tls13_supported_sigalgs[i]}" && break
10949+
tls13_supported_sigalgs[i]=true
10950+
tls13_supported_sigalg_list+=" $sigalg_found"
10951+
else
10952+
"${tls12_supported_sigalgs[i]}" && break
10953+
tls12_supported_sigalgs[i]=true
10954+
tls12_supported_sigalg_list+=" $sigalg_found"
10955+
fi
10956+
done
10957+
done
10958+
tls12_supported_sigalg_list="${tls12_supported_sigalg_list:1}"
10959+
tls13_supported_sigalg_list="${tls13_supported_sigalg_list:1}"
10960+
if "$fs_tls12_offered"; then
10961+
pr_bold " TLS 1.2 sig_algs offered: "
10962+
if [[ -z "$(sed -e 's/[A-Za-z\-]*+SHA1//g' -e 's/[A-Za-z\-]*+MD5//g' -e 's/ //g' <<< "$tls12_supported_sigalg_list")" ]]; then
10963+
prln_svrty_critical "$(out_row_aligned_max_width "$tls12_supported_sigalg_list " " " $TERM_WIDTH)"
10964+
fileout "${jsonID}_TLS12_sig_algs" "CRITICAL" "$tls12_supported_sigalg_list"
10965+
else
10966+
out_row_aligned_max_width_by_entry "$tls12_supported_sigalg_list " " " $TERM_WIDTH pr_sigalg_quality
10967+
outln
10968+
if [[ "$tls12_supported_sigalg_list" =~ MD5 ]]; then
10969+
fileout "${jsonID}_TLS12_sig_algs" "HIGH" "$tls12_supported_sigalg_list"
10970+
elif [[ "$tls12_supported_sigalg_list" =~ SHA1 ]]; then
10971+
fileout "${jsonID}_TLS12_sig_algs" "LOW" "$tls12_supported_sigalg_list"
10972+
else
10973+
fileout "${jsonID}_TLS12_sig_algs" "INFO" "$tls12_supported_sigalg_list"
10974+
fi
10975+
fi
10976+
fi
10977+
if "$fs_tls13_offered"; then
10978+
pr_bold " TLS 1.3 sig_algs offered: "
10979+
# If only SHA1 and MD5 signature algorithms are supported, this is a critical finding.
10980+
# If SHA1 and/or MD5 are supported, but stronger algorithms are also supported, the
10981+
# severity is less.
10982+
if [[ -z "$(sed -e 's/[A-Za-z\-]*+SHA1//g' -e 's/[A-Za-z\-]*+MD5//g' -e 's/ //g' <<< "$tls13_supported_sigalg_list")" ]]; then
10983+
prln_svrty_critical "$(out_row_aligned_max_width "$tls13_supported_sigalg_list " " " $TERM_WIDTH)"
10984+
fileout "${jsonID}_TLS13_sig_algs" "CRITICAL" "$tls13_supported_sigalg_list"
10985+
else
10986+
out_row_aligned_max_width_by_entry "$tls13_supported_sigalg_list " " " $TERM_WIDTH pr_sigalg_quality
10987+
outln
10988+
if [[ "$tls13_supported_sigalg_list" =~ MD5 ]]; then
10989+
fileout "${jsonID}_TLS13_sig_algs" "HIGH" "$tls13_supported_sigalg_list"
10990+
elif [[ "$tls13_supported_sigalg_list" =~ SHA1 ]]; then
10991+
fileout "${jsonID}_TLS13_sig_algs" "LOW" "$tls13_supported_sigalg_list"
10992+
else
10993+
fileout "${jsonID}_TLS13_sig_algs" "INFO" "$tls13_supported_sigalg_list"
10994+
fi
10995+
fi
1086410996
fi
1086510997
fi
10866-
outln
1086710998

1086810999
tmpfile_handle ${FUNCNAME[0]}.txt
1086911000
"$using_sockets" && HAS_DH_BITS="$has_dh_bits"

0 commit comments

Comments
 (0)