mirror of
				https://github.com/drwetter/testssl.sh.git
				synced 2025-10-25 22:11:01 +02:00 
			
		
		
		
	Merge branch 'master' into run_allciphers(),run_cipher_per_proto(),-and-SSLv2
This commit is contained in:
		
						commit
						a503d883c7
					
				
							
								
								
									
										489
									
								
								testssl.sh
									
									
									
									
									
								
							
							
						
						
									
										489
									
								
								testssl.sh
									
									
									
									
									
								
							| @ -20,11 +20,11 @@ | ||||
| # license permitted. | ||||
| # If you enclose this script or parts of it in your software, it has to | ||||
| # be accompanied by the same license (see link) and the place where to get | ||||
| # the recent version of this program. Do not violate the license andif | ||||
| # the recent version of this program. Do not violate the license and if | ||||
| # you do not agree to all of these terms, do not use it in the first place. | ||||
| # | ||||
| # OpenSSL which is being used and maybe distributed via one of this projects' | ||||
| # web site is subject to their licensing: https://www.openssl.org/source/license.txt | ||||
| # OpenSSL, which is being used and maybe distributed via one of this projects' | ||||
| # web sites, is subject to their licensing: https://www.openssl.org/source/license.txt | ||||
| # | ||||
| # The client simulation data comes from SSLlabs and is licensed to the 'Qualys SSL Labs | ||||
| # Terms of Use' (v2.2), see https://www.ssllabs.com/downloads/Qualys_SSL_Labs_Terms_of_Use.pdf, | ||||
| @ -42,7 +42,7 @@ | ||||
| # wiki.openssl.org/index.php/Command_Line_Utilities) that it was difficult to resist | ||||
| # wrapping some shell commands around it, which I used for my pen tests. This is how | ||||
| # everything started. | ||||
| # Now it has grown up, it has bash socket support for some features which basically replacing | ||||
| # Now it has grown up, it has bash socket support for some features, which is basically replacing | ||||
| # more and more functions of OpenSSL and will serve as some kind of library in the future. | ||||
| # The socket checks in bash may sound cool and unique -- they are -- but probably you | ||||
| # can achieve e.g. the same result with my favorite interactive shell: zsh (zmodload zsh/net/socket | ||||
| @ -204,7 +204,6 @@ HAS_SSL2=false | ||||
| HAS_SSL3=false | ||||
| HAS_ALPN=false | ||||
| HAS_SPDY=false | ||||
| HAS_SSL2=false | ||||
| ADD_RFC_STR="rfc"                       # display RFC ciphernames | ||||
| PORT=443                                # unless otherwise auto-determined, see below | ||||
| NODE="" | ||||
| @ -225,7 +224,7 @@ URI="" | ||||
| CERT_FINGERPRINT_SHA2="" | ||||
| SHOW_CENSYS_LINK=${SHOW_CENSYS_LINK:-true} | ||||
| STARTTLS_PROTOCOL="" | ||||
| OPTIMAL_PROTO=""                        # we need this for IIS6 (sigh) and OpenSSL 1.02, otherwise some handshakes | ||||
| OPTIMAL_PROTO=""                        # we need this for IIS6 (sigh) and OpenSSL 1.0.2, otherwise some handshakes | ||||
|                                         # will fail, see https://github.com/PeterMosmans/openssl/issues/19#issuecomment-100897892 | ||||
| STARTTLS_OPTIMAL_PROTO=""               # same for STARTTLS, see https://github.com/drwetter/testssl.sh/issues/188 | ||||
| TLS_TIME="" | ||||
| @ -489,11 +488,6 @@ hex2dec() { | ||||
|      echo $((16#$1)) | ||||
| } | ||||
| 
 | ||||
| dec2hex() { | ||||
|      #/usr/bin/printf -- "%x" "$1" | ||||
|      echo $((0x$1)) | ||||
| } | ||||
| 
 | ||||
| # trim spaces for BSD and old sed | ||||
| count_lines() { | ||||
|      wc -l <<<"$1" | sed 's/ //g' | ||||
| @ -966,7 +960,7 @@ run_hpkp() { | ||||
|           out "# of keys: " | ||||
|           if [[ $hpkp_nr_keys -eq 1 ]]; then | ||||
|                pr_svrty_high "1 (NOT ok), " | ||||
|                fileout "hpkp_keys" "NOT ok" "Only one key pinned in HPKP header, this means the site may become unavaiable if the key is revoked" | ||||
|                fileout "hpkp_keys" "NOT ok" "Only one key pinned in HPKP header, this means the site may become unavailable if the key is revoked" | ||||
|           else | ||||
|                out "$hpkp_nr_keys, " | ||||
|                fileout "hpkp_keys" "OK" "$hpkp_nr_keys keys pinned in HPKP header, additional keys are available if the current key is revoked" | ||||
| @ -1077,9 +1071,9 @@ run_server_banner() { | ||||
|                emphasize_stuff_in_headers "$serverbanner" | ||||
|                fileout "serverbanner" "INFO" "Server banner identified: $serverbanner" | ||||
|                if [[ "$serverbanner" = *Microsoft-IIS/6.* ]] && [[ $OSSL_VER == 1.0.2* ]]; then | ||||
|                     pr_warningln "                              It's recommended to run another test w/ OpenSSL 1.01 !" | ||||
|                     pr_warningln "                              It's recommended to run another test w/ OpenSSL 1.0.1 !" | ||||
|                     # see https://github.com/PeterMosmans/openssl/issues/19#issuecomment-100897892 | ||||
|                     fileout "IIS6_openssl_mismatch" "WARN" "It is recommended to rerun this test w/ OpenSSL 1.01\nSee https://github.com/PeterMosmans/openssl/issues/19#issuecomment-100897892" | ||||
|                     fileout "IIS6_openssl_mismatch" "WARN" "It is recommended to rerun this test w/ OpenSSL 1.0.1. See https://github.com/PeterMosmans/openssl/issues/19#issuecomment-100897892" | ||||
|                fi | ||||
|           fi | ||||
|           # mozilla.github.io/server-side-tls/ssl-config-generator/ | ||||
| @ -1393,8 +1387,8 @@ std_cipherlists() { | ||||
|                     ;; | ||||
|                3) # not totally bad | ||||
|                     if [[ $sclient_success -eq 0 ]]; then | ||||
|                          pr_svrty_mediumln "offered (NOT ok)" | ||||
|                          fileout "std_$4" "NOT ok" "$2 offered (NOT ok) - not too bad" | ||||
|                          pr_svrty_mediumln "offered" | ||||
|                          fileout "std_$4" "NOT ok" "$2 offered - not too bad" | ||||
|                     else | ||||
|                          outln "not offered (OK)" | ||||
|                          fileout "std_$4" "OK" "$2 not offered (OK)" | ||||
| @ -1492,7 +1486,7 @@ neat_list(){ | ||||
| 
 | ||||
|      #printf -- "%q" "$kx" | xxd | head -1 | ||||
|      # length correction for color escape codes (printf counts the escape color codes!!) | ||||
|      if printf -- "%q" "$kx" | egrep -aq '.;3.m|E\[1m' ; then     # here's a color code which screws up the formatting with prinf below | ||||
|      if printf -- "%q" "$kx" | egrep -aq '.;3.m|E\[1m' ; then     # here's a color code which screws up the formatting with printf below | ||||
|           while [[ ${#kx} -lt 20 ]]; do | ||||
|                kx="$kx " | ||||
|           done | ||||
| @ -1567,7 +1561,7 @@ test_just_one(){ | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| # test for all ciphers locally configured (w/o distinguishing whether they are good or bad | ||||
| # test for all ciphers locally configured (w/o distinguishing whether they are good or bad) | ||||
| run_allciphers() { | ||||
|      local tmpfile | ||||
|      local -i nr_ciphers=0 | ||||
| @ -2063,7 +2057,7 @@ run_client_simulation() { | ||||
|      ciphers+=("ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DH-DSS-AES256-GCM-SHA384:DHE-DSS-AES256-GCM-SHA384:DH-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA256:DH-RSA-AES256-SHA256:DH-DSS-AES256-SHA256:DHE-RSA-AES256-SHA:DHE-DSS-AES256-SHA:DH-RSA-AES256-SHA:DH-DSS-AES256-SHA:DHE-RSA-CAMELLIA256-SHA:DHE-DSS-CAMELLIA256-SHA:DH-RSA-CAMELLIA256-SHA:DH-DSS-CAMELLIA256-SHA:ECDH-RSA-AES256-GCM-SHA384:ECDH-ECDSA-AES256-GCM-SHA384:ECDH-RSA-AES256-SHA384:ECDH-ECDSA-AES256-SHA384:ECDH-RSA-AES256-SHA:ECDH-ECDSA-AES256-SHA:AES256-GCM-SHA384:AES256-SHA256:AES256-SHA:CAMELLIA256-SHA:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:DH-DSS-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:DH-RSA-AES128-GCM-SHA256:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES128-SHA256:DHE-DSS-AES128-SHA256:DH-RSA-AES128-SHA256:DH-DSS-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA:DH-RSA-AES128-SHA:DH-DSS-AES128-SHA:DHE-RSA-SEED-SHA:DHE-DSS-SEED-SHA:DH-RSA-SEED-SHA:DH-DSS-SEED-SHA:DHE-RSA-CAMELLIA128-SHA:DHE-DSS-CAMELLIA128-SHA:DH-RSA-CAMELLIA128-SHA:DH-DSS-CAMELLIA128-SHA:ECDH-RSA-AES128-GCM-SHA256:ECDH-ECDSA-AES128-GCM-SHA256:ECDH-RSA-AES128-SHA256:ECDH-ECDSA-AES128-SHA256:ECDH-RSA-AES128-SHA:ECDH-ECDSA-AES128-SHA:AES128-GCM-SHA256:AES128-SHA256:AES128-SHA:SEED-SHA:CAMELLIA128-SHA:IDEA-CBC-SHA:ECDHE-RSA-RC4-SHA:ECDHE-ECDSA-RC4-SHA:ECDH-RSA-RC4-SHA:ECDH-ECDSA-RC4-SHA:RC4-SHA:RC4-MD5:ECDHE-RSA-DES-CBC3-SHA:ECDHE-ECDSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:EDH-DSS-DES-CBC3-SHA:DH-RSA-DES-CBC3-SHA:DH-DSS-DES-CBC3-SHA:ECDH-RSA-DES-CBC3-SHA:ECDH-ECDSA-DES-CBC3-SHA:DES-CBC3-SHA:EDH-RSA-DES-CBC-SHA:EDH-DSS-DES-CBC-SHA:DH-RSA-DES-CBC-SHA:DH-DSS-DES-CBC-SHA:DES-CBC-SHA:EXP-EDH-RSA-DES-CBC-SHA:EXP-EDH-DSS-DES-CBC-SHA:EXP-DES-CBC-SHA:EXP-RC2-CBC-MD5:EXP-RC4-MD5") | ||||
|      tlsvers+=("-tls1_2 -tls1_1 -tls1") | ||||
|      sni+=("$SNI") | ||||
|      #warning+=("Tests are based on OpenSSL 1.01, therefore ciphers 0xe and 0xb are missing") | ||||
|      #warning+=("Tests are based on OpenSSL 1.0.1, therefore ciphers 0xe and 0xb are missing") | ||||
|      warning+=("") | ||||
| 
 | ||||
|      names+=("Safari 5.1.9/ OSX 10.6.8   ") | ||||
| @ -2157,7 +2151,7 @@ run_client_simulation() { | ||||
|                #FIXME: awk | ||||
|                proto=$(grep -aw "Protocol" $TMPFILE | sed -e 's/^.*Protocol.*://' -e 's/ //g') | ||||
|                if [[ "$proto" == TLSv1.2 ]]; then | ||||
|                     # OpenSSL reports TLS1.2 even if the connection is TLS1.1 or TLS1.0 Need to figure out which one it is... | ||||
|                     # OpenSSL reports TLS1.2 even if the connection is TLS1.1 or TLS1.0. Need to figure out which one it is... | ||||
|                     for tls in ${tlsvers[i]}; do | ||||
|                          $OPENSSL s_client $tls -cipher ${ciphers[i]} ${protos[i]} $STARTTLS $BUGS $PROXY -connect $NODEIP:$PORT ${sni[i]}  </dev/null >$TMPFILE 2>$ERRFILE | ||||
|                          debugme echo "$OPENSSL s_client $tls -cipher ${ciphers[i]} ${protos[i]} $STARTTLS $BUGS $PROXY -connect $NODEIP:$PORT ${sni[i]}  </dev/null" | ||||
| @ -2212,7 +2206,7 @@ locally_supported() { | ||||
| # 1) we need to have a variable where the results are being stored so that every other test doesn't have to do this again. | ||||
| # 2) the code is too old and one can do that way better | ||||
| # 3) HAS_SSL3/2 does already exist | ||||
| # we should do what's available and faster (openssl vs. sockets) . Keep in mind that the socket reply for SSLv2 returns the number # of ciphers! | ||||
| # we should do what's available and faster (openssl vs. sockets). Keep in mind that the socket reply for SSLv2 returns the number # of ciphers! | ||||
| # | ||||
| # arg1: -ssl2|-ssl3|-tls1 | ||||
| # arg2: doesn't seem to be used in calling, seems to be a textstring with the protocol though | ||||
| @ -2403,10 +2397,10 @@ run_protocols() { | ||||
|                fileout "tls1_2" "NOT ok" "TLSv1.2 is not offered (NOT ok)" | ||||
|                ;;                          # no GCM, penalty | ||||
|           2) | ||||
|      pr_svrty_medium "not offered (NOT ok)" | ||||
|                pr_svrty_medium "not offered" | ||||
|                [[ $DEBUG -eq 1 ]] && out " -- downgraded" | ||||
|                outln | ||||
|                fileout "tls1_2" "NOT ok" "TLSv1.2 is not offered and downgraded to a weaker protocol (NOT ok)" | ||||
|                fileout "tls1_2" "INFO" "TLSv1.2 is not offered and downgraded to a weaker protocol (medium)" | ||||
|                ;; | ||||
|           5) | ||||
|                outln "$supported_no_ciph1" | ||||
| @ -2587,8 +2581,8 @@ run_server_preference() { | ||||
|                "") | ||||
|                     pr_warning "default proto empty" | ||||
|                     if [[ $OSSL_VER == 1.0.2* ]]; then | ||||
|                          outln " (Hint: if IIS6 give OpenSSL 1.01 a try)" | ||||
|                          fileout "order_proto" "WARN" "Default protocol empty (Hint: if IIS6 give OpenSSL 1.01 a try)" | ||||
|                          outln " (Hint: if IIS6 give OpenSSL 1.0.1 a try)" | ||||
|                          fileout "order_proto" "WARN" "Default protocol empty (Hint: if IIS6 give OpenSSL 1.0.1 a try)" | ||||
|                     else | ||||
|                          fileout "order_proto" "WARN" "Default protocol empty" | ||||
|                     fi | ||||
| @ -2626,8 +2620,8 @@ run_server_preference() { | ||||
|                "") | ||||
|                     pr_warning "default cipher empty" ; | ||||
|                     if [[ $OSSL_VER == 1.0.2* ]]; then | ||||
|                          out " (Hint: if IIS6 give OpenSSL 1.01 a try)" | ||||
|                          fileout "order_cipher" "WARN" "Default cipher empty  (Hint: if IIS6 give OpenSSL 1.01 a try)  $remark4default_cipher" | ||||
|                          out " (Hint: if IIS6 give OpenSSL 1.0.1 a try)" | ||||
|                          fileout "order_cipher" "WARN" "Default cipher empty  (Hint: if IIS6 give OpenSSL 1.0.1 a try)  $remark4default_cipher" | ||||
|                     else | ||||
|                          fileout "order_cipher" "WARN" "Default cipher empty  $remark4default_cipher" | ||||
|                     fi | ||||
| @ -2646,11 +2640,11 @@ run_server_preference() { | ||||
|                i=1 | ||||
|                for p in ssl2 ssl3 tls1 tls1_1 tls1_2; do | ||||
|                     if [[ $p == ssl2 ]] && ! "$HAS_SSL2"; then | ||||
|                          out "     (SSLv2: "; local_problem "/usr/bin/openssl doesn't support \"s_client -ssl2\""; outln ")"; | ||||
|                          out "     (SSLv2: "; local_problem "$OPENSSL doesn't support \"s_client -ssl2\""; outln ")"; | ||||
|                          continue | ||||
|                     fi | ||||
|                     if [[ $p == ssl3 ]] && ! "$HAS_SSL3"; then | ||||
|                          out "     (SSLv3: "; local_problem "/usr/bin/openssl doesn't support \"s_client -ssl3\"" ; outln ")"; | ||||
|                          out "     (SSLv3: "; local_problem "$OPENSSL doesn't support \"s_client -ssl3\"" ; outln ")"; | ||||
|                          continue | ||||
|                     fi | ||||
|                     $OPENSSL s_client $STARTTLS -"$p" $BUGS -connect $NODEIP:$PORT $PROXY $SNI </dev/null 2>>$ERRFILE >$TMPFILE | ||||
| @ -2721,11 +2715,11 @@ cipher_pref_check() { | ||||
|      for p in ssl2 ssl3 tls1 tls1_1 tls1_2; do | ||||
|           order="" | ||||
|           if [[ $p == ssl2 ]] && ! "$HAS_SSL2"; then | ||||
|                out "\n     SSLv2:     "; local_problem "/usr/bin/openssl doesn't support \"s_client -ssl2\""; | ||||
|                out "\n     SSLv2:     "; local_problem "$OPENSSL doesn't support \"s_client -ssl2\""; | ||||
|                continue | ||||
|           fi | ||||
|           if [[ $p == ssl3 ]] && ! "$HAS_SSL3"; then | ||||
|                out "\n     SSLv3:     "; local_problem "/usr/bin/openssl doesn't support \"s_client -ssl3\""; | ||||
|                out "\n     SSLv3:     "; local_problem "$OPENSSL doesn't support \"s_client -ssl3\""; | ||||
|                continue | ||||
|           fi | ||||
|           $OPENSSL s_client $STARTTLS -"$p" $BUGS -connect $NODEIP:$PORT $PROXY $SNI </dev/null 2>$ERRFILE >$TMPFILE | ||||
| @ -2924,7 +2918,7 @@ tls_time() { | ||||
|      local now difftime | ||||
|      local spaces="               " | ||||
| 
 | ||||
|      tls_sockets "01" "$TLS_CIPHER"                              # try first TLS 1.0 (mostfrequently used protocol) | ||||
|      tls_sockets "01" "$TLS_CIPHER"                              # try first TLS 1.0 (most frequently used protocol) | ||||
|      [[ -z "$TLS_TIME" ]] && tls_sockets "03" "$TLS12_CIPHER"    #           TLS 1.2 | ||||
|      [[ -z "$TLS_TIME" ]] && tls_sockets "02" "$TLS_CIPHER"      #           TLS 1.1 | ||||
|      [[ -z "$TLS_TIME" ]] && tls_sockets "00" "$TLS_CIPHER"      #           SSL 3 | ||||
| @ -3049,7 +3043,7 @@ certificate_info() { | ||||
|      local cert_keysize=$4 | ||||
|      local ocsp_response=$5 | ||||
|      local ocsp_response_status=$6 | ||||
|      local cert_sig_algo cert_key_algo | ||||
|      local cert_sig_algo cert_sig_hash_algo cert_key_algo | ||||
|      local expire days2expire secs2warn ocsp_uri crl startdate enddate issuer_C issuer_O issuer sans san cn cn_nosni | ||||
|      local cert_fingerprint_sha1 cert_fingerprint_sha2 cert_fingerprint_serial | ||||
|      local policy_oid | ||||
| @ -3082,6 +3076,10 @@ certificate_info() { | ||||
|                pr_svrty_mediumln "SHA1 with RSA" | ||||
|                fileout "${json_prefix}algorithm" "WARN" "Signature Algorithm: SHA1 with RSA (warning)" | ||||
|                ;; | ||||
|           sha224WithRSAEncryption) | ||||
|                outln "SHA224 with RSA" | ||||
|                fileout "${json_prefix}algorithm" "INFO" "Signature Algorithm: SHA224 with RSA" | ||||
|                ;; | ||||
|           sha256WithRSAEncryption) | ||||
|                pr_done_goodln "SHA256 with RSA" | ||||
|                fileout "${json_prefix}algorithm" "OK" "Signature Algorithm: SHA256 with RSA (OK)" | ||||
| @ -3094,10 +3092,75 @@ certificate_info() { | ||||
|                pr_done_goodln "SHA512 with RSA" | ||||
|                fileout "${json_prefix}algorithm" "OK" "Signature Algorithm: SHA512 with RSA (OK)" | ||||
|                ;; | ||||
|           ecdsa-with-SHA1) | ||||
|                pr_svrty_mediumln "ECDSA with SHA1" | ||||
|                fileout "${json_prefix}algorithm" "WARN" "Signature Algorithm: ECDSA with SHA1 (warning)" | ||||
|                ;; | ||||
|           ecdsa-with-SHA224) | ||||
|                outln "ECDSA with SHA224" | ||||
|                fileout "${json_prefix}algorithm" "INFO" "Signature Algorithm: ECDSA with SHA224" | ||||
|                ;; | ||||
|           ecdsa-with-SHA256) | ||||
|                pr_done_goodln "ECDSA with SHA256" | ||||
|                fileout "${json_prefix}algorithm" "OK" "Signature Algorithm: ECDSA with SHA256 (OK)" | ||||
|                ;; | ||||
|           ecdsa-with-SHA384) | ||||
|                pr_done_goodln "ECDSA with SHA384" | ||||
|                fileout "${json_prefix}algorithm" "OK" "Signature Algorithm: ECDSA with SHA384 (OK)" | ||||
|                ;; | ||||
|           ecdsa-with-SHA512) | ||||
|                pr_done_goodln "ECDSA with SHA512" | ||||
|                fileout "${json_prefix}algorithm" "OK" "Signature Algorithm: ECDSA with SHA512 (OK)" | ||||
|                ;; | ||||
|           dsaWithSHA1) | ||||
|                pr_svrty_mediumln "DSA with SHA1" | ||||
|                fileout "${json_prefix}algorithm" "WARN" "Signature Algorithm: DSA with SHA1 (warning)" | ||||
|                ;; | ||||
|           dsa_with_SHA224) | ||||
|                outln "DSA with SHA224" | ||||
|                fileout "${json_prefix}algorithm" "INFO" "Signature Algorithm: DSA with SHA224" | ||||
|                ;; | ||||
|           dsa_with_SHA256) | ||||
|                pr_done_goodln "DSA with SHA256" | ||||
|                fileout "${json_prefix}algorithm" "OK" "Signature Algorithm: DSA with SHA256 (OK)" | ||||
|                ;; | ||||
|           rsassaPss) | ||||
|                cert_sig_hash_algo="$($OPENSSL x509 -in $HOSTCERT -noout -text 2>>$ERRFILE | grep -A 1 "Signature Algorithm" | head -2 | tail -1 | sed 's/^.*Hash Algorithm: //')" | ||||
|                case $cert_sig_hash_algo in | ||||
|                     sha1) | ||||
|                          pr_svrty_mediumln "RSASSA-PSS with SHA1" | ||||
|                          fileout "${json_prefix}algorithm" "WARN" "Signature Algorithm: RSASSA-PSS with SHA1 (warning)" | ||||
|                          ;; | ||||
|                     sha224) | ||||
|                          outln "RSASSA-PSS with SHA224" | ||||
|                          fileout "${json_prefix}algorithm" "INFO" "Signature Algorithm: RSASSA-PSS with SHA224" | ||||
|                          ;; | ||||
|                     sha256) | ||||
|                          pr_done_goodln "RSASSA-PSS with SHA256" | ||||
|                          fileout "${json_prefix}algorithm" "OK" "Signature Algorithm: RSASSA-PSS with SHA256 (OK)" | ||||
|                          ;; | ||||
|                     sha384) | ||||
|                          pr_done_goodln "RSASSA-PSS with SHA384" | ||||
|                          fileout "${json_prefix}algorithm" "OK" "Signature Algorithm: RSASSA-PSS with SHA384 (OK)" | ||||
|                          ;; | ||||
|                     sha512) | ||||
|                          pr_done_goodln "RSASSA-PSS with SHA512" | ||||
|                          fileout "${json_prefix}algorithm" "OK" "Signature Algorithm: RSASSA-PSS with SHA512 (OK)" | ||||
|                          ;; | ||||
|                     *) | ||||
|                          out "RSASSA-PSS with $cert_sig_hash_algo" | ||||
|                          pr_warningln " (Unknown hash algorithm)" | ||||
|                          fileout "${json_prefix}algorithm" "WARN" "Signature Algorithm: RSASSA-PSS with $cert_sig_hash_algo" | ||||
|                     esac | ||||
|                     ;; | ||||
|           md2*) | ||||
|                pr_svrty_criticalln "MD2" | ||||
|                fileout "${json_prefix}algorithm" "NOT ok" "Signature Algorithm: MD2 (NOT ok)" | ||||
|                ;; | ||||
|           md4*) | ||||
|                pr_svrty_criticalln "MD4" | ||||
|                fileout "${json_prefix}algorithm" "NOT ok" "Signature Algorithm: MD4 (NOT ok)" | ||||
|                ;; | ||||
|           md5*) | ||||
|                pr_svrty_criticalln "MD5" | ||||
|                fileout "${json_prefix}algorithm" "NOT ok" "Signature Algorithm: MD5 (NOT ok)" | ||||
| @ -3120,7 +3183,7 @@ certificate_info() { | ||||
|           # http://infoscience.epfl.ch/record/164526/files/NPDF-22.pdf | ||||
|           # see http://csrc.nist.gov/publications/nistpubs/800-57/sp800-57_part1_rev3_general.pdf | ||||
|           # Table 2 @ chapter 5.6.1 (~ p64) | ||||
|           if [[ $cert_sig_algo =~ ecdsa ]] || [[ $cert_key_algo =~ ecPublicKey  ]]; then | ||||
|           if [[ $cert_key_algo =~ ecdsa ]] || [[ $cert_key_algo =~ ecPublicKey  ]]; then | ||||
|                if [[ "$cert_keysize" -le 110 ]]; then       # a guess  | ||||
|                     pr_svrty_critical "$cert_keysize" | ||||
|                     fileout "${json_prefix}key_size" "NOT ok" "Server keys $cert_keysize EC bits (NOT ok)" | ||||
| @ -3140,8 +3203,8 @@ certificate_info() { | ||||
|                     out "keysize: $cert_keysize (not expected, FIXME)" | ||||
|                     fileout "${json_prefix}key_size" "WARN" "Server keys $cert_keysize bits (not expected)" | ||||
|                fi | ||||
|                outln " bit" | ||||
|           elif [[ $cert_sig_algo = *RSA* ]]; then | ||||
|                outln " bits" | ||||
|           elif [[ $cert_key_algo = *RSA* ]] || [[ $cert_key_algo = *rsa* ]] || [[ $cert_key_algo = *dsa* ]]; then | ||||
|                if [[ "$cert_keysize" -le 512 ]]; then | ||||
|                     pr_svrty_critical "$cert_keysize" | ||||
|                     outln " bits" | ||||
| @ -3296,7 +3359,8 @@ certificate_info() { | ||||
| 
 | ||||
|      # http://events.ccc.de/congress/2010/Fahrplan/attachments/1777_is-the-SSLiverse-a-safe-place.pdf, see page 40pp | ||||
|      out "$indent"; pr_bold " EV cert"; out " (experimental)       " | ||||
|      policy_oid=$($OPENSSL x509 -in $HOSTCERT -text 2>>$ERRFILE | awk '/ .Policy: / { print $2 }') | ||||
|      # only the first one, seldom we have two | ||||
|      policy_oid=$($OPENSSL x509 -in $HOSTCERT -text 2>>$ERRFILE | awk '/ .Policy: / { print $2 }' | awk 'NR < 2') | ||||
|      if echo "$issuer" | egrep -q 'Extended Validation|Extended Validated|EV SSL|EV CA' || \ | ||||
|           [[ 2.16.840.1.114028.10.1.2 == "$policy_oid" ]] || \ | ||||
|           [[ 2.16.840.1.114412.1.3.0.2 == "$policy_oid" ]] || \ | ||||
| @ -3410,7 +3474,7 @@ certificate_info() { | ||||
|                     ret=0 | ||||
|                else | ||||
|                     out "(response status unknown)" | ||||
|                     fileout "${json_prefix}ocsp_stapling" "OK" "OCSP stapling : not sure what's going on here, debug: grep -aA 20 "OCSP response"  <<<"$ocsp_response"" | ||||
|                     fileout "${json_prefix}ocsp_stapling" "OK" "OCSP stapling : not sure what's going on here, debug: $ocsp_response" | ||||
|                     debugme grep -a -A20 -B2 "OCSP response"  <<<"$ocsp_response" | ||||
|                     ret=2 | ||||
|                fi | ||||
| @ -3576,7 +3640,7 @@ run_pfs() { | ||||
|      local pfs_ciphers | ||||
| 
 | ||||
|      outln | ||||
|      pr_headlineln " Testing (perfect) forward secrecy, (P)FS -- omitting 3DES, RC4 and Null Encryption here " | ||||
|      pr_headlineln " Testing robust (perfect) forward secrecy, (P)FS -- omitting Null Authentication/Encryption as well as 3DES and RC4 here " | ||||
|      if ! "$HAS_DH_BITS" && "$WIDE"; then | ||||
|           pr_warningln "    (Your $OPENSSL cannot show DH/ECDH bits)" | ||||
|      fi | ||||
| @ -3640,7 +3704,7 @@ run_pfs() { | ||||
|                          out "$pfs_cipher " | ||||
|                     fi | ||||
|                fi | ||||
|                pfs_ciphers+="$pfs_cipher " | ||||
|                [[ $sclient_success -eq 0 ]] && pfs_ciphers+="$pfs_cipher " | ||||
|                debugme rm $tmpfile | ||||
|           done < <($OPENSSL ciphers -V "$pfs_cipher_list" 2>$ERRFILE)      # -V doesn't work with openssl < 1.0 | ||||
|           debugme echo $pfs_offered | ||||
| @ -3734,8 +3798,8 @@ run_spdy() { | ||||
|                fileout "spdy_npn" "INFO" "SPDY/NPN : $tmpstr (advertised)" | ||||
|                ret=0 | ||||
|           else | ||||
|                pr_cyanln "please check manually, server response was ambigious ..." | ||||
|                fileout "spdy_npn" "INFO" "SPDY/NPN : please check manually, server response was ambigious ..." | ||||
|                pr_cyanln "please check manually, server response was ambiguous ..." | ||||
|                fileout "spdy_npn" "INFO" "SPDY/NPN : please check manually, server response was ambiguous ..." | ||||
|                ret=10 | ||||
|           fi | ||||
|      fi | ||||
| @ -4036,92 +4100,268 @@ parse_sslv2_serverhello() { | ||||
| # arg1: name of file with socket reply | ||||
| parse_tls_serverhello() { | ||||
|      local tls_hello_ascii=$(hexdump -v -e '16/1 "%02X"' "$1") | ||||
|      local tls_content_type tls_protocol tls_len_all | ||||
| #TODO: all vars here | ||||
|      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 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 | ||||
| 
 | ||||
|      TLS_TIME="" | ||||
|      DETECTED_TLS_VERSION="" | ||||
| 
 | ||||
|      # server hello, handshake details see http://en.wikipedia.org/wiki/Transport_Layer_Security-SSL#TLS_record | ||||
|      # $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. | ||||
|      # First, extract the handshake and alert messages. | ||||
|      # see http://en.wikipedia.org/wiki/Transport_Layer_Security-SSL#TLS_record | ||||
|      # byte 0:      content type:                 0x14=CCS,    0x15=TLS alert  x16=Handshake,  0x17 Aplication, 0x18=HB | ||||
|      # byte 1+2:    TLS version word, major is 03, minor 00=SSL3, 01=TLS1 02=TLS1.1 03=TLS 1.2 | ||||
|      # byte 3+4:    length all | ||||
|      # byte 5:      handshake type (2=hello)      TLS alert: level (2=fatal), descr (0x28=handshake failure) | ||||
|      # byte 6+7+8:  length server hello | ||||
|      # byte 9+10:   03, TLS version word          see byte 1+2 | ||||
|      # byte 11-14:  TLS timestamp                 for OpenSSL <1.01f | ||||
|      # byte 15-42:  random, 28 bytes | ||||
|      # byte 43:     session id length | ||||
|      # byte 44+45+sid-len:  cipher suite! | ||||
|      # byte 46+sid-len:     compression method:  00: none, 01: deflate | ||||
|      # byte 47+48+sid-len:  extension length | ||||
| 
 | ||||
|      [[ "$DEBUG" -eq 5 ]] && echo $tls_hello_ascii      # one line without any blanks | ||||
|      if [[ -z "$tls_hello_ascii" ]]; then | ||||
|           debugme echo "server hello empty, TCP connection closed" | ||||
|           return 1              # no server hello received | ||||
|      # byte 3+4:    fragment length | ||||
|      # 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:" | ||||
|      fi | ||||
| 
 | ||||
|      # now scrape two bytes out of the reply per byte | ||||
|      tls_content_type="${tls_hello_ascii:0:2}"         # normally this is x16 (Handshake) here | ||||
|      tls_protocol="${tls_hello_ascii:2:4}" | ||||
|      DETECTED_TLS_VERSION=$tls_protocol | ||||
| 
 | ||||
|      tls_len_all=${tls_hello_ascii:6:4} | ||||
| 
 | ||||
|      sid_len_offset=86 | ||||
|      tls_hello="${tls_hello_ascii:10:2}"               # normally this is x02 | ||||
|      tls_protocol2="${tls_hello_ascii:18:4}" | ||||
|      tls_hello_time="${tls_hello_ascii:22:8}" | ||||
| 
 | ||||
|      if [[ $tls_content_type == "15" ]]; then          # TLS ALERT | ||||
|           tls_err_level=${tls_hello_ascii:10:2}        # 1: warning, 2: fatal | ||||
|           tls_err_descr=${tls_hello_ascii:12:2}        # 112/0x70: Unrecognized name, 111/0x6F: certificate_unobtainable, | ||||
|                                                        # 113/0x71: bad_certificate_status_response, #114/0x72: bad_certificate_hash_value | ||||
|           if [[ $DEBUG -ge 2 ]]; then | ||||
|                echo "tls_protocol (reclyr):  0x$tls_protocol" | ||||
|                echo "tls_content_type:       0x$tls_content_type" | ||||
|                echo "tls_len_all:            $tls_len_all" | ||||
|                echo "tls_err_descr:          0x${tls_err_descr} / = $(hex2dec ${tls_err_descr})" | ||||
|                echo "tls_err_level:          ${tls_err_level} (warning:1, fatal:2)" | ||||
|      for (( i=0; i<tls_hello_ascii_len; i=i+msg_len )); do | ||||
|           if [[ $tls_hello_ascii_len-$i -lt 10 ]]; then | ||||
|                # This could just be a result of the server's response being | ||||
|                # split across two or more packets. | ||||
|                continue | ||||
|           fi | ||||
|           # now, here comes a strange thing... -- on the first glance | ||||
|           # IF an apache 2.2/2.4 server e.g. has a default servername configured but we send SNI <myhostname> | ||||
|           # we get a TLS ALERT saying "unrecognized_name" (0x70) and a warning (0x1), see RFC https://tools.ietf.org/html/rfc6066#page-17 | ||||
|           # note that RFC recommended to fail instead: https://tools.ietf.org/html/rfc6066#section-3 | ||||
|           # we need to handle this properly -- otherwise we always return that the protocol or cipher is not available! | ||||
|           if [[ "$tls_err_descr" == 70 ]] && [[ "${tls_err_level}" == "01" ]]; then | ||||
|                sid_len_offset=100                      # we are 2x7 bytes off (formerly: 86 instead of 100) | ||||
|                tls_hello="${tls_hello_ascii:24:2}"     # here, too       (normally this is (02) | ||||
|                tls_protocol2="${tls_hello_ascii:32:4}" # here, too | ||||
|                tls_hello_time="${tls_hello_ascii:36:8}"     # and here, too | ||||
|           else | ||||
|           tls_content_type="${tls_hello_ascii:i:2}" | ||||
|           i=$i+2 | ||||
|           tls_protocol="${tls_hello_ascii:i:4}" | ||||
|           i=$i+4 | ||||
|           msg_len=2*$(hex2dec "${tls_hello_ascii:i:4}") | ||||
|           i=$i+4 | ||||
| 
 | ||||
|           if [[ $DEBUG -ge 2 ]]; then | ||||
|                echo "     tls_protocol (reclyr):  0x$tls_protocol" | ||||
|                out  "     tls_content_type:       0x$tls_content_type" | ||||
|                case $tls_content_type in | ||||
|                     15) outln " (alert)" ;; | ||||
|                     16) outln " (handshake)" ;; | ||||
|                      *) outln ;; | ||||
|                esac | ||||
|                echo "     msg_len:                $((msg_len/2))" | ||||
|                outln | ||||
|           fi | ||||
|           if [[ $tls_content_type != "15" ]] && [[ $tls_content_type != "16" ]]; then | ||||
|                debugme pr_warningln "Content type other than alert or handshake detected." | ||||
|                return 1 | ||||
|           elif [[ "${tls_protocol:0:2}" != "03" ]]; then | ||||
|                debugme pr_warningln "Protocol record_version.major is not 03." | ||||
|                return 1 | ||||
|           fi | ||||
|           DETECTED_TLS_VERSION=$tls_protocol | ||||
| 
 | ||||
|           if [[ $msg_len -gt $tls_hello_ascii_len-$i ]]; then | ||||
|                # This could just be a result of the server's response being | ||||
|                # split across two or more packets. Just grab the part that | ||||
|                # is available. | ||||
|                msg_len=$tls_hello_ascii_len-$i | ||||
|           fi | ||||
| 
 | ||||
|           if [[ $tls_content_type == "16" ]]; then | ||||
|                tls_handshake_ascii="$tls_handshake_ascii${tls_hello_ascii:i:msg_len}" | ||||
|           elif [[ $tls_content_type == "15" ]]; then   # TLS ALERT | ||||
|                tls_alert_ascii="$tls_alert_ascii${tls_hello_ascii:i:msg_len}" | ||||
|           fi | ||||
|      done | ||||
| 
 | ||||
|      # Now check the alert messages. | ||||
|      tls_alert_ascii_len=${#tls_alert_ascii} | ||||
|      if [[ $tls_alert_ascii_len -gt 0 ]]; then | ||||
|           debugme echo "TLS alert messages:" | ||||
|           for (( i=0; i+3 < tls_alert_ascii_len; i=i+4 )); do | ||||
|                tls_err_level=${tls_alert_ascii:i:2}    # 1: warning, 2: fatal | ||||
|                j=$i+2 | ||||
|                tls_err_descr=${tls_alert_ascii:j:2}    # 112/0x70: Unrecognized name, 111/0x6F: certificate_unobtainable, | ||||
|                                                        # 113/0x71: bad_certificate_status_response, #114/0x72: bad_certificate_hash_value | ||||
| 
 | ||||
|                debugme out  "     tls_err_descr:          0x${tls_err_descr} / = $(hex2dec ${tls_err_descr})" | ||||
|                case $tls_err_descr in | ||||
|                     00) tls_alert_descrip="close notify" ;; | ||||
|                     0A) tls_alert_descrip="unexpected message" ;; | ||||
|                     14) tls_alert_descrip="bad record mac" ;; | ||||
|                     15) tls_alert_descrip="decryption failed" ;; | ||||
|                     16) tls_alert_descrip="record overflow" ;; | ||||
|                     1E) tls_alert_descrip="decompression failure" ;; | ||||
|                     28) tls_alert_descrip="handshake failure" ;; | ||||
|                     29) tls_alert_descrip="no certificate RESERVED" ;; | ||||
|                     2A) tls_alert_descrip="bad certificate" ;; | ||||
|                     2B) tls_alert_descrip="unsupported certificate" ;; | ||||
|                     2C) tls_alert_descrip="certificate revoked" ;; | ||||
|                     2D) tls_alert_descrip="certificate expired" ;; | ||||
|                     2E) tls_alert_descrip="certificate unknown" ;; | ||||
|                     2F) tls_alert_descrip="illegal parameter" ;; | ||||
|                     30) tls_alert_descrip="unknown ca" ;; | ||||
|                     31) tls_alert_descrip="access denied" ;; | ||||
|                     32) tls_alert_descrip="decode error" ;; | ||||
|                     33) tls_alert_descrip="decrypt error" ;; | ||||
|                     3C) tls_alert_descrip="export restriction RESERVED" ;; | ||||
|                     46) tls_alert_descrip="protocol version" ;; | ||||
|                     47) tls_alert_descrip="insufficient security" ;; | ||||
|                     50) tls_alert_descrip="internal error" ;; | ||||
|                     56) tls_alert_descrip="inappropriate fallback" ;; | ||||
|                     5A) tls_alert_descrip="user canceled" ;; | ||||
|                     64) tls_alert_descrip="no renegotiation" ;; | ||||
|                     6E) tls_alert_descrip="unsupported extension" ;; | ||||
|                     6F) tls_alert_descrip="certificate unobtainable" ;; | ||||
|                     70) tls_alert_descrip="unrecognized name" ;; | ||||
|                     71) tls_alert_descrip="bad certificate status response" ;; | ||||
|                     72) tls_alert_descrip="bad certificate hash value" ;; | ||||
|                     73) tls_alert_descrip="unknown psk identity" ;; | ||||
|                     78) tls_alert_descrip="no application protocol" ;; | ||||
|                      *) tls_alert_descrip="$(hex2dec "$tls_err_descr")";; | ||||
|                esac | ||||
| 
 | ||||
