Merge pull request #517 from dcooper16/parse_tls_serverhello3

Extend TLS ServerHello parsing (part 3)
This commit is contained in:
Dirk Wetter 2016-11-15 08:17:48 +01:00 committed by GitHub
commit 1d995428e1

View File

@ -6102,18 +6102,20 @@ parse_tls_serverhello() {
local process_full="$2"
local tls_handshake_ascii="" tls_alert_ascii=""
local -i tls_hello_ascii_len tls_handshake_ascii_len tls_alert_ascii_len msg_len
local tls_serverhello_ascii=""
local tls_serverhello_ascii="" tls_certificate_ascii=""
local tls_serverkeyexchange_ascii=""
local -i tls_serverhello_ascii_len=0
local -i tls_serverhello_ascii_len=0 tls_certificate_ascii_len=0
local -i tls_serverkeyexchange_ascii_len=0
local tls_alert_descrip tls_sid_len_hex
local -i tls_sid_len offset extns_offset
local tls_alert_descrip tls_sid_len_hex issuerDN subjectDN CAissuerDN CAsubjectDN
local -i tls_sid_len offset extns_offset nr_certs=0
local tls_msg_type tls_content_type tls_protocol tls_protocol2 tls_hello_time
local tls_err_level tls_err_descr tls_cipher_suite rfc_cipher_suite tls_compression_method
local tls_extensions="" extension_type named_curve_str=""
local -i i j extension_len tls_extensions_len
local -i certificate_list_len certificate_len
local -i curve_type named_curve
local -i dh_bits=0 msb mask
local tmp_der_certfile tmp_pem_certfile
TLS_TIME=""
DETECTED_TLS_VERSION=""
@ -6271,7 +6273,8 @@ parse_tls_serverhello() {
done
fi
# Now extract just the server hello and server key exchange handshake messages.
# Now extract just the server hello, certificate,
# and server key exchange handshake messages.
tls_handshake_ascii_len=${#tls_handshake_ascii}
if [[ $DEBUG -ge 2 ]] && [[ $tls_handshake_ascii_len -gt 0 ]]; then
echo "TLS handshake messages:"
@ -6338,6 +6341,13 @@ parse_tls_serverhello() {
fi
tls_serverhello_ascii="${tls_handshake_ascii:i:msg_len}"
tls_serverhello_ascii_len=$msg_len
elif [[ "$process_full" == "all" ]] && [[ "$tls_msg_type" == "0B" ]]; then
if [[ -n "$tls_certificate_ascii" ]]; then
debugme pr_warningln "Response contained more than one Certificate handshake message."
return 1
fi
tls_certificate_ascii="${tls_handshake_ascii:i:msg_len}"
tls_certificate_ascii_len=$msg_len
elif ( [[ "$process_full" == "all" ]] || [[ "$process_full" == "ephemeralkey" ]] ) && [[ "$tls_msg_type" == "0C" ]]; then
if [[ -n "$tls_serverkeyexchange_ascii" ]]; then
debugme pr_warningln "Response contained more than one ServerKeyExchange handshake message."
@ -6361,7 +6371,7 @@ parse_tls_serverhello() {
return 1
fi
# Parse the server hello handshake message
# First parse the server hello handshake message
# byte 0+1: 03, TLS version word see byte 1+2
# byte 2-5: TLS timestamp for OpenSSL <1.01f
# byte 6-33: random, 28 bytes
@ -6515,6 +6525,94 @@ parse_tls_serverhello() {
outln
fi
# Now parse the Certificate message.
if [[ "$process_full" == "all" ]]; then
[[ -e "$HOSTCERT" ]] && rm "$HOSTCERT"
[[ -e "$TEMPDIR/intermediatecerts.pem" ]] && rm "$TEMPDIR/intermediatecerts.pem"
fi
if [[ $tls_certificate_ascii_len -ne 0 ]]; then
# The first certificate is the server's certificate. If there are anything
# subsequent certificates, they are intermediate certificates.
if [[ $tls_certificate_ascii_len -lt 12 ]]; then
debugme echo "Malformed Certificate Handshake message in ServerHello."
tmpfile_handle $FUNCNAME.txt
return 1
fi
certificate_list_len=2*$(hex2dec "${tls_certificate_ascii:0:6}")
if [[ $certificate_list_len -ne $tls_certificate_ascii_len-6 ]]; then
debugme echo "Malformed Certificate Handshake message in ServerHello."
tmpfile_handle $FUNCNAME.txt
return 1
fi
# Place server's certificate in $HOSTCERT
certificate_len=2*$(hex2dec "${tls_certificate_ascii:6:6}")
if [[ $certificate_len -gt $tls_certificate_ascii_len-12 ]]; then
debugme echo "Malformed Certificate Handshake message in ServerHello."
tmpfile_handle $FUNCNAME.txt
return 1
fi
tmp_der_certfile=$(mktemp $TEMPDIR/der_cert.XXXXXX) || return 1
asciihex_to_binary_file "${tls_certificate_ascii:12:certificate_len}" "$tmp_der_certfile"
$OPENSSL x509 -inform DER -in "$tmp_der_certfile" -outform PEM -out "$HOSTCERT" 2>$ERRFILE
if [[ $? -ne 0 ]]; then
debugme echo "Malformed certificate in Certificate Handshake message in ServerHello."
rm "$tmp_der_certfile"
tmpfile_handle $FUNCNAME.txt
return 1
fi
rm "$tmp_der_certfile"
get_pub_key_size
echo "===============================================================================" >> $TMPFILE
echo "---" >> $TMPFILE
echo "Certificate chain" >> $TMPFILE
subjectDN="$($OPENSSL x509 -in $HOSTCERT -noout -subject)"
issuerDN="$($OPENSSL x509 -in $HOSTCERT -noout -issuer)"
echo " $nr_certs s:${subjectDN:9}" >> $TMPFILE
echo " i:${issuerDN:8}" >> $TMPFILE
cat "$HOSTCERT" >> $TMPFILE
echo "" > "$TEMPDIR/intermediatecerts.pem"
# Place and additional certificates in $TEMPDIR/intermediatecerts.pem
for (( i=12+certificate_len; i<tls_certificate_ascii_len; i=i+certificate_len )); do
if [[ $tls_certificate_ascii_len-$i -lt 6 ]]; then
debugme echo "Malformed Certificate Handshake message in ServerHello."
tmpfile_handle $FUNCNAME.txt
return 1
fi
certificate_len=2*$(hex2dec "${tls_certificate_ascii:i:6}")
i+=6
if [[ $certificate_len -gt $tls_certificate_ascii_len-$i ]]; then
debugme echo "Malformed certificate in Certificate Handshake message in ServerHello."
tmpfile_handle $FUNCNAME.txt
return 1
fi
tmp_der_certfile=$(mktemp $TEMPDIR/der_cert.XXXXXX) || return 1
asciihex_to_binary_file "${tls_certificate_ascii:i:certificate_len}" "$tmp_der_certfile"
tmp_pem_certfile=$(mktemp $TEMPDIR/pem_cert.XXXXXX) || return 1
$OPENSSL x509 -inform DER -in "$tmp_der_certfile" -outform PEM -out "$tmp_pem_certfile" 2>$ERRFILE
if [[ $? -ne 0 ]]; then
debugme echo "Malformed certificate in Certificate Handshake message in ServerHello."
rm "$tmp_der_certfile" "$tmp_pem_certfile"
tmpfile_handle $FUNCNAME.txt
return 1
fi
nr_certs+=1
CAsubjectDN="$($OPENSSL x509 -in $tmp_pem_certfile -noout -subject)"
CAissuerDN="$($OPENSSL x509 -in $tmp_pem_certfile -noout -issuer)"
echo " $nr_certs s:${CAsubjectDN:9}" >> $TMPFILE
echo " i:${CAissuerDN:8}" >> $TMPFILE
cat "$tmp_pem_certfile" >> $TMPFILE
cat "$tmp_pem_certfile" >> "$TEMPDIR/intermediatecerts.pem"
rm "$tmp_der_certfile" "$tmp_pem_certfile"
done
echo "---" >> $TMPFILE
echo "Server certificate" >> $TMPFILE
echo "subject=${subjectDN:9}" >> $TMPFILE
echo "issuer=${issuerDN:8}" >> $TMPFILE
echo "---" >> $TMPFILE
fi
# Now parse the server key exchange message
if [[ $tls_serverkeyexchange_ascii_len -ne 0 ]]; then
if [[ $rfc_cipher_suite =~ "TLS_ECDHE_" ]] || [[ $rfc_cipher_suite =~ "TLS_ECDH_anon" ]]; then