From 7e506e5c5a2705857c61abf06fc975b4164806b5 Mon Sep 17 00:00:00 2001 From: David Cooper Date: Wed, 13 Apr 2016 15:39:12 -0400 Subject: [PATCH 1/6] More extensions in socksend_tls_clienthello() This PR adds the signature algorithms, heartbeat, session ticket, and next protocol extensions to the client hello message created by socksend_tls_clienthello() for TLS 1.0 and above. It also adds the supported elliptic curves and ec points format extensions if the client hello message includes any ECC cipher suites. I tested this version against several servers with $EXPERIMENTAL set to true and get the same results as with the current code with $EXPERIMENTAL set to false. --- testssl.sh | 172 ++++++++++++++++++++++++++++++++++------------------- 1 file changed, 110 insertions(+), 62 deletions(-) diff --git a/testssl.sh b/testssl.sh index fb66226..b893487 100755 --- a/testssl.sh +++ b/testssl.sh @@ -4165,41 +4165,128 @@ sslv2_sockets() { # ARG1: TLS version low byte (00: SSLv3, 01: TLS 1.0, 02: TLS 1.1, 03: TLS 1.2) # ARG2: CIPHER_SUITES string socksend_tls_clienthello() { -#FIXME: redo this with all extensions! 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 servername_hexstr len_servername len_servername_hex - local hexdump_format_str - local all_extensions + local hexdump_format_str part1 part2 + local all_extensions="" + local -i i j len_extension local len_sni_listlen len_sni_ext len_extension_hex - local cipher_suites len_ciph_suites len_ciph_suites_word + local cipher_suites len_ciph_suites len_ciph_suites_byte len_ciph_suites_word local len_client_hello_word len_all_word - - #len_servername=$(echo ${#NODE}) - len_servername=${#NODE} - hexdump_format_str="$len_servername/1 \"%02x,\"" - servername_hexstr=$(printf $NODE | hexdump -v -e "${hexdump_format_str}" | sed 's/,$//') + local ecc_cipher_suite_found=false + local extension_signature_algorithms extension_heartbeat + local extension_session_ticket extension_next_protocol extensions_ecc code2network "$2" # convert CIPHER_SUITES cipher_suites="$NW_STR" # we don't have the leading \x here so string length is two byte less, see next -#formatted example for SNI -#00 00 # extension server_name -#00 1a # length = the following +2 = server_name length + 5 -#00 18 # server_name list_length = server_name length +3 -#00 # server_name type (hostname) -#00 15 # server_name length -#66 66 66 66 66 66 2e 66 66 66 66 66 66 66 66 66 66 2e 66 66 66 target.mydomain1.tld # server_name target - - # convert lengths we need to fill in from dec to hex: - len_servername_hex=$(printf "%02x\n" $len_servername) - len_sni_listlen=$(printf "%02x\n" $((len_servername+3))) - len_sni_ext=$(printf "%02x\n" $((len_servername+5))) - len_extension_hex=$(printf "%02x\n" $((len_servername+9))) #FIXME: for TLS 1.2 and IIS servers we need extension_signature_algorithms!! - len_ciph_suites_byte=$(echo ${#cipher_suites}) let "len_ciph_suites_byte += 2" + if [[ "$tls_low_byte" != "00" ]]; then + # Add extensions + + # Check to see if any ECC cipher suites are included in cipher_suites + for (( i=0; i Date: Tue, 3 May 2016 16:48:42 -0400 Subject: [PATCH 2/6] Add padding extension RFC 7685 notes that there is at least one TLS implementation that hangs if the client sends a ClientHello with a TLSCiphertext.length between 256 and 511 bytes, and so the padding extension was defined in order to get around this bug. (OpenSSL s_client includes this extension when the -bugs option is used.) So, I changed socksend_tls_clienthello() to include the padding extension if the CLientHello would have a length between 256 and 511 bytes, making the padding extension just large enough to make the ClientHello 512 bytes. I also fixed a typo (a missing "0x") in the check for whether any ECC ciphers are included in the Client Hello. --- testssl.sh | 47 ++++++++++++++++++++++++++++++++++------------- 1 file changed, 34 insertions(+), 13 deletions(-) diff --git a/testssl.sh b/testssl.sh index b893487..c0e599a 100755 --- a/testssl.sh +++ b/testssl.sh @@ -4170,13 +4170,13 @@ socksend_tls_clienthello() { local servername_hexstr len_servername len_servername_hex local hexdump_format_str part1 part2 local all_extensions="" - local -i i j len_extension - local len_sni_listlen len_sni_ext len_extension_hex + local -i i j len_extension len_padding_extension len_all + local len_sni_listlen len_sni_ext len_extension_hex len_padding_extension_hex local cipher_suites len_ciph_suites len_ciph_suites_byte len_ciph_suites_word local len_client_hello_word len_all_word local ecc_cipher_suite_found=false local extension_signature_algorithms extension_heartbeat - local extension_session_ticket extension_next_protocol extensions_ecc + local extension_session_ticket extension_next_protocol extensions_ecc extension_padding code2network "$2" # convert CIPHER_SUITES cipher_suites="$NW_STR" # we don't have the leading \x here so string length is two byte less, see next @@ -4184,6 +4184,12 @@ socksend_tls_clienthello() { len_ciph_suites_byte=$(echo ${#cipher_suites}) let "len_ciph_suites_byte += 2" + # we have additional 2 chars \x in each 2 byte string and 2 byte ciphers, so we need to divide by 4: + len_ciph_suites=$(printf "%02x\n" $(($len_ciph_suites_byte / 4 ))) + len2twobytes "$len_ciph_suites" + len_ciph_suites_word="$LEN_STR" + #[[ $DEBUG -ge 3 ]] && echo $len_ciph_suites_word + if [[ "$tls_low_byte" != "00" ]]; then # Add extensions @@ -4211,7 +4217,7 @@ socksend_tls_clienthello() { ecc_cipher_suite_found=true && break fi elif [[ "$part1" == "0xcc" ]]; then - if [[ "$part2" == "0xa8" ]] || [[ "$part2" == "0xa9" ]] || [[ "$part2" == "0xac" ]] || [[ "$part2" == "13" ]] || [[ "$part2" == "0x14" ]]; then + if [[ "$part2" == "0xa8" ]] || [[ "$part2" == "0xa9" ]] || [[ "$part2" == "0xac" ]] || [[ "$part2" == "0x13" ]] || [[ "$part2" == "0x14" ]]; then ecc_cipher_suite_found=true && break fi fi @@ -4282,16 +4288,31 @@ socksend_tls_clienthello() { len_extension+=2 len_extension=$len_extension/4 len_extension_hex=$(printf "%02x\n" $len_extension) - all_extensions=" - ,00, $len_extension_hex # first the len of all extentions. - ,$all_extensions" - fi - # we have additional 2 chars \x in each 2 byte string and 2 byte ciphers, so we need to divide by 4: - len_ciph_suites=$(printf "%02x\n" $(($len_ciph_suites_byte / 4 ))) - len2twobytes "$len_ciph_suites" - len_ciph_suites_word="$LEN_STR" - #[[ $DEBUG -ge 3 ]] && echo $len_ciph_suites_word + # If the length of the Client Hello would be between 256 and 511 bytes, + # then add a padding extension (see RFC 7685) + 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 -gt 508 ]]; then + len_padding_extension=0 + else + len_padding_extension=$((508 - 0x$len_ciph_suites - 0x2b - 0x$len_extension_hex - 0x2)) + fi + len_padding_extension_hex=$(printf "%02x\n" $len_padding_extension) + len2twobytes "$len_padding_extension_hex" + all_extensions="$all_extensions\\x00\\x15\\x${LEN_STR:0:2}\\x${LEN_STR:4:2}" + for (( i=0; i Date: Thu, 5 May 2016 17:08:40 -0400 Subject: [PATCH 3/6] Signature Algorithms extension for TLSv1.2 only Changed to only include the signature algorithms extension for TLSv1.2, since RFC 5246 says: Note: this extension is not meaningful for TLS versions prior to 1.2. Clients MUST NOT offer it if they are offering prior versions. However, even if clients do offer it, the rules specified in [TLSEXT] require servers to ignore extensions they do not understand. Inclusion of the extension for TLS 1.1 didn't seem to cause any harm, but it seems better to follow the RFC and not include it for TLSv1.0 or TLSv1.1. --- testssl.sh | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/testssl.sh b/testssl.sh index c0e599a..8bc6fc0 100755 --- a/testssl.sh +++ b/testssl.sh @@ -4272,11 +4272,17 @@ socksend_tls_clienthello() { ,00 # server_name type (hostname) ,00, $len_servername_hex # server_name length. We assume len(hostname) < FF - 9 ,$servername_hexstr # server_name target - ,$extension_signature_algorithms ,$extension_heartbeat ,$extension_session_ticket ,$extension_next_protocol" + # RFC 5246 says that clients MUST NOT offer the signature algorithms + # extension if they are offering TLS versions prior to 1.2. + if [[ "$tls_low_byte" == "03" ]]; then + all_extensions="$all_extensions + ,$extension_signature_algorithms" + fi + if $ecc_cipher_suite_found; then all_extensions="$all_extensions ,$extensions_ecc" From 07a8bd3143203354f6a4b59f99d1505f83c23066 Mon Sep 17 00:00:00 2001 From: David Cooper Date: Wed, 11 May 2016 09:24:07 -0400 Subject: [PATCH 4/6] Support version negotiation test The new test in PR #346 sends a TLSv1.4 ClientHello, so socksend_tls_clienthello() needs to include the signature algorithms extension if $tls_low_byte >= 3 rather than only if it is equal to 3. --- testssl.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testssl.sh b/testssl.sh index 8bc6fc0..83a05f6 100755 --- a/testssl.sh +++ b/testssl.sh @@ -4278,7 +4278,7 @@ socksend_tls_clienthello() { # RFC 5246 says that clients MUST NOT offer the signature algorithms # extension if they are offering TLS versions prior to 1.2. - if [[ "$tls_low_byte" == "03" ]]; then + if [[ "0x$tls_low_byte" -ge "0x03" ]]; then all_extensions="$all_extensions ,$extension_signature_algorithms" fi From fa866f64588844bfc14dbfc1d5883d0ec1fa2ff8 Mon Sep 17 00:00:00 2001 From: David Cooper Date: Tue, 7 Jun 2016 14:23:33 -0400 Subject: [PATCH 5/6] Update CREDITS.md --- CREDITS.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CREDITS.md b/CREDITS.md index 6b6651b..967c0bb 100644 --- a/CREDITS.md +++ b/CREDITS.md @@ -21,9 +21,11 @@ - JSON and CSV output - Client simulations -* dcooper16 +* David Cooper - Detection + output of multiple certificates - several cleanups of server certificate related stuff + - improved parsing of TLS ServerHello messages + - speed improvements when testing all ciphers * Jean Marsault - client auth: ideas, code snipplets From d858edca1b17f1cb1b77bed5bcd2ef4d5e675b32 Mon Sep 17 00:00:00 2001 From: Dirk Date: Tue, 7 Jun 2016 23:06:58 +0200 Subject: [PATCH 6/6] - filled PROTOS_OFFERED w sense - minor fixes for fileout - introduced "fixme()" --- testssl.sh | 66 +++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 45 insertions(+), 21 deletions(-) diff --git a/testssl.sh b/testssl.sh index 6ad7746..0be8cf8 100755 --- a/testssl.sh +++ b/testssl.sh @@ -324,14 +324,14 @@ pr_liteblueln() { pr_liteblue "$1"; outln; } pr_blue() { [[ "$COLOR" -eq 2 ]] && ( "$COLORBLIND" && out "\033[1;32m$1" || out "\033[1;34m$1" ) || out "$1"; pr_off; } # used for head lines of single tests pr_blueln() { pr_blue "$1"; outln; } -pr_warning() { [[ "$COLOR" -eq 2 ]] && out "\033[0;35m$1" || pr_underline "$1"; pr_off; } # litemagentai | local problem: one test cannot be done -pr_warningln() { pr_warning "$1"; outln; } -pr_magenta() { [[ "$COLOR" -eq 2 ]] && out "\033[1;35m$1" || pr_underline "$1"; pr_off; } # Fatal error: quitting because of this! +pr_warning() { [[ "$COLOR" -eq 2 ]] && out "\033[0;35m$1" || pr_underline "$1"; pr_off; } # some local problem: one test cannot be done +pr_warningln() { pr_warning "$1"; outln; } # litemagenya +pr_magenta() { [[ "$COLOR" -eq 2 ]] && out "\033[1;35m$1" || pr_underline "$1"; pr_off; } # fatal error: quitting because of this! pr_magentaln() { pr_magenta "$1"; outln; } -pr_litecyan() { [[ "$COLOR" -eq 2 ]] && out "\033[0;36m$1" || out "$1"; pr_off; } # not yet used +pr_litecyan() { [[ "$COLOR" -eq 2 ]] && out "\033[0;36m$1" || out "$1"; pr_off; } # not yet used pr_litecyanln() { pr_litecyan "$1"; outln; } -pr_cyan() { [[ "$COLOR" -eq 2 ]] && out "\033[1;36m$1" || out "$1"; pr_off; } # additional hint +pr_cyan() { [[ "$COLOR" -eq 2 ]] && out "\033[1;36m$1" || out "$1"; pr_off; } # additional hint pr_cyanln() { pr_cyan "$1"; outln; } pr_litegreyln() { pr_litegrey "$1"; outln; } @@ -375,8 +375,11 @@ pr_headlineln() { pr_headline "$1" ; outln; } pr_squoted() { out "'$1'"; } pr_dquoted() { out "\"$1\""; } -local_problem_ln() { pr_warningln "Local problem: $1"; } local_problem() { pr_warning "Local problem: $1"; } +local_problem_ln() { pr_warningln "Local problem: $1"; } + +fixme() { pr_warning "fixme: $1"; } +fixme() { pr_warningln "fixme: $1"; } ### color switcher (see e.g. https://linuxtidbits.wordpress.com/2008/08/11/output-color-on-bash-scripts/ ### http://www.tldp.org/HOWTO/Bash-Prompt-HOWTO/x405.html @@ -642,17 +645,17 @@ runs_HTTP() { *) if $CLIENT_AUTH; then out "certificate based authentication => skipping all HTTP checks" echo "certificate based authentication => skipping all HTTP checks" >$TMPFILE - fileout "client_auth" "WARN" "certificate based authentication => skipping all HTTP checks" + fileout "client_auth" "INFO" "certificate based authentication => skipping all HTTP checks" else out " Couldn't determine what's running on port $PORT" if $ASSUMING_HTTP; then SERVICE=HTTP out " -- ASSUMING_HTTP set though" - fileout "service" "WARN" "Couldn't determine service, --ASSUMING_HTTP set" + fileout "service" "DEBUG" "Couldn't determine service, --ASSUMING_HTTP set" ret=0 else out ", assuming no HTTP service => skipping all HTTP checks" - fileout "service" "WARN" "Couldn't determine service, skipping all HTTP checks" + fileout "service" "DEBUG" "Couldn't determine service, skipping all HTTP checks" ret=1 fi fi @@ -1011,7 +1014,7 @@ run_hpkp() { out "\n$spaces" pr_svrty_high " No matching key for pins found " out "(CAs pinned? -- not checked for yet)" - fileout "hpkp_keymatch" "WARN" "The TLS key does not match any key pinned in the HPKP header. If you pinned a CA key you can ignore this" + fileout "hpkp_keymatch" "DEBUG" "The TLS key does not match any key pinned in the HPKP header. If you pinned a CA key you can ignore this" fi else out "--" @@ -2217,6 +2220,12 @@ run_prototest_openssl() { # 7: no local support } +# idempotent function to add SSL/TLS protocols. It should ease testing +# PROTOS_OFFERED's content is in openssl terminology +add_tls_offered() { + grep -w "$1" <<< "$PROTOS_OFFERED" || PROTOS_OFFERED+="$1 " +} + # the protocol check needs to be revamped. It sucks, see above run_protocols() { @@ -2256,6 +2265,7 @@ run_protocols() { 0) pr_svrty_criticalln "offered (NOT ok)" fileout "sslv2" "NOT ok" "SSLv2 is offered (NOT ok)" + add_tls_offered "ssl2" ;; 1) pr_done_bestln "not offered (OK)" @@ -2264,6 +2274,7 @@ run_protocols() { 5) pr_svrty_high "CVE-2015-3197: $supported_no_ciph2"; fileout "sslv2" "WARN" "CVE-2015-3197: SSLv2 is $supported_no_ciph2" + add_tls_offered "ssl2" ;; 7) fileout "sslv2" "INFO" "SSLv2 is not tested due to lack of local support" @@ -2281,6 +2292,7 @@ run_protocols() { 0) pr_svrty_highln "offered (NOT ok)" fileout "sslv3" "NOT ok" "SSLv3 is offered (NOT ok)" + add_tls_offered "ssl3" ;; 1) pr_done_bestln "not offered (OK)" @@ -2294,7 +2306,8 @@ run_protocols() { fileout "sslv3" "WARN" "SSLv3 is $supported_no_ciph1" pr_svrty_high "$supported_no_ciph2" outln "(may need debugging)" - ;; # protocol ok, but no cipher + add_tls_offered "ssl3" + ;; 7) fileout "sslv3" "INFO" "SSLv3 is not tested due to lack of local support" ;; # no local support @@ -2310,6 +2323,7 @@ run_protocols() { 0) outln "offered" fileout "tls1" "INFO" "TLSv1.0 is offered" + add_tls_offered "tls1" ;; # nothing wrong with it -- per se 1) outln "not offered" @@ -2320,10 +2334,12 @@ run_protocols() { [[ $DEBUG -eq 1 ]] && out " -- downgraded" outln fileout "tls1" "MEDIUM" "TLSv1.0 is not offered, and downgraded to SSL" + add_tls_offered "tls1" ;; 5) outln "$supported_no_ciph1" # protocol ok, but no cipher fileout "tls1" "WARN" "TLSv1.0 is $supported_no_ciph1" + add_tls_offered "tls1" ;; 7) fileout "tlsv1" "INFO" "TLSv1.0 is not tested due to lack of local support" @@ -2340,6 +2356,7 @@ run_protocols() { 0) outln "offered" fileout "tls1_1" "INFO" "TLSv1.1 is offered" + add_tls_offered "tls1_1" ;; # nothing wrong with it 1) outln "not offered" @@ -2354,6 +2371,7 @@ run_protocols() { 5) outln "$supported_no_ciph1" fileout "tls1_1" "WARN" "TLSv1.1 is $supported_no_ciph1" + add_tls_offered "tls1_1" ;; # protocol ok, but no cipher 7) fileout "tls1_1" "INFO" "TLSv1.1 is not tested due to lack of local support" @@ -2370,6 +2388,7 @@ run_protocols() { 0) pr_done_bestln "offered (OK)" fileout "tls1_2" "OK" "TLSv1.2 is offered (OK)" + add_tls_offered "tls1_2" ;; # GCM cipher in TLS 1.2: very good! 1) pr_svrty_mediumln "not offered" @@ -2384,11 +2403,13 @@ run_protocols() { 5) outln "$supported_no_ciph1" fileout "tls1_2" "WARN" "TLSv1.2 is $supported_no_ciph1" + add_tls_offered "tls1_2" ;; # protocol ok, but no cipher 7) fileout "tls1_2" "INFO" "TLSv1.2 is not tested due to lack of local support" ;; # no local support esac + return 0 } @@ -2735,7 +2756,7 @@ check_tls12_pref() { order="$cipher" tested_cipher="-$cipher" else - pr_warningln "fixme: something weird happened around line $((LINENO - 6))" + fixmeln "something weird happened around line $((LINENO - 6))" return 1 fi while true; do @@ -2755,6 +2776,8 @@ check_tls12_pref() { # second cipher set didn't succeed: we can just output everything out " $order" fi + + tmpfile_handle $FUNCNAME.txt return 0 } @@ -2790,7 +2813,7 @@ cipher_pref_check() { # thus we reduce the number of ciphers we throw at the server and put later everything together # see #189 # so far, this was only observed in TLS 1.2 - check_tls12_pref "$cipher" + order=$(check_tls12_pref "$cipher") else out " $cipher" # this is the first cipher for protocol while true; do @@ -2827,7 +2850,7 @@ cipher_pref_check() { order+=" $cipher" done outln - [[ -z $order ]] || fileout "order_spdy_$p" "INFO" "Default cipher order for SPDY protocol $p:order" + [[ -n $order ]] && fileout "order_spdy_$p" "INFO" "Default cipher order for SPDY protocol $p: $order" done fi @@ -4482,6 +4505,7 @@ sslv2_sockets() { [[ "$DEBUG" -ge 2 ]] && out " ($lines lines) " if [[ "$lines" -gt 1 ]]; then nr_ciphers_detected=$((V2_HELLO_CIPHERSPEC_LENGTH / 3)) + add_tls_offered "ssl2" if [[ 0 -eq "$nr_ciphers_detected" ]]; then pr_svrty_highln "supported but couldn't detect a cipher and vulnerable to CVE-2015-3197 "; fileout "sslv2" "NOT ok" "SSLv2 offered (NOT ok), vulnerable to CVE-2015-3197" @@ -5428,11 +5452,11 @@ run_drown() { parse_sslv2_serverhello "$SOCK_REPLY_FILE" case $? in 7) # strange reply, couldn't convert the cipher spec length to a hex number - pr_cyan "strange v2 reply " + fixme "strange v2 reply " 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 reply (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)") @@ -5441,16 +5465,16 @@ run_drown() { nr_ciphers_detected=$((V2_HELLO_CIPHERSPEC_LENGTH / 3)) if [[ 0 -eq "$nr_ciphers_detected" ]]; then pr_svrty_highln "CVE-2015-3197: SSLv2 supported but couldn't detect a cipher (NOT ok)"; - fileout "DROWN" "NOT ok" "SSLv2 offered (NOT ok), CVE-2015-3197: but could not detect a cipher" + fileout "drown" "NOT ok" "SSLv2 offered (NOT ok), CVE-2015-3197: but could not detect a cipher" else pr_svrty_criticalln "vulnerable (NOT ok), SSLv2 offered with $nr_ciphers_detected ciphers"; - fileout "DROWN" "NOT ok" "vulnerable (NOT ok), SSLv2 offered with $nr_ciphers_detected ciphers" + fileout "drown" "NOT ok" "vulnerable (NOT ok), SSLv2 offered with $nr_ciphers_detected ciphers" fi fi ret=1 ;; *) pr_done_bestln "not vulnerable on this port (OK)" - fileout "DROWN" "OK" "not vulnerable to DROWN" + fileout "drown" "OK" "not vulnerable to DROWN" outln "$spaces make sure you don't use this certificate elsewhere with SSLv2 enabled services" if [[ "$DEBUG" -ge 1 ]] || "$SHOW_CENSYS_LINK"; then # not advertising it as it after 5 tries and account is needed @@ -5725,7 +5749,7 @@ 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. Get precompiled bins or compile https://github.com/PeterMosmans/openssl ." + fileout "old_fart" "ERROR" "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 } @@ -7354,4 +7378,4 @@ fi exit $? -# $Id: testssl.sh,v 1.495 2016/06/07 11:02:57 dirkw Exp $ +# $Id: testssl.sh,v 1.496 2016/06/07 21:06:57 dirkw Exp $