|                if [[ $DEBUG -ge 2 ]]; then | ||||
|                     outln " ($tls_alert_descrip)" | ||||
|                     out  "     tls_err_level:          ${tls_err_level}" | ||||
|                     case $tls_err_level in | ||||
|                          01) outln " (warning)" ;; | ||||
|                          02) outln " (fatal)" ;; | ||||
|                           *) outln ;; | ||||
|                     esac | ||||
|                     outln | ||||
|                fi | ||||
|                if [[ "$tls_err_level" != "01" ]] && [[ "$tls_err_level" != "02" ]]; then | ||||
|                     debugme pr_warningln "Unexpected AlertLevel (0x$tls_err_level)." | ||||
|                     return 1 | ||||
|                elif [[ "$tls_err_level" == "02" ]]; then | ||||
|                     # Fatal alert | ||||
|                     return 1 | ||||
|                fi | ||||
|           done | ||||
|      fi | ||||
| 
 | ||||
|      # 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:" | ||||
|      fi | ||||
|      for (( i=0; i<tls_handshake_ascii_len; i=i+msg_len )); do | ||||
|           if [[ $tls_handshake_ascii_len-$i -lt 8 ]]; then | ||||
|                # This could just be a result of the server's response being | ||||
|                # split across two or more packets. | ||||
|                continue | ||||
|           fi | ||||
|           tls_msg_type="${tls_handshake_ascii:i:2}" | ||||
|           i=$i+2 | ||||
|           msg_len=2*$(hex2dec "${tls_handshake_ascii:i:6}") | ||||
|           i=$i+6 | ||||
| 
 | ||||
