Check for RFC 8879 certificate compression

This commit adds a check for whether the server supports certificate compression (RFC 8879). If it does, then the list of supprted compression methods is output in the server's preference order.
This commit is contained in:
David Cooper 2021-08-04 14:39:12 -04:00
parent b603d57146
commit fa1ccdb565
3 changed files with 90 additions and 8 deletions

View File

@ -30,6 +30,7 @@
* Headerflag X-XSS-Protection is now labeled as INFO
* Client simulation runs in wide mode which is even better readable
* Added --reqheader to support custom headers in HTTP requests
* Test for support for RFC 8879 certificate compression
### Features implemented / improvements in 3.0

View File

@ -23,12 +23,13 @@ Full contribution, see git log.
- experimental "eTLS" detection
- parallel mass testing!
- RFC <--> OpenSSL cipher name space switches for the command line
- better error msg suppression (not fully installed openssl
- better error msg suppression (not fully installed openssl)
- GREASE support
- Bleichenbacher / ROBOT vulnerability test
- several protocol preferences improvements
- pwnedkeys.com support
- CT support
- RFC 8879, certificate compression
- Lots of fixes and improvements
##### Further credits (in alphabetical order)

View File

@ -7510,6 +7510,49 @@ determine_tls_extensions() {
return $success
}
# Return a list of the certificate compression methods supported (RFC 8879)
determine_cert_compression() {
# 1=zlib, 2=brotli, 3=zstd
local -a supported_compression_methods=("" "false" "false" "false")
local -i i len nr_compression_methods=3
local len1 len2 methods_to_test method_found method_nr methods_found=""
# Certificate compression is only supported by TLS 1.3.
[[ $(has_server_protocol "tls1_3") -eq 1 ]] && tm_out "" && return 1
while true; do
methods_to_test=""
for (( i=1; i <= nr_compression_methods; i++ )); do
! "${supported_compression_methods[i]}" && methods_to_test+=" ,00,$(printf "%02x" $i)"
done
len=$((2*${#methods_to_test}/7))
# If there are no more compression methods remaining to be tested, then quit.
[[ $len -eq 0 ]] && break
len1=$(printf "%02x" "$len")
len2=$(printf "%02x" "$((len+1))")
tls_sockets "04" "$TLS13_CIPHER" "all+" "00,1b, 00,$len2, $len1$methods_to_test"
if [[ $? -ne 0 ]]; then
add_proto_offered tls1_3 no
tm_out ""
return 1
fi
add_proto_offered tls1_3 yes
method_found="$(awk '/Certificate Compression Algorithm: / { print $4 $5 }' "$TEMPDIR/$NODEIP.parse_tls_serverhello.txt")"
[[ -z "$method_found" ]] && break
[[ -z "$methods_found" ]] && tmpfile_handle ${FUNCNAME[0]}.txt "$TEMPDIR/$NODEIP.parse_tls_serverhello.txt"
method_found="${method_found//(//}"
method_found="${method_found//)/}"
method_nr="${method_found%%/*}"
supported_compression_methods[method_nr]=true
methods_found+=" $method_found"
done
if [[ -n "$methods_found" ]]; then
methods_found="${methods_found:1}"
else
methods_found="none"
fi
tm_out "$methods_found"
return 0
}
extract_certificates() {
local version="$1"
@ -9500,6 +9543,7 @@ run_server_defaults() {
local -a ciphers_to_test certificate_type
local -a -i success
local cn_nosni cn_sni sans_nosni sans_sni san tls_extensions client_auth_ca
local cert_compression_methods
local using_sockets=true
"$SSL_NATIVE" && using_sockets=false
@ -9707,6 +9751,9 @@ run_server_defaults() {
done
determine_tls_extensions
cert_compression_methods="$(determine_cert_compression)"
[[ -n "$cert_compression_methods" ]] && [[ "$cert_compression_methods" != "none" ]] && \
extract_new_tls_extensions "$TEMPDIR/$NODEIP.determine_cert_compression.txt"
if [[ $? -eq 0 ]] && [[ "$OPTIMAL_PROTO" != -ssl2 ]]; then
cp "$TEMPDIR/$NODEIP.determine_tls_extensions.txt" $TMPFILE
@ -9847,6 +9894,16 @@ run_server_defaults() {
tls_time
jsonID="cert_compression"
if [[ $(has_server_protocol "tls1_3") -eq 0 ]]; then
jsonID="certificate_compression"
pr_bold " Certificate Compression "
outln "$cert_compression_methods"
fileout "$jsonID" "INFO" "$cert_compression_methods"
else
fileout "$jsonID" "INFO" "N/A"
fi
jsonID="clientAuth"
pr_bold " Client Authentication "
outln "$CLIENT_AUTH"
@ -13137,6 +13194,7 @@ parse_tls_serverhello() {
local tls_msg_type tls_content_type tls_protocol tls_protocol2 tls_hello_time
local tls_err_level tls_err_descr_no tls_cipher_suite rfc_cipher_suite tls_compression_method
local tls_extensions="" extension_type named_curve_str="" named_curve_oid
local cert_compression_method="" cert_compression_method_str=""
local -i i j extension_len extn_len tls_extensions_len ocsp_response_len=0 ocsp_response_list_len ocsp_resp_offset
local -i certificate_list_len certificate_len cipherlist_len
local -i curve_type named_curve
@ -13401,18 +13459,20 @@ parse_tls_serverhello() {
[[ $DEBUG -ge 1 ]] && tmpfile_handle ${FUNCNAME[0]}.txt
return 1
fi
cert_compression_method="${tls_handshake_ascii:i:4}"
case $cert_compression_method in
0001) cert_compression_method_str="ZLIB" ;;
0002) cert_compression_method_str="Brotli" ;;
0003) cert_compression_method_str="Zstandard" ;;
*) cert_compression_method_str="unrecognized" ;;
esac
if [[ $DEBUG -ge 3 ]]; then
tm_out " Certificate Compression Algorithm: ${tls_handshake_ascii:i:4}"
case ${tls_handshake_ascii:i:4} in
0001) tmln_out " (ZLIB)" ;;
0002) tmln_out " (Brotli)" ;;
0003) tmln_out " (Zstandard)" ;;
*) tmln_out ;;
esac
tmln_out " Certificate Compression Algorithm: $cert_compression_method ($cert_compression_method_str)"
offset=$((i+4))
tmln_out " Uncompressed certificate length: $(printf "%d" 0x${tls_handshake_ascii:offset:6})"
tmln_out
fi
tls_extensions+="TLS server extension \"compress_certificate\" (id=27), len=0\n"
if [[ "$process_full" =~ all ]] && "$HAS_ZLIB" && [[ "${tls_handshake_ascii:i:4}" == 0001 ]]; then
offset=$((i+4))
tls_certificate_ascii_len=2*0x${tls_handshake_ascii:offset:6}
@ -13872,6 +13932,9 @@ parse_tls_serverhello() {
esac
echo "===============================================================================" >> $TMPFILE
fi
if [[ -n "$cert_compression_method" ]]; then
echo "Certificate Compression Algorithm: $cert_compression_method ($cert_compression_method_str)" >> $TMPFILE
fi
[[ -n "$tls_extensions" ]] && echo -e "$tls_extensions" >> $TMPFILE
if [[ $DEBUG -ge 3 ]]; then
@ -14827,6 +14890,23 @@ prepare_tls_clienthello() {
all_extensions+="$extension_supported_point_formats"
fi
if [[ "0x$tls_low_byte" -ge 0x04 ]] && [[ ! "$extra_extensions_list" =~ " 001b " ]]; then
# If the response needs to be decrypted, then indicate support
# for ZLIB certificate compression if $OPENSSL can decompress
# the result. If the response does not need to be decrypted,
# then indicate support for all certificate compression methods,
# as the response does not need to be decompressed.
if [[ "$process_full" =~ all ]]; then
if "$HAS_ZLIB"; then
[[ -n "$all_extensions" ]] && all_extensions+=","
all_extensions+="00,1b,00,03,02,00,01"
fi
else
[[ -n "$all_extensions" ]] && all_extensions+=","
all_extensions+="00,1b,00,07,06,00,01,00,02,00,03"
fi
fi
if [[ -n "$extra_extensions" ]]; then
[[ -n "$all_extensions" ]] && all_extensions+=","
all_extensions+="$extra_extensions"