@@ -277,7 +277,7 @@ KNOWN_OSSL_PROB=false # We need OpenSSL a few times. This vari
277
277
DETECTED_TLS_VERSION="" # .. as hex string, e.g. 0300 or 0303
278
278
APP_TRAF_KEY_INFO="" # Information about the application traffic keys for a TLS 1.3 connection.
279
279
TLS13_ONLY=false # Does the server support TLS 1.3 ONLY?
280
- TLS_EXTENSIONS=""
280
+ declare -a TLS_EXTENSIONS=()
281
281
TLS13_CERT_COMPRESS_METHODS=""
282
282
CERTIFICATE_TRANSPARENCY_SOURCE=""
283
283
V2_HELLO_CIPHERSPEC_LENGTH=0
@@ -7882,6 +7882,7 @@ sclient_connect_successful() {
7882
7882
7883
7883
extract_new_tls_extensions() {
7884
7884
local tls_extensions
7885
+ local -i i
7885
7886
7886
7887
# this is not beautiful (grep+sed)
7887
7888
# but maybe we should just get the ids and do a private matching, according to
@@ -7895,12 +7896,15 @@ extract_new_tls_extensions() {
7895
7896
if [[ -n "$tls_extensions" ]]; then
7896
7897
# check to see if any new TLS extensions were returned and add any new ones to TLS_EXTENSIONS
7897
7898
while read -d "\"" -r line; do
7898
- if [[ $line != "" ]] && [[ ! "$TLS_EXTENSIONS" =~ "$line" ]]; then
7899
- #FIXME: This is a string of quoted strings, so this seems to determine the output format already. Better e.g. would be an array
7900
- TLS_EXTENSIONS+=" \"${line}\""
7899
+ if [[ $line != "" ]] && [[ ! "${TLS_EXTENSIONS[*]}" =~ "$line" ]]; then
7900
+ i=${#TLS_EXTENSIONS[*]}
7901
+ while [[ $i -gt 0 ]] && [[ ${TLS_EXTENSIONS[i-1]#*/#} -gt ${line#*/#} ]]; do
7902
+ TLS_EXTENSIONS[i]="${TLS_EXTENSIONS[i-1]}"
7903
+ i=$((i-1))
7904
+ done
7905
+ TLS_EXTENSIONS[i]="$line"
7901
7906
fi
7902
7907
done <<<$tls_extensions
7903
- [[ "${TLS_EXTENSIONS:0:1}" == " " ]] && TLS_EXTENSIONS="${TLS_EXTENSIONS:1}"
7904
7908
fi
7905
7909
}
7906
7910
@@ -7916,7 +7920,7 @@ extract_new_tls_extensions() {
7916
7920
determine_tls_extensions() {
7917
7921
local addcmd
7918
7922
local -i success=1
7919
- local line params="" tls_extensions=""
7923
+ local line params="" tls_extensions="" extn
7920
7924
local alpn_proto alpn="" alpn_list_len_hex alpn_extn_len_hex
7921
7925
local -i alpn_list_len alpn_extn_len
7922
7926
local cbc_cipher_list="ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA256:DH-RSA-AES256-SHA256:DH-DSS-AES256-SHA256:DHE-RSA-AES256-SHA:DHE-DSS-AES256-SHA:DH-RSA-AES256-SHA:DH-DSS-AES256-SHA:ECDHE-RSA-CAMELLIA256-SHA384:ECDHE-ECDSA-CAMELLIA256-SHA384:DHE-RSA-CAMELLIA256-SHA256:DHE-DSS-CAMELLIA256-SHA256:DH-RSA-CAMELLIA256-SHA256:DH-DSS-CAMELLIA256-SHA256:DHE-RSA-CAMELLIA256-SHA:DHE-DSS-CAMELLIA256-SHA:DH-RSA-CAMELLIA256-SHA:DH-DSS-CAMELLIA256-SHA:ECDH-RSA-AES256-SHA384:ECDH-ECDSA-AES256-SHA384:ECDH-RSA-AES256-SHA:ECDH-ECDSA-AES256-SHA:ECDH-RSA-CAMELLIA256-SHA384:ECDH-ECDSA-CAMELLIA256-SHA384:AES256-SHA256:AES256-SHA:CAMELLIA256-SHA256:CAMELLIA256-SHA:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:DHE-RSA-AES128-SHA256:DHE-DSS-AES128-SHA256:DH-RSA-AES128-SHA256:DH-DSS-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA:DH-RSA-AES128-SHA:DH-DSS-AES128-SHA:ECDHE-RSA-CAMELLIA128-SHA256:ECDHE-ECDSA-CAMELLIA128-SHA256:DHE-RSA-CAMELLIA128-SHA256:DHE-DSS-CAMELLIA128-SHA256:DH-RSA-CAMELLIA128-SHA256:DH-DSS-CAMELLIA128-SHA256:DHE-RSA-SEED-SHA:DHE-DSS-SEED-SHA:DH-RSA-SEED-SHA:DH-DSS-SEED-SHA:DHE-RSA-CAMELLIA128-SHA:DHE-DSS-CAMELLIA128-SHA:DH-RSA-CAMELLIA128-SHA:DH-DSS-CAMELLIA128-SHA:ECDH-RSA-AES128-SHA256:ECDH-ECDSA-AES128-SHA256:ECDH-RSA-AES128-SHA:ECDH-ECDSA-AES128-SHA:ECDH-RSA-CAMELLIA128-SHA256:ECDH-ECDSA-CAMELLIA128-SHA256:AES128-SHA256:AES128-SHA:CAMELLIA128-SHA256:SEED-SHA:CAMELLIA128-SHA:IDEA-CBC-SHA:ECDHE-RSA-DES-CBC3-SHA:ECDHE-ECDSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:EDH-DSS-DES-CBC3-SHA:DH-RSA-DES-CBC3-SHA:DH-DSS-DES-CBC3-SHA:ECDH-RSA-DES-CBC3-SHA:ECDH-ECDSA-DES-CBC3-SHA:DES-CBC3-SHA:EXP1024-DHE-DSS-DES-CBC-SHA:EDH-RSA-DES-CBC-SHA:EDH-DSS-DES-CBC-SHA:DH-RSA-DES-CBC-SHA:DH-DSS-DES-CBC-SHA:EXP1024-DES-CBC-SHA:DES-CBC-SHA:EXP-EDH-RSA-DES-CBC-SHA:EXP-EDH-DSS-DES-CBC-SHA:EXP-DES-CBC-SHA:EXP-RC2-CBC-MD5:EXP-DH-DSS-DES-CBC-SHA:EXP-DH-RSA-DES-CBC-SHA"
@@ -7938,7 +7942,7 @@ determine_tls_extensions() {
7938
7942
alpn_extn_len_hex=$(printf "%04x" $alpn_extn_len)
7939
7943
tls_extensions+=", 00,10,${alpn_extn_len_hex:0:2},${alpn_extn_len_hex:2:2},${alpn_list_len_hex:0:2},${alpn_list_len_hex:2:2}$alpn"
7940
7944
fi
7941
- if [[ ! "$TLS_EXTENSIONS" =~ encrypt-then-mac ]]; then
7945
+ if [[ ! "${ TLS_EXTENSIONS[*]} " =~ encrypt-then-mac ]]; then
7942
7946
tls_sockets "03" "$cbc_cipher_list_hex, 00,ff" "all" "$tls_extensions"
7943
7947
success=$?
7944
7948
fi
@@ -7963,7 +7967,7 @@ determine_tls_extensions() {
7963
7967
else
7964
7968
addcmd="$SNI"
7965
7969
fi
7966
- if [[ ! "$TLS_EXTENSIONS" =~ encrypt-then-mac ]]; then
7970
+ if [[ ! "${ TLS_EXTENSIONS[*]} " =~ encrypt-then-mac ]]; then
7967
7971
$OPENSSL s_client $(s_client_options "$STARTTLS $BUGS -connect $NODEIP:$PORT $PROXY $addcmd $OPTIMAL_PROTO -tlsextdebug $params -cipher $cbc_cipher_list") </dev/null 2>$ERRFILE >$TMPFILE
7968
7972
sclient_connect_successful $? $TMPFILE
7969
7973
success=$?
@@ -7978,7 +7982,13 @@ determine_tls_extensions() {
7978
7982
fi
7979
7983
7980
7984
# Keep it "on file" for debugging purposes
7981
- [[ "$DEBUG" -ge 1 ]] && safe_echo "$TLS_EXTENSIONS" >"$TEMPDIR/$NODE.$NODEIP.tls_extensions.txt"
7985
+ if [[ "$DEBUG" -ge 1 ]]; then
7986
+ tls_extensions=""
7987
+ for extn in "${TLS_EXTENSIONS[@]}"; do
7988
+ tls_extensions+=" \"${extn}\""
7989
+ done
7990
+ safe_echo "${tls_extensions:1}" >"$TEMPDIR/$NODE.$NODEIP.tls_extensions.txt"
7991
+ fi
7982
7992
7983
7993
return $success
7984
7994
}
@@ -8863,7 +8873,7 @@ certificate_transparency() {
8863
8873
# determine_tls_extensions() discovered an SCT TLS extension. If the server has more than
8864
8874
# one certificate, then it is possible that an SCT TLS extension is returned for some
8865
8875
# certificates, but not for all of them.
8866
- if [[ $number_of_certificates -eq 1 ]] && [[ "$TLS_EXTENSIONS" =~ signed\ certificate\ timestamps ]]; then
8876
+ if [[ $number_of_certificates -eq 1 ]] && [[ "${ TLS_EXTENSIONS[*]} " =~ signed\ certificate\ timestamps ]]; then
8867
8877
CERTIFICATE_TRANSPARENCY_SOURCE="TLS extension"
8868
8878
return 0
8869
8879
fi
@@ -10074,7 +10084,7 @@ run_server_defaults() {
10074
10084
local -a ocsp_response_binary ocsp_response ocsp_response_status sni_used tls_version ct
10075
10085
local -a ciphers_to_test certificate_type
10076
10086
local -a -i success
10077
- local cn_nosni cn_sni sans_nosni sans_sni san tls_extensions client_auth_ca
10087
+ local cn_nosni cn_sni sans_nosni sans_sni san tls_extensions extn client_auth_ca
10078
10088
local using_sockets=true
10079
10089
10080
10090
"$SSL_NATIVE" && using_sockets=false
@@ -10326,7 +10336,7 @@ run_server_defaults() {
10326
10336
outln
10327
10337
10328
10338
pr_bold " TLS extensions (standard) "
10329
- if [[ -z "$ TLS_EXTENSIONS" ]]; then
10339
+ if [[ ${# TLS_EXTENSIONS[*]} -eq 0 ]]; then
10330
10340
outln "(none)"
10331
10341
fileout "TLS_extensions" "INFO" "(none)"
10332
10342
else
@@ -10337,12 +10347,17 @@ run_server_defaults() {
10337
10347
# across lines, temporarily replace space characters within the text
10338
10348
# of an extension with "}", and then convert the "}" back to space in
10339
10349
# the output of out_row_aligned_max_width().
10340
- tls_extensions="${TLS_EXTENSIONS// /{}"
10350
+ tls_extensions=""
10351
+ for extn in "${TLS_EXTENSIONS[@]}"; do
10352
+ tls_extensions+=" \"${extn}\""
10353
+ done
10354
+ tls_extensions="${tls_extensions:1}"
10355
+ fileout "TLS_extensions" "INFO" "$tls_extensions"
10356
+ tls_extensions="${tls_extensions// /{}"
10341
10357
tls_extensions="${tls_extensions//\"{\"/\" \"}"
10342
10358
tls_extensions="$(out_row_aligned_max_width "$tls_extensions" " " $TERM_WIDTH)"
10343
10359
tls_extensions="${tls_extensions//{/ }"
10344
10360
outln "$tls_extensions"
10345
- fileout "TLS_extensions" "INFO" "$TLS_EXTENSIONS"
10346
10361
fi
10347
10362
10348
10363
pr_bold " Session Ticket RFC 5077 hint "
@@ -16710,8 +16725,8 @@ run_heartbleed(){
16710
16725
return 1
16711
16726
fi
16712
16727
16713
- [[ -z "$ TLS_EXTENSIONS" ]] && determine_tls_extensions
16714
- if [[ ! "${TLS_EXTENSIONS}" =~ heartbeat ]]; then
16728
+ [[ ${# TLS_EXTENSIONS[*]} -eq 0 ]] && determine_tls_extensions
16729
+ if [[ ! "${TLS_EXTENSIONS[*] }" =~ heartbeat ]]; then
16715
16730
pr_svrty_best "not vulnerable (OK)"
16716
16731
outln ", no heartbeat extension"
16717
16732
fileout "$jsonID" "OK" "not vulnerable, no heartbeat extension" "$cve" "$cwe"
@@ -17015,8 +17030,8 @@ run_ticketbleed() {
17015
17030
fi
17016
17031
17017
17032
# highly unlikely that it is NOT supported. We may loose time here but it's more solid
17018
- [[ -z "$ TLS_EXTENSIONS" ]] && determine_tls_extensions
17019
- if [[ ! "${TLS_EXTENSIONS}" =~ "session ticket" ]]; then
17033
+ [[ ${# TLS_EXTENSIONS[*]} -eq 0 ]] && determine_tls_extensions
17034
+ if [[ ! "${TLS_EXTENSIONS[*] }" =~ "session ticket" ]]; then
17020
17035
pr_svrty_best "not vulnerable (OK)"
17021
17036
outln ", no session ticket extension"
17022
17037
fileout "$jsonID" "OK" "no session ticket extension" "$cve" "$cwe"
@@ -19118,7 +19133,7 @@ run_winshock() {
19118
19133
# (~ sub_check_curves) which is some work. But also for the sake of clean code this needs to be done.
19119
19134
19120
19135
19121
- [[ -z "$ TLS_EXTENSIONS" ]] && determine_tls_extensions
19136
+ [[ ${# TLS_EXTENSIONS[*]} -eq 0 ]] && determine_tls_extensions
19122
19137
# Basis of the following https://en.wikipedia.org/wiki/Comparison_of_TLS_implementations#Extensions
19123
19138
# Our standard: https://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml
19124
19139
@@ -19132,9 +19147,9 @@ run_winshock() {
19132
19147
local -a forbidden_tls_ext=("encrypt-then-mac" "max fragment length")
19133
19148
# Open whether ec_point_formats, supported_groups(=elliptic_curves), heartbeat are supported under windows <=2012
19134
19149
# key_share and supported_versions are extensions which came with TLS 1.3. We checked the protocol before.
19135
- if [[ -n "$ TLS_EXTENSIONS" ]]; then
19150
+ if [[ ${# TLS_EXTENSIONS[*]} -gt 0 ]]; then
19136
19151
# Check whether there are any TLS extension which should not be available under <= Windows 2012 R2
19137
- for tls_ext in $ TLS_EXTENSIONS; do
19152
+ for tls_ext in "${ TLS_EXTENSIONS[@]}" ; do
19138
19153
# We use the whole array, got to be careful when the array becomes bigger (unintended match)
19139
19154
if [[ ${forbidden_tls_ext[@]} =~ $tls_ext ]]; then
19140
19155
pr_svrty_best "not vulnerable (OK)"; outln " - TLS extension $tls_ext detected"
@@ -24376,7 +24391,7 @@ reset_hostdepended_vars() {
24376
24391
NR_OSSL_FAIL=0
24377
24392
NR_STARTTLS_FAIL=0
24378
24393
NR_HEADER_FAIL=0
24379
- TLS_EXTENSIONS=""
24394
+ TLS_EXTENSIONS=()
24380
24395
TLS13_CERT_COMPRESS_METHODS=""
24381
24396
CERTIFICATE_TRANSPARENCY_SOURCE=""
24382
24397
PROTOS_OFFERED=""
0 commit comments