|           if [[ $DEBUG -ge 2 ]]; then | ||||
|                out  "     handshake type:         0x${tls_msg_type}" | ||||
|                case $tls_msg_type in | ||||
|                     00) outln " (hello_request)" ;; | ||||
|                     01) outln " (client_hello)" ;; | ||||
|                     02) outln " (server_hello)" ;; | ||||
|                     03) outln " (hello_verify_request)" ;; | ||||
|                     04) outln " (NewSessionTicket)" ;; | ||||
|                     0B) outln " (certificate)" ;; | ||||
|                     0C) outln " (server_key_exchange)" ;; | ||||
|                     0D) outln " (certificate_request)" ;; | ||||
|                     0E) outln " (server_hello_done)" ;; | ||||
|                     0F) outln " (certificate_verify)" ;; | ||||
|                     10) outln " (client_key_exchange)" ;; | ||||
|                     14) outln " (finished)" ;; | ||||
|                     15) outln " (certificate_url)" ;; | ||||
|                     16) outln " (certificate_status)" ;; | ||||
|                     17) outln " (supplemental_data)" ;; | ||||
|                     *) outln ;; | ||||
|                esac | ||||
|                echo "     msg_len:                $((msg_len/2))" | ||||
|                outln | ||||
|           fi | ||||
|           if [[ $msg_len -gt $tls_handshake_ascii_len-$i ]]; then | ||||
|                # This could just be a result of the server's response being | ||||
|                # split across two or more packets. Just grab the part that | ||||
|                # is available. | ||||
|                msg_len=$tls_handshake_ascii_len-$i | ||||
|           fi | ||||
| 
 | ||||
