mirror of
				https://github.com/drwetter/testssl.sh.git
				synced 2025-10-30 21:35:26 +01:00 
			
		
		
		
	Compare selected version against supported_versions
If a supported_versions extension was included in the ClientHello, then check that the version returned by the server was included in the ClientHello's supported_versions extension. OpenSSL will respond to a TLSv1.3 ClientHello that only specifies 0304 in its supported_versions extension with a ServerHello that specifies whatever draft of TLSv1.3 it currently supports (e.g., 7F16). The result is that run_protocols() incorrectly reports that OpenSSL supports TLSv1.3 "final" in addition to whatever draft version it supports. This PR fixes that problem by treating it as a failed connection when the ClientHello offers only 0304 and the ServerHello specifies something else (e.g., 7F16). Performing this check is actually a requirement for clients in Section 4.2.1 of draft-ietf-tls-tls13-22. So, including this check will also help make client simulations more accurate when clients that support TLSv1.3 are added to client-simulation.txt.
This commit is contained in:
		
							
								
								
									
										70
									
								
								testssl.sh
									
									
									
									
									
								
							
							
						
						
									
										70
									
								
								testssl.sh
									
									
									
									
									
								
							| @@ -8864,14 +8864,14 @@ parse_tls_serverhello() { | |||||||
|      # byte 37+sid-len:     compression method:  00: none, 01: deflate, 64: LZS |      # byte 37+sid-len:     compression method:  00: none, 01: deflate, 64: LZS | ||||||
|      # byte 38+39+sid-len:  extension length |      # byte 38+39+sid-len:  extension length | ||||||
|      tls_protocol2="${tls_serverhello_ascii:0:4}" |      tls_protocol2="${tls_serverhello_ascii:0:4}" | ||||||
|      [[ "${tls_protocol2:0:2}" == "7F" ]] && tls_protocol2="0304" |      DETECTED_TLS_VERSION="$tls_protocol2" | ||||||
|      if [[ "${tls_protocol2:0:2}" != "03" ]]; then |      [[ "${DETECTED_TLS_VERSION:0:2}" == "7F" ]] && DETECTED_TLS_VERSION="0304" | ||||||
|  |      if [[ "${DETECTED_TLS_VERSION:0:2}" != "03" ]]; then | ||||||
|           debugme tmln_warning "server_version.major in ServerHello is not 03." |           debugme tmln_warning "server_version.major in ServerHello is not 03." | ||||||
|           return 1 |           return 1 | ||||||
|      fi |      fi | ||||||
|      DETECTED_TLS_VERSION="$tls_protocol2" |  | ||||||
|  |  | ||||||
|      if [[ "0x${tls_protocol2:2:2}" -le "0x03" ]]; then |      if [[ "0x${DETECTED_TLS_VERSION:2:2}" -le "0x03" ]]; then | ||||||
|           tls_hello_time="${tls_serverhello_ascii:4:8}" |           tls_hello_time="${tls_serverhello_ascii:4:8}" | ||||||
|           [[ "$TLS_DIFFTIME_SET" || "$DEBUG" ]] && TLS_TIME=$(hex2dec "$tls_hello_time") |           [[ "$TLS_DIFFTIME_SET" || "$DEBUG" ]] && TLS_TIME=$(hex2dec "$tls_hello_time") | ||||||
|           tls_sid_len_hex="${tls_serverhello_ascii:68:2}" |           tls_sid_len_hex="${tls_serverhello_ascii:68:2}" | ||||||
| @@ -8887,7 +8887,7 @@ parse_tls_serverhello() { | |||||||
|  |  | ||||||
|      tls_cipher_suite="${tls_serverhello_ascii:offset:4}" |      tls_cipher_suite="${tls_serverhello_ascii:offset:4}" | ||||||
|  |  | ||||||
|      if [[ "0x${tls_protocol2:2:2}" -le "0x03" ]]; then |      if [[ "0x${DETECTED_TLS_VERSION:2:2}" -le "0x03" ]]; then | ||||||
|           let offset=74+$tls_sid_len |           let offset=74+$tls_sid_len | ||||||
|           tls_compression_method="${tls_serverhello_ascii:offset:2}" |           tls_compression_method="${tls_serverhello_ascii:offset:2}" | ||||||
|           let extns_offset=76+$tls_sid_len |           let extns_offset=76+$tls_sid_len | ||||||
| @@ -8896,8 +8896,8 @@ parse_tls_serverhello() { | |||||||
|      fi |      fi | ||||||
|  |  | ||||||
|      if [[ $tls_serverhello_ascii_len -gt $extns_offset ]] && \ |      if [[ $tls_serverhello_ascii_len -gt $extns_offset ]] && \ | ||||||
|         ( [[ "$process_full" == "all" ]] || [[ "$tls_protocol2" == "0303" ]] || \ |         ( [[ "$process_full" == "all" ]] || [[ "$DETECTED_TLS_VERSION" == "0303" ]] || \ | ||||||
|           ( [[ "$process_full" == "ephemeralkey" ]] && [[ "0x${tls_protocol2:2:2}" -gt "0x03" ]] ) ); then |           ( [[ "$process_full" == "ephemeralkey" ]] && [[ "0x${DETECTED_TLS_VERSION:2:2}" -gt "0x03" ]] ) ); then | ||||||
|           if [[ $tls_serverhello_ascii_len -lt $extns_offset+4 ]]; then |           if [[ $tls_serverhello_ascii_len -lt $extns_offset+4 ]]; then | ||||||
|                debugme echo "Malformed response" |                debugme echo "Malformed response" | ||||||
|                return 1 |                return 1 | ||||||
| @@ -9050,8 +9050,8 @@ parse_tls_serverhello() { | |||||||
|                           fi |                           fi | ||||||
|                           let offset=$extns_offset+12+$i |                           let offset=$extns_offset+12+$i | ||||||
|                           tls_protocol2="${tls_serverhello_ascii:offset:4}" |                           tls_protocol2="${tls_serverhello_ascii:offset:4}" | ||||||
|                           [[ "${tls_protocol2:0:2}" == "7F" ]] && tls_protocol2="0304" |  | ||||||
|                           DETECTED_TLS_VERSION="$tls_protocol2" |                           DETECTED_TLS_VERSION="$tls_protocol2" | ||||||
|  |                           [[ "${DETECTED_TLS_VERSION:0:2}" == "7F" ]] && DETECTED_TLS_VERSION="0304" | ||||||
|                           ;; |                           ;; | ||||||
|                     002C) tls_extensions+="TLS server extension \"cookie\" (id=44), len=$extension_len\n" ;; |                     002C) tls_extensions+="TLS server extension \"cookie\" (id=44), len=$extension_len\n" ;; | ||||||
|                     002D) tls_extensions+="TLS server extension \"psk key exchange modes\" (id=45), len=$extension_len\n" ;; |                     002D) tls_extensions+="TLS server extension \"psk key exchange modes\" (id=45), len=$extension_len\n" ;; | ||||||
| @@ -9089,10 +9089,10 @@ parse_tls_serverhello() { | |||||||
|           done |           done | ||||||
|      fi |      fi | ||||||
|  |  | ||||||
|      if [[ "$tls_protocol2" == "0300" ]]; then |      if [[ "$DETECTED_TLS_VERSION" == "0300" ]]; then | ||||||
|           echo "Protocol  : SSLv3" >> $TMPFILE |           echo "Protocol  : SSLv3" >> $TMPFILE | ||||||
|      else |      else | ||||||
|           echo "Protocol  : TLSv1.$((0x$tls_protocol2-0x0301))" >> $TMPFILE |           echo "Protocol  : TLSv1.$((0x$DETECTED_TLS_VERSION-0x0301))" >> $TMPFILE | ||||||
|      fi |      fi | ||||||
|      echo "===============================================================================" >> $TMPFILE |      echo "===============================================================================" >> $TMPFILE | ||||||
|      if [[ $TLS_NR_CIPHERS -ne 0 ]]; then |      if [[ $TLS_NR_CIPHERS -ne 0 ]]; then | ||||||
| @@ -9120,7 +9120,7 @@ parse_tls_serverhello() { | |||||||
|                echo "${TLS13_KEY_SHARES[named_curve]}" >> $TMPFILE |                echo "${TLS13_KEY_SHARES[named_curve]}" >> $TMPFILE | ||||||
|      fi |      fi | ||||||
|      echo "===============================================================================" >> $TMPFILE |      echo "===============================================================================" >> $TMPFILE | ||||||
|      if [[ "0x${tls_protocol2:2:2}" -le "0x03" ]]; then |      if [[ "0x${DETECTED_TLS_VERSION:2:2}" -le "0x03" ]]; then | ||||||
|           case $tls_compression_method in |           case $tls_compression_method in | ||||||
|                00) echo "Compression: NONE" >> $TMPFILE ;; |                00) echo "Compression: NONE" >> $TMPFILE ;; | ||||||
|                01) echo "Compression: zlib compression" >> $TMPFILE ;; |                01) echo "Compression: zlib compression" >> $TMPFILE ;; | ||||||
| @@ -9135,9 +9135,9 @@ parse_tls_serverhello() { | |||||||
|           echo "TLS server hello message:" |           echo "TLS server hello message:" | ||||||
|           if [[ $DEBUG -ge 4 ]]; then |           if [[ $DEBUG -ge 4 ]]; then | ||||||
|                echo "     tls_protocol:           0x$tls_protocol2" |                echo "     tls_protocol:           0x$tls_protocol2" | ||||||
|                [[ "0x${tls_protocol2:2:2}" -le "0x03" ]] && echo "     tls_sid_len:            0x$tls_sid_len_hex / = $((tls_sid_len/2))" |                [[ "0x${DETECTED_TLS_VERSION:2:2}" -le "0x03" ]] && echo "     tls_sid_len:            0x$tls_sid_len_hex / = $((tls_sid_len/2))" | ||||||
|           fi |           fi | ||||||
|           if [[ "0x${tls_protocol2:2:2}" -le "0x03" ]]; then |           if [[ "0x${DETECTED_TLS_VERSION:2:2}" -le "0x03" ]]; then | ||||||
|                echo -n "     tls_hello_time:         0x$tls_hello_time " |                echo -n "     tls_hello_time:         0x$tls_hello_time " | ||||||
|                parse_date "$TLS_TIME" "+%Y-%m-%d %r" "%s"                  # in debugging mode we don't mind the cycles and don't use TLS_DIFFTIME_SET |                parse_date "$TLS_TIME" "+%Y-%m-%d %r" "%s"                  # in debugging mode we don't mind the cycles and don't use TLS_DIFFTIME_SET | ||||||
|           fi |           fi | ||||||
| @@ -9156,7 +9156,7 @@ parse_tls_serverhello() { | |||||||
|                     echo "     dh_bits:                ECDH, $named_curve_str, $dh_bits bits" |                     echo "     dh_bits:                ECDH, $named_curve_str, $dh_bits bits" | ||||||
|                fi |                fi | ||||||
|           fi |           fi | ||||||
|           if [[ "0x${tls_protocol2:2:2}" -le "0x03" ]]; then |           if [[ "0x${DETECTED_TLS_VERSION:2:2}" -le "0x03" ]]; then | ||||||
|                echo -n "     tls_compression_method: 0x$tls_compression_method " |                echo -n "     tls_compression_method: 0x$tls_compression_method " | ||||||
|                case $tls_compression_method in |                case $tls_compression_method in | ||||||
|                     00) echo "(NONE)" ;; |                     00) echo "(NONE)" ;; | ||||||
| @@ -9200,6 +9200,37 @@ parse_tls_serverhello() { | |||||||
|           fi |           fi | ||||||
|      fi |      fi | ||||||
|  |  | ||||||
|  |      # If the ClientHello included a supported_versions extension, then check that the | ||||||
|  |      # $DETECTED_TLS_VERSION appeared in the list offered in the ClientHello. | ||||||
|  |      if [[ "${TLS_CLIENT_HELLO:0:2}" == "01" ]]; then | ||||||
|  |           # get position of cipher lists (just after session id) | ||||||
|  |           offset=78+2*$(hex2dec "${TLS_CLIENT_HELLO:76:2}") | ||||||
|  |           # get position of compression methods | ||||||
|  |           offset+=4+2*$(hex2dec "${TLS_CLIENT_HELLO:offset:4}") | ||||||
|  |           # get position of extensions | ||||||
|  |           extns_offset=$offset+6+2*$(hex2dec "${TLS_CLIENT_HELLO:offset:2}") | ||||||
|  |           len1=${#TLS_CLIENT_HELLO} | ||||||
|  |           for (( i=extns_offset; i < len1; i=i+8+extension_len )); do | ||||||
|  |                extension_type="${TLS_CLIENT_HELLO:i:4}" | ||||||
|  |                offset=4+$i | ||||||
|  |                extension_len=2*$(hex2dec "${TLS_CLIENT_HELLO:offset:4}") | ||||||
|  |                if [[ "$extension_type" == "002b" ]]; then | ||||||
|  |                     offset+=6 | ||||||
|  |                     tls_protocol2="$(tolower "$tls_protocol2")" | ||||||
|  |                     for (( j=0; j < extension_len-2; j=j+4 )); do | ||||||
|  |                          [[ "${TLS_CLIENT_HELLO:offset:4}" == "$tls_protocol2" ]] && break | ||||||
|  |                          offset+=4 | ||||||
|  |                     done | ||||||
|  |                     if [[ $j -eq $extension_len-2 ]]; then | ||||||
|  |                          debugme echo "The ServerHello specifies a version that wasn't offered in the ClientHello." | ||||||
|  |                          tmpfile_handle $FUNCNAME.txt | ||||||
|  |                          return 1 | ||||||
|  |                     fi | ||||||
|  |                     break | ||||||
|  |                fi | ||||||
|  |           done | ||||||
|  |      fi | ||||||
|  |  | ||||||
|      # Now parse the Certificate message. |      # Now parse the Certificate message. | ||||||
|      if [[ "$process_full" == "all" ]]; then |      if [[ "$process_full" == "all" ]]; then | ||||||
|           [[ -e "$HOSTCERT" ]] && rm "$HOSTCERT" |           [[ -e "$HOSTCERT" ]] && rm "$HOSTCERT" | ||||||
| @@ -9961,6 +9992,17 @@ socksend_tls_clienthello() { | |||||||
|      printf -- "$data" >&5 2>/dev/null & |      printf -- "$data" >&5 2>/dev/null & | ||||||
|      sleep $USLEEP_SND |      sleep $USLEEP_SND | ||||||
|  |  | ||||||
|  |      if [[ "$tls_low_byte" -gt 0x03 ]]; then | ||||||
|  |           TLS_CLIENT_HELLO="$(echo -n "$NW_STR" | tr 'A-F' 'a-f' | \ | ||||||
|  |                sed -e 's/\\x0\\/\\x00\\/g' -e 's/\\x1\\/\\x01\\/g' \ | ||||||
|  |                -e 's/\\x2\\/\\x02\\/g' -e 's/\\x3\\/\\x03\\/g' -e 's/\\x4\\/\\x04\\/g' \ | ||||||
|  |                -e 's/\\x5\\/\\x05\\/g' -e 's/\\x6\\/\\x06\\/g' -e 's/\\x7\\/\\x07\\/g' \ | ||||||
|  |                -e 's/\\x8\\/\\x08\\/g' -e 's/\\x9\\/\\x09\\/g' -e 's/\\xa\\/\\x0a\\/g' \ | ||||||
|  |                -e 's/\\xb\\/\\x0b\\/g' -e 's/\\xc\\/\\x0c\\/g' -e 's/\\xd\\/\\x0d\\/g' \ | ||||||
|  |                -e 's/\\xe\\/\\x0e\\/g' -e 's/\\xf\\/\\x0f\\/g' -e 's/\\x//g')" | ||||||
|  |           TLS_CLIENT_HELLO="${TLS_CLIENT_HELLO:10}" | ||||||
|  |      fi | ||||||
|  |  | ||||||
|      return 0 |      return 0 | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 David Cooper
					David Cooper