From 907126a285634b53f120635a5ab604a591fdecd3 Mon Sep 17 00:00:00 2001 From: David Cooper Date: Wed, 23 Nov 2022 08:35:45 -0800 Subject: [PATCH] Fix extract_calist() When a server supports client authentication, extract_calist() extracts the list of supported certification authorities sent by the server. extract_calist() uses different code to extract the list from a TLS 1.3 response than from a TLS 1.2 or earlier response, since the CertificateRequest message was changed for TLS 1.3. For TLS 1.2 and earlier, extract_calist() assumes that the CertificateRequest message is a sequence of certificate types, signature algorithms, and certification authorities. However, the signature algorithms field was added in TLS 1.2 and does not appear in TLS 1.1 and earlier. So, the current code does not work unless the server supports TLS 1.2 or TLS 1.3. This commit fixes the problem by checking whether the response is a TLS 1.2 response, and skipping over the extraction of the signature algorithms field if the response is neither TLS 1.2 nor TLS 1.3. --- testssl.sh | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/testssl.sh b/testssl.sh index cdde42e..68914e5 100755 --- a/testssl.sh +++ b/testssl.sh @@ -21299,14 +21299,19 @@ print_dn() { # distinguished names that are in the CA list. extract_calist() { local response="$1" - local is_tls13=false + local is_tls12=false is_tls13=false local certreq calist="" certtypes sigalgs dn local calist_string="" local -i len type - # Determine whether this is a TLS 1.3 response, since the information - # is encoded in a different place for TLS 1.3. - [[ "$response" =~ \<\<\<\ TLS\ 1.3[\,]?\ Handshake\ \[length\ [0-9a-fA-F]*\]\,\ CertificateRequest ]] && is_tls13=true + # Determine whether this is a TLS 1.2 or TLS 1.3 response, since the information + # is encoded in a different place for TLS 1.3 and the CertificateRequest message + # differs between TLS 1.2 and TLS 1.1 and earlier. + if [[ "$response" =~ \<\<\<\ TLS\ 1.3[\,]?\ Handshake\ \[length\ [0-9a-fA-F]*\]\,\ CertificateRequest ]]; then + is_tls13=true + elif [[ "$response" =~ \<\<\<\ TLS\ 1.2[\,]?\ Handshake\ \[length\ [0-9a-fA-F]*\]\,\ CertificateRequest ]]; then + is_tls12=true + fi # Extract just the CertificateRequest message as an ASCII-HEX string. certreq="${response##*CertificateRequest}" @@ -21342,15 +21347,17 @@ extract_calist() { # struct { # ClientCertificateType certificate_types<1..2^8-1>; # SignatureAndHashAlgorithm - # supported_signature_algorithms<2^16-1>; + # supported_signature_algorithms<2^16-1>; - only present in TLS 1.2 # DistinguishedName certificate_authorities<0..2^16-1>; # } CertificateRequest; len=2*$(hex2dec "${certreq:0:2}") certtypes="${certreq:2:len}" certreq="${certreq:$((len+2))}" - len=2*$(hex2dec "${certreq:0:4}") - sigalgs="${certreq:4:len}" - certreq="${certreq:$((len+4))}" + if "$is_tls12"; then + len=2*$(hex2dec "${certreq:0:4}") + sigalgs="${certreq:4:len}" + certreq="${certreq:$((len+4))}" + fi len=2*$(hex2dec "${certreq:0:4}") calist="${certreq:4:len}" fi