mirror of
				https://github.com/drwetter/testssl.sh.git
				synced 2025-10-30 21:35:26 +01:00 
			
		
		
		
	Merge pull request #1114 from dcooper16/run_pfs_dh_groups
Checking for DH groups in run_pfs()
This commit is contained in:
		
							
								
								
									
										98
									
								
								testssl.sh
									
									
									
									
									
								
							
							
						
						
									
										98
									
								
								testssl.sh
									
									
									
									
									
								
							| @@ -5419,20 +5419,28 @@ run_cipherlists() { | |||||||
|      return $ret |      return $ret | ||||||
| } | } | ||||||
|  |  | ||||||
|  | # The return value is an indicator of the quality of the DH key length in $1: | ||||||
|  | #   1 = pr_svrty_critical, 2 = pr_svrty_high, 3 = pr_svrty_medium, 4 = pr_svrty_low | ||||||
|  | #   5 = neither good nor bad, 6 = pr_svrty_good, 7 = pr_svrty_best | ||||||
| pr_dh_quality() { | pr_dh_quality() { | ||||||
|      local bits="$1" |      local bits="$1" | ||||||
|      local string="$2" |      local string="$2" | ||||||
|  |  | ||||||
|      if [[ "$bits" -le 600 ]]; then |      if [[ "$bits" -le 600 ]]; then | ||||||
|           pr_svrty_critical "$string" |           pr_svrty_critical "$string" | ||||||
|  |           return 1 | ||||||
|      elif [[ "$bits" -le 800 ]]; then |      elif [[ "$bits" -le 800 ]]; then | ||||||
|           pr_svrty_high "$string" |           pr_svrty_high "$string" | ||||||
|  |           return 2 | ||||||
|      elif [[ "$bits" -le 1280 ]]; then |      elif [[ "$bits" -le 1280 ]]; then | ||||||
|           pr_svrty_medium "$string" |           pr_svrty_medium "$string" | ||||||
|  |           return 3 | ||||||
|      elif [[ "$bits" -ge 2048 ]]; then |      elif [[ "$bits" -ge 2048 ]]; then | ||||||
|           pr_svrty_good "$string" |           pr_svrty_good "$string" | ||||||
|  |           return 6 | ||||||
|      else |      else | ||||||
|           out "$string" |           out "$string" | ||||||
|  |           return 5 | ||||||
|      fi |      fi | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -8435,6 +8443,8 @@ run_pfs() { | |||||||
|      local -i nr_supported_ciphers=0 nr_curves=0 nr_ossl_curves=0 i j low high |      local -i nr_supported_ciphers=0 nr_curves=0 nr_ossl_curves=0 i j low high | ||||||
|      local pfs_ciphers curves_offered="" curves_to_test temp |      local pfs_ciphers curves_offered="" curves_to_test temp | ||||||
|      local len1 len2 curve_found |      local len1 len2 curve_found | ||||||
|  |      local key_bitstring quality_str | ||||||
|  |      local -i len_dh_p quality | ||||||
|      local has_dh_bits="$HAS_DH_BITS" |      local has_dh_bits="$HAS_DH_BITS" | ||||||
|      local using_sockets=true |      local using_sockets=true | ||||||
|      local jsonID="PFS" |      local jsonID="PFS" | ||||||
| @@ -8786,26 +8796,23 @@ run_pfs() { | |||||||
|           fi |           fi | ||||||
|      fi |      fi | ||||||
|      if "$using_sockets" && ( "$pfs_tls13_offered" || ( "$ffdhe_offered" && "$EXPERIMENTAL" ) ); then |      if "$using_sockets" && ( "$pfs_tls13_offered" || ( "$ffdhe_offered" && "$EXPERIMENTAL" ) ); then | ||||||
|           # find out what groups from RFC 7919 are supported. |           # find out what groups are supported. | ||||||
|           nr_curves=0 |           nr_curves=0 | ||||||
|           for curve in "${ffdhe_groups_output[@]}"; do |           for curve in "${ffdhe_groups_output[@]}"; do | ||||||
|                supported_curve[nr_curves]=false |                supported_curve[nr_curves]=false | ||||||
|  |                [[ "$DH_GROUP_OFFERED" =~ "$curve" ]] && supported_curve[nr_curves]=true | ||||||
|                nr_curves+=1 |                nr_curves+=1 | ||||||
|           done |           done | ||||||
|           protos_to_try="" |           protos_to_try="" | ||||||
|           "$pfs_tls13_offered" && protos_to_try="04" |           "$pfs_tls13_offered" && protos_to_try="04" | ||||||
|           if "$ffdhe_offered" && "$EXPERIMENTAL"; then |           if "$ffdhe_offered" && "$EXPERIMENTAL"; then | ||||||
|                # Check to see whether RFC 7919 is supported (see Section 4 of RFC 7919) |                if "$pfs_tls13_offered"; then | ||||||
|                tls_sockets "03" "${ffdhe_cipher_list_hex:2}, 00,ff" "ephemeralkey" "00, 0a, 00, 04, 00, 02, 01, fb" |                     protos_to_try="04 03" | ||||||
|                sclient_success=$? |                else | ||||||
|                if [[ $sclient_success -ne 0 ]] && [[ $sclient_success -ne 2 ]]; then |                     protos_to_try="03" | ||||||
|                     if "$pfs_tls13_offered"; then |  | ||||||
|                          protos_to_try="04 03" |  | ||||||
|                     else |  | ||||||
|                          protos_to_try="03" |  | ||||||
|                     fi |  | ||||||
|                fi |                fi | ||||||
|           fi |           fi | ||||||
|  |           curve_found="" | ||||||
|           for proto in $protos_to_try; do |           for proto in $protos_to_try; do | ||||||
|                while true; do |                while true; do | ||||||
|                     curves_to_test="" |                     curves_to_test="" | ||||||
| @@ -8821,6 +8828,10 @@ run_pfs() { | |||||||
|                     temp=$(awk -F': ' '/^Server Temp Key/ { print $2 }' "$TEMPDIR/$NODEIP.parse_tls_serverhello.txt") |                     temp=$(awk -F': ' '/^Server Temp Key/ { print $2 }' "$TEMPDIR/$NODEIP.parse_tls_serverhello.txt") | ||||||
|                     curve_found="${temp#*, }" |                     curve_found="${temp#*, }" | ||||||
|                     curve_found="${curve_found%%,*}" |                     curve_found="${curve_found%%,*}" | ||||||
|  |                     if [[ "$proto" == "03" ]] && [[ -z "$DH_GROUP_OFFERED" ]] && [[ "$curve_found" =~ ffdhe ]]; then | ||||||
|  |                          DH_GROUP_OFFERED="RFC7919/$curve_found" | ||||||
|  |                          DH_GROUP_LEN_P="${curve_found#ffdhe}" | ||||||
|  |                     fi | ||||||
|                     [[ ! "$curve_found" =~ ffdhe ]] && break |                     [[ ! "$curve_found" =~ ffdhe ]] && break | ||||||
|                     for (( i=0; i < nr_curves; i++ )); do |                     for (( i=0; i < nr_curves; i++ )); do | ||||||
|                          ! "${supported_curve[i]}" && [[ "${ffdhe_groups_output[i]}" == "$curve_found" ]] && break |                          ! "${supported_curve[i]}" && [[ "${ffdhe_groups_output[i]}" == "$curve_found" ]] && break | ||||||
| @@ -8833,10 +8844,51 @@ run_pfs() { | |||||||
|           for (( i=0; i < nr_curves; i++ )); do |           for (( i=0; i < nr_curves; i++ )); do | ||||||
|                "${supported_curve[i]}" && curves_offered+="${ffdhe_groups_output[i]} " |                "${supported_curve[i]}" && curves_offered+="${ffdhe_groups_output[i]} " | ||||||
|           done |           done | ||||||
|  |           curves_offered="$(strip_trailing_space "$curves_offered")" | ||||||
|  |           if "$ffdhe_offered" && "$EXPERIMENTAL" && [[ -z "$curves_offered" ]] && [[ -z "$curve_found" ]]; then | ||||||
|  |                # Some servers will fail if the supported_groups extension is present. | ||||||
|  |                tls_sockets "03" "${ffdhe_cipher_list_hex:2}, 00,ff" "ephemeralkey" | ||||||
|  |                sclient_success=$? | ||||||
|  |                if [[ $sclient_success -eq 0 ]] || [[ $sclient_success -eq 2 ]]; then | ||||||
|  |                     temp=$(awk -F': ' '/^Server Temp Key/ { print $2 }' "$TEMPDIR/$NODEIP.parse_tls_serverhello.txt") | ||||||
|  |                     curve_found="${temp#*, }" | ||||||
|  |                     curve_found="${curve_found%%,*}" | ||||||
|  |                fi | ||||||
|  |           fi | ||||||
|  |           if [[ -z "$curves_offered" ]] && [[ -n "$curve_found" ]]; then | ||||||
|  |                # The server is not using one of the groups from RFC 7919. | ||||||
|  |                key_bitstring="$(awk '/-----BEGIN PUBLIC KEY/,/-----END PUBLIC KEY/ { print $0 }' $TEMPDIR/$NODEIP.parse_tls_serverhello.txt)" | ||||||
|  |                get_common_prime "$jsonID" "$key_bitstring" "" | ||||||
|  |                [[ $? -eq 0 ]] && curves_offered="$DH_GROUP_OFFERED" && len_dh_p=$DH_GROUP_LEN_P | ||||||
|  |           fi | ||||||
|           if [[ -n "$curves_offered" ]]; then |           if [[ -n "$curves_offered" ]]; then | ||||||
|                pr_bold " RFC 7919 DH groups offered:  " |                if [[ ! "$curves_offered" =~ ffdhe ]] || [[ ! "$curves_offered" =~ \  ]]; then | ||||||
|                outln "$curves_offered" |                     pr_bold " Finite field group offered:  " | ||||||
|                fileout "RFC7919_DH_groups" "INFO" "$curves_offered" |                else | ||||||
|  |                     pr_bold " Finite field groups offered: " | ||||||
|  |                fi | ||||||
|  |                if [[ "$curves_offered" =~ ffdhe ]]; then | ||||||
|  |                     pr_svrty_good "$curves_offered" | ||||||
|  |                     quality=6 | ||||||
|  |                else | ||||||
|  |                     out "$curves_offered (" | ||||||
|  |                     pr_dh_quality "$len_dh_p" "$len_dh_p bits" | ||||||
|  |                     quality=$? | ||||||
|  |                     out ")" | ||||||
|  |                fi | ||||||
|  |                case "$quality" in | ||||||
|  |                     1) quality_str="CRITICAL" ;; | ||||||
|  |                     2) quality_str="HIGH" ;; | ||||||
|  |                     3) quality_str="MEDIUM" ;; | ||||||
|  |                     4) quality_str="LOW" ;; | ||||||
|  |                     5) quality_str="INFO" ;; | ||||||
|  |                     6|7) quality_str="OK" ;; | ||||||
|  |                esac | ||||||
|  |                if [[ "$curves_offered" =~ Unknown ]]; then | ||||||
|  |                     fileout "DHE_groups" "$quality_str" "$curves_offered ($len_dh_p bits)" | ||||||
|  |                else | ||||||
|  |                     fileout "DHE_groups" "$quality_str" "$curves_offered" | ||||||
|  |                fi | ||||||
|           fi |           fi | ||||||
|      fi |      fi | ||||||
|      outln |      outln | ||||||
| @@ -13878,7 +13930,11 @@ out_common_prime() { | |||||||
|      local cwe="$3" |      local cwe="$3" | ||||||
|  |  | ||||||
|      # now size matters -- i.e. the bit size ;-) |      # now size matters -- i.e. the bit size ;-) | ||||||
|      if [[ $DH_GROUP_LEN_P -le 512 ]]; then |      [[ "$DH_GROUP_OFFERED" == ffdhe* ]] && [[ ! "$DH_GROUP_OFFERED" =~ \  ]] && DH_GROUP_OFFERED="RFC7919/$DH_GROUP_OFFERED" | ||||||
|  |      if [[ "$DH_GROUP_OFFERED" =~ ffdhe ]] && [[ "$DH_GROUP_OFFERED" =~ \  ]]; then | ||||||
|  |           out "common primes detected: "; pr_italic "$DH_GROUP_OFFERED" | ||||||
|  |           fileout "$jsonID2" "INFO" "$DH_GROUP_OFFERED" "$cve" "$cwe" | ||||||
|  |      elif [[ $DH_GROUP_LEN_P -le 512 ]]; then | ||||||
|           pr_svrty_critical "VULNERABLE (NOT ok):"; out " common prime "; pr_italic "$DH_GROUP_OFFERED"; out " detected ($DH_GROUP_LEN_P bits)" |           pr_svrty_critical "VULNERABLE (NOT ok):"; out " common prime "; pr_italic "$DH_GROUP_OFFERED"; out " detected ($DH_GROUP_LEN_P bits)" | ||||||
|           fileout "$jsonID2" "CRITICAL" "$DH_GROUP_OFFERED" "$cve" "$cwe" |           fileout "$jsonID2" "CRITICAL" "$DH_GROUP_OFFERED" "$cve" "$cwe" | ||||||
|      elif [[ $DH_GROUP_LEN_P -le 1024 ]]; then |      elif [[ $DH_GROUP_LEN_P -le 1024 ]]; then | ||||||
| @@ -13969,7 +14025,13 @@ run_logjam() { | |||||||
|      fi |      fi | ||||||
|  |  | ||||||
|      # Try all ciphers that use an ephemeral DH key. If successful, check whether the key uses a weak prime. |      # Try all ciphers that use an ephemeral DH key. If successful, check whether the key uses a weak prime. | ||||||
|      if "$using_sockets"; then |      if [[ -n "$DH_GROUP_OFFERED" ]]; then | ||||||
|  |           if [[ "$DH_GROUP_OFFERED" =~ Unknown ]]; then | ||||||
|  |                subret=0                 # no common DH key detected | ||||||
|  |           else | ||||||
|  |                subret=1                 # known prime/DH key | ||||||
|  |           fi | ||||||
|  |      elif "$using_sockets"; then | ||||||
|           tls_sockets "03" "$all_dh_ciphers, 00,ff" "ephemeralkey" |           tls_sockets "03" "$all_dh_ciphers, 00,ff" "ephemeralkey" | ||||||
|           sclient_success=$? |           sclient_success=$? | ||||||
|           if [[ $sclient_success -eq 0 ]] || [[ $sclient_success -eq 2 ]]; then |           if [[ $sclient_success -eq 0 ]] || [[ $sclient_success -eq 2 ]]; then | ||||||
| @@ -14000,10 +14062,8 @@ run_logjam() { | |||||||
|           fi |           fi | ||||||
|      fi |      fi | ||||||
|  |  | ||||||
|      # FIXME: The following logic comes too late if we have already a check for DH groups in run_pfs() |  | ||||||
|      # now the final test for common primes, -n "$DH_GROUP_OFFERED" indicates we did this already |  | ||||||
|      if [[ -n "$key_bitstring" ]]; then |      if [[ -n "$key_bitstring" ]]; then | ||||||
|            if [[ -z "$DH_GROUP_OFFERED" ]]; then |           if [[ -z "$DH_GROUP_OFFERED" ]]; then | ||||||
|                get_common_prime "$jsonID2" "$key_bitstring" "$spaces" |                get_common_prime "$jsonID2" "$key_bitstring" "$spaces" | ||||||
|                ret=$?                   # no common primes file would be ret=1 --> we should treat that some place else before |                ret=$?                   # no common primes file would be ret=1 --> we should treat that some place else before | ||||||
|           fi |           fi | ||||||
| @@ -14012,7 +14072,7 @@ run_logjam() { | |||||||
|           else |           else | ||||||
|                subret=1                 # known prime/DH key |                subret=1                 # known prime/DH key | ||||||
|           fi |           fi | ||||||
|      else |      elif [[ -z "$DH_GROUP_OFFERED" ]]; then | ||||||
|           subret=3 |           subret=3 | ||||||
|      fi |      fi | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Dirk Wetter
					Dirk Wetter