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.
This commit is contained in:
David Cooper 2022-11-23 08:35:45 -08:00
parent a4666087e8
commit 907126a285
1 changed files with 15 additions and 8 deletions

View File

@ -21299,14 +21299,19 @@ print_dn() {
# distinguished names that are in the CA list. # distinguished names that are in the CA list.
extract_calist() { extract_calist() {
local response="$1" local response="$1"
local is_tls13=false local is_tls12=false is_tls13=false
local certreq calist="" certtypes sigalgs dn local certreq calist="" certtypes sigalgs dn
local calist_string="" local calist_string=""
local -i len type local -i len type
# Determine whether this is a TLS 1.3 response, since the information # 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. # is encoded in a different place for TLS 1.3 and the CertificateRequest message
[[ "$response" =~ \<\<\<\ TLS\ 1.3[\,]?\ Handshake\ \[length\ [0-9a-fA-F]*\]\,\ CertificateRequest ]] && is_tls13=true # 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. # Extract just the CertificateRequest message as an ASCII-HEX string.
certreq="${response##*CertificateRequest}" certreq="${response##*CertificateRequest}"
@ -21342,15 +21347,17 @@ extract_calist() {
# struct { # struct {
# ClientCertificateType certificate_types<1..2^8-1>; # ClientCertificateType certificate_types<1..2^8-1>;
# SignatureAndHashAlgorithm # 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>; # DistinguishedName certificate_authorities<0..2^16-1>;
# } CertificateRequest; # } CertificateRequest;
len=2*$(hex2dec "${certreq:0:2}") len=2*$(hex2dec "${certreq:0:2}")
certtypes="${certreq:2:len}" certtypes="${certreq:2:len}"
certreq="${certreq:$((len+2))}" certreq="${certreq:$((len+2))}"
len=2*$(hex2dec "${certreq:0:4}") if "$is_tls12"; then
sigalgs="${certreq:4:len}" len=2*$(hex2dec "${certreq:0:4}")
certreq="${certreq:$((len+4))}" sigalgs="${certreq:4:len}"
certreq="${certreq:$((len+4))}"
fi
len=2*$(hex2dec "${certreq:0:4}") len=2*$(hex2dec "${certreq:0:4}")
calist="${certreq:4:len}" calist="${certreq:4:len}"
fi fi