From 98aaab5e1212f1a53eafcf5a13b06fe677ae4f96 Mon Sep 17 00:00:00 2001 From: David Cooper Date: Thu, 3 Nov 2016 10:18:27 -0400 Subject: [PATCH] Extend TLS ServerHello parsing (part 1) This PR extended `parse_tls_serverhello()` in a few ways: * If the "full" response is to be parsed, then additional checks are performed to verify that `$tls_hello_ascii` contains the entire response * The extensions field is parsed and the list of extensions found is placed in `$TLS_EXTENSIONS` (if the "full" response is being parsed). * Initial support for TLS 1.3 is added: - Accounts for differences between TLS 1.2 ServerHello and TLS 1.3 ServerHello (as outlined in PR #499). - Recognizes new alerts and handshake message types. - Allows for server response to include message fragments of type "application data" --- testssl.sh | 225 ++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 178 insertions(+), 47 deletions(-) diff --git a/testssl.sh b/testssl.sh index b5368b6..1bc5121 100755 --- a/testssl.sh +++ b/testssl.sh @@ -5851,24 +5851,26 @@ check_tls_serverhellodone() { } # arg1: ASCII-HEX encoded reply +# arg2: (optional): "all" - process full response (including Certificate and certificate_status handshake messages) +# "ephemeralkey" - extract the server's ephemeral key (if any) parse_tls_serverhello() { local tls_hello_ascii="$1" + 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 -i tls_serverhello_ascii_len=0 local tls_alert_descrip tls_sid_len_hex - local -i tls_sid_len offset + local -i tls_sid_len offset extns_offset local tls_msg_type tls_content_type tls_protocol tls_protocol2 tls_hello_time local tls_err_level tls_err_descr tls_cipher_suite tls_compression_method - local -i i + local tls_extensions="" extension_type + local -i i j extension_len tls_extensions_len TLS_TIME="" DETECTED_TLS_VERSION="" [[ -n "$tls_hello_ascii" ]] && echo "CONNECTED(00000003)" > $TMPFILE - # $tls_hello_ascii may contain trailing whitespace. Remove it: - tls_hello_ascii="${tls_hello_ascii%%[!0-9A-F]*}" [[ "$DEBUG" -eq 5 ]] && echo $tls_hello_ascii # one line without any blanks # Client messages, including handshake messages, are carried by the record layer. @@ -5880,13 +5882,19 @@ parse_tls_serverhello() { # bytes 5...: message fragment tls_hello_ascii_len=${#tls_hello_ascii} if [[ $DEBUG -ge 2 ]] && [[ $tls_hello_ascii_len -gt 0 ]]; then - echo "TLS message fragments:" + echo "TLS message fragments:" fi for (( i=0; i> $TMPFILE ;; + 02) echo -n "fatal " >> $TMPFILE ;; + esac + echo "alert $tls_alert_descrip" >> $TMPFILE + echo "===============================================================================" >> $TMPFILE if [[ $DEBUG -ge 2 ]]; then outln " ($tls_alert_descrip)" out " tls_err_level: ${tls_err_level}" @@ -5991,6 +6017,7 @@ parse_tls_serverhello() { return 1 elif [[ "$tls_err_level" == "02" ]]; then # Fatal alert + tmpfile_handle $FUNCNAME.txt return 1 fi done @@ -5999,13 +6026,19 @@ parse_tls_serverhello() { # Now extract just the server hello handshake message. tls_handshake_ascii_len=${#tls_handshake_ascii} if [[ $DEBUG -ge 2 ]] && [[ $tls_handshake_ascii_len -gt 0 ]]; then - echo "TLS handshake messages:" + echo "TLS handshake messages:" fi for (( i=0; i> $TMPFILE @@ -6107,24 +6223,39 @@ parse_tls_serverhello() { else echo "Cipher : $(show_rfc_style "x${tls_cipher_suite:0:4}")" >> $TMPFILE fi - echo "===============================================================================" >> $TMPFILE + if [[ "0x${tls_protocol2:2:2}" -le "0x03" ]]; then + case $tls_compression_method in + 00) echo "Compression: NONE" >> $TMPFILE ;; + 01) echo "Compression: zlib compression" >> $TMPFILE ;; + 40) echo "Compression: LZS compression" >> $TMPFILE ;; + *) echo "Compression: unrecognized compression method" >> $TMPFILE ;; + esac + echo "===============================================================================" >> $TMPFILE + fi if [[ $DEBUG -ge 2 ]]; then echo "TLS server hello message:" if [[ $DEBUG -ge 4 ]]; then echo " tls_protocol: 0x$tls_protocol2" - echo " tls_sid_len: 0x$tls_sid_len_hex / = $((tls_sid_len/2))" + [[ "0x${tls_protocol2:2:2}" -le "0x03" ]] && echo " tls_sid_len: 0x$tls_sid_len_hex / = $((tls_sid_len/2))" + fi + if [[ "0x${tls_protocol2:2:2}" -le "0x03" ]]; then + echo -n " tls_hello_time: 0x$tls_hello_time " + parse_date "$TLS_TIME" "+%Y-%m-%d %r" "%s" fi - echo -n " tls_hello_time: 0x$tls_hello_time " - parse_date "$TLS_TIME" "+%Y-%m-%d %r" "%s" echo " tls_cipher_suite: 0x$tls_cipher_suite" - echo -n " tls_compression_method: 0x$tls_compression_method " - case $tls_compression_method in - 00) echo "(NONE)" ;; - 01) echo "(zlib compression)" ;; - 40) echo "(LZS compression)" ;; - *) echo "(unrecognized compression method)" ;; - esac + if [[ "0x${tls_protocol2:2:2}" -le "0x03" ]]; then + echo -n " tls_compression_method: 0x$tls_compression_method " + case $tls_compression_method in + 00) echo "(NONE)" ;; + 01) echo "(zlib compression)" ;; + 40) echo "(LZS compression)" ;; + *) echo "(unrecognized compression method)" ;; + esac + fi + if [[ "$process_full" == "all" ]]; then + echo " tls_extensions: $TLS_EXTENSIONS" + fi outln fi tmpfile_handle $FUNCNAME.txt