|           if [[ "$tls_msg_type" == "02" ]]; then | ||||
|                if [[ -n "$tls_serverhello_ascii" ]]; then | ||||
|                     debugme pr_warningln "Response contained more than one ServerHello handshake message." | ||||
|                     return 1 | ||||
|                fi | ||||
|                tls_serverhello_ascii="${tls_handshake_ascii:i:msg_len}" | ||||
|                tls_serverhello_ascii_len=$msg_len | ||||
|           fi | ||||
|      done | ||||
| 
 | ||||
|      if [[ $tls_serverhello_ascii_len -eq 0 ]]; then | ||||
|           debugme echo "server hello empty, TCP connection closed" | ||||
|           return 1              # no server hello received | ||||
|      elif [[ $tls_serverhello_ascii_len -lt 76 ]]; then | ||||
|           debugme echo "Malformed response" | ||||
|           return 1 | ||||
|      elif [[ "${tls_handshake_ascii:0:2}" != "02" ]]; then | ||||
|           # the ServerHello MUST be the first handshake message | ||||
|           debugme pr_warningln "The first handshake protocol message is not a ServerHello." | ||||
|           return 1 | ||||
|      fi | ||||
| 
 | ||||
|      # 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 | ||||
|      # byte 34:     session id length | ||||
|      # byte 35+36+sid-len:  cipher suite! | ||||
|      # byte 37+sid-len:     compression method:  00: none, 01: deflate, 64: LZS | ||||
|      # byte 38+39+sid-len:  extension length | ||||
|      tls_protocol2="${tls_serverhello_ascii:0:4}" | ||||
|      if [[ "${tls_protocol2:0:2}" != "03" ]]; then | ||||
|           debugme pr_warningln "server_version.major in ServerHello is not 03." | ||||
|           return 1 | ||||
|      fi | ||||
|      DETECTED_TLS_VERSION="$tls_protocol2" | ||||
| 
 | ||||
