mirror of
				https://github.com/drwetter/testssl.sh.git
				synced 2025-10-31 15:41:02 +01:00 
			
		
		
		
	Merge pull request #507 from dcooper16/tls_sockets_extra_extensions
Allow caller to provide extra extensions to tls_sockets()
This commit is contained in:
		
						commit
						18c4164902
					
				
							
								
								
									
										104
									
								
								testssl.sh
									
									
									
									
									
								
							
							
						
						
									
										104
									
								
								testssl.sh
									
									
									
									
									
								
							| @ -6582,6 +6582,7 @@ sslv2_sockets() { | |||||||
| 
 | 
 | ||||||
| # ARG1: TLS version low byte (00: SSLv3,  01: TLS 1.0,  02: TLS 1.1,  03: TLS 1.2) | # ARG1: TLS version low byte (00: SSLv3,  01: TLS 1.0,  02: TLS 1.1,  03: TLS 1.2) | ||||||
| # ARG2: CIPHER_SUITES string | # ARG2: CIPHER_SUITES string | ||||||
|  | # ARG3: (optional) additional request extensions | ||||||
| socksend_tls_clienthello() { | socksend_tls_clienthello() { | ||||||
|      local tls_low_byte="$1" |      local tls_low_byte="$1" | ||||||
|      local tls_word_reclayer="03, 01"      # the first TLS version number is the record layer and always 0301 -- except: SSLv3 |      local tls_word_reclayer="03, 01"      # the first TLS version number is the record layer and always 0301 -- except: SSLv3 | ||||||
| @ -6594,10 +6595,12 @@ socksend_tls_clienthello() { | |||||||
|      local len_client_hello_word len_all_word |      local len_client_hello_word len_all_word | ||||||
|      local ecc_cipher_suite_found=false |      local ecc_cipher_suite_found=false | ||||||
|      local extension_signature_algorithms extension_heartbeat |      local extension_signature_algorithms extension_heartbeat | ||||||
|      local extension_session_ticket extension_next_protocol extensions_ecc extension_padding |      local extension_session_ticket extension_next_protocol extension_padding | ||||||
|  |      local extension_supported_groups="" extension_supported_point_formats="" | ||||||
|  |      local extra_extensions extra_extensions_list="" | ||||||
| 
 | 
 | ||||||
|      code2network "$2"             # convert CIPHER_SUITES |      code2network "$(echo "$2" | tr 'A-Z' 'a-z')"   # convert CIPHER_SUITES | ||||||
|      cipher_suites="$NW_STR"       # we don't have the leading \x here so string length is two byte less, see next |      cipher_suites="$NW_STR"                      # we don't have the leading \x here so string length is two byte less, see next | ||||||
| 
 | 
 | ||||||
|      len_ciph_suites_byte=$(echo ${#cipher_suites}) |      len_ciph_suites_byte=$(echo ${#cipher_suites}) | ||||||
|      let "len_ciph_suites_byte += 2" |      let "len_ciph_suites_byte += 2" | ||||||
| @ -6626,7 +6629,7 @@ socksend_tls_clienthello() { | |||||||
|                     elif [[ "$part2" -ge "0x5c" ]] && [[ "$part2" -le "0x63" ]]; then |                     elif [[ "$part2" -ge "0x5c" ]] && [[ "$part2" -le "0x63" ]]; then | ||||||
|                          ecc_cipher_suite_found=true && break |                          ecc_cipher_suite_found=true && break | ||||||
|                     elif [[ "$part2" -ge "0x70" ]] && [[ "$part2" -le "0x79" ]]; then |                     elif [[ "$part2" -ge "0x70" ]] && [[ "$part2" -le "0x79" ]]; then | ||||||
|                     ecc_cipher_suite_found=true && break |                          ecc_cipher_suite_found=true && break | ||||||
|                     elif [[ "$part2" -ge "0x86" ]] && [[ "$part2" -le "0x8d" ]]; then |                     elif [[ "$part2" -ge "0x86" ]] && [[ "$part2" -le "0x8d" ]]; then | ||||||
|                          ecc_cipher_suite_found=true && break |                          ecc_cipher_suite_found=true && break | ||||||
|                     elif [[ "$part2" -ge "0x9a" ]] && [[ "$part2" -le "0x9b" ]]; then |                     elif [[ "$part2" -ge "0x9a" ]] && [[ "$part2" -le "0x9b" ]]; then | ||||||
| @ -6673,43 +6676,79 @@ socksend_tls_clienthello() { | |||||||
|           extension_next_protocol=" |           extension_next_protocol=" | ||||||
|           33, 74, 00, 00" |           33, 74, 00, 00" | ||||||
| 
 | 
 | ||||||
|           # Supported Elliptic Curves Extension and Supported Point Formats Extension. |           if "$ecc_cipher_suite_found"; then | ||||||
|           extensions_ecc=" |                # Supported Groups Extension | ||||||
|           00, 0a,                    # Type: Supported Elliptic Curves , see RFC 4492 |                extension_supported_groups=" | ||||||
|           00, 3e, 00, 3c,            # lengths |                00, 0a,                    # Type: Supported Elliptic Curves , see RFC 4492 | ||||||
|           00, 0e, 00, 0d, 00, 19, 00, 1c, 00, 1e, 00, 0b, 00, 0c, 00, 1b, |                00, 3e, 00, 3c,            # lengths | ||||||
|           00, 18, 00, 09, 00, 0a, 00, 1a, 00, 16, 00, 17, 00, 1d, 00, 08, |                00, 0e, 00, 0d, 00, 19, 00, 1c, 00, 1e, 00, 0b, 00, 0c, 00, 1b, | ||||||
|           00, 06, 00, 07, 00, 14, 00, 15, 00, 04, 00, 05, 00, 12, 00, 13, |                00, 18, 00, 09, 00, 0a, 00, 1a, 00, 16, 00, 17, 00, 1d, 00, 08, | ||||||
|           00, 01, 00, 02, 00, 03, 00, 0f, 00, 10, 00, 11, |                00, 06, 00, 07, 00, 14, 00, 15, 00, 04, 00, 05, 00, 12, 00, 13, | ||||||
|           00, 0b,                    # Type: Supported Point Formats , see RFC 4492 |                00, 01, 00, 02, 00, 03, 00, 0f, 00, 10, 00, 11" | ||||||
|           00, 02,                    # len |                # Supported Point Formats Extension | ||||||
|           01, 00" |                extension_supported_point_formats=" | ||||||
|  |                00, 0b,                    # Type: Supported Point Formats , see RFC 4492  | ||||||
|  |                00, 02,                    # len | ||||||
|  |                01, 00" | ||||||
|  |           fi | ||||||
| 
 | 
 | ||||||
|           all_extensions=" |           # Each extension should appear in the ClientHello at most once. So, | ||||||
|            $extension_heartbeat |           # find out what extensions were provided as an argument and only use | ||||||
|           ,$extension_session_ticket |           # the provided values for those extensions. | ||||||
|           ,$extension_next_protocol" |           extra_extensions="$(echo "$3" | tr 'A-Z' 'a-z')" | ||||||
|  |           code2network "$extra_extensions" | ||||||
|  |           len_all=${#extra_extensions} | ||||||
|  |           for (( i=0; i < len_all; i=i+16+4*0x$len_extension_hex )); do | ||||||
|  |                part2=$i+4 | ||||||
|  |                extra_extensions_list+=" ${NW_STR:i:2}${NW_STR:part2:2} " | ||||||
|  |                j=$i+8 | ||||||
|  |                part2=$j+4 | ||||||
|  |                len_extension_hex="${NW_STR:j:2}${NW_STR:part2:2}" | ||||||
|  |           done | ||||||
| 
 | 
 | ||||||
|           if [[ -n "$SNI" ]]; then |           if [[ -n "$SNI" ]] && [[ ! "$extra_extensions_list" =~ " 0000 " ]]; then | ||||||
|                all_extensions="$all_extensions |                all_extensions=" | ||||||
|                ,00, 00                  # extension server_name |                 00, 00                  # extension server_name | ||||||
|                ,00, $len_sni_ext        # length SNI EXT |                ,00, $len_sni_ext        # length SNI EXT | ||||||
|                ,00, $len_sni_listlen    # server_name list_length |                ,00, $len_sni_listlen    # server_name list_length | ||||||
|                ,00                      # server_name type (hostname) |                ,00                      # server_name type (hostname) | ||||||
|                ,00, $len_servername_hex # server_name length. We assume len(hostname) < FF - 9 |                ,00, $len_servername_hex # server_name length. We assume len(hostname) < FF - 9 | ||||||
|                ,$servername_hexstr"     # server_name target |                ,$servername_hexstr"     # server_name target | ||||||
|           fi |           fi | ||||||
|  |           if [[ ! "$extra_extensions_list" =~ " 000f " ]]; then | ||||||
|  |                [[ -n "$all_extensions" ]] && all_extensions+="," | ||||||
|  |                all_extensions+="$extension_heartbeat" | ||||||
|  |           fi | ||||||
|  |           if [[ ! "$extra_extensions_list" =~ " 0023 " ]]; then | ||||||
|  |                [[ -n "$all_extensions" ]] && all_extensions+="," | ||||||
|  |                all_extensions+="$extension_session_ticket" | ||||||
|  |           fi | ||||||
|  | 
 | ||||||
|  |           # If the ClientHello will include the ALPN extension, then don't include the NPN extension. | ||||||
|  |           if [[ ! "$extra_extensions_list" =~ " 3374 " ]] && [[ ! "$extra_extensions_list" =~ " 0010 " ]]; then | ||||||
|  |                [[ -n "$all_extensions" ]] && all_extensions+="," | ||||||
|  |                all_extensions+="$extension_next_protocol" | ||||||
|  |           fi | ||||||
| 
 | 
 | ||||||
|           # RFC 5246 says that clients MUST NOT offer the signature algorithms |           # RFC 5246 says that clients MUST NOT offer the signature algorithms | ||||||
|           # extension if they are offering TLS versions prior to 1.2. |           # extension if they are offering TLS versions prior to 1.2. | ||||||
|           if [[ "0x$tls_low_byte" -ge "0x03" ]]; then |           if [[ "0x$tls_low_byte" -ge "0x03" ]] && [[ ! "$extra_extensions_list" =~ " 000d " ]]; then | ||||||
|                all_extensions="$all_extensions |                [[ -n "$all_extensions" ]] && all_extensions+="," | ||||||
|                ,$extension_signature_algorithms" |                all_extensions+="$extension_signature_algorithms" | ||||||
|           fi |           fi | ||||||
| 
 | 
 | ||||||
|           if $ecc_cipher_suite_found; then |           if [[ -n "$extension_supported_groups" ]] && [[ ! "$extra_extensions_list" =~ " 000a " ]]; then | ||||||
|                all_extensions="$all_extensions |                [[ -n "$all_extensions" ]] && all_extensions+="," | ||||||
|                ,$extensions_ecc" |                all_extensions+="$extension_supported_groups" | ||||||
|  |           fi | ||||||
|  |           if [[ -n "$extension_supported_point_formats" ]] && [[ ! "$extra_extensions_list" =~ " 000b " ]]; then | ||||||
|  |                [[ -n "$all_extensions" ]] && all_extensions+="," | ||||||
|  |                all_extensions+="$extension_supported_point_formats" | ||||||
|  |           fi | ||||||
|  | 
 | ||||||
|  |           if [[ -n "$extra_extensions" ]]; then | ||||||
|  |                [[ -n "$all_extensions" ]] && all_extensions+="," | ||||||
|  |                all_extensions+="$extra_extensions" | ||||||
|           fi |           fi | ||||||
| 
 | 
 | ||||||
|           code2network "$all_extensions" # convert extensions |           code2network "$all_extensions" # convert extensions | ||||||
| @ -6722,11 +6761,11 @@ socksend_tls_clienthello() { | |||||||
|           # If the length of the Client Hello would be between 256 and 511 bytes, |           # If the length of the Client Hello would be between 256 and 511 bytes, | ||||||
|           # then add a padding extension (see RFC 7685) |           # then add a padding extension (see RFC 7685) | ||||||
|           len_all=$((0x$len_ciph_suites + 0x2b + 0x$len_extension_hex + 0x2)) |           len_all=$((0x$len_ciph_suites + 0x2b + 0x$len_extension_hex + 0x2)) | ||||||
|           if [[ $len_all -ge 256 ]] && [[ $len_all -le 511 ]]; then |           if [[ $len_all -ge 256 ]] && [[ $len_all -le 511 ]] && [[ ! "$extra_extensions_list" =~ " 0015 " ]]; then | ||||||
|                if [[ $len_all -gt 508 ]]; then |                if [[ $len_all -gt 508 ]]; then | ||||||
|                    len_padding_extension=0 |                     len_padding_extension=0 | ||||||
|                else |                else | ||||||
|                    len_padding_extension=$((508 - 0x$len_ciph_suites - 0x2b - 0x$len_extension_hex - 0x2)) |                     len_padding_extension=$((508 - 0x$len_ciph_suites - 0x2b - 0x$len_extension_hex - 0x2)) | ||||||
|                fi |                fi | ||||||
|                len_padding_extension_hex=$(printf "%02x\n" $len_padding_extension) |                len_padding_extension_hex=$(printf "%02x\n" $len_padding_extension) | ||||||
|                len2twobytes "$len_padding_extension_hex" |                len2twobytes "$len_padding_extension_hex" | ||||||
| @ -6799,6 +6838,7 @@ socksend_tls_clienthello() { | |||||||
| # arg2: (optional) list of cipher suites | # arg2: (optional) list of cipher suites | ||||||
| # arg3: (optional): "all" - process full response (including Certificate and certificate_status handshake messages) | # arg3: (optional): "all" - process full response (including Certificate and certificate_status handshake messages) | ||||||
| #                   "ephemeralkey" - extract the server's ephemeral key (if any) | #                   "ephemeralkey" - extract the server's ephemeral key (if any) | ||||||
|  | # arg4: (optional) additional request extensions | ||||||
| tls_sockets() { | tls_sockets() { | ||||||
|      local -i ret=0 |      local -i ret=0 | ||||||
|      local -i save=0 |      local -i save=0 | ||||||
| @ -6821,7 +6861,7 @@ tls_sockets() { | |||||||
|      fi |      fi | ||||||
| 
 | 
 | ||||||
|      debugme echo "sending client hello..." |      debugme echo "sending client hello..." | ||||||
|      socksend_tls_clienthello "$tls_low_byte" "$cipher_list_2send" |      socksend_tls_clienthello "$tls_low_byte" "$cipher_list_2send" "$4" | ||||||
|      ret=$?                             # 6 means opening socket didn't succeed, e.g. timeout |      ret=$?                             # 6 means opening socket didn't succeed, e.g. timeout | ||||||
| 
 | 
 | ||||||
|      # if sending didn't succeed we don't bother |      # if sending didn't succeed we don't bother | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user