See #1429.
OpenBSD 6.6 had an offset with the HTTP header time of -3600 seconds.
This PR fixes that by adding the GMT time zone to parse_date()'s
HAS_FREEBSDDATE incarnation. That doesn't matter to FreeBSD.
Also now for older OpenBSDs the local and remote time are now
in the same format:
```
HTTP clock skew remote: Thu, 09 Jan 2020 12:52:32 GMT
local: Thu, 09 Jan 2020 12:52:02 GMT
``
so that a time difference is easier to spot.
OpenBSD's grep seems to interpret "-w <EXPR>:" differently
than Linux or MacOSX/FreeBSD in a sense that this doesn't
matchs, see #1430.
This PR fixes that by squashing the w option in all occuorrences.
In addition it removes the SOCKETHEADER if-statement which was
introduced looking forward a while back. It's not happening soon
at least and the variable was not initialized either.
... and reorder manpages also so that --warnings, --connect-timeout
and --openssl-timeout appear in the "input parameter" section.
The HTML manpage looks in the diff view quite different as previously
another computer was used for converting the source format with ronn(1).
The manpage in (g)roff format was manually edited with .RE / .RS
for provide indented bulletpoints.
See also #1419
* It'll be a warning now when a host certificate was issued after
March 1st, 2018 which has a lifetime >825 days, independent
whether it is an internal certificate or not. This can
change later, as browsers treat those certificates different
as "official ones"
* Still the 5 or 10 year threshold overrides this
* For older OpenBSDs there's now a better date format support
used in the expiration and validity period of a host certificate.
It mimics in bash the conversion of other date binaries. It is
not accurate so it might be off a day or at maximum two, probably
as a month has 30.42 days and not 30.
* The date output for OpenBSD is now in line with other OS. Previously
we just echoed the lines in openssl x509 output whereas now we
convert that
The expression 'grep -aw "Public-Key:"' hiccuped on the colon
under OpenBSD, so that any bitsize on a certificate had wrong
values, see #1425. (FreeBSD was fine)
This PR fixes that. It updates the expression by using awk and
bash internal functions.
The same problem occured in run_robot(). The strong typing of
pubkeybits had to be relaxed to a dynamic typing, unless we
choose to define a second string variable.
* old OpenBSD kinda works
* let's encrypt section moved so that OpenBSD can use it too
* Days are wrong
* Date format is not the same as with e.g. GNUdate (but should be)
* variables y m d not declared
* date warning for openbsd completely missing
As noted in #1418 LLMNR (Link-Local Multicast Name Resolution)
resolution times out when using x as an argument to "-connect".
This commit fixes that by replacing "-connect x" by "-connect invalid."
which is supposedly also generally more "DNS query friendly", see
https://tools.ietf.org/html/rfc6761#section-6.4 .
In addition this commit adds a check in get_common_prime() whether
the openssl version used has pkey support. If not with old openssl
versions and previously testssl.sh terminated after presenting garbledoutput.
(This was found as tested how very old version of openssl versions
handle "-connect invalid.")
If the server is known not to support TLS 1.3 (as well as TLS 1.2, TLS 1.1, and TLS 1), then mention TLS 1.3 in the list of not supported protocols. While lack of TLS 1.3 support is not part of the reason that no fallback is possible, it is part of the reason that the result is reported as prln_svrty_high.
If $high_proto is set to something other than SSLv3, support for SSLv3 will not have been determined by determine_optimal_sockets_params(), but it may have been determined later (e.g., by run_protocols()). So, this commit changes the loop to always check for SSLv3 support (without calling "$OPENSSL s_client" if $HAS_SSL3 is false). The check for whether the fallback test can be performed is moved until after the loop
This PR fixes a couple of places where "$OPENSSL s_client" is called with "-ssl3" even if SSLv3 is not supported.
The fix in ciphers_by_strength() is easy, as the issue only occurs if "$using_sockets" is true. If SSLv3 (or TLSv1.3) is not supported, then testing using "$OPENSSL s_client" is skipped and all of the supported ciphers are found using tls_sockets().
The fix for run_tls_fallback_scsv() is more complicated. While it is easy to avoid calling "$OPENSSL s_client" with "-ssl3" if SSLv3 is not supported, it is not easy to determine the correct message to present to the user if support for SSLv3 (and possibly also TLSv1.3) is unknown.
For the case in which $high_proto cannot be set, I believe that I have covered all of the possibilities, but an not sure if the correct message/rating is used in every case.
For the case in which it is not possible to determine whether SSLv3 is the $low_proto, more could be done. If $high_proto is TLS 1.1 or TLS 1, then this PR is okay, as it is possible that SSLv3 would be the fallback protocol, but there is no way to tell. However, it seems unlikely that a server would support TLS 1.2 and SSLv3, but not TLS 1.1 or TLS 1. So, perhaps if $high_proto is TLS 1.2 and the server does not support TLS 1.1 or TLS 1, it should just be assumed that SSLv3 is not supported, even if it cannot be tested.
At the moment, testssl.sh does not correctly derive the handshake traffic keys in the case that the server responds to the initial ClientHello with a HelloRetryRequest. The handshake traffic keys are computed incorrectly because the wrong messages are provided to derive-handshake-traffic-keys() for input to the Transcript-Hash calculation:
* TLS_CLIENT_HELLO is not updated to contain the value of the second ClientHello, and so the first ClientHello is being provided to derive-handshake-traffic-keys() as both the first and the second ClientHello.
* In middlebox compatibility mode the server may send a dummy ChangeCipherSpec message immediately after the HelloRetryRequest. Since it is part of the server's response to the initial ClientHello, the ChangeCipherSpec message is included in the $hrr that is sent to derive-handshake-traffic-keys(), but it should not be included in the computation of the Transcript-Hash.
This PR fixes the above two problems by updating TLS_CLIENT_HELLO when a second ClientHello is sent and by removing any ChangeCipherSpec message (140303000101) from the end of the server's initial response.
* Severity of RC4 in run_cipherlists() is now high as everywhere else
* Same for RC2 and DES. Only Export, NULL and ADH remain critical
* 3DES and IDEA in run_cipherlists() is now medium (see #1393)
* CBC3 SEED 3DES IDEA added in pr_cipher_quality()
* MD5 added to pr_cipher_quality() and labled as high
* double RC2 switch statemnet removed in pr_cipher_quality()
* timeouts are not default anymore but need a cmdline param (or ENV param)
* check whether "timeout" exists
Also:
* allow OPENSSL_TIMEOUT to be passed via ENV similar to others
* replace timeout variable in run_robot() by robottimeout, to avoid
misunderstandings by a human
ToDos: see inline. Mainly if timeout isn't available, testssl.sh doesn't
work.
Not to self: help function still says 60 second is default.
When printing a long HTTP security header, this commit causes every row after the first one to be indented by two additional spaces. In the case of very long headers, this extra indentation makes it a little easier for readers to see where the next security header begins.
When printing out HTTP security headers, run_security_headers() uses out_row_aligned_max_width(), since some headers are very long and need to be wrapped. At the moment, however, the first line is too long. The problem is that while "$header $HEADERVALUE" is printed in the indented area, only $HEADERVALUE is passed to out_row_aligned_max_width().
This PR fixes the problem by passing "$header $HEADERVALUE" to out_row_aligned_max_width() so that the the first line is wrapped at the correct place.
testssl.sh hiccups when a user supplied after --json*/--html/-csv
a filename instead of using the corresponding --json*file/--htmlfile/-csvfile
arguments, see #1397.
This PR adresses that in a sense that it tries to detect to following
argument of --json*/--html/-csv. If that matches a suspected filename
it bails out using fatal().
This is not intended to be perfect (when the pattern doesn't match)
but catches the user error in an early stage. See also #1398
Currently sub_cipherlists() and pr_cipher_quality() use different numbers for the same cipher quality ratings. sub_cipherlists() uses:
-2 = pr_svrty_critical, -1= pr_svrty_high, 0 = pr_svrty_low, 1 = pr_svrty_good, 2 = pr_svrty_best
while pr_cipher_quality() uses:
1 = pr_svrty_critical, 2 = pr_svrty_high, 3 = pr_svrty_medium, 4 = pr_svrty_low
5 = neither good nor bad, 6 = pr_svrty_good, 7 = pr_svrty_best
This PR changes sub_cipherlists() (and run_cipherlists()) to use the same numbers for cipher quality as pr_cipher_quality(). It does not change any of the ratings assigned to ciphers by run_cipherlists() or pr_cipher_quality(), so the two are still not in alignment. But, hopefully using the same numbering in both functions will make it a bit easier to compare them and bring them into alignment.
This resolves a regression introduced with IDN support (see also #1370).
* in check_resolver_bins() the determination of HAS_DIG_NOIDNOUT=true was wrong
* in get_*_record() the check for the bool variable was wrong
* in get_*_record() we shouldn't use quotes as they might be expand to a quoted arg
This PR fixes some indentation issues. The PR is a bit long, but it only makes changes to indentation (except for one comment line, where a trailing space character is removed).
This PR fixes#1385.
sub_session_resumption() returns 3 when $CLIENT_AUTH is true. However, the comment at the beginning of the function indicates that 6 will be returned. run_server_defaults() is prepared to handle a return value of 6 (to indicate client auth), but is not expecting 3 as a possible return value.
In cases where the probes for reading memory from the server side were not
successful (=not vulnerable) the TCP connection was not shut down properly --
leading to and undefined state and probably causing problems to a consecutive
check. The server side then assumably from time to time just didn't return
anything which caused a integration test (t/08_isHTML_valid.t) to fail
randomly.
This PR properly terminates the TCP socket connection. Also, as sending the
close notification before closing the socket was duplicated in testssl.sh
that went to a separate function.
See comment in #1375:
https://github.com/drwetter/testssl.sh/pull/1375#issuecomment-554424814
This PR enhances support for the latest versions of OpenSSL and LibreSSL.
The development version of OpenSSL at https://github.com/openssl/openssl/ is version 3.0.0-dev. So, checks for OpenSSL versions need to support this version as well. At the same time, the latest versions of LibreSSL are 3.0.0, 3.0.1, and 3.0.2, so version number alone will no longer be sufficient to distinguish between OpenSSL and LibreSSL.
In addition to checks for these new version numbers, this PR addresses a couple of other issues:
- In LibreSSL, the "$OPENSSL ciphers" command will not accept any protocol version other than "-tls1" as a parameter (and even including "-tls1" as an option is described as "deprecated"). So, this PR ensures that "$OPENSSL ciphers" is not passed any protocol version option other than "-tls1" is LibreSSL is being used.
- In OpenSSL 3.0.0-dev, the "$OPENSSL dgst" can no longer be used to compute HMACs, but a new "$OPENSSL mac" function has been created. So, this PR changes hmac() to use "$OPENSSL mac" with OpenSSL 3.0.0-dev.
Note that I have not tested the modified version of sub_session_resumption(). I am just assuming that OpenSSL 3.0.0-dev works the same as OpenSSL 1.1.1 and that all versions of LibreSSL work the same as OpenSSL 1.1.0 and earlier.
When tls_sockets() is used for run_protocols(), for each protocol version the results will indicate whether the server responded to a ClientHello for that protocol version with (1) a ServerHello for that same protocol version, (2) a ServerHello for a different (hopefully lower) protocol version, or (3) a handshake failure.
Currently, however, run_prototest_openssl() does not distinguish between cases in which the server responds with a ServerHello for a different (hopefully lower) protocol version and cases in which the server responds with a handshake failure. This PR changes run_prototest_openssl() so that it distinguishes between these two cases (as long as $OPENSSL supports the protocol version specified in the ServerHello).
Making use of the additional information provided by run_prototest_openssl(), this PR also modifies run_protocols() to check that version negotiation was performed correctly even if $using_sockets is false.
Note that one special case needed to be addressed. If an SSLv3-only server is being tested using an $OPENSSL that does not support SSLv3, then $latest_supported must not be set to SSLv3. In the case of a server like this, it is possible that support for SSLv3 will be determined by determine_optimal_sockets_params(), which will cause run_protocols() to report that the server supports SSLv3, even though $OPENSSL does not support SSLv3 and testing is being performed in --ssl-native mode. If $latest_supported were set, then later tests in run_protocols() would incorrectly report a version negotiation failure, even though the failure to connect was a result of a limitation of $OPENSSL rather than a fault of the server.
When running in debugging mode, HAS_DIG and friends was
still false as check_resolver_bins() was called too late.
This amends basically bac0f66112 .
In cases where a certificate has two CNs, the output contained
a linefeed. This replaces the line feed by a space.
This fixes a bug e.g. when supplying a proxy by a DNS name, testssl couldn't resolve the name as the HAS_ variables initialized by ``check_resolver_bins()`` was done later than ``check_proxy()``.
The patch just puts ``check_resolver_bins()`` earlier in "main"
run_prototest_openssl() currently calls "$OPENSSL s_client" twice, once with $PROXY and once without. The problem is that the results of the first call are just ignored. This commit changes run_prototest_openssl() so that the attempt without $PROXY is only tried if the first attempt was unsuccessful.
If --ssl-native is being used and the server supports SSLv2, but does not support any SSLv2 ciphers, there is a missing line break after the warning message is printed.