|      tls_hello_time="${tls_serverhello_ascii:4:8}" | ||||
|      TLS_TIME=$(hex2dec "$tls_hello_time") | ||||
|      tls_sid_len=$(hex2dec "${tls_hello_ascii:$sid_len_offset:2}") | ||||
|      let sid_offset=$sid_len_offset+2+$tls_sid_len*2 | ||||
|      tls_cipher_suite="${tls_hello_ascii:$sid_offset:4}" | ||||
|      let sid_offset=$sid_len_offset+6++$tls_sid_len*2 | ||||
|      tls_compression_method="${tls_hello_ascii:$sid_offset:2}" | ||||
| 
 | ||||
|      tls_sid_len_hex="${tls_serverhello_ascii:68:2}" | ||||
|      tls_sid_len=2*$(hex2dec "$tls_sid_len_hex") | ||||
|      let offset=70+$tls_sid_len | ||||
| 
 | ||||
|      if [[ $tls_serverhello_ascii_len -lt 76+$tls_sid_len ]]; then | ||||
|           debugme echo "Malformed response" | ||||
|           return 1 | ||||
|      fi | ||||
| 
 | ||||
|      tls_cipher_suite="${tls_serverhello_ascii:$offset:4}" | ||||
| 
 | ||||
|      let offset=74+$tls_sid_len | ||||
|      tls_compression_method="${tls_serverhello_ascii:$offset:2}" | ||||
| 
 | ||||
