diff --git a/Readme.md b/Readme.md
index 51904dc..d1919af 100644
--- a/Readme.md
+++ b/Readme.md
@@ -41,7 +41,7 @@ of the limitations of disabled features from the openssl client are gone due to
checks. testssl.sh also works on otherunixoid system out of the box, supposed they have
`/bin/bash` and standard tools like sed and awk installed. System V needs to have GNU versions
of grep and sed installed. MacOS X and Windows (using MSYS2 or cygwin) work too. OpenSSL
-version >= 1 is a must. OpenSSL version >= 1.0.2 is needed for better LOGJAM checks and to
+version >= 1 is a must. OpenSSL version >= 1.0.2 is needed for better LOGJAM checks and to
display bit strengths for key exchanges.
Update notification here or @ [twitter](https://twitter.com/drwetter).
@@ -49,19 +49,20 @@ Update notification here or @ [twitter](https://twitter.com/drwetter).
#### Features implemented in [2.9dev](Readme.md#devel)
* Support of supplying timeout value for ``openssl connect`` -- useful for batch/mass scanning
* TLS 1.2 protocol check via socket
-* Further TLS socket improvements (handshake parsing, completeness, robustness)
-* non-flat JSON support
-* in file output (CSV, JSON flat, JSON non-flat) support of a minimum severity level (only above supplied level there will be output)
-* testing 359 default ciphers (``testssl.sh -e``) with a mixture of sockets and openssl. Same speed as with openssl only but addtional ciphers such as post-quantum ciphers, new CHAHA20/POLY1305, CamelliaGCM etc.
-* finding more TLS extensions via sockets
+* Further tests via TLS sockets and improvements (handshake parsing, completeness, robustness)
+* Finding more TLS extensions via sockets
+* Using bash sockets where ever possible
* TLS Supported Groups Registry (RFC 7919), key shares extension
-* using bash sockets where ever possible
+* Non-flat JSON support
+* File output (CSV, JSON flat, JSON non-flat) supports a minimum severity level (only above supplied level there will be output)
+* Native HTML support instead going through 'aha'
+* Testing 359 default ciphers (``testssl.sh -e``) with a mixture of sockets and openssl. Same speed as with openssl only but addtional ciphers such as post-quantum ciphers, new CHAHA20/POLY1305, CamelliaGCM etc.
* LUCKY13 and SWEET32 checks
* LOGJAM: now checking also for known DH parameters
* Check for CAA RR
-* better formatting of output
-* choice showing the RFC naming scheme only
-
+* Check for OCSP must staple
+* Better formatting of output (indentation)
+* Choice showing the RFC naming scheme only
#### Features planned in 2.9dev
@@ -73,7 +74,7 @@ Contributions, feedback, bug reports are welcome! For contributions please
note: One patch per feature -- bug fix/improvement. Please test your
changes thouroughly as reliability is important for this project.
-There's [coding guideline](https://github.com/drwetter/testssl.sh/wiki/Coding-Style).
+There's a [coding guideline](https://github.com/drwetter/testssl.sh/wiki/Coding-Style).
Please file bug reports @ https://github.com/drwetter/testssl.sh/issues.
@@ -85,8 +86,9 @@ Help is needed here.
#### Bug reports
-Please file bugs in the issue tracker. Do not forget to provide detailed information, see https://github.com/drwetter/testssl.sh/wiki/Bug-reporting. (Nobody can read your thoughts
--- yet. And only agencies your screen) ;-)
+Please file bugs in the issue tracker. Do not forget to provide detailed information,
+see https://github.com/drwetter/testssl.sh/wiki/Bug-reporting. (Nobody can read your
+thoughts -- yet. And only agencies your screen) ;-)
----
diff --git a/testssl.sh b/testssl.sh
index f30f581..fa70164 100755
--- a/testssl.sh
+++ b/testssl.sh
@@ -144,7 +144,7 @@ COLORBLIND=${COLORBLIND:-false} # if true, swap blue and green in the ou
SHOW_EACH_C=${SHOW_EACH_C:-false} # where individual ciphers are tested show just the positively ones tested
SHOW_SIGALGO=${SHOW_SIGALGO:-false} # "secret" switch whether testssl.sh shows the signature algorithm for -E / -e
SNEAKY=${SNEAKY:-false} # is the referer and useragent we leave behind just usual?
-QUIET=${QUIET:-false} # don't output the banner. By doing this yiu acknowledge usage term appearing in the banner
+QUIET=${QUIET:-false} # don't output the banner. By doing this you acknowledge usage term appearing in the banner
SSL_NATIVE=${SSL_NATIVE:-false} # we do per default bash sockets where possible "true": switch back to "openssl native"
ASSUME_HTTP=${ASSUME_HTTP:-false} # in seldom cases (WAF, old servers, grumpy SSL) service detection fails. "True" enforces HTTP checks
BUGS=${BUGS:-""} # -bugs option from openssl, needed for some BIG IP F5
@@ -159,6 +159,8 @@ WIDE=${WIDE:-false} # whether to display for some options ju
LOGFILE=${LOGFILE:-""} # logfile if used
JSONFILE=${JSONFILE:-""} # jsonfile if used
CSVFILE=${CSVFILE:-""} # csvfile if used
+HTMLFILE=${HTMLFILE:-""} # HTML if used
+HTMLHEADER=true # include HTML headers and footers in HTML file, if one is being created
APPEND=${APPEND:-false} # append to csv/json file instead of overwriting it
GIVE_HINTS=false # give an addtional info to findings
HAS_IPv6=${HAS_IPv6:-false} # if you have OpenSSL with IPv6 support AND IPv6 networking set it to yes
@@ -551,84 +553,165 @@ declare TLS_CIPHER_EXPORT=()
declare TLS_CIPHER_OSSL_SUPPORTED=()
###### output functions ######
-# a little bit of sanitzing with bash internal search&replace -- otherwise printf will hiccup at '%' and '--' does the rest.
-out(){
-# if [[ "$BASH_VERSINFO" -eq 4 ]]; then
- printf -- "%b" "${1//%/%%}"
-# else
-# /usr/bin/printf -- "${1//%/%%}"
-# fi
+
+# For HTML output, replace any HTML reserved characters with the entity name
+html_reserved(){
+ sed -e 's/\&/\&/g' -e 's/\</g' -e 's/>/\>/g' -e 's/"/\"/g' -e "s/'/\'/g" <<< "$1"
+}
+
+html_out() {
+ "$do_html" || return
+ [[ -n "$HTMLFILE" ]] && [[ ! -d "$HTMLFILE" ]] && printf -- "%b" "${1//%/%%}" >> "$HTMLFILE"
+ # here and other printf's: a little bit of sanitzing with bash internal search&replace -- otherwise printf will hiccup at '%'. '--' and %b do the rest.
+}
+
+out() {
+ printf -- "%b" "${1//%/%%}"
+ html_out "$1"
}
outln() { out "$1\n"; }
+
+tm_out(){
+ printf -- "%b" "${1//%/%%}"
+}
+tmln_out() { tm_out "$1\n"; }
+
#TODO: Still no shell injection safe but if just run it from the cmd line: that's fine
# color print functions, see also http://www.tldp.org/HOWTO/Bash-Prompt-HOWTO/x329.html
-pr_liteblue() { [[ "$COLOR" -eq 2 ]] && ( "$COLORBLIND" && out "\033[0;32m$1" || out "\033[0;34m$1" ) || out "$1"; pr_off; } # not yet used
-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; }
+tm_liteblue() { [[ "$COLOR" -eq 2 ]] && ( "$COLORBLIND" && tm_out "\033[0;32m$1" || tm_out "\033[0;34m$1" ) || tm_out "$1"; tm_off; } # not yet used
+pr_liteblue() { tm_liteblue "$1"; [[ "$COLOR" -eq 2 ]] && ( "$COLORBLIND" && html_out "$(html_reserved "$1")" || html_out "$(html_reserved "$1")" ) || html_out "$(html_reserved "$1")"; }
+tmln_liteblue() { tm_liteblue "$1"; tmln_out; }
+prln_liteblue() { pr_liteblue "$1"; outln; }
-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; } # litemagenta
-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; }
+tm_blue() { [[ "$COLOR" -eq 2 ]] && ( "$COLORBLIND" && tm_out "\033[1;32m$1" || tm_out "\033[1;34m$1" ) || tm_out "$1"; tm_off; } # used for head lines of single tests
+pr_blue() { tm_blue "$1"; [[ "$COLOR" -eq 2 ]] && ( "$COLORBLIND" && html_out "$(html_reserved "$1")" || html_out "$(html_reserved "$1")" ) || html_out "$(html_reserved "$1")"; }
+tmln_blue() { tm_blue "$1"; tmln_out; }
+prln_blue() { pr_blue "$1"; outln; }
-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_cyanln() { pr_cyan "$1"; outln; }
+# we should be able to use aliases here
+tm_warning() { [[ "$COLOR" -eq 2 ]] && tm_out "\033[0;35m$1" || tm_underline "$1"; tm_off; } # some local problem: one test cannot be done
+tmln_warning() { tm_warning "$1"; tmln_out; } # litemagenta
+pr_warning() { tm_warning "$1"; [[ "$COLOR" -eq 2 ]] && html_out "$(html_reserved "$1")" || ( [[ "$COLOR" -eq 1 ]] && html_out "$(html_reserved "$1")" || html_out "$(html_reserved "$1")" ); }
+prln_warning() { pr_warning "$1"; outln; }
-pr_litegreyln() { pr_litegrey "$1"; outln; } # not really usable on a black background, see ..
-pr_litegrey() { [[ "$COLOR" -eq 2 ]] && out "\033[0;37m$1" || out "$1"; pr_off; } # ... https://github.com/drwetter/testssl.sh/pull/600#issuecomment-276129876
-pr_grey() { [[ "$COLOR" -eq 2 ]] && out "\033[1;30m$1" || out "$1"; pr_off; }
-pr_greyln() { pr_grey "$1"; outln; }
+tm_magenta() { [[ "$COLOR" -eq 2 ]] && tm_out "\033[1;35m$1" || tm_underline "$1"; tm_off; } # fatal error: quitting because of this!
+tmln_magenta() { tm_magenta "$1"; tmln_out; }
+# different as warning above?
+pr_magenta() { tm_magenta "$1"; [[ "$COLOR" -eq 2 ]] && html_out "$(html_reserved "$1")" || ( [[ "$COLOR" -eq 1 ]] && html_out "$(html_reserved "$1")" || html_out "$(html_reserved "$1")" ); }
+prln_magenta() { pr_magenta "$1"; outln; }
-pr_done_good() { [[ "$COLOR" -eq 2 ]] && ( "$COLORBLIND" && out "\033[0;34m$1" || out "\033[0;32m$1" ) || out "$1"; pr_off; } # litegreen (liteblue), This is good
-pr_done_goodln() { pr_done_good "$1"; outln; }
-pr_done_best() { [[ "$COLOR" -eq 2 ]] && ( "$COLORBLIND" && out "\033[1;34m$1" || out "\033[1;32m$1" ) || out "$1"; pr_off; } # green (blue), This is the best
-pr_done_bestln() { pr_done_best "$1"; outln; }
+tm_litecyan() { [[ "$COLOR" -eq 2 ]] && tm_out "\033[0;36m$1" || tm_out "$1"; tm_off; } # not yet used
+tmln_litecyan() { tm_litecyan "$1"; tmln_out; }
+pr_litecyan() { tm_litecyan "$1"; [[ "$COLOR" -eq 2 ]] && html_out "$(html_reserved "$1")" || html_out "$(html_reserved "$1")"; }
+prln_litecyan() { pr_litecyan "$1"; outln; }
-pr_svrty_low() { [[ "$COLOR" -eq 2 ]] && out "\033[1;33m$1" || out "$1"; pr_off; } # yellow brown | academic or minor problem
-pr_svrty_lowln() { pr_svrty_low "$1"; outln; }
-pr_svrty_medium() { [[ "$COLOR" -eq 2 ]] && out "\033[0;33m$1" || out "$1"; pr_off; } # brown | it is not a bad problem but you shouldn't do this
-pr_svrty_mediumln() { pr_svrty_medium "$1"; outln; }
+tm_cyan() { [[ "$COLOR" -eq 2 ]] && tm_out "\033[1;36m$1" || tm_out "$1"; tm_off; } # additional hint
+tmln_cyan() { tm_cyan "$1"; tmln_out; }
+pr_cyan() { tm_cyan "$1"; [[ "$COLOR" -eq 2 ]] && html_out "$(html_reserved "$1")" || html_out "$(html_reserved "$1")"; }
+prln_cyan() { pr_cyan "$1"; outln; }
-pr_svrty_high() { [[ "$COLOR" -eq 2 ]] && out "\033[0;31m$1" || pr_bold "$1"; pr_off; } # litered
-pr_svrty_highln() { pr_svrty_high "$1"; outln; }
-pr_svrty_critical() { [[ "$COLOR" -eq 2 ]] && out "\033[1;31m$1" || pr_bold "$1"; pr_off; } # red
-pr_svrty_criticalln(){ pr_svrty_critical "$1"; outln; }
+tm_litegrey() { [[ "$COLOR" -ne 0 ]] && tm_out "\033[0;37m$1" || tm_out "$1"; tm_off; } # ... https://github.com/drwetter/testssl.sh/pull/600#issuecomment-276129876
+tmln_litegrey() { tm_litegrey "$1"; tmln_out; } # not really usable on a black background, see ..
+prln_litegrey() { pr_litegrey "$1"; outln; }
+pr_litegrey() { tm_litegrey "$1"; [[ "$COLOR" -ne 0 ]] && html_out "$(html_reserved "$1")" || html_out "$(html_reserved "$1")"; }
-pr_deemphasize() { out "$1"; } # hook for a weakened screen output, see #600
-pr_deemphasizeln() { outln "$1"; }
+tm_grey() { [[ "$COLOR" -ne 0 ]] && tm_out "\033[1;30m$1" || tm_out "$1"; tm_off; }
+pr_grey() { tm_grey "$1"; [[ "$COLOR" -ne 0 ]] && html_out "$(html_reserved "$1")" || html_out "$(html_reserved "$1")"; }
+tmln_grey() { tm_grey "$1"; tmln_out; }
+prln_grey() { pr_grey "$1"; outln; }
+
+tm_done_good() { [[ "$COLOR" -eq 2 ]] && ( "$COLORBLIND" && tm_out "\033[0;34m$1" || tm_out "\033[0;32m$1" ) || tm_out "$1"; tm_off; } # litegreen (liteblue), This is good
+tmln_done_good() { tm_done_good "$1"; tmln_out; }
+pr_done_good() { tm_done_good "$1"; [[ "$COLOR" -eq 2 ]] && ( "$COLORBLIND" && html_out "$(html_reserved "$1")" || html_out "$(html_reserved "$1")" ) || html_out "$(html_reserved "$1")"; }
+prln_done_good() { pr_done_good "$1"; outln; }
+
+tm_done_best() { [[ "$COLOR" -eq 2 ]] && ( "$COLORBLIND" && tm_out "\033[1;34m$1" || tm_out "\033[1;32m$1" ) || tm_out "$1"; tm_off; } # green (blue), This is the best
+tmln_done_best() { tm_done_best "$1"; tmln_out; }
+pr_done_best() { tm_done_best "$1"; [[ "$COLOR" -eq 2 ]] && ( "$COLORBLIND" && html_out "$(html_reserved "$1")" || html_out "$(html_reserved "$1")" ) || html_out "$(html_reserved "$1")"; }
+prln_done_best() { pr_done_best "$1"; outln; }
+
+tm_svrty_low() { [[ "$COLOR" -eq 2 ]] && tm_out "\033[1;33m$1" || tm_out "$1"; tm_off; } # yellow brown | academic or minor problem
+tmln_svrty_low() { tm_svrty_low "$1"; tmln_out; }
+pr_svrty_low() { tm_svrty_low "$1"; [[ "$COLOR" -eq 2 ]] && html_out "$(html_reserved "$1")" || html_out "$(html_reserved "$1")"; }
+prln_svrty_low() { pr_svrty_low "$1"; outln; }
+
+tm_svrty_medium() { [[ "$COLOR" -eq 2 ]] && tm_out "\033[0;33m$1" || tm_out "$1"; tm_off; } # brown | it is not a bad problem but you shouldn't do this
+pr_svrty_medium() { tm_svrty_medium "$1"; [[ "$COLOR" -eq 2 ]] && html_out "$(html_reserved "$1")" || html_out "$(html_reserved "$1")"; }
+tmln_svrty_medium(){ tm_svrty_medium "$1"; tmln_out; }
+prln_svrty_medium(){ pr_svrty_medium "$1"; outln; }
+
+tm_svrty_high() { [[ "$COLOR" -eq 2 ]] && tm_out "\033[0;31m$1" || tm_bold "$1"; tm_off; } # litered
+pr_svrty_high() { tm_svrty_high "$1"; [[ "$COLOR" -eq 2 ]] && html_out "$(html_reserved "$1")" || ( [[ "$COLOR" -eq 1 ]] && html_out "$(html_reserved "$1")" || html_out "$(html_reserved "$1")" ); }
+tmln_svrty_high() { tm_svrty_high "$1"; tmln_out; }
+prln_svrty_high() { pr_svrty_high "$1"; outln; }
+
+tm_svrty_critical() { [[ "$COLOR" -eq 2 ]] && tm_out "\033[1;31m$1" || tm_bold "$1"; tm_off; } # red
+pr_svrty_critical() { tm_svrty_critical "$1"; [[ "$COLOR" -eq 2 ]] && html_out "$(html_reserved "$1")" || ( [[ "$COLOR" -eq 1 ]] && html_out "$(html_reserved "$1")" || html_out "$(html_reserved "$1")" ); }
+tmln_svrty_critical() { tm_svrty_critical "$1"; tmln_out; }
+prln_svrty_critical() { pr_svrty_critical "$1"; outln; }
+
+tm_deemphasize() { tm_out "$1"; } # hook for a weakened screen output, see #600
+pr_deemphasize() { tm_deemphasize "$1"; html_out "$(html_reserved "$1")"; }
+tmln_deemphasize() { tm_deemphasize "$1"; tmln_out; }
+prln_deemphasize() { pr_deemphasize "$1"; outln; }
# color=1 functions
-pr_off() { [[ "$COLOR" -ne 0 ]] && out "\033[m"; }
-pr_bold() { [[ "$COLOR" -ne 0 ]] && out "\033[1m$1" || out "$1"; pr_off; }
-pr_boldln() { pr_bold "$1" ; outln; }
-pr_italic() { [[ "$COLOR" -ne 0 ]] && out "\033[3m$1" || out "$1"; pr_off; }
-pr_italicln() { pr_italic "$1" ; outln; }
-pr_strikethru() { [[ "$COLOR" -ne 0 ]] && out "\033[9m$1" || out "$1"; pr_off; } # ugly!
-pr_strikethruln() { pr_strikethru "$1" ; outln; }
-pr_underline() { [[ "$COLOR" -ne 0 ]] && out "\033[4m$1" || out "$1"; pr_off; }
-pr_underlineln() { pr_underline "$1"; outln; }
-pr_reverse() { [[ "$COLOR" -ne 0 ]] && out "\033[7m$1" || out "$1"; pr_off; }
-pr_reverse_bold() { [[ "$COLOR" -ne 0 ]] && out "\033[7m\033[1m$1" || out "$1"; pr_off; }
+tm_off() { [[ "$COLOR" -ne 0 ]] && tm_out "\033[m"; }
+
+tm_bold() { [[ "$COLOR" -ne 0 ]] && tm_out "\033[1m$1" || tm_out "$1"; tm_off; }
+tmln_bold() { tm_bold "$1"; tmln_out; }
+pr_bold() { tm_bold "$1"; [[ "$COLOR" -ne 0 ]] && html_out "$(html_reserved "$1")" || html_out "$(html_reserved "$1")"; }
+prln_bold() { pr_bold "$1" ; outln; }
+
+tm_italic() { [[ "$COLOR" -ne 0 ]] && tm_out "\033[3m$1" || tm_out "$1"; tm_off; }
+tmln_italic() { tm_italic "$1" ; outln; }
+pr_italic() { tm_italic "$1"; [[ "$COLOR" -ne 0 ]] && html_out "$(html_reserved "$1")" || html_out "$(html_reserved "$1")"; }
+prln_italic() { pr_italic "$1"; tmln_out; }
+
+tm_strikethru() { [[ "$COLOR" -ne 0 ]] && tm_out "\033[9m$1" || tm_out "$1"; tm_off; } # ugly!
+tmln_strikethru() { tm_strikethru "$1"; tmln_out; }
+pr_strikethru() { tm_strikethru "$1"; [[ "$COLOR" -ne 0 ]] && html_out "$(html_reserved "$1")" || html_out "$(html_reserved "$1")"; }
+prln_strikethru() { pr_strikethru "$1" ; outln; }
+
+tm_underline() { [[ "$COLOR" -ne 0 ]] && tm_out "\033[4m$1" || tm_out "$1"; tm_off; }
+tmln_underline() { tm_underline "$1"; tmln_out; }
+pr_underline() { tm_underline "$1"; [[ "$COLOR" -ne 0 ]] && html_out "$(html_reserved "$1")" || html_out "$(html_reserved "$1")"; }
+prln_underline() { pr_underline "$1"; outln; }
+
+tm_reverse() { [[ "$COLOR" -ne 0 ]] && tm_out "\033[7m$1" || tm_out "$1"; tm_off; }
+tm_reverse_bold() { [[ "$COLOR" -ne 0 ]] && tm_out "\033[7m\033[1m$1" || tm_out "$1"; tm_off; }
+pr_reverse() { tm_reverse "$1"; [[ "$COLOR" -ne 0 ]] && html_out "$(html_reserved "$1")" || html_out "$(html_reserved "$1")"; }
+pr_reverse_bold() { tm_reverse_bold "$1"; [[ "$COLOR" -ne 0 ]] && html_out "$(html_reserved "$1")" || html_out "$(html_reserved "$1")"; }
#pr_headline() { pr_blue "$1"; }
#http://misc.flogisoft.com/bash/tip_colors_and_formatting
-#pr_headline() { [[ "$COLOR" -eq 2 ]] && out "\033[1;30m\033[47m$1" || out "$1"; pr_off; }
-pr_headline() { [[ "$COLOR" -ne 0 ]] && out "\033[1m\033[4m$1" || out "$1"; pr_off; }
+#pr_headline() { [[ "$COLOR" -eq 2 ]] && out "\033[1;30m\033[47m$1" || out "$1"; tm_off; }
+tm_headline() { [[ "$COLOR" -ne 0 ]] && tm_out "\033[1m\033[4m$1" || tm_out "$1"; tm_off; }
+tmln_headline() { tm_headline "$1"; tmln_out; }
+pr_headline() { tm_headline "$1"; [[ "$COLOR" -ne 0 ]] && html_out "$(html_reserved "$1")" || html_out "$(html_reserved "$1")"; }
pr_headlineln() { pr_headline "$1" ; outln; }
+tm_squoted() { tm_out "'$1'"; }
pr_squoted() { out "'$1'"; }
+tm_dquoted() { tm_out "\"$1\""; }
pr_dquoted() { out "\"$1\""; }
-local_problem() { pr_warning "Local problem: $1"; }
-local_problem_ln() { pr_warningln "Local problem: $1"; }
+# either files couldn't be found or openssl isn't good enough (which shouldn't happen anymore)
+tm_local_problem() { tm_warning "Local problem: $1"; }
+tmln_local_problem() { tmln_warning "Local problem: $1"; }
+pr_local_problem() { pr_warning "Local problem: $1"; }
+prln_local_problem() { prln_warning "Local problem: $1"; }
-fixme() { pr_warning "fixme: $1"; }
-fixmeln() { pr_warningln "fixme: $1"; }
+# general failure
+tm_fixme() { tm_warning "Fixme: $1"; }
+tmln_fixme() { tmln_warning "Fixme: $1"; }
+pr_fixme() { pr_warning "Fixme: $1"; }
+prln_fixme() { prln_warning "Fixme: $1"; }
+
+pr_url() { tm_out "$1"; html_out "$1"; }
+pr_boldurl() { tm_bold "$1"; html_out "$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
@@ -735,37 +818,17 @@ fileout_json_footer() {
fileout_json_section() {
case $1 in
- 1)
- echo -e " \"protocols\" : ["
- ;;
- 2)
- echo -e ",\n \"ciphers\" : ["
- ;;
- 3)
- echo -e ",\n \"pfs\" : ["
- ;;
- 4)
- echo -e ",\n \"serverPreferences\" : ["
- ;;
- 5)
- echo -e ",\n \"serverDefaults\" : ["
- ;;
- 6)
- echo -e ",\n \"headerResponse\" : ["
- ;;
- 7)
- echo -e ",\n \"vulnerabilities\" : ["
- ;;
- 8)
- echo -e ",\n \"cipherTests\" : ["
- ;;
- 9)
- echo -e ",\n \"browserSimulations\": ["
- ;;
- *)
- echo "invalid section"
- ;;
- esac
+ 1) echo -e " \"protocols\" : [" ;;
+ 2) echo -e ",\n \"ciphers\" : [" ;;
+ 3) echo -e ",\n \"pfs\" : [" ;;
+ 4) echo -e ",\n \"serverPreferences\" : [" ;;
+ 5) echo -e ",\n \"serverDefaults\" : [" ;;
+ 6) echo -e ",\n \"headerResponse\" : [" ;;
+ 7) echo -e ",\n \"vulnerabilities\" : [" ;;
+ 8) echo -e ",\n \"cipherTests\" : [" ;;
+ 9) echo -e ",\n \"browserSimulations\": [" ;;
+ *) echo "invalid section" ;;
+ esac
}
fileout_section_header(){
@@ -840,9 +903,8 @@ is_json_format() {
( [[ -f "$JSONFILE" ]] && ("$do_json" || "$do_pretty_json") )
}
-################# JSON FILE FORMATING END ####################
-
##################### FILE FORMATING #########################
+
fileout_header() {
if "$APPEND"; then
if [[ -f "$JSONFILE" ]]; then
@@ -886,9 +948,77 @@ fileout() { # ID, SEVERITY, FINDING, CVE, CWE, HINT
"$FIRST_FINDING" && FIRST_FINDING=false
fi
}
+
+################# JSON FILE FORMATING END. HTML START ####################
+
+html_header() {
+ local fname_prefix
+
+ # Don't create HTML headers and footers in the following scenarios:
+ # * HTML output is not being created.
+ # * mass testing is being performed and each test will have its own HTML file.
+ # * this is an individual test within a mass test and all HTML output is being placed in a single file.
+ if ! "$do_html" || \
+ ( "$do_mass_testing" && ( [[ -z "$HTMLFILE" ]] || [[ -d "$HTMLFILE" ]] ) ) || \
+ ( "$APPEND" && [[ -n "$HTMLFILE" ]] && [[ ! -d "$HTMLFILE" ]] ); then
+ HTMLHEADER=false
+ return 0
+ fi
+
+ if "$do_display_only"; then
+ fname_prefix="local-ciphers"
+ elif "$do_mass_testing"; then
+ :
+ elif "$do_mx_all_ips"; then
+ fname_prefix="mx-$URI"
+ else
+ ( [[ -z "$HTMLFILE" ]] || [[ -d "$HTMLFILE" ]] ) && parse_hn_port "${URI}" # NODE, URL_PATH, PORT, IPADDR and IP46ADDR is set now
+ fname_prefix="$NODE"_"$PORT"
+ fi
+
+ if [[ -n "$HTMLFILE" ]] && [[ ! -d "$HTMLFILE" ]]; then
+ rm -f "$HTMLFILE"
+ elif [[ -z "$HTMLFILE" ]]; then
+ HTMLFILE=$fname_prefix-$(date +"%Y%m%d-%H%M".html)
+ else
+ HTMLFILE=$HTMLFILE/$fname_prefix-$(date +"%Y%m%d-%H%M".html)
+ fi
+ html_out "\n"
+ html_out "\n"
+ html_out "\n"
+ html_out "\n"
+ html_out "
\n"
+ html_out "\n"
+ html_out "testssl.sh\n"
+ html_out "\n"
+ html_out "\n"
+ html_out "\n"
+ return 0
+}
+
+html_banner() {
+ if "$APPEND" && "$HTMLHEADER"; then
+ html_out "## Scan started as: \"$PROG_NAME $CMDLINE\"\n"
+ html_out "## at $HNAME:$OPENSSL_LOCATION\n"
+ html_out "## version testssl: $VERSION ${GIT_REL_SHORT:-$CVS_REL_SHORT} from $REL_DATE\n"
+ html_out "## version openssl: \"$OSSL_VER\" from \"$OSSL_BUILD_DATE\")\n\n"
+ fi
+}
+
+html_footer() {
+ if "$HTMLHEADER"; then
+ html_out "
\n"
+ html_out "\n"
+ html_out "\n"
+ fi
+ return 0
+}
+
+################# HTML FILE FORMATING END ####################
+
################### FILE FORMATING END #########################
-###### helper function definitions ######
+###### START helper function definitions ######
if [[ $(uname) == "Linux" ]] ; then
toupper() { echo -n "${1^^}" ; }
@@ -956,21 +1086,65 @@ trim_trailing_space() {
echo "${1%%*( )}"
}
+# retrieve cipher from ServerHello (via openssl)
+get_cipher() {
+ awk '/Cipher *:/ { print $3 }' "$1"
+ #awk '/\/ && !/Cipher is/ && !/^New/ { print $3 }' "$1"
+}
+
+# retrieve protocol from ServerHello (via openssl)
+get_protocol() {
+ awk '/Protocol *:/ { print $3 }' "$1"
+}
+
+is_number() {
+ [[ "$1" =~ ^[1-9][0-9]*$ ]] && \
+ return 0 || \
+ return 1
+}
+
+is_ipv4addr() {
+ local octet="(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])"
+ local ipv4address="$octet\\.$octet\\.$octet\\.$octet"
+
+ [[ -z "$1" ]] && return 1
+ # more than numbers, important for hosts like AAA.BBB.CCC.DDD.in-addr.arpa.DOMAIN.TLS
+ [[ -n $(tr -d '0-9\.' <<< "$1") ]] && return 1
+
+ grep -Eq "$ipv4address" <<< "$1" && \
+ return 0 || \
+ return 1
+}
+
+# a bit easier
+is_ipv6addr() {
+ [[ -z "$1" ]] && return 1
+ # less than 2x ":"
+ [[ $(count_lines "$(tr ':' '\n' <<< "$1")") -le 1 ]] && \
+ return 1
+ #check on chars allowed:
+ [[ -n "$(tr -d '0-9:a-fA-F ' <<< "$1" | sed -e '/^$/d')" ]] && \
+ return 1
+ return 0
+}
+
+
+###### END helper function definitions ######
+
# prints out multiple lines in $1, left aligned by spaces in $2
out_row_aligned() {
local first=true
- echo "$1" | while read line; do
+ while read line; do
"$first" && \
first=false || \
out "$2"
outln "$line"
- done
+ done <<< "$1"
}
# prints text over multiple lines, trying to make no line longer than $max_width.
-# Each line is indented with $spaces and each word in $text is printed using
-# $print_function.
+# Each line is indented with $spaces and each word in $text is printed using $print_function.
out_row_aligned_max_width() {
local text="$1"
local spaces="$2"
@@ -1027,37 +1201,6 @@ out_row_aligned_max_width() {
return 0
}
-is_number() {
- [[ "$1" =~ ^[1-9][0-9]*$ ]] && \
- return 0 || \
- return 1
-}
-
-is_ipv4addr() {
- local octet="(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])"
- local ipv4address="$octet\\.$octet\\.$octet\\.$octet"
-
- [[ -z "$1" ]] && return 1
- # more than numbers, important for hosts like AAA.BBB.CCC.DDD.in-addr.arpa.DOMAIN.TLS
- [[ -n $(tr -d '0-9\.' <<< "$1") ]] && return 1
-
- echo -n "$1" | grep -Eq "$ipv4address" && \
- return 0 || \
- return 1
-}
-
-# a bit easier
-is_ipv6addr() {
- [[ -z "$1" ]] && return 1
- # less than 2x ":"
- [[ $(count_lines "$(echo -n "$1" | tr ':' '\n')") -le 1 ]] && \
- return 1
- #check on chars allowed:
- [[ -n "$(tr -d '0-9:a-fA-F ' <<< "$1" | sed -e '/^$/d')" ]] && \
- return 1
- return 0
-}
-
tmpfile_handle() {
mv $TMPFILE "$TEMPDIR/$NODEIP.$1" 2>/dev/null
@@ -1067,7 +1210,7 @@ tmpfile_handle() {
# arg1: line with comment sign, tabs and so on
filter_input() {
- echo "$1" | sed -e 's/#.*$//' -e '/^$/d' | tr -d '\n' | tr -d '\t'
+ sed -e 's/#.*$//' -e '/^$/d' <<< "$1" | tr -d '\n' | tr -d '\t'
}
# dl's any URL (argv1) via HTTP 1.1 GET from port 80, arg2: file to store http body
@@ -1094,7 +1237,6 @@ http_get() {
# myfile=$(mktemp $TEMPDIR/http_get.XXXXXX.txt)
# http_get "http://crl.startssl.com/sca-server1.crl" "$myfile"
-
wait_kill(){
local pid=$1 # pid we wait for or kill
local maxsleep=$2 # how long we wait before killing
@@ -1174,7 +1316,7 @@ string_to_asciihex() {
output+="$(printf "%02x," "'${string:i:1}")"
done
[[ -n "$string" ]] && output+="$(printf "%02x" "'${string:eos:1}")"
- out "$output"
+ tm_out "$output"
return 0
}
@@ -1208,11 +1350,13 @@ service_detection() {
HTTP)
out " $SERVICE"
fileout "service" "INFO" "Service detected: $SERVICE"
- ret=0 ;;
+ ret=0
+ ;;
IMAP|POP|SMTP|NNTP)
out " $SERVICE, thus skipping HTTP specific checks"
fileout "service" "INFO" "Service detected: $SERVICE, thus skipping HTTP specific checks"
- ret=0 ;;
+ ret=0
+ ;;
*) if $CLIENT_AUTH; then
out "certificate based authentication => skipping all HTTP checks"
echo "certificate based authentication => skipping all HTTP checks" >$TMPFILE
@@ -1296,7 +1440,7 @@ run_http_header() {
case $HTTP_STATUS_CODE in
301|302|307|308)
redirect=$(grep -a '^Location' $HEADERFILE | sed 's/Location: //' | tr -d '\r\n')
- out ", redirecting to \"$redirect\""
+ out ", redirecting to \""; pr_url "$redirect"; out "\""
if [[ $redirect == "http://"* ]]; then
pr_svrty_high " -- Redirect to insecure URL (NOT ok)"
fileout "HTTP_STATUS_CODE" "HIGH" \, "Redirect to insecure URL. Url: \"$redirect\""
@@ -1323,7 +1467,7 @@ run_http_header() {
"Testing HTTP header response @ \"$URL_PATH\", $HTTP_STATUS_CODE$msg_thereafter (Hint: better try another URL)"
;;
401)
- grep -aq "^WWW-Authenticate" $HEADERFILE && out " "; strip_lf "$(grep -a "^WWW-Authenticate" $HEADERFILE)"
+ grep -aq "^WWW-Authenticate" $HEADERFILE && out " "; out "$(strip_lf "$(grep -a "^WWW-Authenticate" $HEADERFILE)")"
fileout "HTTP_STATUS_CODE" "INFO" \
"Testing HTTP header response @ \"$URL_PATH\", $HTTP_STATUS_CODE$msg_thereafter $(grep -a "^WWW-Authenticate" $HEADERFILE)"
;;
@@ -1414,7 +1558,7 @@ run_http_date() {
out "Got no HTTP time, maybe try different URL?";
fileout "http_clock_skew" "INFO" "HTTP clock skew not measured. Got no HTTP time, maybe try different URL?"
fi
- debugme out ", epoch: $HTTP_TIME"
+ debugme tm_out ", epoch: $HTTP_TIME"
fi
outln
detect_ipv4
@@ -1448,7 +1592,7 @@ detect_header() {
out "\n$spaces"
# first awk matches the key, second extracts the from the first line the value, be careful with quotes here!
HEADERVALUE=$(grep -Faiw "$key:" $HEADERFILE | sed 's/^.*://' | head -1)
- [[ $DEBUG -ge 2 ]] && pr_italic "$HEADERVALUE" && out "\n$spaces"
+ [[ $DEBUG -ge 2 ]] && tm_italic "$HEADERVALUE" && tm_out "\n$spaces"
fileout "$2""_multiple" "WARN" "Multiple $2 headers. Using first header: $HEADERVALUE"
return $nr
fi
@@ -1613,7 +1757,7 @@ run_hpkp() {
# Get the SPKIs first
spki=$(tr ';' '\n' < $TMPFILE | tr -d ' ' | tr -d '\"' | awk -F'=' '/pin.*=/ { print $2 }')
- debugme outln "\n$spki"
+ debugme tmln_out "\n$spki"
# Look at the host certificate first
# get the key fingerprint from the host certificate
@@ -1663,7 +1807,7 @@ run_hpkp() {
pr_done_good "$hpkp_spki"
fileout "hpkp_$hpkp_spki" "OK" "SPKI $hpkp_spki matches the host certificate"
fi
- debugme out "\n $hpkp_spki | $hpkp_spki_hostcert"
+ debugme tm_out "\n $hpkp_spki | $hpkp_spki_hostcert"
# Check for intermediate match
if ! "$certificate_found"; then
@@ -1729,7 +1873,7 @@ run_hpkp() {
if [[ -n "${backup_spki_str[0]}" ]]; then
pr_done_good "${backup_spki[0]}"
#out " Root CA: "
- pr_italicln " ${backup_spki_str[0]}"
+ tm_italic " ${backup_spki_str[0]}"
else
outln "${backup_spki[0]}"
fi
@@ -1739,26 +1883,26 @@ run_hpkp() {
# it's a Root CA outside the chain
pr_done_good "$spaces_indented ${backup_spki[i]}"
#out " Root CA: "
- pr_italicln " ${backup_spki_str[i]}"
+ tm_italic " ${backup_spki_str[i]}"
else
outln "$spaces_indented ${backup_spki[i]}"
fi
done
if [[ ! -f "$ca_hashes" ]] && "$spki_match"; then
out "$spaces "
- pr_warningln "Attribution of further hashes couldn't be done as $ca_hashes could not be found"
+ prln_warning "Attribution of further hashes couldn't be done as $ca_hashes could not be found"
fileout "hpkp_spkimatch" "WARN" "Attribution of further hashes couldn't be done as $ca_hashes could not be found"
fi
# If all else fails...
if ! "$spki_match"; then
"$has_backup_spki" && out "$spaces" # we had a few lines with backup SPKIs already
- pr_svrty_highln " No matching key for SPKI found "
+ prln_svrty_high " No matching key for SPKI found "
fileout "hpkp_spkimatch" "HIGH" "None of the SPKI match your host certificate, intermediate CA or known root CAs. You may have bricked this site"
fi
if ! "$has_backup_spki"; then
- pr_svrty_highln " No backup keys found. Loss/compromise of the currently pinned key(s) will lead to bricked site. "
+ prln_svrty_high " No backup keys found. Loss/compromise of the currently pinned key(s) will lead to bricked site. "
fileout "hpkp_backup" "HIGH" "No backup keys found. Loss/compromise of the currently pinned key(s) will lead to bricked site."
fi
else
@@ -1771,9 +1915,13 @@ run_hpkp() {
}
emphasize_stuff_in_headers(){
+ local html_brown=""
+ local html_yellow=""
+ local html_off="<\\/span>"
+
# see http://www.grymoire.com/Unix/Sed.html#uh-3
# outln "$1" | sed "s/[0-9]*/$brown&${off}/g"
- outln "$1" | sed -e "s/\([0-9]\)/${brown}\1${off}/g" \
+ tmln_out "$1" | sed -e "s/\([0-9]\)/${brown}\1${off}/g" \
-e "s/Debian/${yellow}\Debian${off}/g" \
-e "s/Win32/${yellow}\Win32${off}/g" \
-e "s/Win64/${yellow}\Win64${off}/g" \
@@ -1802,6 +1950,41 @@ emphasize_stuff_in_headers(){
-e "s/X-Powered-By/${yellow}X-Powered-By${off}/g" \
-e "s/X-UA-Compatible/${yellow}X-UA-Compatible${off}/g" \
-e "s/X-AspNet-Version/${yellow}X-AspNet-Version${off}/g"
+
+ if "$do_html"; then
+ html_out "$(tm_out "$1" | sed -e 's/\&/\&/g' \
+ -e 's/\</g' -e 's/>/\>/g' -e 's/"/\"/g' -e "s/'/\'/g" \
+ -e "s/\([0-9]\)/${html_brown}\1${html_off}/g" \
+ -e "s/Debian/${html_yellow}\Debian${html_off}/g" \
+ -e "s/Win32/${html_yellow}\Win32${html_off}/g" \
+ -e "s/Win64/${html_yellow}\Win64${html_off}/g" \
+ -e "s/Ubuntu/${html_yellow}Ubuntu${html_off}/g" \
+ -e "s/ubuntu/${html_yellow}ubuntu${html_off}/g" \
+ -e "s/jessie/${html_yellow}jessie${html_off}/g" \
+ -e "s/squeeze/${html_yellow}squeeze${html_off}/g" \
+ -e "s/wheezy/${html_yellow}wheezy${html_off}/g" \
+ -e "s/lenny/${html_yellow}lenny${html_off}/g" \
+ -e "s/SUSE/${html_yellow}SUSE${html_off}/g" \
+ -e "s/Red Hat Enterprise Linux/${html_yellow}Red Hat Enterprise Linux${html_off}/g" \
+ -e "s/Red Hat/${html_yellow}Red Hat${html_off}/g" \
+ -e "s/CentOS/${html_yellow}CentOS${html_off}/g" \
+ -e "s/Via/${html_yellow}Via${html_off}/g" \
+ -e "s/X-Forwarded/${html_yellow}X-Forwarded${html_off}/g" \
+ -e "s/Liferay-Portal/${html_yellow}Liferay-Portal${html_off}/g" \
+ -e "s/X-Cache-Lookup/${html_yellow}X-Cache-Lookup${html_off}/g" \
+ -e "s/X-Cache/${html_yellow}X-Cache${html_off}/g" \
+ -e "s/X-Squid/${html_yellow}X-Squid${html_off}/g" \
+ -e "s/X-Server/${html_yellow}X-Server${html_off}/g" \
+ -e "s/X-Varnish/${html_yellow}X-Varnish${html_off}/g" \
+ -e "s/X-OWA-Version/${html_yellow}X-OWA-Version${html_off}/g" \
+ -e "s/MicrosoftSharePointTeamServices/${html_yellow}MicrosoftSharePointTeamServices${html_off}/g" \
+ -e "s/X-Application-Context/${html_yellow}X-Application-Context${html_off}/g" \
+ -e "s/X-Version/${html_yellow}X-Version${html_off}/g" \
+ -e "s/X-Powered-By/${html_yellow}X-Powered-By${html_off}/g" \
+ -e "s/X-UA-Compatible/${html_yellow}X-UA-Compatible${html_off}/g" \
+ -e "s/X-AspNet-Version/${html_yellow}X-AspNet-Version${html_off}/g")"
+ html_out "\n"
+ fi
}
run_server_banner() {
@@ -1821,7 +2004,7 @@ 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.0.1 !"
+ prln_warning " 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.0.1. See https://github.com/PeterMosmans/openssl/issues/19#issuecomment-100897892"
fi
@@ -2009,7 +2192,7 @@ run_more_flags() {
#TODO: I am not testing for the correctness or anything stupid yet, e.g. "X-Frame-Options: allowall" or Access-Control-Allow-Origin: *
if "$first"; then
- pr_svrty_mediumln "--"
+ prln_svrty_medium "--"
fileout "sec_headers" "MEDIUM" "No security (or other interesting) headers detected"
ret=1
else
@@ -2024,15 +2207,15 @@ run_more_flags() {
# #1: string with 2 opensssl codes, output is same in NSS/ssllabs terminology
normalize_ciphercode() {
if [[ "${1:2:2}" == "00" ]]; then
- out "$(tolower "x${1:7:2}")"
+ tm_out "$(tolower "x${1:7:2}")"
else
- out "$(tolower "x${1:2:2}${1:7:2}${1:12:2}")"
+ tm_out "$(tolower "x${1:2:2}${1:7:2}${1:12:2}")"
fi
return 0
}
prettyprint_local() {
- local arg
+ local arg line
local hexc hexcode dash ciph sslvers kx auth enc mac export
local re='^[0-9A-Fa-f]+$'
@@ -2055,8 +2238,7 @@ prettyprint_local() {
if [[ -z "$1" ]]; then
$OPENSSL ciphers -V 'ALL:COMPLEMENTOFALL:@STRENGTH' 2>$ERRFILE | while read hexcode dash ciph sslvers kx auth enc mac export ; do # -V doesn't work with openssl < 1.0
hexc="$(normalize_ciphercode $hexcode)"
- neat_list "$hexc" "$ciph" "$kx" "$enc"
- outln
+ outln "$(neat_list "$hexc" "$ciph" "$kx" "$enc")"
done
else
#for arg in $(echo $@ | sed 's/,/ /g'); do
@@ -2065,8 +2247,9 @@ prettyprint_local() {
hexc="$(normalize_ciphercode $hexcode)"
# for numbers we don't do word matching:
[[ $arg =~ $re ]] && \
- neat_list "$hexc" "$ciph" "$kx" "$enc" | grep -ai "$arg" || \
- neat_list "$hexc" "$ciph" "$kx" "$enc" | grep -wai "$arg"
+ line="$(neat_list "$hexc" "$ciph" "$kx" "$enc" | grep -ai "$arg")" || \
+ line="$(neat_list "$hexc" "$ciph" "$kx" "$enc" | grep -wai "$arg")"
+ [[ -n "$line" ]] && outln "$line"
done
done
fi
@@ -2178,13 +2361,13 @@ std_cipherlists() {
;;
esac
tmpfile_handle $FUNCNAME.$debugname.txt
- [[ $DEBUG -ge 1 ]] && outln " -- $1" || outln #FIXME: should be in standard output at some time
+ [[ $DEBUG -ge 1 ]] && out " -- $1" || outln #FIXME: should be in standard output at some time
else
- singlespaces=$(echo "$2" | sed -e 's/ \+/ /g' -e 's/^ //' -e 's/ $//g' -e 's/ //g')
+ singlespaces=$(sed -e 's/ \+/ /g' -e 's/^ //' -e 's/ $//g' -e 's/ //g' <<< "$2")
if [[ "$OPTIMAL_PROTO" == "-ssl2" ]]; then
- local_problem_ln "No $singlespaces for SSLv2 configured in $OPENSSL"
+ prln_local_problem "No $singlespaces for SSLv2 configured in $OPENSSL"
else
- local_problem_ln "No $singlespaces configured in $OPENSSL"
+ prln_local_problem "No $singlespaces configured in $OPENSSL"
fi
fileout "std_$4" "WARN" "Cipher $2 ($1) not supported by local OpenSSL ($OPENSSL)"
fi
@@ -2217,7 +2400,7 @@ openssl2rfc() {
[[ "$1" == "${TLS_CIPHER_OSSL_NAME[i]}" ]] && rfcname="${TLS_CIPHER_RFC_NAME[i]}" && break
done
[[ "$rfcname" == "-" ]] && rfcname=""
- [[ -n "$rfcname" ]] && out "$rfcname"
+ [[ -n "$rfcname" ]] && tm_out "$rfcname"
return 0
}
@@ -2229,7 +2412,7 @@ rfc2openssl() {
[[ "$1" == "${TLS_CIPHER_RFC_NAME[i]}" ]] && ossl_name="${TLS_CIPHER_OSSL_NAME[i]}" && break
done
[[ "$ossl_name" == "-" ]] && ossl_name=""
- [[ -n "$ossl_name" ]] && out "$ossl_name"
+ [[ -n "$ossl_name" ]] && tm_out "$ossl_name"
return 0
}
@@ -2249,24 +2432,24 @@ show_rfc_style(){
[[ "$hexcode" == "${TLS_CIPHER_HEXCODE[i]}" ]] && rfcname="${TLS_CIPHER_RFC_NAME[i]}" && break
done
[[ "$rfcname" == "-" ]] && rfcname=""
- [[ -n "$rfcname" ]] && out "$rfcname"
+ [[ -n "$rfcname" ]] && tm_out "$rfcname"
return 0
}
neat_header(){
if [[ "$DISPLAY_CIPHERNAMES" =~ rfc ]]; then
- printf -- "Hexcode Cipher Suite Name (RFC) KeyExch. Encryption Bits"
- [[ "$DISPLAY_CIPHERNAMES" != "rfc-only" ]] && printf -- " Cipher Suite Name (OpenSSL)"
+ out "$(printf -- "Hexcode Cipher Suite Name (RFC) KeyExch. Encryption Bits")"
+ [[ "$DISPLAY_CIPHERNAMES" != "rfc-only" ]] && out "$(printf -- " Cipher Suite Name (OpenSSL)")"
outln
- printf -- "%s------------------------------------------------------------------------------------------"
- [[ "$DISPLAY_CIPHERNAMES" != "rfc-only" ]] && printf -- "---------------------------------------"
+ out "$(printf -- "%s------------------------------------------------------------------------------------------")"
+ [[ "$DISPLAY_CIPHERNAMES" != "rfc-only" ]] && out "$(printf -- "---------------------------------------")"
outln
else
- printf -- "Hexcode Cipher Suite Name (OpenSSL) KeyExch. Encryption Bits"
- [[ "$DISPLAY_CIPHERNAMES" != "openssl-only" ]] && printf -- " Cipher Suite Name (RFC)"
+ out "$(printf -- "Hexcode Cipher Suite Name (OpenSSL) KeyExch. Encryption Bits")"
+ [[ "$DISPLAY_CIPHERNAMES" != "openssl-only" ]] && out "$(printf -- " Cipher Suite Name (RFC)")"
outln
- printf -- "%s--------------------------------------------------------------------------"
- [[ "$DISPLAY_CIPHERNAMES" != "openssl-only" ]] && printf -- "---------------------------------------------------"
+ out "$(printf -- "%s--------------------------------------------------------------------------")"
+ [[ "$DISPLAY_CIPHERNAMES" != "openssl-only" ]] && out "$(printf -- "---------------------------------------------------")"
outln
fi
}
@@ -2278,11 +2461,12 @@ neat_header(){
# arg4: encryption (maybe included "export")
# arg5: "true" if the cipher's "quality" should be highlighted
# "false" if the line should be printed in light grey
-# empty if line should be printed in black
+# empty if line should be returned as a string
neat_list(){
local hexcode="$1"
local ossl_cipher="$2" tls_cipher=""
- local kx enc strength line
+ local kx enc strength line what_dh bits
+ local -i i len
kx="${3//Kx=/}"
enc="${4//Enc=/}"
@@ -2297,7 +2481,7 @@ neat_list(){
[[ "$DISPLAY_CIPHERNAMES" != "openssl-only" ]] && tls_cipher="$(show_rfc_style "$hexcode")"
- if [[ "$5" == "false" ]]; then
+ if [[ "$5" != "true" ]]; then
if [[ "$DISPLAY_CIPHERNAMES" =~ rfc ]]; then
line="$(printf -- " %-7s %-49s %-10s %-12s%-8s" "$hexcode" "$tls_cipher" "$kx" "$enc" "$strength")"
[[ "$DISPLAY_CIPHERNAMES" != "rfc-only" ]] && line+="$(printf -- " %-33s${SHOW_EACH_C:+ %-0s}" "$ossl_cipher")"
@@ -2305,28 +2489,36 @@ neat_list(){
line="$(printf -- " %-7s %-33s %-10s %-12s%-8s" "$hexcode" "$ossl_cipher" "$kx" "$enc" "$strength")"
[[ "$DISPLAY_CIPHERNAMES" != "openssl-only" ]] && line+="$(printf -- " %-49s${SHOW_EACH_C:+ %-0s}" "$tls_cipher")"
fi
- pr_deemphasize "$line"
+ if [[ -z "$5" ]]; then
+ tm_out "$line"
+ else
+ pr_deemphasize "$line"
+ fi
return 0
fi
-
- #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 printf below
- while [[ ${#kx} -lt 20 ]]; do
- kx="$kx "
- done
- elif printf -- "%q" "$kx" | grep -aq 'E\[m' ; then # for color=1/0 we have the pr_off which screws up the formatting
- while [[ ${#kx} -lt 13 ]]; do # so it'll be filled up ok
- kx="$kx "
- done
- fi
- #echo "${#kx}" # should be always 20 / 13
+ read what_dh bits <<< "$kx"
+ len=${#kx}
if [[ "$DISPLAY_CIPHERNAMES" =~ rfc ]]; then
- printf -- " %-7s %-49s %-10s %-12s%-8s" "$hexcode" "$tls_cipher" "$kx" "$enc" "$strength"
- [[ "$DISPLAY_CIPHERNAMES" != "rfc-only" ]] && printf -- " %-33s${SHOW_EACH_C:+ %-0s}" "$ossl_cipher"
+ out "$(printf -- " %-7s %-49s " "$hexcode" "$tls_cipher")"
else
- printf -- " %-7s %-33s %-10s %-12s%-8s" "$hexcode" "$ossl_cipher" "$kx" "$enc" "$strength"
- [[ "$DISPLAY_CIPHERNAMES" != "openssl-only" ]] && printf -- " %-49s${SHOW_EACH_C:+ %-0s}" "$tls_cipher"
+ out "$(printf -- " %-7s %-33s " "$hexcode" "$ossl_cipher")"
+ fi
+ out "$what_dh"
+ if [[ -n "$bits" ]]; then
+ if [[ $what_dh == "DH" ]] || [[ $what_dh == "EDH" ]]; then
+ pr_dh_quality "$bits" " $bits"
+ elif [[ $what_dh == "ECDH" ]]; then
+ pr_ecdh_quality "$bits" " $bits"
+ fi
+ fi
+ for (( i=len; i<10; i++ )); do
+ out " "
+ done
+ out "$(printf -- " %-12s%-8s" "$enc" "$strength")"
+ if [[ "$DISPLAY_CIPHERNAMES" == rfc ]]; then
+ out "$(printf -- " %-33s${SHOW_EACH_C:+ %-0s}" "$ossl_cipher")"
+ elif [[ "$DISPLAY_CIPHERNAMES" == openssl ]]; then
+ out "$(printf -- " %-49s${SHOW_EACH_C:+ %-0s}" "$tls_cipher")"
fi
}
@@ -2359,7 +2551,7 @@ test_just_one(){
[[ $TLS_NR_CIPHERS == 0 ]] && ! "$SSL_NATIVE" && ! "$FAST" && pr_warning " Cipher mapping not available, doing a fallback to openssl"
if ! "$HAS_DH_BITS"; then
[[ $TLS_NR_CIPHERS == 0 ]] && ! "$SSL_NATIVE" && ! "$FAST" && out "."
- pr_warningln " (Your $OPENSSL cannot show DH/ECDH bits)"
+ prln_warning " (Your $OPENSSL cannot show DH/ECDH bits)"
fi
fi
outln
@@ -2701,7 +2893,7 @@ run_allciphers() {
outln
if ! "$HAS_DH_BITS"; then
[[ $TLS_NR_CIPHERS == 0 ]] && ! "$SSL_NATIVE" && ! "$FAST" && out "."
- pr_warningln " Your $OPENSSL cannot show DH/ECDH bits"
+ prln_warning " Your $OPENSSL cannot show DH/ECDH bits"
fi
fi
outln
@@ -2878,12 +3070,12 @@ run_cipher_per_proto() {
outln
if ! "$HAS_DH_BITS"; then
[[ $TLS_NR_CIPHERS == 0 ]] && ! "$SSL_NATIVE" && ! "$FAST" && out "."
- pr_warningln " (Your $OPENSSL cannot show DH/ECDH bits)"
+ prln_warning " (Your $OPENSSL cannot show DH/ECDH bits)"
fi
fi
outln
neat_header
- outln " -ssl2 22 SSLv2\n -ssl3 00 SSLv3\n -tls1 01 TLS 1\n -tls1_1 02 TLS 1.1\n -tls1_2 03 TLS 1.2"| while read proto proto_hex proto_text; do
+ tm_out " -ssl2 22 SSLv2\n -ssl3 00 SSLv3\n -tls1 01 TLS 1\n -tls1_1 02 TLS 1.1\n -tls1_2 03 TLS 1.2\n" | while read proto proto_hex proto_text; do
"$using_sockets" || locally_supported "$proto" "$proto_text" || continue
"$using_sockets" && out "$proto_text "
outln
@@ -3182,7 +3374,7 @@ create_client_simulation_tls_clienthello() {
if [[ $offset -ge $tls_handshake_ascii_len ]]; then
# No extensions
- out "$tls_handshake_ascii"
+ tm_out "$tls_handshake_ascii"
return 0
fi
@@ -3215,7 +3407,7 @@ create_client_simulation_tls_clienthello() {
done
if ! $sni_extension_found; then
- out "$tls_handshake_ascii"
+ tm_out "$tls_handshake_ascii"
return 0
fi
@@ -3234,7 +3426,7 @@ create_client_simulation_tls_clienthello() {
tls_handshake_ascii_len_hex=$(printf "%02x\n" $tls_handshake_ascii_len)
len2twobytes "$tls_handshake_ascii_len_hex"
tls_handshake_ascii="${tls_content_type}${tls_version_reclayer}${LEN_STR:0:2}${LEN_STR:4:2}${tls_handshake_ascii}"
- out "$tls_handshake_ascii"
+ tm_out "$tls_handshake_ascii"
return 0
}
@@ -3303,7 +3495,7 @@ client_simulation_sockets() {
fi
done
- debugme outln "reading server hello..."
+ debugme tmln_out "reading server hello..."
if [[ "$DEBUG" -ge 4 ]]; then
hexdump -C $SOCK_REPLY_FILE | head -6
echo
@@ -3323,7 +3515,7 @@ client_simulation_sockets() {
# see https://secure.wand.net.nz/trac/libprotoident/wiki/SSL
lines=$(count_lines "$(hexdump -C "$SOCK_REPLY_FILE" 2>$ERRFILE)")
- debugme out " (returned $lines lines) "
+ debugme tm_out " (returned $lines lines) "
# determine the return value for higher level, so that they can tell what the result is
if [[ $save -eq 1 ]] || [[ $lines -eq 1 ]]; then
@@ -3331,7 +3523,7 @@ client_simulation_sockets() {
else
ret=0
fi
- debugme outln
+ debugme tmln_out
close_socket
TMPFILE=$SOCK_REPLY_FILE
@@ -3363,6 +3555,14 @@ run_client_simulation() {
local name tls proto cipher temp what_dh bits has_dh_bits
local using_sockets=true
+ # source the external file
+ . $TESTSSL_INSTALL_DIR/etc/client_simulation.txt 2>/dev/null
+ if [[ $? -ne 0 ]]; then
+ prln_local_problem "couldn't find client simulation data in $TESTSSL_INSTALL_DIR/etc/client_simulation.txt"
+ return 1
+ fi
+
+ #FIXME, see client_simulation branch which has to be merged
if "$SSL_NATIVE" || [[ -n "$STARTTLS" ]]; then
using_sockets=false
fi
@@ -3372,754 +3572,15 @@ run_client_simulation() {
return 0
fi
- # FIXME: At a certain time we should put the following to an external file
- names+=("Android 2.3.7 ")
- short+=("android_237")
- protos+=("-no_tls1_2 -no_tls1_1 -no_ssl2")
- ciphers+=("RC4-MD5:RC4-SHA:AES128-SHA:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA:DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:EDH-DSS-DES-CBC3-SHA:DES-CBC-SHA:EDH-RSA-DES-CBC-SHA:EDH-DSS-DES-CBC-SHA:EXP-RC4-MD5:EXP-DES-CBC-SHA:EXP-EDH-RSA-DES-CBC-SHA:EXP-EDH-DSS-DES-CBC-SHA")
- tlsvers+=("-tls1")
- sni+=("")
- warning+=("")
- handshakebytes+=("160301004b010000470301531f3de6b36804738bbb94a6ecd570a544789c3bb0a6ef8b9d702f997d928d4b00002000040005002f00330032000a00160013000900150012000300080014001100ff0100")
- lowest_protocol+=("0x0300")
- highest_protocol+=("0x0301")
- service+=("HTTP")
- minDhBits+=(-1)
- maxDhBits+=(-1)
- minRsaBits+=(-1)
- maxRsaBits+=(-1)
- minEcdsaBits+=(-1)
- requiresSha2+=(false)
-
- names+=("Android 4.0.4 ")
- short+=("android_404")
- protos+=("-no_tls1_2 -no_tls1_1 -no_ssl2")
- ciphers+=("ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES256-SHA:DHE-DSS-AES256-SHA:ECDH-RSA-AES256-SHA:ECDH-ECDSA-AES256-SHA:AES256-SHA:ECDHE-RSA-DES-CBC3-SHA:ECDHE-ECDSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:EDH-DSS-DES-CBC3-SHA:ECDH-RSA-DES-CBC3-SHA:ECDH-ECDSA-DES-CBC3-SHA:DES-CBC3-SHA:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA:ECDH-RSA-AES128-SHA:ECDH-ECDSA-AES128-SHA:AES128-SHA:ECDHE-RSA-RC4-SHA:ECDHE-ECDSA-RC4-SHA:ECDH-RSA-RC4-SHA:ECDH-ECDSA-RC4-SHA:RC4-SHA:RC4-MD5")
- tlsvers+=("-tls1")
- sni+=("$SNI")
- warning+=("")
- handshakebytes+=("16030100c6010000c20301531f479cc7785f455ca7a70142af5be929c1ba931eedbf46dba6b6638da75e95000038c014c00a00390038c00fc0050035c012c00800160013c00dc003000ac013c00900330032c00ec004002fc011c007c00cc0020005000400ff020100006000000014001200000f7777772e73736c6c6162732e636f6d000b000403000102000a00340032000100020003000400050006000700080009000a000b000c000d000e000f00100011001200130014001500160017001800190023000033740000")
- lowest_protocol+=("0x0300")
- highest_protocol+=("0x0301")
- service+=("HTTP")
- minDhBits+=(-1)
- maxDhBits+=(-1)
- minRsaBits+=(-1)
- maxRsaBits+=(-1)
- minEcdsaBits+=(-1)
- requiresSha2+=(false)
-
- names+=("Android 4.1.1 ")
- short+=("android_411")
- protos+=("-no_tls1_2 -no_tls1_1 -no_ssl2")
- ciphers+=("ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:SRP-DSS-AES-256-CBC-SHA:SRP-RSA-AES-256-CBC-SHA:DHE-RSA-AES256-SHA:DHE-DSS-AES256-SHA:ECDH-RSA-AES256-SHA:ECDH-ECDSA-AES256-SHA:AES256-SHA:ECDHE-RSA-DES-CBC3-SHA:ECDHE-ECDSA-DES-CBC3-SHA:SRP-DSS-3DES-EDE-CBC-SHA:SRP-RSA-3DES-EDE-CBC-SHA:EDH-RSA-DES-CBC3-SHA:EDH-DSS-DES-CBC3-SHA:ECDH-RSA-DES-CBC3-SHA:ECDH-ECDSA-DES-CBC3-SHA:DES-CBC3-SHA:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:SRP-DSS-AES-128-CBC-SHA:SRP-RSA-AES-128-CBC-SHA:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA:ECDH-RSA-AES128-SHA:ECDH-ECDSA-AES128-SHA:AES128-SHA:ECDHE-RSA-RC4-SHA:ECDHE-ECDSA-RC4-SHA:ECDH-RSA-RC4-SHA:ECDH-ECDSA-RC4-SHA:RC4-SHA:RC4-MD5")
- tlsvers+=("-tls1")
- sni+=("$SNI")
- warning+=("")
- handshakebytes+=("16030100d7010000d30301531f3f6dd9eb5f6b3586c628cc2cdc82cdb259b1a096237ba4df30dbbc0f26fb000044c014c00ac022c02100390038c00fc0050035c012c008c01cc01b00160013c00dc003000ac013c009c01fc01e00330032c00ec004002fc011c007c00cc0020005000400ff020100006500000014001200000f7777772e73736c6c6162732e636f6d000b000403000102000a00340032000e000d0019000b000c00180009000a00160017000800060007001400150004000500120013000100020003000f0010001100230000000f00010133740000")
- lowest_protocol+=("0x0300")
- highest_protocol+=("0x0301")
- service+=("HTTP")
- minDhBits+=(-1)
- maxDhBits+=(-1)
- minRsaBits+=(-1)
- maxRsaBits+=(-1)
- minEcdsaBits+=(-1)
- requiresSha2+=(false)
-
- names+=("Android 4.2.2 ")
- short+=("android_422")
- protos+=("-no_tls1_2 -no_tls1_1 -no_ssl2")
- ciphers+=("ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:SRP-DSS-AES-256-CBC-SHA:SRP-RSA-AES-256-CBC-SHA:DHE-RSA-AES256-SHA:DHE-DSS-AES256-SHA:ECDH-RSA-AES256-SHA:ECDH-ECDSA-AES256-SHA:AES256-SHA:ECDHE-RSA-DES-CBC3-SHA:ECDHE-ECDSA-DES-CBC3-SHA:SRP-DSS-3DES-EDE-CBC-SHA:SRP-RSA-3DES-EDE-CBC-SHA:EDH-RSA-DES-CBC3-SHA:EDH-DSS-DES-CBC3-SHA:ECDH-RSA-DES-CBC3-SHA:ECDH-ECDSA-DES-CBC3-SHA:DES-CBC3-SHA:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:SRP-DSS-AES-128-CBC-SHA:SRP-RSA-AES-128-CBC-SHA:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA:ECDH-RSA-AES128-SHA:ECDH-ECDSA-AES128-SHA:AES128-SHA:ECDHE-RSA-RC4-SHA:ECDHE-ECDSA-RC4-SHA:ECDH-RSA-RC4-SHA:ECDH-ECDSA-RC4-SHA:RC4-SHA:RC4-MD5")
- tlsvers+=("-tls1")
- sni+=("$SNI")
- warning+=("")
- handshakebytes+=("16030100d1010000cd0301531f40a89e11d5681f563f3dad094375227035d4e9d2c1654d7d3954e3254558000044c014c00ac022c02100390038c00fc0050035c012c008c01cc01b00160013c00dc003000ac013c009c01fc01e00330032c00ec004002fc011c007c00cc0020005000400ff0100006000000014001200000f7777772e73736c6c6162732e636f6d000b000403000102000a00340032000e000d0019000b000c00180009000a00160017000800060007001400150004000500120013000100020003000f001000110023000033740000")
- lowest_protocol+=("0x0300")
- highest_protocol+=("0x0301")
- minDhBits+=(-1)
- maxDhBits+=(-1)
- minRsaBits+=(-1)
- maxRsaBits+=(-1)
- minEcdsaBits+=(-1)
- requiresSha2+=(false)
-
- names+=("Android 4.3 ")
- short+=("android_43")
- protos+=("-no_tls1_2 -no_tls1_1 -no_ssl2")
- ciphers+=("ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:SRP-DSS-AES-256-CBC-SHA:SRP-RSA-AES-256-CBC-SHA:DHE-RSA-AES256-SHA:DHE-DSS-AES256-SHA:ECDH-RSA-AES256-SHA:ECDH-ECDSA-AES256-SHA:AES256-SHA:ECDHE-RSA-DES-CBC3-SHA:ECDHE-ECDSA-DES-CBC3-SHA:SRP-DSS-3DES-EDE-CBC-SHA:SRP-RSA-3DES-EDE-CBC-SHA:EDH-RSA-DES-CBC3-SHA:EDH-DSS-DES-CBC3-SHA:ECDH-RSA-DES-CBC3-SHA:ECDH-ECDSA-DES-CBC3-SHA:DES-CBC3-SHA:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:SRP-DSS-AES-128-CBC-SHA:SRP-RSA-AES-128-CBC-SHA:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA:ECDH-RSA-AES128-SHA:ECDH-ECDSA-AES128-SHA:AES128-SHA:ECDHE-RSA-RC4-SHA:ECDHE-ECDSA-RC4-SHA:ECDH-RSA-RC4-SHA:ECDH-ECDSA-RC4-SHA:RC4-SHA:RC4-MD5")
- tlsvers+=("-tls1")
- sni+=("$SNI")
- warning+=("")
- handshakebytes+=("16030100d1010000cd0301531f41c3c5110dd688458e5e48e06d30814572ad7b8f9d9df1b0a8820b270685000044c014c00ac022c02100390038c00fc0050035c012c008c01cc01b00160013c00dc003000ac013c009c01fc01e00330032c00ec004002fc011c007c00cc0020005000400ff0100006000000014001200000f7777772e73736c6c6162732e636f6d000b000403000102000a00340032000e000d0019000b000c00180009000a00160017000800060007001400150004000500120013000100020003000f001000110023000033740000")
- lowest_protocol+=("0x0300")
- highest_protocol+=("0x0301")
- service+=("HTTP")
- minDhBits+=(-1)
- maxDhBits+=(-1)
- minRsaBits+=(-1)
- maxRsaBits+=(-1)
- minEcdsaBits+=(-1)
- requiresSha2+=(false)
-
- names+=("Android 4.4.2 ")
- short+=("android_442")
- protos+=("-no_ssl2")
- ciphers+=("ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-DSS-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA256:DHE-RSA-AES256-SHA:DHE-DSS-AES256-SHA:AES256-GCM-SHA384:AES256-SHA256:AES256-SHA:ECDHE-RSA-DES-CBC3-SHA:ECDHE-ECDSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:EDH-DSS-DES-CBC3-SHA:DES-CBC3-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:DHE-DSS-AES128-GCM-SHA256:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES128-SHA256:DHE-DSS-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA:AES128-GCM-SHA256:AES128-SHA256:AES128-SHA:ECDHE-RSA-RC4-SHA:ECDHE-ECDSA-RC4-SHA:RC4-SHA:RC4-MD5")
- tlsvers+=("-tls1_2 -tls1_1 -tls1")
- sni+=("$SNI")
- warning+=("")
- handshakebytes+=("16030100d1010000cd0303531f4317998fb70d57feded18c14433a1b665f963f7e3b1b045b6cc3d61bf21300004cc030c02cc014c00a00a3009f006b006a00390038009d003d0035c012c00800160013000ac02fc02bc027c023c013c00900a2009e0067004000330032009c003c002fc011c0070005000400ff0100005800000014001200000f7777772e73736c6c6162732e636f6d000b00020100000a0008000600190018001700230000000d00220020060106020603050105020503040104020403030103020303020102020203010133740000")
- lowest_protocol+=("0x0300")
- highest_protocol+=("0x0303")
- service+=("HTTP")
- minDhBits+=(-1)
- maxDhBits+=(-1)
- minRsaBits+=(-1)
- maxRsaBits+=(-1)
- minEcdsaBits+=(-1)
- requiresSha2+=(false)
-
- names+=("Android 5.0.0 ")
- short+=("android_500")
- protos+=("-no_ssl2")
- ciphers+=("ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-CHACHA20-POLY1305:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES256-SHA:DHE-DSS-AES256-SHA:AES256-SHA:ECDHE-RSA-DES-CBC3-SHA:ECDHE-ECDSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:EDH-DSS-DES-CBC3-SHA:DES-CBC3-SHA:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:DHE-DSS-AES128-GCM-SHA256:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA:AES128-GCM-SHA256:AES128-SHA:ECDHE-RSA-RC4-SHA:ECDHE-ECDSA-RC4-SHA:RC4-SHA:RC4-MD5")
- tlsvers+=("-tls1_2 -tls1_1 -tls1")
- sni+=("$SNI")
- warning+=("")
- handshakebytes+=("16030100bd010000b9030354c21737f3d9d10696c91debf12415f9c45833a83cfbbd4c60c9b91407d2316b000038cc14cc13cc15c014c00a003900380035c012c00800160013000ac02fc02bc013c00900a2009e00330032009c002fc011c0070005000400ff0100005800000014001200000f6465762e73736c6c6162732e636f6d00230000000d00220020060106020603050105020503040104020403030103020303020102020203010133740000000b00020100000a00080006001900180017")
- lowest_protocol+=("0x0300")
- highest_protocol+=("0x0303")
- service+=("HTTP")
- minDhBits+=(-1)
- maxDhBits+=(-1)
- minRsaBits+=(-1)
- maxRsaBits+=(-1)
- minEcdsaBits+=(-1)
- requiresSha2+=(false)
-
- names+=("Baidu Jan 2015 ")
- short+=("baidu_jan_2015")
- protos+=("-no_tls1_2 -no_tls1_1 -no_ssl2")
- ciphers+=("ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-CAMELLIA256-SHA:DHE-DSS-CAMELLIA256-SHA:DHE-RSA-AES256-SHA:DHE-DSS-AES256-SHA:ECDH-RSA-AES256-SHA:ECDH-ECDSA-AES256-SHA:CAMELLIA256-SHA:AES256-SHA:ECDHE-ECDSA-RC4-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-RC4-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-CAMELLIA128-SHA:DHE-DSS-CAMELLIA128-SHA:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA:ECDH-RSA-RC4-SHA:ECDH-RSA-AES128-SHA:ECDH-ECDSA-RC4-SHA:ECDH-ECDSA-AES128-SHA:SEED-SHA:CAMELLIA128-SHA:RC4-MD5:RC4-SHA:AES128-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:EDH-DSS-DES-CBC3-SHA:ECDH-RSA-DES-CBC3-SHA:ECDH-ECDSA-DES-CBC3-SHA:DES-CBC3-SHA")
- tlsvers+=("-tls1")
- sni+=("$SNI")
- warning+=("")
- handshakebytes+=("16030100a30100009f030154c1a814c755540538a93b25e7824623d0ee9fc294ee752869cf76819edb3aa200004800ffc00ac0140088008700390038c00fc00500840035c007c009c011c0130045004400330032c00cc00ec002c0040096004100040005002fc008c01200160013c00dc003feff000a0100002e00000014001200000f6465762e73736c6c6162732e636f6d000a00080006001700180019000b0002010000230000")
- lowest_protocol+=("0x0300")
- highest_protocol+=("0x0301")
- service+=("HTTP")
- minDhBits+=(-1)
- maxDhBits+=(-1)
- minRsaBits+=(-1)
- maxRsaBits+=(-1)
- minEcdsaBits+=(-1)
- requiresSha2+=(false)
-
- names+=("BingPreview Jan 2015 ")
- short+=("bingpreview_jan_2015")
- protos+=("-no_ssl2")
- 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:SRP-DSS-AES-256-CBC-SHA:SRP-RSA-AES-256-CBC-SHA:DHE-DSS-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA256:DHE-RSA-AES256-SHA:DHE-DSS-AES256-SHA:DHE-RSA-CAMELLIA256-SHA:DHE-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-DES-CBC3-SHA:ECDHE-ECDSA-DES-CBC3-SHA:SRP-DSS-3DES-EDE-CBC-SHA:SRP-RSA-3DES-EDE-CBC-SHA:EDH-RSA-DES-CBC3-SHA:EDH-DSS-DES-CBC3-SHA:ECDH-RSA-DES-CBC3-SHA:ECDH-ECDSA-DES-CBC3-SHA:DES-CBC3-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:SRP-DSS-AES-128-CBC-SHA:SRP-RSA-AES-128-CBC-SHA:DHE-DSS-AES128-GCM-SHA256:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES128-SHA256:DHE-DSS-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA:DHE-RSA-SEED-SHA:DHE-DSS-SEED-SHA:DHE-RSA-CAMELLIA128-SHA:DHE-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:EDH-RSA-DES-CBC-SHA:EDH-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+=("")
- handshakebytes+=("16030101510100014d030354c13b79c1ca7169ae70c45d43311f9290d8ac1e326dfc36ff0aa99ea85406d50000a0c030c02cc028c024c014c00ac022c02100a3009f006b006a0039003800880087c032c02ec02ac026c00fc005009d003d00350084c012c008c01cc01b00160013c00dc003000ac02fc02bc027c023c013c009c01fc01e00a2009e0067004000330032009a009900450044c031c02dc029c025c00ec004009c003c002f009600410007c011c007c00cc002000500040015001200090014001100080006000300ff020100008300000014001200000f6465762e73736c6c6162732e636f6d000b000403000102000a00340032000e000d0019000b000c00180009000a00160017000800060007001400150004000500120013000100020003000f00100011000d002200200601060206030501050205030401040204030301030203030201020202030101000f000101")
- lowest_protocol+=("0x0300")
- highest_protocol+=("0x0303")
- service+=("HTTP")
- minDhBits+=(-1)
- maxDhBits+=(-1)
- minRsaBits+=(-1)
- maxRsaBits+=(-1)
- minEcdsaBits+=(-1)
- requiresSha2+=(false)
-
- names+=("Chrome 47 / OSX ")
- short+=("chrome_47_osx")
- protos+=("-no_ssl2 -no_ssl3")
- ciphers+=("ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES256-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES128-SHA:AES128-GCM-SHA256:AES256-SHA:AES128-SHA:DES-CBC3-SHA")
- tlsvers+=("-tls1_2 -tls1_1 -tls1")
- sni+=("$SNI")
- warning+=("")
- handshakebytes+=("16030100ca010000c6030361f8858af23cda649baf596105ec66bfe5b4642046c486e3e5321b26588392f400001ec02bc02f009ecc14cc13c00ac0140039c009c0130033009c0035002f000a0100007fff0100010000000014001200000f6465762e73736c6c6162732e636f6d0017000000230000000d001600140601060305010503040104030301030302010203000500050100000000337400000012000000100017001508687474702f312e3108737064792f332e3102683275500000000b00020100000a0006000400170018")
- lowest_protocol+=("0x0301")
- highest_protocol+=("0x0303")
- service+=("HTTP")
- minDhBits+=(1024)
- maxDhBits+=(-1)
- minRsaBits+=(-1)
- maxRsaBits+=(8192)
- minEcdsaBits+=(-1)
- requiresSha2+=(false)
-
- names+=("Firefox 31.3.0ESR / Win7 ")
- short+=("firefox_3130esr_win7")
- protos+=("-no_ssl2 -no_ssl3")
- ciphers+=("ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:ECDHE-RSA-AES256-SHA:ECDHE-RSA-DES-CBC3-SHA:ECDHE-ECDSA-RC4-SHA:ECDHE-RSA-RC4-SHA:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA:DHE-RSA-CAMELLIA128-SHA:DHE-RSA-AES256-SHA:DHE-DSS-AES256-SHA:DHE-RSA-CAMELLIA256-SHA:EDH-RSA-DES-CBC3-SHA:AES128-SHA:CAMELLIA128-SHA:AES256-SHA:CAMELLIA256-SHA:DES-CBC3-SHA:RC4-SHA:RC4-MD5")
- tlsvers+=("-tls1_2 -tls1_1 -tls1")
- sni+=("$SNI")
- warning+=("")
- handshakebytes+=("16030100b1010000ad030357ce74b9799a67f62ffd7f53fde81675039c3597b2b17f9e18dbbbd418dd68f600002ec02bc02fc00ac009c013c014c012c007c0110033003200450039003800880016002f004100350084000a000500040100005600000014001200000f6465762e73736c6c6162732e636f6dff01000100000a00080006001700180019000b000201000023000033740000000500050100000000000d0012001004010501020104030503020304020202")
- lowest_protocol+=("0x0301")
- highest_protocol+=("0x0303")
- service+=("HTTP")
- minDhBits+=(-1)
- maxDhBits+=(-1)
- minRsaBits+=(-1)
- maxRsaBits+=(-1)
- minEcdsaBits+=(-1)
- requiresSha2+=(false)
-
- names+=("Firefox 42 OS X ")
- short+=("firefox_42_osx")
- protos+=("-no_ssl2 -no_ssl3")
- ciphers+=("ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA:AES128-SHA:AES256-SHA:DES-CBC3-SHA")
- tlsvers+=("-tls1_2 -tls1_1 -tls1")
- sni+=("$SNI")
- warning+=("")
- handshakebytes+=("16030100b8010000b403038abe51f10e414011c88d4807c3cf465ae02ba1ef74dd1d59a0b8f04c4f13c969000016c02bc02fc00ac009c013c01400330039002f0035000a0100007500000014001200000f6465762e73736c6c6162732e636f6dff01000100000a00080006001700180019000b00020100002300003374000000100017001502683208737064792f332e3108687474702f312e31000500050100000000000d001600140401050106010201040305030603020304020202")
- lowest_protocol+=("0x0301")
- highest_protocol+=("0x0303")
- service+=("HTTP")
- minDhBits+=(1023)
- maxDhBits+=(-1)
- minRsaBits+=(-1)
- maxRsaBits+=(-1)
- minEcdsaBits+=(-1)
- requiresSha2+=(false)
-
- names+=("GoogleBot Feb 2015 ")
- short+=("googlebot_feb_2015")
- protos+=("-no_ssl2")
- ciphers+=("ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-RC4-SHA:ECDHE-RSA-RC4-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:AES128-GCM-SHA256:RC4-SHA:RC4-MD5:AES128-SHA:DES-CBC3-SHA:AES256-SHA:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA:EDH-RSA-DES-CBC3-SHA:EDH-DSS-DES-CBC3-SHA:DHE-RSA-AES256-SHA:DHE-DSS-AES256-SHA")
- tlsvers+=("-tls1_2 -tls1_1 -tls1")
- sni+=("$SNI")
- warning+=("")
- handshakebytes+=("16030100db010000d70303d9c72e000f6a7f0a156840bd4aa9fd0612df4aeb69a1a1c6452c5f1f4d0ba6b000002ac02bc02fc007c011c009c013c00ac014009c00050004002f000a003500330032001600130039003800ff0100008400000014001200000f6465762e73736c6c6162732e636f6d00230000000d0020001e06010602060305010502050304010402040303010302030302010202020333740000000b000403000102000a00340032000e000d0019000b000c00180009000a00160017000800060007001400150004000500120013000100020003000f00100011")
- lowest_protocol+=("0x0300")
- highest_protocol+=("0x0303")
- service+=("HTTP")
- minDhBits+=(-1)
- maxDhBits+=(-1)
- minRsaBits+=(-1)
- maxRsaBits+=(-1)
- minEcdsaBits+=(-1)
- requiresSha2+=(false)
-
- names+=("IE 6 XP ")
- short+=("ie_6_xp")
- protos+=("-no_tls1_2 -no_tls1_1 -no_tls1")
- tlsvers+=("")
- ciphers+=("RC4-MD5:RC4-SHA:DES-CBC3-SHA:RC4-MD5:DES-CBC3-MD5:RC2-CBC-MD5:DES-CBC-SHA:DES-CBC-MD5:EXP1024-RC4-SHA:EXP1024-DES-CBC-SHA:EXP-RC4-MD5:EXP-RC2-CBC-MD5:EXP-RC4-MD5:EXP-RC2-CBC-MD5:EDH-DSS-DES-CBC3-SHA:EDH-DSS-DES-CBC-SHA:EXP1024-DHE-DSS-DES-CBC-SHA")
- sni+=("")
- warning+=("")
- handshakebytes+=("804c01030000330000001000000400000500000a0100800700c003008000000906004000006400006200000300000602008004008000001300001200006317411550ac4c45ccbc8f4538dbc56d3a")
- lowest_protocol+=("0x0200")
- highest_protocol+=("0x0300")
- service+=("HTTP")
- minDhBits+=(-1)
- maxDhBits+=(-1)
- minRsaBits+=(-1)
- maxRsaBits+=(-1)
- minEcdsaBits+=(-1)
- requiresSha2+=(false)
-
- names+=("IE 7 Vista ")
- short+=("ie_7_vista")
- protos+=("-no_tls1_2 -no_tls1_1 -no_ssl2")
- ciphers+=("AES128-SHA:AES256-SHA:RC4-SHA:DES-CBC3-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES128-SHA:ECDHE-RSA-AES256-SHA:DHE-DSS-AES128-SHA:DHE-DSS-AES256-SHA:EDH-DSS-DES-CBC3-SHA:RC4-MD5")
- tlsvers+=("-tls1")
- sni+=("$SNI")
- warning+=("")
- handshakebytes+=("160301007d01000079030151fa62ab452795b7003c5f93ab677dbf57dd62bfa39e0ffaaeabe45b06552452000018002f00350005000ac009c00ac013c01400320038001300040100003800000014001200000f7777772e73736c6c6162732e636f6d000500050100000000000a00080006001700180019000b00020100ff01000100")
- lowest_protocol+=("0x0300")
- highest_protocol+=("0x0301")
- service+=("HTTP")
- minDhBits+=(-1)
- maxDhBits+=(-1)
- minRsaBits+=(-1)
- maxRsaBits+=(-1)
- minEcdsaBits+=(-1)
- requiresSha2+=(false)
-
- names+=("IE 8 XP ")
- short+=("ie_8_xp")
- protos+=("-no_tls1_2 -no_tls1_1 -no_ssl2")
- ciphers+=("RC4-MD5:RC4-SHA:DES-CBC3-SHA:DES-CBC-SHA:EXP1024-RC4-SHA:EXP1024-DES-CBC-SHA:EXP-RC4-MD5:EXP-RC2-CBC-MD5:EDH-DSS-DES-CBC3-SHA:EDH-DSS-DES-CBC-SHA:EXP1024-DHE-DSS-DES-CBC-SHA")
- tlsvers+=("-tls1")
- sni+=("")
- warning+=("")
- handshakebytes+=("16030100410100003d030151fa5ac223f1d72558e48bb4f144baa494403ca6c360349cbd1449997d8dd1ec00001600040005000a000900640062000300060013001200630100")
- lowest_protocol+=("0x0300")
- highest_protocol+=("0x0301")
- service+=("HTTP")
- minDhBits+=(-1)
- maxDhBits+=(-1)
- minRsaBits+=(-1)
- maxRsaBits+=(-1)
- minEcdsaBits+=(-1)
- requiresSha2+=(false)
-
- names+=("IE 8-10 Win 7 ")
- short+=("ie_8-10_win7")
- protos+=("-no_tls1_2 -no_tls1_1 -no_ssl2")
- ciphers+=("ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:AES256-SHA:AES128-SHA:ECDHE-ECDSA-AES256-SHA:ECDHE-ECDSA-AES128-SHA:DHE-DSS-AES256-SHA:DHE-DSS-AES128-SHA:DES-CBC3-SHA:EDH-DSS-DES-CBC3-SHA:RC4-SHA:RC4-MD5")
- tlsvers+=("-tls1")
- sni+=("$SNI")
- warning+=("")
- handshakebytes+=("160301007d01000079030155f092059b76ac28cceda732dac7f07a52aecc126f8ed890ab80e12e7eca049c000018c014c0130035002fc00ac00900380032000a0013000500040100003800000014001200000f6465762e73736c6c6162732e636f6d000500050100000000000a00080006001700180019000b00020100ff01000100")
- lowest_protocol+=("0x0300")
- highest_protocol+=("0x0301")
- service+=("HTTP")
- minDhBits+=(1024)
- maxDhBits+=(4096)
- minRsaBits+=(-1)
- maxRsaBits+=(16384)
- minEcdsaBits+=(-1)
- requiresSha2+=(false)
-
- names+=("IE 11 Win 7 ")
- short+=("ie_11_win7")
- protos+=("-no_ssl2")
- ciphers+=("ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-ECDSA-AES256-SHA:ECDHE-ECDSA-AES128-SHA:DHE-DSS-AES256-SHA256:DHE-DSS-AES128-SHA256:DHE-DSS-AES256-SHA:DHE-DSS-AES128-SHA:DES-CBC3-SHA:EDH-DSS-DES-CBC3-SHA:RC4-SHA:RC4-MD5")
- tlsvers+=("-tls1_2 -tls1_1 -tls1")
- sni+=("$SNI")
- warning+=("")
- handshakebytes+=("16030300b1010000ad030354c22c0a4842eab5a1a10763a3c16df20357f1ba3fac1c67136e09bfa94c5c0f000034c028c027c014c013009f009e009d009c003d003c0035002fc02cc02bc024c023c00ac009006a004000380032000a00130005000401000050ff0100010000000014001200000f6465762e73736c6c6162732e636f6d000500050100000000000a00080006001700180019000b00020100000d00140012040105010601020104030503060302030202")
- lowest_protocol+=("0x0300")
- highest_protocol+=("0x0303")
- service+=("HTTP")
- minDhBits+=(-1)
- maxDhBits+=(-1)
- minRsaBits+=(-1)
- maxRsaBits+=(-1)
- minEcdsaBits+=(-1)
- requiresSha2+=(false)
-
- names+=("IE 11 Win 8.1 ")
- short+=("ie_11_win81")
- protos+=("-no_ssl2")
- ciphers+=("AES128-SHA256:AES128-SHA:AES256-SHA256:AES256-SHA:DES-CBC3-SHA:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA:DHE-DSS-AES128-SHA256:DHE-DSS-AES128-SHA:DHE-DSS-AES256-SHA256:DHE-DSS-AES256-SHA:EDH-DSS-DES-CBC3-SHA")
- tlsvers+=("-tls1_2 -tls1_1 -tls1")
- sni+=("$SNI")
- warning+=("")
- handshakebytes+=("16030300bb010000b7030352678fd707022be386508c7e5837f03bcb1b91c372733322f87872ff873af1db000026003c002f003d0035000ac027c013c014c02bc023c02cc024c009c00a00400032006a0038001301000068ff0100010000000014001200000f7777772e73736c6c6162732e636f6d000500050100000000000a0006000400170018000b00020100000d0010000e04010501020104030503020302020023000000100012001006737064792f3308687474702f312e3133740000")
- lowest_protocol+=("0x0300")
- highest_protocol+=("0x0303")
- service+=("HTTP")
- minDhBits+=(-1)
- maxDhBits+=(-1)
- minRsaBits+=(-1)
- maxRsaBits+=(-1)
- minEcdsaBits+=(-1)
- requiresSha2+=(false)
-
- names+=("IE 10 Win Phone 8.0 ")
- short+=("ie_10_winphone80")
- protos+=("-no_tls1_2 -no_tls1_1 -no_ssl2")
- ciphers+=("AES128-SHA:AES256-SHA:RC4-SHA:DES-CBC3-SHA:ECDHE-RSA-AES128-SHA:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA:DHE-DSS-AES128-SHA:DHE-DSS-AES256-SHA:EDH-DSS-DES-CBC3-SHA:RC4-MD5")
- tlsvers+=("-tls1")
- sni+=("$SNI")
- warning+=("")
- handshakebytes+=("160301007f0100007b0301536487d458b1a364f27085798ca9e06353f0b300baeecd775e6ccc90a97037c2000018002f00350005000ac013c014c009c00a00320038001300040100003aff0100010000000014001200000f7777772e73736c6c6162732e636f6d000500050100000000000a0006000400170018000b0002010000230000")
- lowest_protocol+=("0x0300")
- highest_protocol+=("0x0301")
- service+=("HTTP")
- minDhBits+=(-1)
- maxDhBits+=(-1)
- minRsaBits+=(-1)
- maxRsaBits+=(-1)
- minEcdsaBits+=(-1)
- requiresSha2+=(false)
-
- names+=("IE 11 Win Phone 8.1 ")
- short+=("ie_11_winphone81")
- protos+=("-no_ssl2")
- ciphers+=("AES128-SHA256:AES128-SHA:AES256-SHA256:AES256-SHA:DES-CBC3-SHA:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA:DHE-DSS-AES128-SHA256:DHE-DSS-AES128-SHA:DHE-DSS-AES256-SHA256:DHE-DSS-AES256-SHA:EDH-DSS-DES-CBC3-SHA")
- tlsvers+=("-tls1_2 -tls1_1 -tls1")
- sni+=("$SNI")
- warning+=("")
- handshakebytes+=("16030300bb010000b703035363d297ad92a8fe276a4e5b9395d593e96fff9c3df0987e5dfbab544ce05832000026003c002f003d0035000ac027c013c014c02bc023c02cc024c009c00a00400032006a0038001301000068ff0100010000000014001200000f7777772e73736c6c6162732e636f6d000500050100000000000a0006000400170018000b00020100000d0010000e04010501020104030503020302020023000000100012001006737064792f3308687474702f312e3133740000")
- lowest_protocol+=("0x0300")
- highest_protocol+=("0x0303")
- service+=("HTTP")
- minDhBits+=(-1)
- maxDhBits+=(-1)
- minRsaBits+=(-1)
- maxRsaBits+=(-1)
- minEcdsaBits+=(-1)
- requiresSha2+=(false)
-
- names+=("IE 11 Win Phone 8.1 Update ")
- short+=("ie_11_winphone81update")
- protos+=("-no_ssl2")
- ciphers+=("ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-ECDSA-AES256-SHA:ECDHE-ECDSA-AES128-SHA:DHE-DSS-AES256-SHA256:DHE-DSS-AES128-SHA256:DHE-DSS-AES256-SHA:DHE-DSS-AES128-SHA:DES-CBC3-SHA:EDH-DSS-DES-CBC3-SHA")
- tlsvers+=("-tls1_2 -tls1_1 -tls1")
- sni+=("$SNI")
- warning+=("")
- handshakebytes+=("16030300c5010000c103035537a79a55362d42c3b3308fea91e85c5656021153d0a4baf03e7fef6e315c72000030c028c027c014c013009f009e009d009c003d003c0035002fc02cc02bc024c023c00ac009006a004000380032000a001301000068ff0100010000000014001200000f6465762e73736c6c6162732e636f6d000500050100000000000a0006000400170018000b00020100000d0010000e04010501020104030503020302020023000000100012001006737064792f3308687474702f312e3133740000")
- lowest_protocol+=("0x0300")
- highest_protocol+=("0x0303")
- service+=("HTTP")
- minDhBits+=(-1)
- maxDhBits+=(-1)
- minRsaBits+=(-1)
- maxRsaBits+=(-1)
- minEcdsaBits+=(-1)
- requiresSha2+=(false)
-
- names+=("IE 11 Win 10 ")
- short+=("ie_11_win10")
- protos+=("-no_ssl2 -no_ssl3")
- ciphers+=("ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-ECDSA-AES256-SHA:ECDHE-ECDSA-AES128-SHA:DHE-DSS-AES256-SHA256:DHE-DSS-AES128-SHA256:DHE-DSS-AES256-SHA:DHE-DSS-AES128-SHA:DES-CBC3-SHA:EDH-DSS-DES-CBC3-SHA")
- tlsvers+=("-tls1_2 -tls1_1 -tls1")
- sni+=("$SNI")
- warning+=("")
- handshakebytes+=("16030300c9010000c50303558923f4d57c2d79aba0360f4030073f0554d057176bd610fb2aa74ee4407361000034c030c02fc028c027c014c013009f009e009d009c003d003c0035002fc02cc02bc024c023c00ac009006a004000380032000a00130100006800000014001200000f6465762e73736c6c6162732e636f6d000500050100000000000a0006000400170018000b00020100000d00140012040105010201040305030203020206010603002300000010000e000c02683208687474702f312e3100170000ff01000100")
- lowest_protocol+=("0x0301")
- highest_protocol+=("0x0303")
- service+=("HTTP")
- minDhBits+=(1024)
- maxDhBits+=(4096)
- minRsaBits+=(-1)
- maxRsaBits+=(16384)
- minEcdsaBits+=(-1)
- requiresSha2+=(false)
-
- names+=("Edge 13 Win 10 ")
- short+=("edge_13_win10")
- protos+=("-no_ssl2 -no_ssl3")
- ciphers+=("ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES256-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:DES-CBC3-SHA:DHE-DSS-AES256-SHA256:DHE-DSS-AES128-SHA256:DHE-DSS-AES256-SHA:DHE-DSS-AES128-SHA:EDH-DSS-DES-CBC3-SHA")
- tlsvers+=("-tls1_2 -tls1_1 -tls1")
- sni+=("$SNI")
- warning+=("")
- handshakebytes+=("16030300d3010000cf0303565ee009f8e3f685347567b3edfd626034a1125966e4d818ec6f57a022d2fc9e000034c02cc02bc030c02f009f009ec024c023c028c027c00ac009c014c013009d009c003d003c0035002f000a006a00400038003200130100007200000014001200000f6465762e73736c6c6162732e636f6d000500050100000000000a0006000400170018000b00020100000d00140012040105010201040305030203020206010603002300000010000e000c02683208687474702f312e310017000055000006000100020002ff01000100")
- lowest_protocol+=("0x0301")
- highest_protocol+=("0x0303")
- service+=("HTTP")
- minDhBits+=(1024)
- maxDhBits+=(4096)
- minRsaBits+=(-1)
- maxRsaBits+=(16384)
- minEcdsaBits+=(-1)
- requiresSha2+=(false)
-
- names+=("Edge 13 Win Phone 10 ")
- short+=("edge_13_winphone10")
- protos+=("-no_ssl2 -no_ssl3")
- ciphers+=("ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES256-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:DES-CBC3-SHA:DHE-DSS-AES256-SHA256:DHE-DSS-AES128-SHA256:DHE-DSS-AES256-SHA:DHE-DSS-AES128-SHA:EDH-DSS-DES-CBC3-SHA")
- tlsvers+=("-tls1_2 -tls1_1 -tls1")
- sni+=("$SNI")
- warning+=("")
- handshakebytes+=("16030300d3010000cf0303565ee836e62e7b9b734f4dca5f3f1ad62dc4e5f87bdf6c90f325b6a2e0012705000034c02cc02bc030c02f009f009ec024c023c028c027c00ac009c014c013009d009c003d003c0035002f000a006a00400038003200130100007200000014001200000f6465762e73736c6c6162732e636f6d000500050100000000000a0006000400170018000b00020100000d00140012040105010201040305030203020206010603002300000010000e000c02683208687474702f312e310017000055000006000100020002ff01000100")
- lowest_protocol+=("0x0301")
- highest_protocol+=("0x0303")
- service+=("HTTP")
- minDhBits+=(1024)
- maxDhBits+=(4096)
- minRsaBits+=(-1)
- maxRsaBits+=(16384)
- minEcdsaBits+=(-1)
- requiresSha2+=(false)
-
- names+=("Java 6u45 ")
- short+=("java_6u45")
- protos+=("-no_tls1_2 -no_tls1_1")
- ciphers+=("RC4-MD5:RC4-MD5:RC4-SHA:AES128-SHA:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA:DES-CBC3-SHA:DES-CBC3-MD5:EDH-RSA-DES-CBC3-SHA:EDH-DSS-DES-CBC3-SHA:DES-CBC-SHA:DES-CBC-MD5:EDH-RSA-DES-CBC-SHA:EDH-DSS-DES-CBC-SHA:EXP-RC4-MD5:EXP-RC4-MD5:EXP-DES-CBC-SHA:EXP-EDH-RSA-DES-CBC-SHA:EXP-EDH-DSS-DES-CBC-SHA")
- tlsvers+=("-tls1")
- sni+=("")
- warning+=("")
- handshakebytes+=("8065010301003c0000002000000401008000000500002f00003300003200000a0700c00000160000130000090600400000150000120000030200800000080000140000110000ff52173357f48ce6722f974dbb429b9279208d1cf5b9088947c9ba16d9ecbc0fa6")
- lowest_protocol+=("0x0200")
- highest_protocol+=("0x0301")
- service+=("ANY")
- minDhBits+=(-1)
- maxDhBits+=(1024)
- minRsaBits+=(-1)
- maxRsaBits+=(-1)
- minEcdsaBits+=(-1)
- requiresSha2+=(false)
-
- names+=("Java 7u25 ")
- short+=("java_7u25")
- protos+=("-no_ssl2 -no_tls1_2 -no_tls1_1")
- ciphers+=("ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:AES128-SHA:ECDH-ECDSA-AES128-SHA:ECDH-RSA-AES128-SHA:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA:ECDHE-ECDSA-RC4-SHA:ECDHE-RSA-RC4-SHA:RC4-SHA:ECDH-ECDSA-RC4-SHA:ECDH-RSA-RC4-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:DES-CBC3-SHA:ECDH-ECDSA-DES-CBC3-SHA:ECDH-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:EDH-DSS-DES-CBC3-SHA:RC4-MD5")
- tlsvers+=("-tls1")
- sni+=("$SNI")
- warning+=("")
- handshakebytes+=("16030100ad010000a9030152178334e8b855253e50e4623e475b6941c18cc312de6395a98e1cd4fd6735e700002ac009c013002fc004c00e00330032c007c0110005c002c00cc008c012000ac003c00d00160013000400ff01000056000a0034003200170001000300130015000600070009000a0018000b000c0019000d000e000f001000110002001200040005001400080016000b0002010000000014001200000f7777772e73736c6c6162732e636f6d")
- lowest_protocol+=("0x0300")
- highest_protocol+=("0x0301")
- service+=("ANY")
- minDhBits+=(-1)
- maxDhBits+=(1024)
- minRsaBits+=(-1)
- maxRsaBits+=(-1)
- minEcdsaBits+=(-1)
- requiresSha2+=(false)
-
- names+=("Java 8u31 ")
- short+=("java_8u31")
- protos+=("-no_ssl2 -no_ssl3")
- ciphers+=("ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:AES128-SHA256:ECDH-ECDSA-AES128-SHA256:ECDH-RSA-AES128-SHA256:DHE-RSA-AES128-SHA256:DHE-DSS-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:AES128-SHA:ECDH-ECDSA-AES128-SHA:ECDH-RSA-AES128-SHA:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:AES128-GCM-SHA256:ECDH-ECDSA-AES128-GCM-SHA256:ECDH-RSA-AES128-GCM-SHA256:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:DES-CBC3-SHA:ECDH-ECDSA-DES-CBC3-SHA:ECDH-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:EDH-DSS-DES-CBC3-SHA:ECDHE-ECDSA-RC4-SHA:ECDHE-RSA-RC4-SHA:RC4-SHA:ECDH-ECDSA-RC4-SHA:ECDH-RSA-RC4-SHA:RC4-MD5")
- tlsvers+=("-tls1_2 -tls1_1 -tls1")
- sni+=("$SNI")
- warning+=("")
- handshakebytes+=("16030300e7010000e3030354c21168512b37f2a7410028c16673626ff931146918c7b29f78150b7339e5af000046c023c027003cc025c02900670040c009c013002fc004c00e00330032c02bc02f009cc02dc031009e00a2c008c012000ac003c00d00160013c007c0110005c002c00c000400ff01000074000a0034003200170001000300130015000600070009000a0018000b000c0019000d000e000f001000110002001200040005001400080016000b00020100000d001a001806030601050305010403040103030301020302010202010100000014001200000f6465762e73736c6c6162732e636f6d")
- lowest_protocol+=("0x0301")
- highest_protocol+=("0x0303")
- service+=("ANY")
- minDhBits+=(-1)
- maxDhBits+=(2048)
- minRsaBits+=(-1)
- maxRsaBits+=(-1)
- minEcdsaBits+=(-1)
- requiresSha2+=(false)
-
- names+=("OpenSSL 0.9.8y ")
- short+=("openssl_098y")
- protos+=("-no_ssl2 -no_tls1_2 -no_tls1_1")
- ciphers+=("DHE-RSA-AES256-SHA:DHE-DSS-AES256-SHA:AES256-SHA:EDH-RSA-DES-CBC3-SHA:EDH-DSS-DES-CBC3-SHA:DES-CBC3-SHA:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA:AES128-SHA:IDEA-CBC-SHA:RC4-SHA:RC4-MD5:EDH-RSA-DES-CBC-SHA:EDH-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")
- sni+=("$SNI")
- warning+=("")
- handshakebytes+=("16030100730100006f0301521782e707c1a780d3124742f35573dbb693babe5d3a7e9405c706af18b636bf00002a00390038003500160013000a00330032002f0007000500040015001200090014001100080006000300ff0100001c00000014001200000f7777772e73736c6c6162732e636f6d00230000")
- lowest_protocol+=("0x0300")
- highest_protocol+=("0x0301")
- service+=("ANY")
- minDhBits+=(-1)
- maxDhBits+=(-1)
- minRsaBits+=(-1)
- maxRsaBits+=(-1)
- minEcdsaBits+=(-1)
- requiresSha2+=(false)
-
- names+=("OpenSSL 1.0.1l ")
- short+=("openssl_101l")
- protos+=("-no_ssl2")
- 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:DHE-DSS-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA256:DHE-RSA-AES256-SHA:DHE-DSS-AES256-SHA:DHE-RSA-CAMELLIA256-SHA:DHE-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:DHE-DSS-AES128-GCM-SHA256:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES128-SHA256:DHE-DSS-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA:DHE-RSA-SEED-SHA:DHE-DSS-SEED-SHA:DHE-RSA-CAMELLIA128-SHA:DHE-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:ECDH-RSA-DES-CBC3-SHA:ECDH-ECDSA-DES-CBC3-SHA:DES-CBC3-SHA:EDH-RSA-DES-CBC-SHA:EDH-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+=("")
- handshakebytes+=("160301014f0100014b030332b230e5dd8c5573c219a243f397e31f407c7a93b60a26e7c3d5cca06a566fe1000094c030c02cc028c024c014c00a00a3009f006b006a0039003800880087c032c02ec02ac026c00fc005009d003d00350084c02fc02bc027c023c013c00900a2009e0067004000330032009a009900450044c031c02dc029c025c00ec004009c003c002f009600410007c011c007c00cc00200050004c012c00800160013c00dc003000a0015001200090014001100080006000300ff0100008e00000014001200000f6465762e73736c6c6162732e636f6d000b000403000102000a00340032000e000d0019000b000c00180009000a00160017000800060007001400150004000500120013000100020003000f0010001100230000000d0020001e060106020603050105020503040104020403030103020303020102020203000500050100000000000f000101")
- lowest_protocol+=("0x0300")
- highest_protocol+=("0x0303")
- service+=("ANY")
- minDhBits+=(-1)
- maxDhBits+=(-1)
- minRsaBits+=(-1)
- maxRsaBits+=(-1)
- minEcdsaBits+=(-1)
- requiresSha2+=(false)
-
- names+=("OpenSSL 1.0.2e ")
- short+=("openssl_102e")
- protos+=("-no_ssl2")
- 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")
- tlsvers+=("-tls1_2 -tls1_1 -tls1")
- sni+=("$SNI")
- #warning+=("Tests are based on OpenSSL 1.0.1, therefore ciphers 0xe and 0xb are missing")
- warning+=("")
- handshakebytes+=("16030101590100015503032a9db79b37d9364a9a685dc25bfec88c21ef88c206a20b9801108c67607e79800000b6c030c02cc028c024c014c00a00a500a300a1009f006b006a0069006800390038003700360088008700860085c032c02ec02ac026c00fc005009d003d00350084c02fc02bc027c023c013c00900a400a200a0009e00670040003f003e0033003200310030009a0099009800970045004400430042c031c02dc029c025c00ec004009c003c002f009600410007c011c007c00cc00200050004c012c008001600130010000dc00dc003000a00150012000f000c000900ff0100007600000014001200000f6465762e73736c6c6162732e636f6d000b000403000102000a001c001a00170019001c001b0018001a0016000e000d000b000c0009000a00230000000d0020001e060106020603050105020503040104020403030103020303020102020203000500050100000000000f000101")
- lowest_protocol+=("0x0300")
- highest_protocol+=("0x0303")
- service+=("ANY")
- minDhBits+=(-1)
- maxDhBits+=(-1)
- minRsaBits+=(-1)
- maxRsaBits+=(-1)
- minEcdsaBits+=(-1)
- requiresSha2+=(false)
-
- names+=("Safari 5.1.9 OS X 10.6.8 ")
- short+=("safari_519_osx1068")
- protos+=("-no_ssl2 -no_tls1_2 -no_tls1_1")
- ciphers+=("ECDHE-ECDSA-AES256-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-ECDSA-RC4-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-AES128-SHA:ECDHE-RSA-AES256-SHA:ECDHE-RSA-RC4-SHA:ECDHE-RSA-DES-CBC3-SHA:ECDH-ECDSA-AES128-SHA:ECDH-ECDSA-AES256-SHA:ECDH-ECDSA-RC4-SHA:ECDH-ECDSA-DES-CBC3-SHA:ECDH-RSA-AES128-SHA:ECDH-RSA-AES256-SHA:ECDH-RSA-RC4-SHA:ECDH-RSA-DES-CBC3-SHA:AES128-SHA:RC4-SHA:RC4-MD5:AES256-SHA:DES-CBC3-SHA:DES-CBC-SHA:EXP-RC4-MD5:EXP-DES-CBC-SHA:EXP-RC2-CBC-MD5:DHE-DSS-AES128-SHA:DHE-RSA-AES128-SHA:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:EDH-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC-SHA:EXP-EDH-RSA-DES-CBC-SHA:EDH-DSS-DES-CBC3-SHA:EDH-DSS-DES-CBC-SHA:EXP-EDH-DSS-DES-CBC-SHA")
- tlsvers+=("-tls1")
- sni+=("$SNI")
- warning+=("")
- handshakebytes+=("160301009d01000099030151d15dc2887b1852fd4291e36c3f4e8a35266e15dd6354779fbf5438b59b42da000046c00ac009c007c008c013c014c011c012c004c005c002c003c00ec00fc00cc00d002f000500040035000a000900030008000600320033003800390016001500140013001200110100002a00000014001200000f7777772e73736c6c6162732e636f6d000a00080006001700180019000b00020100")
- lowest_protocol+=("0x0300")
- highest_protocol+=("0x0301")
- service+=("HTTP")
- minDhBits+=(-1)
- maxDhBits+=(-1)
- minRsaBits+=(-1)
- maxRsaBits+=(4096)
- minEcdsaBits+=(-1)
- requiresSha2+=(false)
-
- names+=("Safari 6 iOS 6.0.1 ")
- short+=("safari_6_ios601")
- protos+=("-no_ssl2")
- ciphers+=("ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-ECDSA-AES256-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-ECDSA-RC4-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:ECDHE-RSA-RC4-SHA:ECDHE-RSA-DES-CBC3-SHA:ECDH-ECDSA-AES256-SHA384:ECDH-ECDSA-AES128-SHA256:ECDH-RSA-AES256-SHA384:ECDH-RSA-AES128-SHA256:ECDH-ECDSA-AES128-SHA:ECDH-ECDSA-AES256-SHA:ECDH-ECDSA-RC4-SHA:ECDH-ECDSA-DES-CBC3-SHA:ECDH-RSA-AES128-SHA:ECDH-RSA-AES256-SHA:ECDH-RSA-RC4-SHA:ECDH-RSA-DES-CBC3-SHA:AES256-SHA256:AES128-SHA256:AES128-SHA:RC4-SHA:RC4-MD5:AES256-SHA:DES-CBC3-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA:EDH-RSA-DES-CBC3-SHA:ECDHE-ECDSA-NULL-SHA:ECDHE-RSA-NULL-SHA:ECDH-ECDSA-NULL-SHA:ECDH-RSA-NULL-SHA:NULL-SHA256:NULL-SHA:NULL-MD5")
- tlsvers+=("-tls1_2 -tls1_1 -tls1")
- sni+=("$SNI")
- warning+=("")
- handshakebytes+=("16030300bf010000bb030351d15ce21834380a8b5f491a00790b6d097014bb1e04124706631c6a6a3f973800005800ffc024c023c00ac009c007c008c028c027c014c013c011c012c026c025c02ac029c004c005c002c003c00ec00fc00cc00d003d003c002f000500040035000a0067006b003300390016c006c010c001c00b003b000200010100003a00000014001200000f7777772e73736c6c6162732e636f6d000a00080006001700180019000b00020100000d000c000a05010401020104030203")
- lowest_protocol+=("0x0300")
- highest_protocol+=("0x0303")
- service+=("HTTP")
- minDhBits+=(-1)
- maxDhBits+=(-1)
- minRsaBits+=(-1)
- maxRsaBits+=(4096)
- minEcdsaBits+=(-1)
- requiresSha2+=(false)
-
- names+=("Safari 6.0.4 OS X 10.8.4 ")
- short+=("safari_604_osx1084")
- protos+=("-no_ssl2 -no_tls1_2 -no_tls1_1")
- ciphers+=("ECDHE-ECDSA-AES256-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-ECDSA-RC4-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:ECDHE-RSA-RC4-SHA:ECDHE-RSA-DES-CBC3-SHA:ECDH-ECDSA-AES128-SHA:ECDH-ECDSA-AES256-SHA:ECDH-ECDSA-RC4-SHA:ECDH-ECDSA-DES-CBC3-SHA:ECDH-RSA-AES128-SHA:ECDH-RSA-AES256-SHA:ECDH-RSA-RC4-SHA:ECDH-RSA-DES-CBC3-SHA:AES128-SHA:RC4-SHA:RC4-MD5:AES256-SHA:DES-CBC3-SHA:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA:EDH-RSA-DES-CBC3-SHA")
- tlsvers+=("-tls1")
- sni+=("$SNI")
- warning+=("")
- handshakebytes+=("16030100a9010000a5030151fa327c6576dadde1e8a89d4d45bdc1d0c107b8cbe998337e02ca419a0bcb30204dd1c85d9fbc1607b27a35ec9dfd1dae2c589483843a73999c9de205748633b1003200ffc00ac009c007c008c014c013c011c012c004c005c002c003c00ec00fc00cc00d002f000500040035000a0033003900160100002a00000014001200000f7777772e73736c6c6162732e636f6d000a00080006001700180019000b00020100")
- lowest_protocol+=("0x0300")
- highest_protocol+=("0x0301")
- service+=("HTTP")
- minDhBits+=(-1)
- maxDhBits+=(-1)
- minRsaBits+=(-1)
- maxRsaBits+=(4096)
- minEcdsaBits+=(-1)
- requiresSha2+=(false)
-
- names+=("Safari 7 iOS 7.1 ")
- short+=("safari_7_ios71")
- protos+=("-no_ssl2")
- ciphers+=("ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-ECDSA-AES256-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-ECDSA-RC4-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:ECDHE-RSA-RC4-SHA:ECDHE-RSA-DES-CBC3-SHA:ECDH-ECDSA-AES256-SHA384:ECDH-ECDSA-AES128-SHA256:ECDH-RSA-AES256-SHA384:ECDH-RSA-AES128-SHA256:ECDH-ECDSA-AES256-SHA:ECDH-ECDSA-AES128-SHA:ECDH-ECDSA-RC4-SHA:ECDH-ECDSA-DES-CBC3-SHA:ECDH-RSA-AES256-SHA:ECDH-RSA-AES128-SHA:ECDH-RSA-RC4-SHA:ECDH-RSA-DES-CBC3-SHA:AES256-SHA256:AES128-SHA256:AES128-SHA:RC4-SHA:RC4-MD5:AES256-SHA:DES-CBC3-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA:EDH-RSA-DES-CBC3-SHA")
- tlsvers+=("-tls1_2 -tls1_1 -tls1")
- sni+=("$SNI")
- warning+=("")
- handshakebytes+=("16030100b1010000ad0303532017204048bb5331c62bf295ab4c2f2b3964f515c649a7d0947c8102d7348600004a00ffc024c023c00ac009c007c008c028c027c014c013c011c012c026c025c02ac029c005c004c002c003c00fc00ec00cc00d003d003c002f000500040035000a0067006b0033003900160100003a00000014001200000f7777772e73736c6c6162732e636f6d000a00080006001700180019000b00020100000d000c000a05010401020104030203")
- lowest_protocol+=("0x0300")
- highest_protocol+=("0x0303")
- service+=("HTTP")
- minDhBits+=(-1)
- maxDhBits+=(-1)
- minRsaBits+=(-1)
- maxRsaBits+=(4096)
- minEcdsaBits+=(-1)
- requiresSha2+=(false)
-
- names+=("Safari 7 OS X 10.9 ")
- short+=("safari_7_osx109")
- protos+=("-no_ssl2")
- ciphers+=("ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-ECDSA-AES256-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-ECDSA-RC4-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:ECDHE-RSA-RC4-SHA:ECDHE-RSA-DES-CBC3-SHA:ECDH-ECDSA-AES256-SHA384:ECDH-ECDSA-AES128-SHA256:ECDH-RSA-AES256-SHA384:ECDH-RSA-AES128-SHA256:ECDH-ECDSA-AES256-SHA:ECDH-ECDSA-AES128-SHA:ECDH-ECDSA-RC4-SHA:ECDH-ECDSA-DES-CBC3-SHA:ECDH-RSA-AES256-SHA:ECDH-RSA-AES128-SHA:ECDH-RSA-RC4-SHA:ECDH-RSA-DES-CBC3-SHA:AES256-SHA256:AES128-SHA256:AES128-SHA:RC4-SHA:RC4-MD5:AES256-SHA:DES-CBC3-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA:EDH-RSA-DES-CBC3-SHA")
- tlsvers+=("-tls1_2 -tls1_1 -tls1")
- sni+=("$SNI")
- warning+=("")
- handshakebytes+=("16030100d1010000cd030351fa3664edce86d82606540539ccd388418b1a5cb8cfda5e15349c635d4b028b203bf83c63e3da6777e407300b5d657e429f11cd7d857977e4390fda365b8d4664004a00ffc024c023c00ac009c007c008c028c027c014c013c011c012c026c025c02ac029c005c004c002c003c00fc00ec00cc00d003d003c002f000500040035000a0067006b0033003900160100003a00000014001200000f7777772e73736c6c6162732e636f6d000a00080006001700180019000b00020100000d000c000a05010401020104030203")
- lowest_protocol+=("0x0300")
- highest_protocol+=("0x0303")
- service+=("HTTP")
- minDhBits+=(-1)
- maxDhBits+=(-1)
- minRsaBits+=(-1)
- maxRsaBits+=(4096)
- minEcdsaBits+=(-1)
- requiresSha2+=(false)
-
- names+=("Safari 8 iOS 8.4 ")
- short+=("safari_8_ios84")
- protos+=("-no_ssl2")
- ciphers+=("ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-ECDSA-AES256-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:ECDHE-RSA-DES-CBC3-SHA:ECDH-ECDSA-AES256-SHA384:ECDH-ECDSA-AES128-SHA256:ECDH-ECDSA-AES256-SHA:ECDH-ECDSA-AES128-SHA:ECDH-ECDSA-DES-CBC3-SHA:ECDH-RSA-AES256-SHA384:ECDH-RSA-AES128-SHA256:ECDH-RSA-AES256-SHA:ECDH-RSA-AES128-SHA:ECDH-RSA-DES-CBC3-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:EDH-RSA-DES-CBC3-SHA:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:DES-CBC3-SHA:ECDHE-ECDSA-RC4-SHA:ECDHE-RSA-RC4-SHA:ECDH-ECDSA-RC4-SHA:ECDH-RSA-RC4-SHA:RC4-SHA:RC4-MD5")
- tlsvers+=("-tls1_2 -tls1_1 -tls1")
- sni+=("$SNI")
- warning+=("")
- handshakebytes+=("16030100b5010000b1030354c20f1647345d0cac1db29f0489aab5e2016e6b2baca65e8c5eb6dd48a1fcd400004a00ffc024c023c00ac009c008c028c027c014c013c012c026c025c005c004c003c02ac029c00fc00ec00d006b0067003900330016003d003c0035002f000ac007c011c002c00c000500040100003e00000014001200000f6465762e73736c6c6162732e636f6d000a00080006001700180019000b00020100000d000c000a0501040102010403020333740000")
- lowest_protocol+=("0x0300")
- highest_protocol+=("0x0303")
- service+=("HTTP")
- minDhBits+=(768)
- maxDhBits+=(-1)
- minRsaBits+=(-1)
- maxRsaBits+=(4096)
- minEcdsaBits+=(-1)
- requiresSha2+=(false)
-
- names+=("Safari 8 OS X 10.10 ")
- short+=("safari_8_osx1010")
- protos+=("-no_ssl2")
- ciphers+=("ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-ECDSA-AES256-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:ECDHE-RSA-DES-CBC3-SHA:ECDH-ECDSA-AES256-SHA384:ECDH-ECDSA-AES128-SHA256:ECDH-ECDSA-AES256-SHA:ECDH-ECDSA-AES128-SHA:ECDH-ECDSA-DES-CBC3-SHA:ECDH-RSA-AES256-SHA384:ECDH-RSA-AES128-SHA256:ECDH-RSA-AES256-SHA:ECDH-RSA-AES128-SHA:ECDH-RSA-DES-CBC3-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:EDH-RSA-DES-CBC3-SHA:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:DES-CBC3-SHA:ECDHE-ECDSA-RC4-SHA:ECDHE-RSA-RC4-SHA:ECDH-ECDSA-RC4-SHA:ECDH-RSA-RC4-SHA:RC4-SHA:RC4-MD5")
- tlsvers+=("-tls1_2 -tls1_1 -tls1")
- sni+=("$SNI")
- warning+=("")
- handshakebytes+=("16030100b5010000b1030354c20a44e0d7681f3d55d7e9a764b67e6ffa6722c17b21e15bc2c9c98892460a00004a00ffc024c023c00ac009c008c028c027c014c013c012c026c025c005c004c003c02ac029c00fc00ec00d006b0067003900330016003d003c0035002f000ac007c011c002c00c000500040100003e00000014001200000f6465762e73736c6c6162732e636f6d000a00080006001700180019000b00020100000d000c000a0501040102010403020333740000")
- lowest_protocol+=("0x0300")
- highest_protocol+=("0x0303")
- service+=("HTTP")
- minDhBits+=(768)
- maxDhBits+=(-1)
- minRsaBits+=(-1)
- maxRsaBits+=(8192)
- minEcdsaBits+=(-1)
- requiresSha2+=(false)
-
- names+=("Safari 9 iOS 9 ")
- short+=("safari_9_ios9")
- protos+=("-no_ssl2 -no_ssl3")
- ciphers+=("ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-ECDSA-AES256-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:ECDHE-RSA-DES-CBC3-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:DES-CBC3-SHA:ECDHE-ECDSA-RC4-SHA:ECDHE-RSA-RC4-SHA:RC4-SHA:RC4-MD5")
- tlsvers+=("-tls1_2 -tls1_1 -tls1")
- sni+=("$SNI")
- warning+=("")
- handshakebytes+=("16030100e2010000de030355fb38fdc94c6c1ff6ee066f0e69579f40a83ce5454787e8834b60fd8c31e5ac00003400ffc02cc02bc024c023c00ac009c008c030c02fc028c027c014c013c012009d009c003d003c0035002f000ac007c011000500040100008100000014001200000f6465762e73736c6c6162732e636f6d000a00080006001700180019000b00020100000d000e000c0501040102010503040302033374000000100030002e0268320568322d31360568322d31350568322d313408737064792f332e3106737064792f3308687474702f312e3100050005010000000000120000")
- lowest_protocol+=("0x0301")
- highest_protocol+=("0x0303")
- service+=("HTTP")
- minDhBits+=(768)
- maxDhBits+=(-1)
- minRsaBits+=(-1)
- maxRsaBits+=(8192)
- minEcdsaBits+=(-1)
- requiresSha2+=(false)
-
- names+=("Safari 9 OS X 10.11 ")
- short+=("safari_9_osx1011")
- protos+=("-no_ssl2 -no_ssl3")
- ciphers+=("ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-ECDSA-AES256-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:ECDHE-RSA-DES-CBC3-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:DES-CBC3-SHA:ECDHE-ECDSA-RC4-SHA:ECDHE-RSA-RC4-SHA:RC4-SHA:RC4-MD5")
- tlsvers+=("-tls1_2 -tls1_1 -tls1")
- sni+=("$SNI")
- warning+=("")
- handshakebytes+=("16030100e2010000de030355def1c4d1f6a12227389012da236581104b0bfa8b8a5bc849372531349dccc600003400ffc02cc02bc024c023c00ac009c008c030c02fc028c027c014c013c012009d009c003d003c0035002f000ac007c011000500040100008100000014001200000f6465762e73736c6c6162732e636f6d000a00080006001700180019000b00020100000d000e000c0501040102010503040302033374000000100030002e0268320568322d31360568322d31350568322d313408737064792f332e3106737064792f3308687474702f312e3100050005010000000000120000")
- lowest_protocol+=("0x0301")
- highest_protocol+=("0x0303")
- service+=("HTTP")
- minDhBits+=(768)
- maxDhBits+=(-1)
- minRsaBits+=(-1)
- maxRsaBits+=(8192)
- minEcdsaBits+=(-1)
- requiresSha2+=(false)
-
- names+=("Apple ATS 9 iOS 9 ")
- short+=("safari_9_osx1011")
- protos+=("-no_ssl2 -no_ssl3 -no_tls1 -no_tls1_1")
- ciphers+=("ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-ECDSA-AES256-SHA:ECDHE-ECDSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES128-SHA")
- tlsvers+=("-tls1_2")
- sni+=("$SNI")
- warning+=("")
- handshakebytes+=("16030100b9010000b50303282275d1356ba8ceec8897786197b80f96d83a06d9205200a677f850c4b822f2000018c02cc02bc024c023c00ac009c030c02fc028c027c01300ff0201000073000b000403000102000a003a0038000e000d0019001c000b000c001b00180009000a001a00160017000800060007001400150004000500120013000100020003000f0010001100230000000d0020001e060106020603050105020503040104020403030103020303020102020203000f000101")
- lowest_protocol+=("0x0303")
- highest_protocol+=("0x0303")
- service+=("HTTP")
- minDhBits+=(768)
- maxDhBits+=(-1)
- minRsaBits+=(-1)
- maxRsaBits+=(8192)
- minEcdsaBits+=(-1)
- requiresSha2+=(false)
-
outln
if "$using_sockets"; then
- pr_headlineln " Running browser simulations via sockets (experimental) "
+ pr_headlineln " Running browser simulations via sockets "
else
- pr_headline " Running browser simulations via openssl (experimental) "
+ pr_headline " Running browser simulations via openssl "
fi
outln
- debugme outln
+ debugme tmln_out
for name in "${short[@]}"; do
#FIXME: printf formatting would look better, especially if we want a wide option here
out " ${names[i]} "
@@ -4156,9 +3617,10 @@ run_client_simulation() {
outln "No connection"
fileout "client_${short[i]}" "INFO" "$(strip_spaces "${names[i]}") client simulation: No connection"
else
- #FIXME: awk
- proto=$(grep -aw "Protocol" $TMPFILE | sed -e 's/^.*Protocol.*://' -e 's/ //g')
+ proto=$(get_protocol $TMPFILE)
+ # hack:
[[ "$proto" == TLSv1 ]] && proto="TLSv1.0"
+ [[ "$proto" == SSLv3 ]] && proto="SSLv3 "
if [[ "$proto" == TLSv1.2 ]] && ( ! "$using_sockets" || [[ -z "${handshakebytes[i]}" ]] ); then
# 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
@@ -4183,14 +3645,13 @@ run_client_simulation() {
fi
done
fi
- #FiXME: awk
- cipher=$(grep -wa Cipher $TMPFILE | egrep -avw "New|is" | sed -e 's/ //g' -e 's/^Cipher://')
+ cipher=$(get_cipher $TMPFILE)
if [[ "$DISPLAY_CIPHERNAMES" =~ openssl ]] && ( [[ "$cipher" == TLS_* ]] || [[ "$cipher" == SSL_* ]] ); then
cipher="$(rfc2openssl "$cipher")"
- [[ -z "$cipher" ]] && cipher=$(grep -wa Cipher $TMPFILE | egrep -avw "New|is" | sed -e 's/ //g' -e 's/^Cipher://')
+ [[ -z "$cipher" ]] && cipher=$(get_cipher $TMPFILE)
elif [[ "$DISPLAY_CIPHERNAMES" =~ rfc ]] && [[ "$cipher" != TLS_* ]] && [[ "$cipher" != SSL_* ]]; then
cipher="$(openssl2rfc "$cipher")"
- [[ -z "$cipher" ]] && cipher=$(grep -wa Cipher $TMPFILE | egrep -avw "New|is" | sed -e 's/ //g' -e 's/^Cipher://')
+ [[ -z "$cipher" ]] && cipher=$(get_cipher $TMPFILE)
fi
out "$proto $cipher"
"$using_sockets" && [[ -n "${handshakebytes[i]}" ]] && has_dh_bits=$HAS_DH_BITS && HAS_DH_BITS=true
@@ -4216,7 +3677,7 @@ run_client_simulation() {
locally_supported() {
[[ -n "$2" ]] && out "$2 "
if $OPENSSL s_client "$1" -connect x 2>&1 | grep -aq "unknown option"; then
- local_problem_ln "$OPENSSL doesn't support \"s_client $1\""
+ prln_local_problem "$OPENSSL doesn't support \"s_client $1\""
return 7
fi
return 0
@@ -4262,7 +3723,7 @@ run_prototest_openssl() {
# 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 "
+ grep -qw "$1" <<< "$PROTOS_OFFERED" || PROTOS_OFFERED+="$1 "
}
# function which checks whether SSLv2 - TLS 1.2 is being offereed
@@ -4288,13 +3749,13 @@ run_protocols() {
if "$SSL_NATIVE"; then
using_sockets=false
- pr_underlineln "via native openssl"
+ prln_underline "via native openssl"
else
using_sockets=true
if [[ -n "$STARTTLS" ]]; then
- pr_underlineln "via sockets "
+ prln_underline "via sockets "
else
- pr_underlineln "via sockets except SPDY+HTTP2 "
+ prln_underline "via sockets except SPDY+HTTP2 "
fi
fi
outln
@@ -4310,21 +3771,21 @@ run_protocols() {
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)"
+ prln_done_best "not offered (OK)"
fileout "sslv2" "OK" "SSLv2 is not offered"
;;
0) # reset
- pr_done_bestln "not offered (OK)"
+ prln_done_best "not offered (OK)"
fileout "sslv2" "OK" "SSLv2 is not offered"
;;
3) # everything else
lines=$(count_lines "$(hexdump -C "$TEMPDIR/$NODEIP.sslv2_sockets.dd" 2>/dev/null)")
- [[ "$DEBUG" -ge 2 ]] && out " ($lines lines) "
+ [[ "$DEBUG" -ge 2 ]] && tm_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 ";
+ prln_svrty_high "supported but couldn't detect a cipher and vulnerable to CVE-2015-3197 ";
fileout "sslv2" "HIGH" "SSLv2 is offered, vulnerable to CVE-2015-3197"
else
pr_svrty_critical "offered (NOT ok), also VULNERABLE to DROWN attack";
@@ -4333,26 +3794,22 @@ run_protocols() {
fi
fi ;;
esac
- debugme outln
+ debugme tmln_out
else
run_prototest_openssl "-ssl2"
case $? in
- 0)
- pr_svrty_criticalln "offered (NOT ok)"
+ 0) prln_svrty_critical "offered (NOT ok)"
fileout "sslv2" "CRITICAL" "SSLv2 is offered"
add_tls_offered "ssl2"
;;
- 1)
- pr_done_bestln "not offered (OK)"
+ 1) prln_done_best "not offered (OK)"
fileout "sslv2" "OK" "SSLv2 is not offered"
;;
- 5)
- pr_svrty_high "CVE-2015-3197: $supported_no_ciph2";
+ 5) pr_svrty_high "CVE-2015-3197: $supported_no_ciph2";
fileout "sslv2" "HIGH" "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"
+ 7) fileout "sslv2" "INFO" "SSLv2 is not tested due to lack of local support"
;; # no local support
esac
fi
@@ -4364,35 +3821,30 @@ run_protocols() {
run_prototest_openssl "-ssl3"
fi
case $? in
- 0)
- pr_svrty_highln "offered (NOT ok)"
+ 0) prln_svrty_high "offered (NOT ok)"
fileout "sslv3" "HIGH" "SSLv3 is offered"
latest_supported="0300"
latest_supported_string="SSLv3"
add_tls_offered "ssl3"
;;
- 1)
- pr_done_bestln "not offered (OK)"
+ 1) prln_done_best "not offered (OK)"
fileout "sslv3" "OK" "SSLv3 is not offered"
;;
- 2)
- if [[ "$DETECTED_TLS_VERSION" == 03* ]]; then
+ 2) if [[ "$DETECTED_TLS_VERSION" == 03* ]]; then
detected_version_string="TLSv1.$((0x$DETECTED_TLS_VERSION-0x0301))"
- pr_svrty_criticalln "server responded with higher version number ($detected_version_string) than requested by client (NOT ok)"
+ prln_svrty_critical "server responded with higher version number ($detected_version_string) than requested by client (NOT ok)"
fileout "sslv3" "CRITICAL" "SSLv3: server responded with higher version number ($detected_version_string) than requested by client"
else
- pr_svrty_criticalln "server responded with version number ${DETECTED_TLS_VERSION:0:2}.${DETECTED_TLS_VERSION:2:2} (NOT ok)"
+ prln_svrty_critical "server responded with version number ${DETECTED_TLS_VERSION:0:2}.${DETECTED_TLS_VERSION:2:2} (NOT ok)"
fileout "sslv3" "CRITICAL" "SSLv3: server responded with version number ${DETECTED_TLS_VERSION:0:2}.${DETECTED_TLS_VERSION:2:2}"
fi
;;
- 5)
- pr_svrty_high "$supported_no_ciph2"
+ 5) pr_svrty_high "$supported_no_ciph2"
fileout "sslv3" "HIGH" "SSLv3 is $supported_no_ciph1"
outln "(may need debugging)"
add_tls_offered "ssl3"
;;
- 7)
- fileout "sslv3" "INFO" "SSLv3 is not tested due to lack of local support"
+ 7) fileout "sslv3" "INFO" "SSLv3 is not tested due to lack of local support"
;; # no local support
esac
@@ -4403,45 +3855,40 @@ run_protocols() {
run_prototest_openssl "-tls1"
fi
case $? in
- 0)
- outln "offered"
+ 0) outln "offered"
fileout "tls1" "INFO" "TLSv1.0 is offered"
latest_supported="0301"
latest_supported_string="TLSv1.0"
add_tls_offered "tls1"
;; # nothing wrong with it -- per se
- 1)
- out "not offered"
+ 1) out "not offered"
if ! "$using_sockets" || [[ -z $latest_supported ]]; then
outln
fileout "tls1" "INFO" "TLSv1.0 is not offered" # neither good or bad
else
- pr_svrty_criticalln " -- connection failed rather than downgrading to $latest_supported_string (NOT ok)"
+ prln_svrty_critical " -- connection failed rather than downgrading to $latest_supported_string (NOT ok)"
fileout "tls1" "CRITICAL" "TLSv1.0: connection failed rather than downgrading to $latest_supported_string"
fi
;;
- 2)
- pr_svrty_medium "not offered"
+ 2) pr_svrty_medium "not offered"
if [[ "$DETECTED_TLS_VERSION" == "0300" ]]; then
- [[ $DEBUG -eq 1 ]] && out " -- downgraded"
+ [[ $DEBUG -eq 1 ]] && tm_out " -- downgraded"
outln
fileout "tls1" "MEDIUM" "TLSv1.0 is not offered, and downgraded to SSL"
elif [[ "$DETECTED_TLS_VERSION" == 03* ]]; then
detected_version_string="TLSv1.$((0x$DETECTED_TLS_VERSION-0x0301))"
- pr_svrty_criticalln " -- server responded with higher version number ($detected_version_string) than requested by client"
+ prln_svrty_critical " -- server responded with higher version number ($detected_version_string) than requested by client"
fileout "tls1" "CRITICAL" "TLSv1.0: server responded with higher version number ($detected_version_string) than requested by client"
else
- pr_svrty_criticalln " -- server responded with version number ${DETECTED_TLS_VERSION:0:2}.${DETECTED_TLS_VERSION:2:2}"
+ prln_svrty_critical " -- server responded with version number ${DETECTED_TLS_VERSION:0:2}.${DETECTED_TLS_VERSION:2:2}"
fileout "tls1" "CRITICAL" "TLSv1.0: server responded with version number ${DETECTED_TLS_VERSION:0:2}.${DETECTED_TLS_VERSION:2:2}"
fi
;;
- 5)
- outln "$supported_no_ciph1" # protocol ok, but no cipher
+ 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"
+ 7) fileout "tlsv1" "INFO" "TLSv1.0 is not tested due to lack of local support"
;; # no local support
esac
@@ -4452,48 +3899,43 @@ run_protocols() {
run_prototest_openssl "-tls1_1"
fi
case $? in
- 0)
- outln "offered"
+ 0) outln "offered"
fileout "tls1_1" "INFO" "TLSv1.1 is offered"
latest_supported="0302"
latest_supported_string="TLSv1.1"
add_tls_offered "tls1_1"
;; # nothing wrong with it
- 1)
- out "not offered"
+ 1) out "not offered"
if ! "$using_sockets" || [[ -z $latest_supported ]]; then
outln
fileout "tls1_1" "INFO" "TLSv1.1 is not offered" # neither good or bad
else
- pr_svrty_criticalln " -- connection failed rather than downgrading to $latest_supported_string"
+ prln_svrty_critical " -- connection failed rather than downgrading to $latest_supported_string"
fileout "tls1_1" "CRITICAL" "TLSv1.1: connection failed rather than downgrading to $latest_supported_string"
fi
;;
- 2)
- out "not offered"
+ 2) out "not offered"
if [[ "$DETECTED_TLS_VERSION" == "$latest_supported" ]]; then
- [[ $DEBUG -eq 1 ]] && out " -- downgraded"
+ [[ $DEBUG -eq 1 ]] && tm_out " -- downgraded"
outln
fileout "tls1_1" "CRITICAL" "TLSv1.1 is not offered, and downgraded to a weaker protocol"
elif [[ "$DETECTED_TLS_VERSION" == "0300" ]] && [[ "$latest_supported" == "0301" ]]; then
- pr_svrty_criticalln " -- server supports TLSv1.0, but downgraded to SSLv3 (NOT ok)"
+ prln_svrty_critical " -- server supports TLSv1.0, but downgraded to SSLv3 (NOT ok)"
fileout "tls1_1" "CRITICAL" "TLSv1.1 is not offered, and downgraded to SSLv3 rather than TLSv1.0"
elif [[ "$DETECTED_TLS_VERSION" == 03* ]] && [[ 0x$DETECTED_TLS_VERSION -gt 0x0302 ]]; then
detected_version_string="TLSv1.$((0x$DETECTED_TLS_VERSION-0x0301))"
- pr_svrty_criticalln " -- server responded with higher version number ($detected_version_string) than requested by client (NOT ok)"
+ prln_svrty_critical " -- server responded with higher version number ($detected_version_string) than requested by client (NOT ok)"
fileout "tls1_1" "CRITICAL" "TLSv1.1 is not offered, server responded with higher version number ($detected_version_string) than requested by client"
else
- pr_svrty_criticalln " -- server responded with version number ${DETECTED_TLS_VERSION:0:2}.${DETECTED_TLS_VERSION:2:2} (NOT ok)"
+ prln_svrty_critical " -- server responded with version number ${DETECTED_TLS_VERSION:0:2}.${DETECTED_TLS_VERSION:2:2} (NOT ok)"
fileout "tls1_1" "CRITICAL" "TLSv1.1: server responded with version number ${DETECTED_TLS_VERSION:0:2}.${DETECTED_TLS_VERSION:2:2}"
fi
;;
- 5)
- outln "$supported_no_ciph1"
+ 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"
+ 7) fileout "tls1_1" "INFO" "TLSv1.1 is not tested due to lack of local support"
;; # no local support
esac
@@ -4504,52 +3946,47 @@ run_protocols() {
run_prototest_openssl "-tls1_2"
fi
case $? in
- 0)
- pr_done_bestln "offered (OK)"
+ 0) prln_done_best "offered (OK)"
fileout "tls1_2" "OK" "TLSv1.2 is offered"
latest_supported="0303"
latest_supported_string="TLSv1.2"
add_tls_offered "tls1_2"
;; # GCM cipher in TLS 1.2: very good!
- 1)
- pr_svrty_medium "not offered"
+ 1) pr_svrty_medium "not offered"
if ! "$using_sockets" || [[ -z $latest_supported ]]; then
outln
fileout "tls1_2" "MEDIUM" "TLSv1.2 is not offered" # no GCM, penalty
else
- pr_svrty_criticalln " -- connection failed rather than downgrading to $latest_supported_string"
+ prln_svrty_critical " -- connection failed rather than downgrading to $latest_supported_string"
fileout "tls1_2" "CRITICAL" "TLSv1.2: connection failed rather than downgrading to $latest_supported_string"
fi
;;
- 2)
- pr_svrty_medium "not offered"
+ 2) pr_svrty_medium "not offered"
if [[ "$DETECTED_TLS_VERSION" == "0300" ]]; then
detected_version_string="SSLv3"
elif [[ "$DETECTED_TLS_VERSION" == 03* ]]; then
detected_version_string="TLSv1.$((0x$DETECTED_TLS_VERSION-0x0301))"
fi
if [[ "$DETECTED_TLS_VERSION" == "$latest_supported" ]]; then
- [[ $DEBUG -eq 1 ]] && out " -- downgraded"
+ [[ $DEBUG -eq 1 ]] && tm_out " -- downgraded"
outln
fileout "tls1_2" "MEDIUM" "TLSv1.2 is not offered and downgraded to a weaker protocol"
elif [[ "$DETECTED_TLS_VERSION" == 03* ]] && [[ 0x$DETECTED_TLS_VERSION -lt 0x$latest_supported ]]; then
- pr_svrty_criticalln " -- server supports $latest_supported_string, but downgraded to $detected_version_string"
+ prln_svrty_critical " -- server supports $latest_supported_string, but downgraded to $detected_version_string"
fileout "tls1_2" "CRITICAL" "TLSv1.2 is not offered, and downgraded to $detected_version_string rather than $latest_supported_string"
elif [[ "$DETECTED_TLS_VERSION" == 03* ]] && [[ 0x$DETECTED_TLS_VERSION -gt 0x0303 ]]; then
- pr_svrty_criticalln " -- server responded with higher version number ($detected_version_string) than requested by client"
+ prln_svrty_critical " -- server responded with higher version number ($detected_version_string) than requested by client"
fileout "tls1_2" "CRITICAL" "TLSv1.2 is not offered, server responded with higher version number ($detected_version_string) than requested by client"
else
- pr_svrty_criticalln " -- server responded with version number ${DETECTED_TLS_VERSION:0:2}.${DETECTED_TLS_VERSION:2:2}"
+ prln_svrty_critical " -- server responded with version number ${DETECTED_TLS_VERSION:0:2}.${DETECTED_TLS_VERSION:2:2}"
fileout "tls1_2" "CRITICAL" "TLSv1.2: server responded with version number ${DETECTED_TLS_VERSION:0:2}.${DETECTED_TLS_VERSION:2:2}"
fi
;;
- 5)
- outln "$supported_no_ciph1"
+ 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"
+ 7) fileout "tls1_2" "INFO" "TLSv1.2 is not tested due to lack of local support"
;; # no local support
esac
return 0
@@ -4613,6 +4050,44 @@ run_std_cipherlists() {
return 0
}
+pr_dh_quality() {
+ local bits="$1"
+ local string="$2"
+
+ if [[ "$bits" -le 600 ]]; then
+ pr_svrty_critical "$string"
+ elif [[ "$bits" -le 800 ]]; then
+ pr_svrty_high "$string"
+ elif [[ "$bits" -le 1280 ]]; then
+ pr_svrty_medium "$string"
+ elif [[ "$bits" -ge 2048 ]]; then
+ pr_done_good "$string"
+ else
+ out "$string"
+ fi
+}
+
+pr_ecdh_quality() {
+ local bits="$1"
+ local string="$2"
+
+ if [[ "$bits" -le 80 ]]; then # has that ever existed?
+ pr_svrty_critical "$string"
+ elif [[ "$bits" -le 108 ]]; then # has that ever existed?
+ pr_svrty_high "$string"
+ elif [[ "$bits" -le 163 ]]; then
+ pr_svrty_medium "$string"
+ elif [[ "$bits" -le 193 ]]; then # hmm, according to https://wiki.openssl.org/index.php/Elliptic_Curve_Cryptography it should ok
+ pr_svrty_low "$string" # but openssl removed it https://github.com/drwetter/testssl.sh/issues/299#issuecomment-220905416
+ elif [[ "$bits" -le 224 ]]; then
+ out "$string"
+ elif [[ "$bits" -gt 224 ]]; then
+ pr_done_good "$string"
+ else
+ out "$string"
+ fi
+}
+
pr_ecdh_curve_quality() {
curve="$1"
local -i bits=0
@@ -4649,29 +4124,14 @@ pr_ecdh_curve_quality() {
"X25519") bits=253 ;;
"X448") bits=448 ;;
esac
-
- if [[ "$bits" -le 80 ]]; then # has that ever existed?
- pr_svrty_critical "$curve"
- elif [[ "$bits" -le 108 ]]; then # has that ever existed?
- pr_svrty_high "$curve"
- elif [[ "$bits" -le 163 ]]; then
- pr_svrty_medium "$curve"
- elif [[ "$bits" -le 193 ]]; then # hmm, according to https://wiki.openssl.org/index.php/Elliptic_Curve_Cryptography it should ok
- pr_svrty_low "$curve" # but openssl removed it https://github.com/drwetter/testssl.sh/issues/299#issuecomment-220905416
- elif [[ "$bits" -le 224 ]]; then
- out "$curve"
- elif [[ "$bits" -gt 224 ]]; then
- pr_done_good "$curve"
- else
- out "$curve"
- fi
+ pr_ecdh_quality "$bits" "$curve"
}
# Print $2 based on the quality of the cipher in $1. If $2 is empty, print $1.
# The return value is an indicator of the quality of the cipher in $1:
# 0 = $1 is empty
# 1 = pr_svrty_critical, 2 = pr_svrty_high, 3 = pr_svrty_medium, 4 = pr_svrty_low
-# 5 = neither good nor bad, 6 = pr_done_good, 7 = pr_done_best
+# 5 = neither good nor bad, 6 = pr_done_good, 7 = pr_done_best
pr_cipher_quality() {
local cipher="$1"
local text="$2"
@@ -4764,57 +4224,46 @@ read_dhbits_from_file() {
what_dh="ECDH"
fi
- if [[ -n "$curve" ]]; then
- debugme echo ">$HAS_DH_BITS|$what_dh($curve)|$bits<"
- else
- debugme echo ">$HAS_DH_BITS|$what_dh|$bits<"
+ if [[ -z "$2" ]]; then
+ if [[ -n "$curve" ]]; then
+ debugme echo ">$HAS_DH_BITS|$what_dh($curve)|$bits<"
+ else
+ debugme echo ">$HAS_DH_BITS|$what_dh|$bits<"
+ fi
fi
[[ -n "$what_dh" ]] && HAS_DH_BITS=true # FIX 190
if [[ -z "$what_dh" ]] && ! "$HAS_DH_BITS"; then
- if [[ -z "$2" ]]; then
+ if [[ "$2" == "string" ]]; then
+ tm_out "$old_fart"
+ elif [[ -z "$2" ]]; then
pr_warning "$old_fart"
fi
return 0
fi
- [[ -n "$bits" ]] && [[ -z "$2" ]] && out ", "
+ if [[ "$2" == "quiet" ]]; then
+ tm_out "$bits"
+ return 0
+ fi
+
+ [[ -z "$2" ]] && [[ -n "$bits" ]] && out ", "
if [[ $what_dh == "DH" ]] || [[ $what_dh == "EDH" ]]; then
- if [[ -z "$2" ]]; then
- add="bit DH"
- [[ -n "$curve" ]] && add+=" ($curve)"
- fi
- if [[ "$bits" -le 600 ]]; then
- pr_svrty_critical "$bits $add"
- elif [[ "$bits" -le 800 ]]; then
- pr_svrty_high "$bits $add"
- elif [[ "$bits" -le 1280 ]]; then
- pr_svrty_medium "$bits $add"
- elif [[ "$bits" -ge 2048 ]]; then
- pr_done_good "$bits $add"
+ add="bit DH"
+ [[ -n "$curve" ]] && add+=" ($curve)"
+ if [[ "$2" == "string" ]]; then
+ tm_out ", $bits $add"
else
- out "$bits $add"
+ pr_dh_quality "$bits" "$bits $add"
fi
# https://wiki.openssl.org/index.php/Elliptic_Curve_Cryptography, http://www.keylength.com/en/compare/
elif [[ $what_dh == "ECDH" ]]; then
- if [[ -z "$2" ]]; then
- add="bit ECDH"
- [[ -n "$curve" ]] && add+=" ($curve)"
- fi
- if [[ "$bits" -le 80 ]]; then # has that ever existed?
- pr_svrty_critical "$bits $add"
- elif [[ "$bits" -le 108 ]]; then # has that ever existed?
- pr_svrty_high "$bits $add"
- elif [[ "$bits" -le 163 ]]; then
- pr_svrty_medium "$bits $add"
- elif [[ "$bits" -le 193 ]]; then # hmm, according to https://wiki.openssl.org/index.php/Elliptic_Curve_Cryptography it should ok
- pr_svrty_low "$bits $add" # but openssl removed it https://github.com/drwetter/testssl.sh/issues/299#issuecomment-220905416
- elif [[ "$bits" -le 224 ]]; then
- out "$bits $add"
- elif [[ "$bits" -gt 224 ]]; then
- pr_done_good "$bits $add"
+ add="bit ECDH"
+ [[ -n "$curve" ]] && add+=" ($curve)"
+ if [[ "$2" == "string" ]]; then
+ tm_out ", $bits $add"
else
- out "$bits $add"
+ pr_ecdh_quality "$bits" "$bits $add"
fi
fi
@@ -4863,7 +4312,7 @@ run_server_preference() {
elif [[ -n "$STARTTLS_PROTOCOL" ]]; then
# now it still could be that we hit this bug: https://github.com/drwetter/testssl.sh/issues/188
# workaround is to connect with a protocol
- debugme out "(workaround #188) "
+ debugme tm_out "(workaround #188) "
determine_optimal_proto $STARTTLS_PROTOCOL
$OPENSSL s_client $STARTTLS $STARTTLS_OPTIMAL_PROTO -cipher $list_fwd $BUGS -connect $NODEIP:$PORT $PROXY $addcmd2 $ERRFILE >$TMPFILE
if ! sclient_connect_successful $? $TMPFILE; then
@@ -4876,7 +4325,7 @@ run_server_preference() {
fi
if "$has_cipher_order"; then
- cipher1=$(grep -wa Cipher $TMPFILE | egrep -avw "New|is" | sed -e 's/^ \+Cipher \+://' -e 's/ //g')
+ cipher1=$(get_cipher $TMPFILE)
addcmd2=""
if [[ -n "$STARTTLS_OPTIMAL_PROTO" ]]; then
addcmd2="$STARTTLS_OPTIMAL_PROTO"
@@ -4891,7 +4340,7 @@ run_server_preference() {
fi
$OPENSSL s_client $STARTTLS -cipher $list_reverse $BUGS -connect $NODEIP:$PORT $PROXY $addcmd2 >$ERRFILE >$TMPFILE
# that worked above so no error handling here
- cipher2=$(grep -wa Cipher $TMPFILE | egrep -avw "New|is" | sed -e 's/^ \+Cipher \+://' -e 's/ //g')
+ cipher2=$(get_cipher $TMPFILE)
if [[ "$cipher1" != "$cipher2" ]]; then
pr_svrty_high "nope (NOT ok)"
@@ -4902,7 +4351,7 @@ run_server_preference() {
remark4default_cipher=""
fileout "order" "OK" "Server sets a cipher order"
fi
- debugme out " $cipher1 | $cipher2"
+ debugme tm_out " $cipher1 | $cipher2"
outln
pr_bold " Negotiated protocol "
@@ -4912,14 +4361,14 @@ run_server_preference() {
$OPENSSL s_client $STARTTLS $OPTIMAL_PROTO $BUGS -connect $NODEIP:$PORT $PROXY $sni >$ERRFILE >$TMPFILE
sclient_connect_successful $? $TMPFILE || pr_warning "Handshake error!"
fi
- default_proto=$(grep -aw "Protocol" $TMPFILE | sed -e 's/^.*Protocol.*://' -e 's/ //g')
+ default_proto=$(get_protocol $TMPFILE)
case "$default_proto" in
*TLSv1.2)
- pr_done_bestln $default_proto
+ prln_done_best $default_proto
fileout "order_proto" "OK" "Default protocol TLS1.2"
;;
*TLSv1.1)
- pr_done_goodln $default_proto
+ prln_done_good $default_proto
fileout "order_proto" "OK" "Default protocol TLS1.1"
;;
*TLSv1)
@@ -4927,11 +4376,11 @@ run_server_preference() {
fileout "order_proto" "INFO" "Default protocol TLS1.0"
;;
*SSLv2)
- pr_svrty_criticalln $default_proto
+ prln_svrty_critical $default_proto
fileout "order_proto" "CRITICAL" "Default protocol SSLv2"
;;
*SSLv3)
- pr_svrty_criticalln $default_proto
+ prln_svrty_critical $default_proto
fileout "order_proto" "CRITICAL" "Default protocol SSLv3"
;;
"")
@@ -4950,7 +4399,7 @@ run_server_preference() {
esac
pr_bold " Negotiated cipher "
- default_cipher_ossl=$(grep -aw "Cipher" $TMPFILE | egrep -avw "New|is" | sed -e 's/^.*Cipher.*://' -e 's/ //g')
+ default_cipher_ossl=$(get_cipher $TMPFILE)
if [[ "$DISPLAY_CIPHERNAMES" =~ openssl ]]; then
default_cipher="$default_cipher_ossl"
else
@@ -4959,23 +4408,17 @@ run_server_preference() {
fi
pr_cipher_quality "$default_cipher"
case $? in
- 1)
- fileout "order_cipher" "CRITICAL" "Default cipher: $default_cipher$(read_dhbits_from_file "$TMPFILE") $remark4default_cipher"
+ 1) fileout "order_cipher" "CRITICAL" "Default cipher: $default_cipher$(read_dhbits_from_file "$TMPFILE" "string") $remark4default_cipher"
;;
- 2)
- fileout "order_cipher" "HIGH" "Default cipher: $default_cipher$(read_dhbits_from_file "$TMPFILE") $remark4default_cipher"
+ 2) fileout "order_cipher" "HIGH" "Default cipher: $default_cipher$(read_dhbits_from_file "$TMPFILE" "string") $remark4default_cipher"
;;
- 3)
- fileout "order_cipher" "MEDIUM" "Default cipher: $default_cipher$(read_dhbits_from_file "$TMPFILE") $remark4default_cipher"
+ 3) fileout "order_cipher" "MEDIUM" "Default cipher: $default_cipher$(read_dhbits_from_file "$TMPFILE" "string") $remark4default_cipher"
;;
- 6|7)
- fileout "order_cipher" "OK" "Default cipher: $default_cipher$(read_dhbits_from_file "$TMPFILE") $remark4default_cipher"
+ 6|7) fileout "order_cipher" "OK" "Default cipher: $default_cipher$(read_dhbits_from_file "$TMPFILE" "string") $remark4default_cipher"
;; # best ones
- 4)
- fileout "order_cipher" "LOW" "Default cipher: $default_cipher$(read_dhbits_from_file "$TMPFILE") (cbc) $remark4default_cipher"
+ 4) fileout "order_cipher" "LOW" "Default cipher: $default_cipher$(read_dhbits_from_file "$TMPFILE" "string") (cbc) $remark4default_cipher"
;; # it's CBC. --> lucky13
- 0)
- pr_warning "default cipher empty" ;
+ 0) pr_warning "default cipher empty" ;
if [[ $OSSL_VER == 1.0.2* ]]; then
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"
@@ -4983,8 +4426,7 @@ run_server_preference() {
fileout "order_cipher" "WARN" "Default cipher empty $remark4default_cipher"
fi
;;
- *)
- fileout "order_cipher" "INFO" "Default cipher: $default_cipher$(read_dhbits_from_file "$TMPFILE") $remark4default_cipher"
+ *) fileout "order_cipher" "INFO" "Default cipher: $default_cipher$(read_dhbits_from_file "$TMPFILE" "string") $remark4default_cipher"
;;
esac
read_dhbits_from_file "$TMPFILE"
@@ -4997,7 +4439,7 @@ run_server_preference() {
for p in ssl2 ssl3 tls1 tls1_1 tls1_2; do
if [[ $p == ssl2 ]] && ! "$HAS_SSL2"; then
if ! "$using_sockets" || [[ $TLS_NR_CIPHERS -eq 0 ]]; then
- out " (SSLv2: "; local_problem "$OPENSSL doesn't support \"s_client -ssl2\""; outln ")";
+ out " (SSLv2: "; pr_local_problem "$OPENSSL doesn't support \"s_client -ssl2\""; outln ")";
continue
else
sslv2_sockets "" "true"
@@ -5019,7 +4461,7 @@ run_server_preference() {
fi
fi
done
- [[ $DEBUG -ge 2 ]] && outln "Default cipher for ${proto[i]}: ${cipher[i]}"
+ [[ $DEBUG -ge 2 ]] && tmln_out "Default cipher for ${proto[i]}: ${cipher[i]}"
else
proto[i]=""
cipher[i]=""
@@ -5027,7 +4469,7 @@ run_server_preference() {
fi
elif [[ $p == ssl3 ]] && ! "$HAS_SSL3"; then
if ! "$using_sockets"; then
- out " (SSLv3: "; local_problem "$OPENSSL doesn't support \"s_client -ssl3\"" ; outln ")";
+ out " (SSLv3: "; pr_local_problem "$OPENSSL doesn't support \"s_client -ssl3\"" ; outln ")";
continue
else
tls_sockets "00" "$TLS_CIPHER"
@@ -5039,7 +4481,7 @@ run_server_preference() {
cipher[i]="$(rfc2openssl "$cipher1")"
[[ -z "${cipher[i]}" ]] && cipher[i]="$cipher1"
fi
- [[ $DEBUG -ge 2 ]] && outln "Default cipher for ${proto[i]}: ${cipher[i]}"
+ [[ $DEBUG -ge 2 ]] && tmln_out "Default cipher for ${proto[i]}: ${cipher[i]}"
else
proto[i]=""
cipher[i]=""
@@ -5049,14 +4491,14 @@ run_server_preference() {
[[ "$p" =~ ssl ]] && sni="" || sni="$SNI"
$OPENSSL s_client $STARTTLS -"$p" $BUGS -connect $NODEIP:$PORT $PROXY $sni >$ERRFILE >$TMPFILE
if sclient_connect_successful $? $TMPFILE; then
- proto[i]=$(grep -aw "Protocol" $TMPFILE | sed -e 's/^.*Protocol.*://' -e 's/ //g')
- cipher[i]=$(grep -aw "Cipher" $TMPFILE | egrep -avw "New|is" | sed -e 's/^.*Cipher.*://' -e 's/ //g')
+ proto[i]=$(get_protocol $TMPFILE)
+ cipher[i]=$(get_cipher $TMPFILE)
[[ ${cipher[i]} == "0000" ]] && cipher[i]="" # Hack!
if [[ "$DISPLAY_CIPHERNAMES" =~ rfc ]] && [[ -n "${cipher[i]}" ]]; then
cipher[i]="$(openssl2rfc "${cipher[i]}")"
- [[ -z "${cipher[i]}" ]] && cipher[i]=$(grep -aw "Cipher" $TMPFILE | egrep -avw "New|is" | sed -e 's/^.*Cipher.*://' -e 's/ //g')
+ [[ -z "${cipher[i]}" ]] && cipher[i]=$(get_cipher $TMPFILE)
fi
- [[ $DEBUG -ge 2 ]] && outln "Default cipher for ${proto[i]}: ${cipher[i]}"
+ [[ $DEBUG -ge 2 ]] && tmln_out "Default cipher for ${proto[i]}: ${cipher[i]}"
else
proto[i]=""
cipher[i]=""
@@ -5075,12 +4517,12 @@ run_server_preference() {
if [[ -z "${proto[i]}" ]]; then
cipher[i]=""
else
- cipher[i]=$(grep -aw "Cipher" $TMPFILE | egrep -avw "New|is" | sed -e 's/^.*Cipher.*://' -e 's/ //g')
+ cipher[i]=$(get_cipher $TMPFILE)
if [[ "$DISPLAY_CIPHERNAMES" =~ rfc ]] && [[ -n "${cipher[i]}" ]]; then
cipher[i]="$(openssl2rfc "${cipher[i]}")"
- [[ -z "${cipher[i]}" ]] && cipher[i]=$(grep -aw "Cipher" $TMPFILE | egrep -avw "New|is" | sed -e 's/^.*Cipher.*://' -e 's/ //g')
+ [[ -z "${cipher[i]}" ]] && cipher[i]=$(get_cipher $TMPFILE)
fi
- [[ $DEBUG -ge 2 ]] && outln "Default cipher for ${proto[i]}: ${cipher[i]}"
+ [[ $DEBUG -ge 2 ]] && tmln_out "Default cipher for ${proto[i]}: ${cipher[i]}"
fi
fi
else
@@ -5092,14 +4534,14 @@ run_server_preference() {
if [[ -z "$prev_cipher" ]] || [[ "$prev_cipher" != "${cipher[i]}" ]]; then
[[ -n "$prev_cipher" ]] && outln
if [[ "$DISPLAY_CIPHERNAMES" =~ openssl ]]; then
- printf -- " %-30s %s" "${cipher[i]}:" "${proto[i]}" # print out both
+ out "$(printf -- " %-30s %s" "${cipher[i]}:" "${proto[i]}")" # print out both
else
- printf -- " %-51s %s" "${cipher[i]}:" "${proto[i]}" # print out both
+ out "$(printf -- " %-51s %s" "${cipher[i]}:" "${proto[i]}")" # print out both
fi
- else
+ else
out ", ${proto[i]}" # same cipher --> only print out protocol behind it
- fi
- prev_cipher="${cipher[i]}"
+ fi
+ prev_cipher="${cipher[i]}"
fi
fileout "order_${proto[i]}_cipher" "INFO" "Default cipher on ${proto[i]}: ${cipher[i]} $remark4default_cipher"
done
@@ -5132,7 +4574,7 @@ check_tls12_pref() {
nr_ciphers_found_r1+=1
"$FAST" && break
else
- debugme outln "A: $tested_cipher"
+ debugme tmln_out "A: $tested_cipher"
break
fi
done
@@ -5147,10 +4589,10 @@ check_tls12_pref() {
order+=" $cipher"
batchremoved="$batchremoved:-$cipher"
nr_ciphers_found_r1+=1
- debugme outln "B1: $batchremoved"
+ debugme tmln_out "B1: $batchremoved"
"$FAST" && break
else
- debugme outln "B2: $batchremoved"
+ debugme tmln_out "B2: $batchremoved"
break
# nothing left with batchremoved ciphers, we need to put everything together
fi
@@ -5175,14 +4617,14 @@ check_tls12_pref() {
fi
done
if "$FAST" && [[ $nr_ciphers_found_r2 -ne 1 ]]; then
- fixmeln "something weird happened around line $((LINENO - 14))"
+ prln_fixme "something weird happened around line $((LINENO - 14))"
return 1
elif ! "$FAST" && [[ $nr_ciphers_found_r2 -ne $nr_ciphers_found_r1 ]]; then
- fixmeln "something weird happened around line $((LINENO - 16))"
+ prln_fixme "something weird happened around line $((LINENO - 16))"
return 1
fi
fi
- out "$order"
+ tm_out "$order"
tmpfile_handle $FUNCNAME.txt
return 0
@@ -5205,10 +4647,10 @@ cipher_pref_check() {
pr_bold " Cipher order"
- outln " ssl3 00 SSLv3\n tls1 01 TLSv1\n tls1_1 02 TLSv1.1\n tls1_2 03 TLSv1.2"| while read p proto_hex proto; do
+ tm_out " ssl3 00 SSLv3\n tls1 01 TLSv1\n tls1_1 02 TLSv1.1\n tls1_2 03 TLSv1.2\n" | while read p proto_hex proto; do
order=""; ciphers_found_with_sockets=false
if [[ $p == ssl3 ]] && ! "$HAS_SSL3" && ! "$using_sockets"; then
- out "\n SSLv3: "; local_problem "$OPENSSL doesn't support \"s_client -ssl3\"";
+ out "\n SSLv3: "; pr_local_problem "$OPENSSL doesn't support \"s_client -ssl3\"";
continue
fi
has_server_protocol "$p" || continue
@@ -5376,7 +4818,7 @@ cipher_pref_check() {
if [[ -n "$order" ]]; then
outln
- printf " %-10s " "$proto: "
+ out "$(printf " %-10s " "$proto: ")"
out_row_aligned_max_width "$order" " " $TERM_WIDTH out
fileout "order_$p" "INFO" "Default cipher order for protocol $p: $order"
fi
@@ -5391,7 +4833,7 @@ cipher_pref_check() {
order=""
$OPENSSL s_client $BUGS -nextprotoneg "$p" -connect $NODEIP:$PORT $SNI >$ERRFILE >$TMPFILE
cipher=$(awk '/Cipher.*:/ { print $3 }' $TMPFILE)
- printf " %-10s " "$p:"
+ out "$(printf " %-10s " "$p:")"
tested_cipher="-"$cipher
order="$cipher "
if ! "$FAST"; then
@@ -5436,7 +4878,7 @@ get_host_cert() {
awk '/-----BEGIN/,/-----END/ { print $0 }' $tmpvar >$HOSTCERT
return 0
else
- [[ -z "$1" ]] && pr_warningln "could not retrieve host certificate!"
+ [[ -z "$1" ]] && prln_warning "could not retrieve host certificate!"
#fileout "host_certificate" "WARN" "Could not retrieve host certificate!"
return 1
fi
@@ -5450,17 +4892,17 @@ verify_retcode_helper() {
case $retcode in
# codes from ./doc/apps/verify.pod | verify(1ssl)
- 26) out "(unsupported certificate purpose)" ;; # X509_V_ERR_INVALID_PURPOSE
- 24) out "(certificate unreadable)" ;; # X509_V_ERR_INVALID_CA
- 23) out "(certificate revoked)" ;; # X509_V_ERR_CERT_REVOKED
- 21) out "(chain incomplete, only 1 cert provided)" ;; # X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE
- 20) out "(chain incomplete)" ;; # X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY
- 19) out "(self signed CA in chain)" ;; # X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN
- 18) out "(self signed)" ;; # X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT
- 10) out "(expired)" ;; # X509_V_ERR_CERT_HAS_EXPIRED
- 9) out "(not yet valid)" ;; # X509_V_ERR_CERT_NOT_YET_VALID
- 2) out "(issuer cert missing)" ;; # X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT
- *) ret=1 ; pr_warning " (unknown, pls report) $1" ;;
+ 26) tm_out "(unsupported certificate purpose)" ;; # X509_V_ERR_INVALID_PURPOSE
+ 24) tm_out "(certificate unreadable)" ;; # X509_V_ERR_INVALID_CA
+ 23) tm_out "(certificate revoked)" ;; # X509_V_ERR_CERT_REVOKED
+ 21) tm_out "(chain incomplete, only 1 cert provided)" ;; # X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE
+ 20) tm_out "(chain incomplete)" ;; # X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY
+ 19) tm_out "(self signed CA in chain)" ;; # X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN
+ 18) tm_out "(self signed)" ;; # X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT
+ 10) tm_out "(expired)" ;; # X509_V_ERR_CERT_HAS_EXPIRED
+ 9) tm_out "(not yet valid)" ;; # X509_V_ERR_CERT_NOT_YET_VALID
+ 2) tm_out "(issuer cert missing)" ;; # X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT
+ *) ret=1 ; tm_out " (unknown, pls report) $1" ;;
esac
return $ret
}
@@ -5492,7 +4934,7 @@ determine_trust() {
addtl_warning="(Your $OPENSSL <= 1.0.2 might be too unreliable to determine trust)"
fileout "${json_prefix}chain_of_trust_warn" "WARN" "$addtl_warning"
fi
- debugme outln
+ debugme tmln_out
# if you run testssl.sh from a different path /you can set either TESTSSL_INSTALL_DIR or CA_BUNDLES_PATH to find the CA BUNDLES
if [[ -z $CA_BUNDLES_PATH ]]; then
@@ -5503,7 +4945,7 @@ determine_trust() {
for bundle_fname in $ca_bundles; do
certificate_file[i]=$(basename ${bundle_fname//.pem})
if [[ ! -r $bundle_fname ]]; then
- pr_warningln "\"$bundle_fname\" cannot be found / not readable"
+ prln_warning "\"$bundle_fname\" cannot be found / not readable"
return 7
fi
debugme printf -- " %-12s" "${certificate_file[i]}"
@@ -5519,18 +4961,18 @@ determine_trust() {
if [[ ${verify_retcode[i]} -eq 0 ]]; then
trust[i]=true
some_ok=true
- debugme pr_done_good "Ok "
- debugme outln "${verify_retcode[i]}"
+ debugme tm_done_good "Ok "
+ debugme tmln_out "${verify_retcode[i]}"
else
trust[i]=false
all_ok=false
- debugme pr_svrty_high "not trusted "
- debugme outln "${verify_retcode[i]}"
+ debugme tm_svrty_high "not trusted "
+ debugme tmln_out "${verify_retcode[i]}"
fi
i=$((i + 1))
done
num_ca_bundles=$((i - 1))
- debugme out " "
+ debugme tm_out " "
if $all_ok; then
# all stores ok
pr_done_good "Ok "; pr_warning "$addtl_warning"
@@ -5542,8 +4984,13 @@ determine_trust() {
if ! $some_ok; then
# all failed (we assume with the same issue), we're displaying the reason
out " "
- verify_retcode_helper "${verify_retcode[1]}"
- fileout "${json_prefix}chain_of_trust" "CRITICAL" "All certificate trust checks failed: $(verify_retcode_helper "${verify_retcode[1]}"). $addtl_warning"
+ code="$(verify_retcode_helper "${verify_retcode[1]}")"
+ if [[ "$code" =~ "pls report" ]]; then
+ pr_warning "$code"
+ else
+ out "$code"
+ fi
+ fileout "${json_prefix}chain_of_trust" "CRITICAL" "All certificate trust checks failed: $code. $addtl_warning"
else
# is one ok and the others not ==> display the culprit store
if $some_ok ; then
@@ -5555,15 +5002,20 @@ determine_trust() {
#code="$(verify_retcode_helper ${verify_retcode[i]})"
#notok_was="${certificate_file[i]} $notok_was"
pr_svrty_high " ${certificate_file[i]} "
- verify_retcode_helper "${verify_retcode[i]}"
- notok_was="${certificate_file[i]} $(verify_retcode_helper "${verify_retcode[i]}") $notok_was"
+ code="$(verify_retcode_helper "${verify_retcode[i]}")"
+ if [[ "$code" =~ "pls report" ]]; then
+ pr_warning "$code"
+ else
+ out "$code"
+ fi
+ notok_was="${certificate_file[i]} $code $notok_was"
fi
done
#pr_svrty_high "$notok_was "
#outln "$code"
outln
# lf + green ones
- [[ "$DEBUG" -eq 0 ]] && out "$spaces"
+ [[ "$DEBUG" -eq 0 ]] && tm_out "$spaces"
pr_done_good "OK: $ok_was"
fi
fileout "${json_prefix}chain_of_trust" "CRITICAL" "Some certificate trust checks failed : OK : $ok_was NOT ok: $notok_was $addtl_warning"
@@ -5597,10 +5049,10 @@ tls_time() {
out "$difftime"; out " sec from localtime";
fileout "tls_time" "INFO" "Your TLS time is skewed from your localtime by $difftime seconds"
fi
- debugme out "$TLS_TIME"
+ debugme tm_out "$TLS_TIME"
outln
else
- pr_warningln "SSLv3 through TLS 1.2 didn't return a timestamp"
+ prln_warning "SSLv3 through TLS 1.2 didn't return a timestamp"
fileout "tls_time" "INFO" "No TLS timestamp returned by SSLv3 through TLSv1.2"
fi
return 0
@@ -5778,7 +5230,7 @@ get_server_certificate() {
$OPENSSL s_client $STARTTLS $BUGS $1 -showcerts -connect $NODEIP:$PORT $PROXY $addcmd -$proto -tlsextdebug >$ERRFILE >$TMPFILE
if ! sclient_connect_successful $? $TMPFILE; then
if [ -z "$1" ]; then
- pr_warningln "Strange, no SSL/TLS protocol seems to be supported (error around line $((LINENO - 6)))"
+ prln_warning "Strange, no SSL/TLS protocol seems to be supported (error around line $((LINENO - 6)))"
fi
tmpfile_handle $FUNCNAME.txt
return 7 # this is ugly, I know
@@ -5978,11 +5430,11 @@ must_staple() {
local cert extn
local -i extn_len
local supported=false
-
+
# Note this function is only looking for status_request (5) and not
# status_request_v2 (17), since OpenSSL seems to only include status_request (5)
# in its ClientHello when the "-status" option is used.
-
+
# OpenSSL 1.1.0 supports pretty-printing the "TLS Feature extension." For any
# previous versions of OpenSSL, OpenSSL can only show if the extension OID is present.
if $OPENSSL x509 -in "$HOSTCERT" -noout -text 2>>$ERRFILE | grep -A 1 "TLS Feature:" | grep -q "status_request"; then
@@ -6007,7 +5459,7 @@ must_staple() {
fi
if "$supported"; then
- pr_done_bestln "Supported"
+ prln_done_best "Supported"
fileout "${json_prefix}ocsp_must_staple" "OK" "OCSP must staple : supported"
return 0
else
@@ -6074,19 +5526,19 @@ certificate_info() {
fileout "${json_prefix}algorithm" "INFO" "Signature Algorithm: SHA224 with RSA"
;;
sha256WithRSAEncryption)
- pr_done_goodln "SHA256 with RSA"
+ prln_done_good "SHA256 with RSA"
fileout "${json_prefix}algorithm" "OK" "Signature Algorithm: SHA256 with RSA"
;;
sha384WithRSAEncryption)
- pr_done_goodln "SHA384 with RSA"
+ prln_done_good "SHA384 with RSA"
fileout "${json_prefix}algorithm" "OK" "Signature Algorithm: SHA384 with RSA"
;;
sha512WithRSAEncryption)
- pr_done_goodln "SHA512 with RSA"
+ prln_done_good "SHA512 with RSA"
fileout "${json_prefix}algorithm" "OK" "Signature Algorithm: SHA512 with RSA"
;;
ecdsa-with-SHA1)
- pr_svrty_mediumln "ECDSA with SHA1"
+ prln_svrty_medium "ECDSA with SHA1"
fileout "${json_prefix}algorithm" "MEDIUM" "Signature Algorithm: ECDSA with SHA1"
;;
ecdsa-with-SHA224)
@@ -6094,19 +5546,19 @@ certificate_info() {
fileout "${json_prefix}algorithm" "INFO" "Signature Algorithm: ECDSA with SHA224"
;;
ecdsa-with-SHA256)
- pr_done_goodln "ECDSA with SHA256"
+ prln_done_good "ECDSA with SHA256"
fileout "${json_prefix}algorithm" "OK" "Signature Algorithm: ECDSA with SHA256"
;;
ecdsa-with-SHA384)
- pr_done_goodln "ECDSA with SHA384"
+ prln_done_good "ECDSA with SHA384"
fileout "${json_prefix}algorithm" "OK" "Signature Algorithm: ECDSA with SHA384"
;;
ecdsa-with-SHA512)
- pr_done_goodln "ECDSA with SHA512"
+ prln_done_good "ECDSA with SHA512"
fileout "${json_prefix}algorithm" "OK" "Signature Algorithm: ECDSA with SHA512"
;;
dsaWithSHA1)
- pr_svrty_mediumln "DSA with SHA1"
+ prln_svrty_medium "DSA with SHA1"
fileout "${json_prefix}algorithm" "MEDIUM" "Signature Algorithm: DSA with SHA1"
;;
dsa_with_SHA224)
@@ -6114,14 +5566,14 @@ certificate_info() {
fileout "${json_prefix}algorithm" "INFO" "Signature Algorithm: DSA with SHA224"
;;
dsa_with_SHA256)
- pr_done_goodln "DSA with SHA256"
+ prln_done_good "DSA with SHA256"
fileout "${json_prefix}algorithm" "OK" "Signature Algorithm: DSA with SHA256"
;;
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"
+ prln_svrty_medium "RSASSA-PSS with SHA1"
fileout "${json_prefix}algorithm" "MEDIUM" "Signature Algorithm: RSASSA-PSS with SHA1"
;;
sha224)
@@ -6129,33 +5581,33 @@ certificate_info() {
fileout "${json_prefix}algorithm" "INFO" "Signature Algorithm: RSASSA-PSS with SHA224"
;;
sha256)
- pr_done_goodln "RSASSA-PSS with SHA256"
+ prln_done_good "RSASSA-PSS with SHA256"
fileout "${json_prefix}algorithm" "OK" "Signature Algorithm: RSASSA-PSS with SHA256"
;;
sha384)
- pr_done_goodln "RSASSA-PSS with SHA384"
+ prln_done_good "RSASSA-PSS with SHA384"
fileout "${json_prefix}algorithm" "OK" "Signature Algorithm: RSASSA-PSS with SHA384"
;;
sha512)
- pr_done_goodln "RSASSA-PSS with SHA512"
+ prln_done_good "RSASSA-PSS with SHA512"
fileout "${json_prefix}algorithm" "OK" "Signature Algorithm: RSASSA-PSS with SHA512"
;;
*)
out "RSASSA-PSS with $cert_sig_hash_algo"
- pr_warningln " (Unknown hash algorithm)"
+ prln_warning " (Unknown hash algorithm)"
fileout "${json_prefix}algorithm" "DEBUG" "Signature Algorithm: RSASSA-PSS with $cert_sig_hash_algo"
esac
;;
md2*)
- pr_svrty_criticalln "MD2"
+ prln_svrty_critical "MD2"
fileout "${json_prefix}algorithm" "CRITICAL" "Signature Algorithm: MD2"
;;
md4*)
- pr_svrty_criticalln "MD4"
+ prln_svrty_critical "MD4"
fileout "${json_prefix}algorithm" "CRITICAL" "Signature Algorithm: MD4"
;;
md5*)
- pr_svrty_criticalln "MD5"
+ prln_svrty_critical "MD5"
fileout "${json_prefix}algorithm" "CRITICAL" "Signature Algorithm: MD5"
;;
*)
@@ -6178,7 +5630,7 @@ certificate_info() {
*ecdsa*|*ecPublicKey) out "ECDSA ";;
*GOST*|*gost*) out "GOST ";;
*dh*|*DH*) out "DH " ;;
- *) pr_warning "fixme: $cert_key_algo " ;;
+ *) pr_fixme: "don't know $cert_key_algo " ;;
esac
# https://tools.ietf.org/html/rfc4492, http://www.keylength.com/en/compare/
# http://infoscience.epfl.ch/record/164526/files/NPDF-22.pdf
@@ -6272,9 +5724,9 @@ certificate_info() {
cn_nosni="$(get_cn_from_cert "$HOSTCERT.nosni")"
[[ -z "$cn_nosni" ]] && cn_nosni="no CN field in subject"
fi
- debugme out "\"$NODE\" | \"$cn\" | \"$cn_nosni\""
+ debugme tm_out "\"$NODE\" | \"$cn\" | \"$cn_nosni\""
else
- debugme out "\"$NODE\" | \"$cn\""
+ debugme tm_out "\"$NODE\" | \"$cn\""
fi
#FIXME: check for SSLv3/v2 and look whether it goes to a different CN (probably not polite)
@@ -6326,10 +5778,11 @@ certificate_info() {
issuer_DC="$(awk -F'=' '/DC=/ { print $2 }' <<< "$issuer")"
if [[ "$issuer_O" == "issuer=" ]] || [[ "$issuer_O" == "issuer= " ]] || [[ "$issuer_CN" == "$cn" ]]; then
- pr_svrty_criticalln "self-signed (NOT ok)"
+ prln_svrty_critical "self-signed (NOT ok)"
fileout "${json_prefix}issuer" "CRITICAL" "Issuer: selfsigned"
else
- issuerfinding="$(pr_italic "$issuer_CN")"
+ issuerfinding="$issuer_CN"
+ pr_italic "$issuer_CN"
if [[ -z "$issuer_O" ]] && [[ -n "$issuer_DC" ]]; then
for san in $issuer_DC; do
if [[ -z "$issuer_O" ]]; then
@@ -6341,14 +5794,19 @@ certificate_info() {
fi
if [[ -n "$issuer_O" ]]; then
issuerfinding+=" ("
- issuerfinding+="$(pr_italic "$issuer_O")"
+ out " ("
+ issuerfinding+="$issuer_O"
+ pr_italic "$issuer_O"
if [[ -n "$issuer_C" ]]; then
issuerfinding+=" from "
- issuerfinding+="$(pr_italic "$issuer_C")"
+ out " from "
+ issuerfinding+="$issuer_C"
+ pr_italic "$issuer_C"
fi
issuerfinding+=")"
+ out ")"
fi
- outln "$issuerfinding"
+ outln
fileout "${json_prefix}issuer" "INFO" "Issuer: $issuerfinding"
fi
@@ -6426,7 +5884,7 @@ certificate_info() {
trustfinding_nosni=""
fi
if "$has_dns_sans" && ( [[ $trust_nosni -eq 4 ]] || [[ $trust_nosni -eq 8 ]] ); then
- pr_svrty_mediumln "$trustfinding_nosni"
+ prln_svrty_medium "$trustfinding_nosni"
else
outln "$trustfinding_nosni"
fi
@@ -6478,7 +5936,7 @@ certificate_info() {
fi
expire=$($OPENSSL x509 -in $HOSTCERT -checkend 1 2>>$ERRFILE)
- if ! echo $expire | grep -qw not; then
+ if ! grep -qw not <<< "$expire" ; then
pr_svrty_critical "expired!"
expfinding="expired!"
expok="CRITICAL"
@@ -6671,7 +6129,7 @@ run_server_defaults() {
i=1
newhostcert=$(cat $HOSTCERT)
while [[ $i -le $certs_found ]]; do
- if [ "$newhostcert" == "${previous_hostcert[i]}" ]; then
+ if [[ "$newhostcert" == "${previous_hostcert[i]}" ]]; then
match_found=true
break;
fi
@@ -6756,10 +6214,10 @@ run_server_defaults() {
outln "(none)"
fileout "session_ticket" "INFO" "TLS session tickes RFC 5077 not supported"
else
- lifetime=$(echo $sessticket_str | grep -a lifetime | sed 's/[A-Za-z:() ]//g')
- unit=$(echo $sessticket_str | grep -a lifetime | sed -e 's/^.*'"$lifetime"'//' -e 's/[ ()]//g')
+ lifetime=$(grep -a lifetime <<< "$sessticket_str" | sed 's/[A-Za-z:() ]//g')
+ unit=$(grep -a lifetime <<< "$sessticket_str" | sed -e 's/^.*'"$lifetime"'//' -e 's/[ ()]//g')
out "$lifetime $unit "
- pr_svrty_lowln "(PFS requires session ticket keys to be rotated <= daily)"
+ prln_svrty_low "(PFS requires session ticket keys to be rotated <= daily)"
fileout "session_ticket" "LOW" "TLS session tickes RFC 5077 valid for $lifetime $unit (PFS requires session ticket keys to be rotated at least daily)"
fi
@@ -6809,7 +6267,7 @@ run_pfs() {
[[ $TLS_NR_CIPHERS == 0 ]] && using_sockets=false
outln
- pr_headline " Testing robust (perfect) forward secrecy"; pr_underlineln ", (P)FS -- omitting Null Authentication/Encryption, 3DES, RC4 "
+ pr_headline " Testing robust (perfect) forward secrecy"; prln_underline ", (P)FS -- omitting Null Authentication/Encryption, 3DES, RC4 "
if ! "$using_sockets"; then
[[ $TLS_NR_CIPHERS == 0 ]] && ! "$SSL_NATIVE" && ! "$FAST" && pr_warning " Cipher mapping not available, doing a fallback to openssl"
if ! "$HAS_DH_BITS" && "$WIDE"; then
@@ -6868,7 +6326,7 @@ run_pfs() {
debugme echo $(actually_supported_ciphers $pfs_cipher_list)
if [[ "$nr_supported_ciphers" -le "$CLIENT_MIN_PFS" ]]; then
outln
- local_problem_ln "You only have $nr_supported_ciphers PFS ciphers on the client side "
+ prln_local_problem "You only have $nr_supported_ciphers PFS ciphers on the client side "
fileout "pfs" "WARN" "(Perfect) Forward Secrecy tests: Skipped. You only have $nr_supported_ciphers PFS ciphers on the client site. ($CLIENT_MIN_PFS are required)"
return 1
fi
@@ -6880,7 +6338,7 @@ run_pfs() {
if [[ $sclient_success -ne 0 ]]; then
outln
- pr_svrty_mediumln " No ciphers supporting Forward Secrecy offered"
+ prln_svrty_medium " No ciphers supporting Forward Secrecy offered"
fileout "pfs" "MEDIUM" "(Perfect) Forward Secrecy : No ciphers supporting Forward Secrecy offered"
else
outln
@@ -7133,7 +6591,7 @@ spdy_pre(){
return 1
fi
if ! "$HAS_SPDY"; then
- local_problem "$OPENSSL doesn't support SPDY/NPN";
+ pr_local_problem "$OPENSSL doesn't support SPDY/NPN";
fileout "spdy_npn" "WARN" "SPDY/NPN : not tested $OPENSSL doesn't support SPDY/NPN"
return 7
fi
@@ -7154,7 +6612,7 @@ http2_pre(){
return 1
fi
if ! "$HAS_ALPN" && "$SSL_NATIVE"; then
- local_problem_ln "$OPENSSL doesn't support HTTP2/ALPN";
+ prln_local_problem "$OPENSSL doesn't support HTTP2/ALPN";
fileout "https_alpn" "WARN" "HTTP2/ALPN : HTTP/2 was not tested as $OPENSSL does not support it"
return 7
fi
@@ -7178,13 +6636,13 @@ run_spdy() {
ret=1
else
# now comes a strange thing: "Protocols advertised by server:" is empty but connection succeeded
- if echo $tmpstr | egrep -aq "h2|spdy|http" ; then
+ if egrep -aq "h2|spdy|http" <<< $tmpstr ; then
out "$tmpstr"
outln " (advertised)"
fileout "spdy_npn" "INFO" "SPDY/NPN : $tmpstr (advertised)"
ret=0
else
- pr_cyanln "please check manually, server response was ambiguous ..."
+ prln_cyan "please check manually, server response was ambiguous ..."
fileout "spdy_npn" "INFO" "SPDY/NPN : please check manually, server response was ambiguous ..."
ret=10
fi
@@ -7442,7 +6900,7 @@ fd_socket() {
proyxline=${proyxline#* }
if [[ "${proyxline%% *}" != "200" ]]; then
pr_magenta "Unable to CONNECT via proxy. "
- [[ "$PORT" != 443 ]] && pr_magentaln "Check whether your proxy supports port $PORT and the underlying protocol."
+ [[ "$PORT" != 443 ]] && prln_magenta "Check whether your proxy supports port $PORT and the underlying protocol."
return 6
fi
fi
@@ -7803,7 +7261,7 @@ get_dh_ephemeralkey() {
key_bitstring="$($OPENSSL pkey -pubin -in $tmp_der_key_file -inform DER 2> $ERRFILE)"
rm $tmp_der_key_file
[[ -z "$key_bitstring" ]] && return 1
- out "$key_bitstring"
+ tm_out "$key_bitstring"
return 0
}
@@ -8043,7 +7501,7 @@ parse_tls_serverhello() {
if [[ $tls_hello_ascii_len-$i -lt 10 ]]; then
if [[ "$process_full" == "all" ]]; then
# The entire server response should have been retrieved.
- debugme pr_warningln "Malformed message."
+ debugme tmln_warning "Malformed message."
return 1
else
# This could just be a result of the server's response being
@@ -8059,29 +7517,29 @@ parse_tls_serverhello() {
i=$i+4
if [[ $DEBUG -ge 2 ]]; then
- echo " tls_protocol (reclyr): 0x$tls_protocol"
- out " tls_content_type: 0x$tls_content_type"
+ echo " tls_protocol (reclyr): 0x$tls_protocol"
+ tm_out " tls_content_type: 0x$tls_content_type"
case $tls_content_type in
- 15) outln " (alert)" ;;
- 16) outln " (handshake)" ;;
- 17) outln " (application data)" ;;
- *) outln ;;
+ 15) tmln_out " (alert)" ;;
+ 16) tmln_out " (handshake)" ;;
+ 17) tmln_out " (application data)" ;;
+ *) tmln_out ;;
esac
echo " msg_len: $((msg_len/2))"
- outln
+ tmln_out
fi
if [[ $tls_content_type != "15" ]] && [[ $tls_content_type != "16" ]] && [[ $tls_content_type != "17" ]]; then
- debugme pr_warningln "Content type other than alert, handshake, or application data detected."
+ debugme tmln_warning "Content type other than alert, handshake, or application data detected."
return 1
elif [[ "${tls_protocol:0:2}" != "03" ]]; then
- debugme pr_warningln "Protocol record_version.major is not 03."
+ debugme tmln_warning "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
if [[ "$process_full" == "all" ]]; then
- debugme pr_warningln "Malformed message."
+ debugme tmln_warning "Malformed message."
return 1
else
# This could just be a result of the server's response being
@@ -8101,7 +7559,7 @@ parse_tls_serverhello() {
# Now check the alert messages.
tls_alert_ascii_len=${#tls_alert_ascii}
if [[ "$process_full" == "all" ]] && [[ $tls_alert_ascii_len%4 -ne 0 ]]; then
- debugme pr_warningln "Malformed message."
+ debugme tmln_warning "Malformed message."
return 1
fi
if [[ $tls_alert_ascii_len -gt 0 ]]; then
@@ -8112,7 +7570,7 @@ parse_tls_serverhello() {
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})"
+ debugme tm_out " tls_err_descr: 0x${tls_err_descr} / = $(hex2dec ${tls_err_descr})"
case $tls_err_descr in
00) tls_alert_descrip="close notify" ;;
01) tls_alert_descrip="end of early data" ;;
@@ -8158,17 +7616,17 @@ parse_tls_serverhello() {
echo "alert $tls_alert_descrip" >> $TMPFILE
echo "===============================================================================" >> $TMPFILE
if [[ $DEBUG -ge 2 ]]; then
- outln " ($tls_alert_descrip)"
- out " tls_err_level: ${tls_err_level}"
+ tmln_out " ($tls_alert_descrip)"
+ tm_out " tls_err_level: ${tls_err_level}"
case $tls_err_level in
- 01) outln " (warning)" ;;
- 02) outln " (fatal)" ;;
- *) outln ;;
+ 01) tmln_out " (warning)" ;;
+ 02) tmln_out " (fatal)" ;;
+ *) tmln_out ;;
esac
- outln
+ tmln_out
fi
if [[ "$tls_err_level" != "01" ]] && [[ "$tls_err_level" != "02" ]]; then
- debugme pr_warningln "Unexpected AlertLevel (0x$tls_err_level)."
+ debugme tmln_warning "Unexpected AlertLevel (0x$tls_err_level)."
return 1
elif [[ "$tls_err_level" == "02" ]]; then
# Fatal alert
@@ -8188,7 +7646,7 @@ parse_tls_serverhello() {
if [[ $tls_handshake_ascii_len-$i -lt 8 ]]; then
if [[ "$process_full" == "all" ]]; then
# The entire server response should have been retrieved.
- debugme pr_warningln "Malformed message."
+ debugme tmln_warning "Malformed message."
return 1
else
# This could just be a result of the server's response being
@@ -8202,34 +7660,34 @@ parse_tls_serverhello() {
i=$i+6
if [[ $DEBUG -ge 2 ]]; then
- out " handshake type: 0x${tls_msg_type}"
+ tm_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)" ;;
- 06) outln " (hello_retry_request)" ;;
- 08) outln " (encrypted_extensions)" ;;
- 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)" ;;
- 18) outln " (key_update)" ;;
- *) outln ;;
+ 00) tmln_out " (hello_request)" ;;
+ 01) tmln_out " (client_hello)" ;;
+ 02) tmln_out " (server_hello)" ;;
+ 03) tmln_out " (hello_verify_request)" ;;
+ 04) tmln_out " (NewSessionTicket)" ;;
+ 06) tmln_out " (hello_retry_request)" ;;
+ 08) tmln_out " (encrypted_extensions)" ;;
+ 0B) tmln_out " (certificate)" ;;
+ 0C) tmln_out " (server_key_exchange)" ;;
+ 0D) tmln_out " (certificate_request)" ;;
+ 0E) tmln_out " (server_hello_done)" ;;
+ 0F) tmln_out " (certificate_verify)" ;;
+ 10) tmln_out " (client_key_exchange)" ;;
+ 14) tmln_out " (finished)" ;;
+ 15) tmln_out " (certificate_url)" ;;
+ 16) tmln_out " (certificate_status)" ;;
+ 17) tmln_out " (supplemental_data)" ;;
+ 18) tmln_out " (key_update)" ;;
+ *) tmln_out ;;
esac
echo " msg_len: $((msg_len/2))"
- outln
+ tmln_out
fi
if [[ $msg_len -gt $tls_handshake_ascii_len-$i ]]; then
if [[ "$process_full" == "all" ]]; then
- debugme pr_warningln "Malformed message."
+ debugme tmln_warning "Malformed message."
return 1
else
# This could just be a result of the server's response being
@@ -8241,28 +7699,28 @@ parse_tls_serverhello() {
if [[ "$tls_msg_type" == "02" ]]; then
if [[ -n "$tls_serverhello_ascii" ]]; then
- debugme pr_warningln "Response contained more than one ServerHello handshake message."
+ debugme tmln_warning "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
elif [[ "$process_full" == "all" ]] && [[ "$tls_msg_type" == "0B" ]]; then
if [[ -n "$tls_certificate_ascii" ]]; then
- debugme pr_warningln "Response contained more than one Certificate handshake message."
+ debugme tmln_warning "Response contained more than one Certificate handshake message."
return 1
fi
tls_certificate_ascii="${tls_handshake_ascii:i:msg_len}"
tls_certificate_ascii_len=$msg_len
elif ( [[ "$process_full" == "all" ]] || [[ "$process_full" == "ephemeralkey" ]] ) && [[ "$tls_msg_type" == "0C" ]]; then
if [[ -n "$tls_serverkeyexchange_ascii" ]]; then
- debugme pr_warningln "Response contained more than one ServerKeyExchange handshake message."
+ debugme tmln_warning "Response contained more than one ServerKeyExchange handshake message."
return 1
fi
tls_serverkeyexchange_ascii="${tls_handshake_ascii:i:msg_len}"
tls_serverkeyexchange_ascii_len=$msg_len
elif [[ "$process_full" == "all" ]] && [[ "$tls_msg_type" == "16" ]]; then
if [[ -n "$tls_certificate_status_ascii" ]]; then
- debugme pr_warningln "Response contained more than one certificate_status handshake message."
+ debugme tmln_warning "Response contained more than one certificate_status handshake message."
return 1
fi
tls_certificate_status_ascii="${tls_handshake_ascii:i:msg_len}"
@@ -8279,7 +7737,7 @@ parse_tls_serverhello() {
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."
+ debugme tmln_warning "The first handshake protocol message is not a ServerHello."
return 1
fi
@@ -8293,7 +7751,7 @@ parse_tls_serverhello() {
# 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."
+ debugme tmln_warning "server_version.major in ServerHello is not 03."
return 1
fi
DETECTED_TLS_VERSION="$tls_protocol2"
@@ -8330,7 +7788,7 @@ parse_tls_serverhello() {
fi
tls_extensions_len=$(hex2dec "${tls_serverhello_ascii:extns_offset:4}")*2
if [[ $tls_extensions_len -ne $tls_serverhello_ascii_len-$extns_offset-4 ]]; then
- debugme pr_warningln "Malformed message."
+ debugme tmln_warning "Malformed message."
return 1
fi
for (( i=0; i$ERRFILE)")
- debugme out " (returned $lines lines) "
+ debugme tm_out " (returned $lines lines) "
# determine the return value for higher level, so that they can tell what the result is
if [[ $save -eq 1 ]] || [[ $lines -eq 1 ]]; then
@@ -9222,7 +8680,7 @@ tls_sockets() {
ret=2 # protocol NOT available, server downgraded to $DETECTED_TLS_VERSION
fi
fi
- debugme outln
+ debugme tmln_out
else
debugme echo "stuck on sending: $ret"
fi
@@ -9266,11 +8724,7 @@ run_heartbleed(){
# determine TLS versions offered <-- needs to come from another place
$OPENSSL s_client $STARTTLS $BUGS -connect $NODEIP:$PORT $PROXY -tlsextdebug >$TMPFILE 2>$ERRFILE $TMPFILE 2>$ERRFILE /dev/stdout $TEMPDIR/dh_p.txt
if [[ ! -s "$common_primes_file" ]]; then
- local_problem_ln "couldn't read common primes file $common_primes_file"
+ prln_local_problem "couldn't read common primes file $common_primes_file"
out "${spaces}"
fileout "LOGJAM_common primes" "WARN" "couldn't read common primes file $common_primes_file"
ret=7
@@ -10342,7 +9789,7 @@ run_drown() {
case $? in
7) # strange reply, couldn't convert the cipher spec length to a hex number
- fixme "strange v2 reply "
+ pr_fixme "strange v2 reply "
outln " (rerun with DEBUG >=2)"
[[ $DEBUG -ge 3 ]] && hexdump -C "$TEMPDIR/$NODEIP.sslv2_sockets.dd" | head -1
ret=7
@@ -10350,20 +9797,20 @@ run_drown() {
;;
3) # vulnerable
lines=$(count_lines "$(hexdump -C "$TEMPDIR/$NODEIP.sslv2_sockets.dd" 2>/dev/null)")
- debugme out " ($lines lines) "
+ debugme tm_out " ($lines lines) "
if [[ "$lines" -gt 1 ]]; then
nr_ciphers_detected=$((V2_HELLO_CIPHERSPEC_LENGTH / 3))
if [[ 0 -eq "$nr_ciphers_detected" ]]; then
- pr_svrty_highln "SSLv2 is supported but couldn't detect a cipher (NOT ok)";
+ prln_svrty_high "SSLv2 is supported but couldn't detect a cipher (NOT ok)";
fileout "drown" "HIGH" "SSLv2 is offered, but could not detect a cipher" "$cve" "$cwe" "$hint"
else
- pr_svrty_criticalln "VULNERABLE (NOT ok), SSLv2 offered with $nr_ciphers_detected ciphers";
+ prln_svrty_critical "VULNERABLE (NOT ok), SSLv2 offered with $nr_ciphers_detected ciphers";
fileout "drown" "CRITICAL" "VULNERABLE, SSLv2 offered with $nr_ciphers_detected ciphers" "$cve" "$cwe" "$hint"
fi
fi
ret=1
;;
- *) pr_done_bestln "not vulnerable on this port (OK)"
+ *) prln_done_best "not vulnerable on this port (OK)"
fileout "drown" "OK" "not vulnerable to DROWN" "$cve" "$cwe"
# Any fingerprint that is placed in $RSA_CERT_FINGERPRINT_SHA2 is
# also added to $CERT_FINGERPRINT_SHA2, so if $CERT_FINGERPRINT_SHA2
@@ -10380,7 +9827,9 @@ run_drown() {
if [[ "$DEBUG" -ge 1 ]] || "$SHOW_CENSYS_LINK"; then
# not advertising it as it after 5 tries and account is needed
cert_fingerprint_sha2=${cert_fingerprint_sha2/SHA256 /}
- outln "$spaces https://censys.io/ipv4?q=$cert_fingerprint_sha2 could help you to find out"
+ out "$spaces "
+ pr_url "https://censys.io/ipv4?q=$cert_fingerprint_sha2"
+ outln " could help you to find out"
fileout "drown" "INFO" "make sure you don't use this certificate elsewhere with SSLv2 enabled services, see https://censys.io/ipv4?q=$cert_fingerprint_sha2"
fi
else
@@ -10472,7 +9921,7 @@ run_beast(){
for proto in tls1_1 tls1_2; do
$OPENSSL s_client -state -"$proto" $STARTTLS $BUGS -connect $NODEIP:$PORT $PROXY $SNI 2>>$ERRFILE >$TMPFILE additional pretty structured output as JSON to the specified file
--csv additional output of findings to CSV file in cwd
--csvfile additional output as CSV to the specified file
+ --html additional output as HTML to file
+ --htmlfile additional output as HTML to the specifed file
--hints additional hints to findings
--severity severities with lower level will be filtered for CSV+JSON, possible values
--append if or exists rather append then overwrite
@@ -11322,10 +10777,6 @@ file output options (can also be preset via environment variables):
Options requiring a value can also be called with '=' e.g. testssl.sh -t=smtp --wide --openssl=/usr/bin/openssl .
URI always needs to be the last parameter.
-Need HTML output? Just pipe through "aha" (ANSI HTML Adapter: github.com/theZiz/aha) like
-
- "$PROG_NAME | aha >output.html" or use -log* and convert later
-
EOF
#' Fix syntax highlight on sublime
exit $1
@@ -11451,7 +10902,7 @@ EOF
mybanner() {
local idtag
- local bb
+ local bb1 bb2 bb3
local openssl_location="$(which $OPENSSL)"
local cwd=""
@@ -11460,23 +10911,34 @@ mybanner() {
[[ -z "$GIT_REL" ]] && \
idtag="$CVS_REL" || \
idtag="$GIT_REL -- $CVS_REL_SHORT"
- [[ "$COLOR" -ne 0 ]] && idtag="\033[1;30m$idtag\033[m\033[1m"
- bb=$(cat </dev/null)\" [~$OPENSSL_NR_CIPHERS ciphers]"
out " on $HNAME:"
@@ -11491,25 +10953,26 @@ EOF
else
OPENSSL_LOCATION="$openssl_location"
fi
- echo "$OPENSSL_LOCATION"
+ outln "$OPENSSL_LOCATION"
outln " (built: \"$OSSL_BUILD_DATE\", platform: \"$OSSL_VER_PLATFORM\")\n"
}
cleanup () {
if [[ "$DEBUG" -ge 1 ]]; then
- outln
- pr_underline "DEBUG (level $DEBUG): see files in $TEMPDIR"
- outln
+ tmln_out
+ tm_underline "DEBUG (level $DEBUG): see files in $TEMPDIR"
+ tmln_out
else
[[ -d "$TEMPDIR" ]] && rm -rf "$TEMPDIR";
fi
outln
"$APPEND" || fileout_footer
+ html_footer
}
fatal() {
- pr_magentaln "Fatal error: $1" >&2
+ prln_magenta "Fatal error: $1" >&2
exit $2
# 1: cmd line error
# 2: secondary/other cmd line error
@@ -11535,7 +10998,7 @@ initialize_engine(){
return 1
else # we have engine support
if [[ -n "$OPENSSL_CONF" ]]; then
- pr_warningln "For now I am providing the config file to have GOST support"
+ prln_warning "For now I am providing the config file to have GOST support"
else
OPENSSL_CONF=$TEMPDIR/gost.conf || exit -6
# see https://www.mail-archive.com/openssl-users@openssl.org/msg65395.html
@@ -11570,7 +11033,7 @@ ignore_no_or_lame() {
[[ "$WARNINGS" == off ]] && return 0
[[ "$WARNINGS" == false ]] && return 0
[[ "$WARNINGS" == batch ]] && return 1
- pr_warning "$1 --> "
+ tm_warning "$1 --> "
read a
if [[ "$a" == "$(tolower "$2")" ]]; then
return 0
@@ -11641,10 +11104,10 @@ prepare_logging() {
: # just for clarity: a log file was specified, no need to do anything else
fi
>$LOGFILE
- outln "## Scan started as: \"$PROG_NAME $CMDLINE\"" >>${LOGFILE}
- outln "## at $HNAME:$OPENSSL_LOCATION" >>${LOGFILE}
- outln "## version testssl: $VERSION ${GIT_REL_SHORT:-$CVS_REL_SHORT} from $REL_DATE" >>${LOGFILE}
- outln "## version openssl: \"$OSSL_VER\" from \"$OSSL_BUILD_DATE\")\n" >>${LOGFILE}
+ tmln_out "## Scan started as: \"$PROG_NAME $CMDLINE\"" >>${LOGFILE}
+ tmln_out "## at $HNAME:$OPENSSL_LOCATION" >>${LOGFILE}
+ tmln_out "## version testssl: $VERSION ${GIT_REL_SHORT:-$CVS_REL_SHORT} from $REL_DATE" >>${LOGFILE}
+ tmln_out "## version openssl: \"$OSSL_VER\" from \"$OSSL_BUILD_DATE\")\n" >>${LOGFILE}
exec > >(tee -a ${LOGFILE})
# not decided yet. Maybe good to have a separate file or none at all
#exec 2> >(tee -a ${LOGFILE} >&2)
@@ -12076,7 +11539,7 @@ determine_optimal_proto() {
[[ $all_failed -eq 0 ]] && OPTIMAL_PROTO=""
debugme echo "OPTIMAL_PROTO: $OPTIMAL_PROTO"
if [[ "$OPTIMAL_PROTO" == "-ssl2" ]]; then
- pr_magentaln "$NODEIP:$PORT appears to only support SSLv2."
+ prln_magenta "$NODEIP:$PORT appears to only support SSLv2."
ignore_no_or_lame " Type \"yes\" to proceed and accept false negatives or positives" "yes"
[[ $? -ne 0 ]] && exit -2
fi
@@ -12091,7 +11554,7 @@ determine_optimal_proto() {
pr_bold " $NODEIP:$PORT "
fi
tmpfile_handle $FUNCNAME.txt
- pr_boldln "doesn't seem to be a TLS/SSL enabled server";
+ prln_bold "doesn't seem to be a TLS/SSL enabled server";
ignore_no_or_lame " The results might look ok but they could be nonsense. Really proceed ? (\"yes\" to continue)" "yes"
[[ $? -ne 0 ]] && exit -2
fi
@@ -12163,8 +11626,8 @@ determine_service() {
grep -q '^Server Temp Key' $TMPFILE && HAS_DH_BITS=true # FIX #190
out " Service set:$CORRECT_SPACES STARTTLS via "
fileout "service" "INFO" "$protocol"
- toupper "$protocol"
- [[ -n "$XMPP_HOST" ]] && echo -n " (XMPP domain=\'$XMPP_HOST\')"
+ out "$(toupper "$protocol")"
+ [[ -n "$XMPP_HOST" ]] && out " (XMPP domain=\'$XMPP_HOST\')"
outln
;;
*) outln
@@ -12206,7 +11669,7 @@ display_rdns_etc() {
outln " A record via $CORRECT_SPACES supplied IP \"$CMDLINE_IP\""
fi
if [[ -n "$rDNS" ]]; then
- printf " %-23s %s" "rDNS ($nodeip):"
+ out "$(printf " %-23s %s" "rDNS ($nodeip):")"
out_row_aligned_max_width "$rDNS" " $CORRECT_SPACES" $TERM_WIDTH out
fi
}
@@ -12219,7 +11682,7 @@ datebanner() {
# one line with char $1 over screen width $2
draw_line() {
- printf -- "$1"'%.s' $(eval "echo {1.."$(($2))"}")
+ out "$(printf -- "$1"'%.s' $(eval "echo {1.."$(($2))"}"))"
}
@@ -12263,7 +11726,7 @@ run_mx_all_ips() {
outln
pr_bold "Done testing now all MX records (on port $mxport): "; outln "$mxs"
else
- pr_boldln " $1 has no MX records(s)"
+ prln_bold " $1 has no MX records(s)"
fi
return $ret
}
@@ -12341,6 +11804,7 @@ initialize_globals() {
do_json=false
do_pretty_json=false
do_csv=false
+ do_html=false
do_pfs=false
do_protocols=false
do_rc4=false
@@ -12489,7 +11953,7 @@ parse_cmd_line() {
case $STARTTLS_PROTOCOL in
ftp|smtp|pop3|imap|xmpp|telnet|ldap|nntp|postgres) ;;
ftps|smtps|pop3s|imaps|xmpps|telnets|ldaps|nntps|postgress) ;;
- *) pr_magentaln "\nunrecognized STARTTLS protocol \"$1\", see help" 1>&2
+ *) tmln_magenta "\nunrecognized STARTTLS protocol \"$1\", see help" 1>&2
help 1 ;;
esac
;;
@@ -12648,7 +12112,7 @@ parse_cmd_line() {
[[ $? -eq 0 ]] && shift
case "$WARNINGS" in
batch|off|false) ;;
- *) pr_magentaln "\nwarnings can be either \"batch\", \"off\" or \"false\""
+ *) tmln_magenta "\nwarnings can be either \"batch\", \"off\" or \"false\""
help 1
esac
;;
@@ -12666,7 +12130,7 @@ parse_cmd_line() {
[[ $? -eq 0 ]] && shift
case $DEBUG in
[0-6]) ;;
- *) pr_magentaln "\nunrecognized debug value \"$1\", must be between 0..6" 1>&2
+ *) tmln_magenta_term "\nunrecognized debug value \"$1\", must be between 0..6" 1>&2
help 1
esac
;;
@@ -12676,7 +12140,7 @@ parse_cmd_line() {
case $COLOR in
[0-2]) ;;
*) COLOR=2
- pr_magentaln "\nunrecognized color: \"$1\", must be between 0..2" 1>&2
+ tmln_magenta "\nunrecognized color: \"$1\", must be between 0..2" 1>&2
help 1
esac
;;
@@ -12725,6 +12189,15 @@ parse_cmd_line() {
[[ $? -eq 0 ]] && shift
do_csv=true
;;
+ --html)
+ do_html=true
+ ;; # DEFINITION of HTMLFILE is not arg specified: automagically in parse_hn_port()
+ # following does the same but we can specify a file location additionally
+ --htmlfile)
+ HTMLFILE=$(parse_opt_equal_sign "$1" "$2")
+ [[ $? -eq 0 ]] && shift
+ do_html=true
+ ;;
--append)
APPEND=true
;;
@@ -12745,7 +12218,7 @@ parse_cmd_line() {
no-rfc) DISPLAY_CIPHERNAMES="openssl-only" ;;
openssl) DISPLAY_CIPHERNAMES="openssl" ;;
rfc) DISPLAY_CIPHERNAMES="rfc" ;;
- *) pr_warningln "\nmapping can only be \"no-openssl\", \"no-rfc\", \"openssl\" or \"rfc\""
+ *) tmln_warning "\nmapping can only be \"no-openssl\", \"no-rfc\", \"openssl\" or \"rfc\""
help 1 ;;
esac
;;
@@ -12765,7 +12238,7 @@ parse_cmd_line() {
(--) shift
break
;;
- (-*) pr_warningln "0: unrecognized option \"$1\"" 1>&2;
+ (-*) tmln_warning "0: unrecognized option \"$1\"" 1>&2;
help 1
;;
(*) break
@@ -12797,7 +12270,7 @@ nodeip_to_proper_ip6() {
if is_ipv6addr $NODEIP; then
${UNBRACKTD_IPV6} || NODEIP="[$NODEIP]"
len_nodeip=${#NODEIP}
- CORRECT_SPACES="$(draw_line " " "$((len_nodeip - 17))" )"
+ CORRECT_SPACES="$(printf -- " "'%.s' $(eval "echo {1.."$((len_nodeip - 17))"}"))"
# IPv6 addresses are longer, this varaible takes care that "further IP" and "Service" is properly aligned
fi
}
@@ -12910,6 +12383,7 @@ lets_roll() {
initialize_globals
parse_cmd_line "$@"
+html_header
get_install_dir
set_color_functions
maketempf
@@ -12934,6 +12408,7 @@ if $do_mass_testing; then
exit $?
fi
+html_banner
#TODO: there shouldn't be the need for a special case for --mx, only the ip adresses we would need upfront and the do-parser
if $do_mx_all_ips; then
query_globals # if we have just 1x "do_*" --> we do a standard run -- otherwise just the one specified
@@ -12941,7 +12416,7 @@ if $do_mx_all_ips; then
run_mx_all_ips "${URI}" $PORT # we should reduce run_mx_all_ips to the stuff neccessary as ~15 lines later we have sililar code
ret=$?
else
- parse_hn_port "${URI}" # NODE, URL_PATH, PORT, IPADDR and IP46ADDR is set now
+ [[ -z "$NODE" ]] && parse_hn_port "${URI}" # NODE, URL_PATH, PORT, IPADDR and IP46ADDR is set now
prepare_logging
if ! determine_ip_addresses; then
fatal "No IP address could be determined" 2