|      if [[ $DEBUG -ge 2 ]]; then | ||||
|           echo "tls_protocol (reclyr):  0x$tls_protocol" | ||||
|           echo "tls_hello:              0x$tls_hello" | ||||
|           echo "TLS server hello message:" | ||||
|           if [[ $DEBUG -ge 4 ]]; then | ||||
|                echo "tls_protocol:           0x$tls_protocol2" | ||||
|                echo "tls_sid_len:            0x$(dec2hex $tls_sid_len) / = $tls_sid_len" | ||||
|                echo "     tls_protocol:           0x$tls_protocol2" | ||||
|                echo "     tls_sid_len:            0x$tls_sid_len_hex / = $((tls_sid_len/2))" | ||||
|           fi | ||||
|           echo -n "tls_hello_time:         0x$tls_hello_time " | ||||
|           echo -n "     tls_hello_time:         0x$tls_hello_time " | ||||
|           if "$HAS_GNUDATE"; then | ||||
|                date --date="@$TLS_TIME" "+%Y-%m-%d %r" | ||||
|           else | ||||
|                LC_ALL=C date -j -f %s "$TLS_TIME" "+%Y-%m-%d %r" | ||||
|           fi | ||||
|           echo "tls_cipher_suite:       0x$tls_cipher_suite" | ||||
|           echo "tls_compression_method: 0x$tls_compression_method" | ||||
|           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 | ||||
|           outln | ||||
|      fi | ||||
|      return 0 | ||||
| @ -4149,7 +4389,7 @@ sslv2_sockets() { | ||||
|                outln " (rerun with DEBUG >=2)" | ||||
|                [[ $DEBUG -ge 3 ]] && hexdump -C "$SOCK_REPLY_FILE" | head -1 | ||||
|                ret=7 | ||||
|                fileout "sslv2" "WARN" "SSLv2: received a strange SSLv2 replay (rerun with DEBUG>=2)" | ||||
|                fileout "sslv2" "WARN" "SSLv2: received a strange SSLv2 reply (rerun with DEBUG>=2)" | ||||
|                ;; | ||||
|           1) # no sslv2 server hello returned, like in openlitespeed which returns HTTP! | ||||
|                pr_done_bestln "not offered (OK)" | ||||
| @ -5115,7 +5355,7 @@ run_drown() { | ||||
|                outln " (rerun with DEBUG >=2)" | ||||
|                [[ $DEBUG -ge 3 ]] && hexdump -C "$SOCK_REPLY_FILE" | head -1 | ||||
|                ret=7 | ||||
|                fileout "DROWN" "MINOR_ERROR" "SSLv2: received a strange SSLv2 replay (rerun with DEBUG>=2)" | ||||
|                fileout "DROWN" "MINOR_ERROR" "SSLv2: received a strange SSLv2 reply (rerun with DEBUG>=2)" | ||||
|                ;; | ||||
|           3)   # vulnerable | ||||
|                lines=$(count_lines "$(hexdump -C "$SOCK_REPLY_FILE" 2>/dev/null)") | ||||
| @ -5371,9 +5611,9 @@ run_rc4() { | ||||
|                     fi | ||||
|                     outln | ||||
|                else | ||||
|                     pr_svrty_high "$rc4_cipher " | ||||
|                     [[ $sclient_success -eq 0 ]] && pr_svrty_high "$rc4_cipher " | ||||
|                fi | ||||
|                rc4_detected+="$rc4_cipher " | ||||
|                [[ $sclient_success -eq 0 ]] && rc4_detected+="$rc4_cipher " | ||||
|           done < <($OPENSSL ciphers -V $rc4_ciphers_list:@STRENGTH) | ||||
|           outln | ||||
|           "$WIDE" && pr_svrty_high "VULNERABLE (NOT ok)" | ||||
| @ -5408,11 +5648,11 @@ run_tls_truncation() { | ||||
| 
 | ||||
| old_fart() { | ||||
|      outln "Get precompiled bins or compile https://github.com/PeterMosmans/openssl ." | ||||
|      fileout "old_fart" "WARN" "Your $OPENSSL $OSSL_VER version is an old fart... . It doesn\'t make much sense to proceed.\nGet precompiled bins or compile https://github.com/PeterMosmans/openssl ." | ||||
|      fileout "old_fart" "WARN" "Your $OPENSSL $OSSL_VER version is an old fart... . It doesn\'t make much sense to proceed. Get precompiled bins or compile https://github.com/PeterMosmans/openssl ." | ||||
|      fatal "Your $OPENSSL $OSSL_VER version is an old fart... . It doesn\'t make much sense to proceed." -2 | ||||
| } | ||||
| 
 | ||||
| # try very hard to determine th install path to get ahold of the mapping file | ||||
| # try very hard to determine the install path to get ahold of the mapping file | ||||
| # it provides "keycode/ RFC style name", see RFCs, cipher(1), www.carbonwind.net/TLS_Cipher_Suites_Project/tls_ssl_cipher_suites_simple_table_all.htm | ||||
| get_install_dir() { | ||||
|      #INSTALL_DIR=$(cd "$(dirname "$0")" && pwd)/$(basename "$0") | ||||
| @ -5609,7 +5849,8 @@ special invocations: | ||||
| partly mandatory parameters: | ||||
|      URI                           host|host:port|URL|URL:port   (port 443 is assumed unless otherwise specified) | ||||
|      pattern                       an ignore case word pattern of cipher hexcode or any other string in the name, kx or bits | ||||
|      protocol                      is one of ftp,smtp,pop3,imap,xmpp,telnet,ldap (for the latter two you need e.g. the supplied openssl) | ||||
|      protocol                      is one of the STARTTLS protocols ftp,smtp,pop3,imap,xmpp,telnet,ldap  | ||||
|                                    (for the latter two you need e.g. the supplied openssl) | ||||
| 
 | ||||
| tuning options (can also be preset via environment variables): | ||||
|      --bugs                        enables the "-bugs" option of s_client, needed e.g. for some buggy F5s | ||||
| @ -5867,6 +6108,11 @@ parse_hn_port() { | ||||
|      # strip trailing urlpath | ||||
|      NODE=$(echo "$NODE" | sed -e 's/\/.*$//') | ||||
| 
 | ||||
|      # if there's a trailing ':' probably a starttls/application protocol was specified | ||||
|      if grep -q ':$' <<< $NODE ; then | ||||
|           fatal "\"$1\" is not a valid URI" 1 | ||||
|      fi | ||||
| 
 | ||||
|      # was the address supplied like [AA:BB:CC::]:port ? | ||||
|      if echo "$NODE" | grep -q ']' ; then | ||||
|           tmp_port=$(printf "$NODE" | sed 's/\[.*\]//' | sed 's/://') | ||||
| @ -6190,7 +6436,7 @@ sclient_auth() { | ||||
|           if [[ -z $(awk '/Session-ID: / { print $2 }' "$2") ]]; then      # probably no SSL session | ||||
|                if [[ 2 -eq $(grep -c CERTIFICATE "$2") ]]; then            # do another sanity check to be sure | ||||
|                     CLIENT_AUTH=false | ||||
|                     NO_SSL_SESSIONID=true                                  # NO_SSL_SESSIONI is preset globally to false for all other cases | ||||
|                     NO_SSL_SESSIONID=true                                  # NO_SSL_SESSIONID is preset globally to false for all other cases | ||||
|                     return 0 | ||||
|                fi | ||||
|           fi | ||||
| @ -6408,6 +6654,7 @@ mx_all_ips() { | ||||
| 
 | ||||
| run_mass_testing_parallel() { | ||||
|      local cmdline="" | ||||
|      local global_cmdline=${CMDLINE%%--file*} | ||||
| 
 | ||||
|      if [[ ! -r "$FNAME" ]] && $IKNOW_FNAME; then | ||||
|           fatal "Can't read file \"$FNAME\"" "-1" | ||||
| @ -6418,7 +6665,7 @@ run_mass_testing_parallel() { | ||||
|           cmdline=$(filter_input "$cmdline") | ||||
|           [[ -z "$cmdline" ]] && continue | ||||
|           [[ "$cmdline" == "EOF" ]] && break | ||||
|           cmdline="$0 --warnings=batch -q $cmdline" | ||||
|           cmdline="$0 $global_cmdline --warnings=batch -q $cmdline" | ||||
|           draw_line "=" $((TERM_DWITH / 2)); outln; | ||||
|           determine_logfile | ||||
|           outln "$cmdline" | ||||
| @ -6431,16 +6678,18 @@ run_mass_testing_parallel() { | ||||
| 
 | ||||
| run_mass_testing() { | ||||
|      local cmdline="" | ||||
|      local global_cmdline=${CMDLINE%%--file*} | ||||
| 
 | ||||
|      if [[ ! -r "$FNAME" ]] && "$IKNOW_FNAME"; then | ||||
|           fatal "Can't read file \"$FNAME\"" "-1" | ||||
|      fi | ||||
| 
 | ||||
|      pr_reverse "====== Running in file batch mode with file=\"$FNAME\" ======"; outln "\n" | ||||
|      while read cmdline; do | ||||
|           cmdline=$(filter_input "$cmdline") | ||||
|           [[ -z "$cmdline" ]] && continue | ||||
|           [[ "$cmdline" == "EOF" ]] && break | ||||
|           cmdline="$0 --warnings=batch -q $cmdline" | ||||
|           cmdline="$0 $global_cmdline --warnings=batch -q $cmdline" | ||||
|           draw_line "=" $((TERM_DWITH / 2)); outln; | ||||
|           outln "$cmdline" | ||||
|           $cmdline | ||||
| @ -6794,7 +7043,7 @@ parse_cmd_line() { | ||||
|                     do_logging=true | ||||
|                     ;;   # DEFINITION of LOGFILE if no arg specified: automagically in parse_hn_port() | ||||
|                     # following does the same but we can specify a log location additionally | ||||
|                --logfile=*) | ||||
|                --logfile|--logfile=*) | ||||
|                     LOGFILE=$(parse_opt_equal_sign "$1" "$2") | ||||
|                     [[ $? -eq 0 ]] && shift | ||||
|                     do_logging=true | ||||
| @ -6803,7 +7052,7 @@ parse_cmd_line() { | ||||
|                     do_json=true | ||||
|                     ;;   # DEFINITION of JSONFILE is not arg specified: automagically in parse_hn_port() | ||||
|                     # following does the same but we can specify a log location additionally | ||||
|                --jsonfile=*) | ||||
|                --jsonfile|--jsonfile=*) | ||||
|                     JSONFILE=$(parse_opt_equal_sign "$1" "$2") | ||||
|                     [[ $? -eq 0 ]] && shift | ||||
|                     do_json=true | ||||
| @ -6812,7 +7061,7 @@ parse_cmd_line() { | ||||
|                     do_csv=true | ||||
|                     ;;   # DEFINITION of CSVFILE is not arg specified: automagically in parse_hn_port() | ||||
|                     # following does the same but we can specify a log location additionally | ||||
|                --csvfile=*) | ||||
|                --csvfile|--csvfile=*) | ||||
|                     CSVFILE=$(parse_opt_equal_sign "$1" "$2") | ||||
|                     [[ $? -eq 0 ]] && shift | ||||
|                     do_csv=true | ||||
| @ -7028,4 +7277,4 @@ fi | ||||
| exit $? | ||||
| 
 | ||||
| 
 | ||||
| #  $Id: testssl.sh,v 1.478 2016/03/30 21:28:30 dirkw Exp $ | ||||
| #  $Id: testssl.sh,v 1.487 2016/05/23 20:42:39 dirkw Exp $ | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user