Commit Graph
100 Commits
Author SHA1 Message Date
David Cooper 0be5ca5309 Support DHE/ECDHE servers with uncommon curves
When running in --ssl-native mode, run_fs() will not detect ECDHE ciphers if the server supports both DHE and ECDHE ciphers and the ECDHE ciphers are only supported with curves that are not offered by $OPENSSL by default. This commit fixes this by adding extra connection attempts with the -curves parameter explicitly provided.
2022-04-14 08:51:25 -04:00
David Cooper ac662f8699 Improve compatibility with LibreSSL
Older versions of LibreSSL that do not support TLS 1.3 only include a small list of curves in the supported_groups extension by default, so need to retry with curves explicitly defined even with versions of $OPENSSL that do not support TLS 1.3.
2022-04-14 08:51:25 -04:00
David Cooper dd35be2e4b Fix #2131
This commit fixes #2131 by having run_fs() attempt a TLS 1.2 ClientHello if the initial TLS 1.3 ClientHello fails. The TLS 1.2 ClientHello will offer many more curves than the TLS 1.3 ClientHello offers, and so it may succeed if the server supports ECDHE ciphers, but only with curves that were removed by RFC 8446.
2022-04-14 08:51:25 -04:00
David Cooper cc74256091 Fix setting NO_SESSION_ID
With a TLS 1.3 connection using $OPENSSL, a session ID will only appears as part of a post-handshake session ticket. However, when $OPENSSL s_client is called as in determine_optimal_proto() (i.e., with "< /dev/null"), a post-handshake session ticket will not always be received, even if the server supports it. This can result in NO_SESSION_ID incorrectly being set to true. This commit fixes the issue by setting NO_SESSION_ID to true by default, and then setting it to false if a session ID is returned by any connection to the server.
2022-04-13 09:26:36 -04:00
David Cooper 70b1ee643f Fix #2147
This commit fixes #2147 by having awk search for additional possible strings to start the CRL Distribution Points output. Unless the CRLDP extension is malformed, it will begin with "Full Name", "Relative Name", "Reasons", or "CRL Issuer".
2022-04-12 14:01:02 -04:00
David Cooper 618de1c24e More OpenSSL compatibility fixes
This commit fixes two more issues with using OpenSSL 3.X. When $OPENSSL is used to obtain a fingerprint, OpenSSL 3.X prepends the fingerprint with "sha1" or "sha256" rather than "SHA1" or "SHA256". In addition, the way that OpenSSL 3.X writes distinguished names causes a space character to appear at the beginning of "$cn" and "$issuer_CN" in certificate_info().
2022-04-11 11:23:09 -04:00
David Cooper 09973c8c44 Fix flat JSON file
PR #2140 contains a bug when handling flat JSON files. FIRST_FINDING should only be set to true in the case of structured JSON output, since it is only in that case that fileout_insert_warning() appends a comma to the JSON file. This commit fixes the problem.
2022-04-07 13:57:49 -04:00
David Cooper 6f55a4d08b OpenSSL compatibility fix
OpenSSL 3.0.X uses different names for some elliptic cures in the "Server Temp Key" line than previous previous versions. This commit addresses this issue by checking for both names.
2022-04-07 13:44:42 -04:00
David Cooper 3d0dab4da3 Fix #2138
This commit fixes #2138 by having testssl.sh not wrap early JSON findings in a clientProblem object if the finding is created by a mass testing child and all findings are being placed in a common file. It also sets FIRST_FINDING to true in case another finding is written before the "service" information is written.

Since fileout_insert_warning() adds a comma after the finding is written, the JSON can become corrupted in mass testing if a clientProblem finding is written and then no additional findings are written for that test. In order to try to prevent this, the commit adds several fileout() calls to determine_optimal_proto() in cases in which testssl.sh might exit before testing begins.
2022-04-06 15:41:52 -04:00
David CooperandDirk 9829105450 Reorder output of run_server_preference()
This commit reorders the output of run_server_preference() as discussed in #1311.
2022-04-01 12:50:12 +02:00
David CooperandDirk c14ea2efc8 Use tls_sockets() in run_tls_fallback_scsv()
This commit adds the use of tls_sockets() to run_tls_fallback_scsv() to perform testing when the --ssl-native flag is not used. With this commit, run_tls_fallback_scsv() only uses tls_sockets() instead of $OPENSSL if the ClientHello needs to include the TLS_FALLBACK_SCSV flag, but it is not supported by $OPENSSL, or if the protocol that would be negotiated is SSLv3 and $OPENSSL does not support SSLv3.
2022-04-01 12:50:12 +02:00
David CooperandDirk 008fa228c0 Add DH groups to supported_groups
There is at least one server that will not negotiate TLS_DHE_* cipher suites with TLS 1.2 and below if the supported_groups extension is present but does not include any DH groups. This commit adds the DH groups that are currently in the TLS 1.3 ClientHello to the TLS 1.2 and earlier ClientHello.
2022-04-01 12:50:12 +02:00
David CooperandDirk 7a3ce9c677 Fix sclient_auth
If $connect_success is false, then sclient_auth() does not "return" any value, and the calling function treats this as if sclient_auth() had returned 0.

This commit fixes sclient_auth() so that 1 is returned if $client_success is false.
2022-04-01 12:50:12 +02:00
David CooperandDirk bddf9c967f Include RSA-PSS in ClientHello
This commit changes prepare_tls_clienthello() so that the RSA-PSS algorithms are offered in the signature algorithms extension of TLS 1.2 and below ClientHello messages.
2022-04-01 12:50:12 +02:00
David CooperandDirk 9a1f7f85b7 Fix potential stallling in HTTP query
In run_http_header() the GET command is first sent over TLS using a background process, and then if that does not hang, it is sent again in the foreground. Similarly, service_detection() runs the command in the background.

This commit changes determine_optimal_proto() to follow the example of run_http_header() as protection against the possibility of the HTTP query stalling.
2022-04-01 12:45:59 +02:00
David CooperandDirk 4260ccbd1c Report if couldn't test for client authentication
This commit fixes determine_optimal_proto() and run_server_defaults() so that a "Local problem" is reported if a $URL_PATH is specified, the server is TLS 1.3-only, and $OPENSSL does not support -enable_pha (and the server does not offer client authentication as part of the initial TLS handshake).
2022-04-01 12:45:59 +02:00
David CooperandDirk 0531d5df19 Improve check for client authentication with LibreSSL
Checking for client authentication with TLS 1.3 requires post-handshake authentication, which does not appear to be supported by LibreSSL. This commit improves the check for client authentication when testing a TLS 1.3 server using LibreSSL by having determine_optimal_proto() first test for connectivity with TLS 1.3 without checking for client authentication and then performing a separate check for client authentication using a non-TLS 1.3 protocol.

This commit only affects the flow of the program if a $URL_PATH is specified, the server supports TLS 1.3, and $OPENSSL supports TLS 1.3 but not -enable_pha.

testss.sh may still provide incorrect information about client authentication if a $URL_PATH is provided, the server is TLS 1.3-only, and LibreSSL is used.
2022-04-01 12:45:59 +02:00
David CooperandDirk a66e3cd3ad Improve check for client authentication
Based on initial testing, this commit improves the check for client authentication in the case that the server only requests client authentication for specific URLs. However, it does not work correctly if the server supports TLS 1.3 and $OPENSSL is a version of LibreSSL that supports TLS 1.3 in s_client. The problem is that LibreSSL does not support post-handshake authentication with TLS 1.3
2022-04-01 12:45:59 +02:00
David CooperandDirk 555c6eb4d0 WIP: Improve check for client authentication
As noted in #1709, some servers will only request client authentication if a specific URL is requested. This commit modifies the check for client authentication, in the case that a $URL_PATH is provided, by having testssl.sh perform a GET request on the URL provided on the command line.
2022-04-01 12:45:59 +02:00
David Cooper fa5d13eb06 Reorder output of run_server_preference()
This commit reorders the output of run_server_preference() as discussed in #1311.
2022-03-22 15:40:49 -04:00
David Cooper 7e9d724d68 Use tls_sockets() in run_tls_fallback_scsv()
This commit adds the use of tls_sockets() to run_tls_fallback_scsv() to perform testing when the --ssl-native flag is not used. With this commit, run_tls_fallback_scsv() only uses tls_sockets() instead of $OPENSSL if the ClientHello needs to include the TLS_FALLBACK_SCSV flag, but it is not supported by $OPENSSL, or if the protocol that would be negotiated is SSLv3 and $OPENSSL does not support SSLv3.
2022-03-22 15:10:28 -04:00
David Cooper 3cd8e810ac Add DH groups to supported_groups
There is at least one server that will not negotiate TLS_DHE_* cipher suites with TLS 1.2 and below if the supported_groups extension is present but does not include any DH groups. This commit adds the DH groups that are currently in the TLS 1.3 ClientHello to the TLS 1.2 and earlier ClientHello.
2022-03-09 10:33:51 -05:00
David Cooper 909513773d Fix sclient_auth
If $connect_success is false, then sclient_auth() does not "return" any value, and the calling function treats this as if sclient_auth() had returned 0.

This commit fixes sclient_auth() so that 1 is returned if $client_success is false.
2022-03-08 14:57:47 -05:00
David Cooper c713866bc1 Include RSA-PSS in ClientHello
This commit changes prepare_tls_clienthello() so that the RSA-PSS algorithms are offered in the signature algorithms extension of TLS 1.2 and below ClientHello messages.
2022-03-08 11:45:55 -05:00
David Cooper 680dc9ee01 Fix potential stallling in HTTP query
In run_http_header() the GET command is first sent over TLS using a background process, and then if that does not hang, it is sent again in the foreground. Similarly, service_detection() runs the command in the background.

This commit changes determine_optimal_proto() to follow the example of run_http_header() as protection against the possibility of the HTTP query stalling.
2022-01-06 15:33:37 -05:00
David Cooper 50fe6ca96b Report if couldn't test for client authentication
This commit fixes determine_optimal_proto() and run_server_defaults() so that a "Local problem" is reported if a $URL_PATH is specified, the server is TLS 1.3-only, and $OPENSSL does not support -enable_pha (and the server does not offer client authentication as part of the initial TLS handshake).
2022-01-06 15:33:36 -05:00
David Cooper 48819c56e9 Improve check for client authentication with LibreSSL
Checking for client authentication with TLS 1.3 requires post-handshake authentication, which does not appear to be supported by LibreSSL. This commit improves the check for client authentication when testing a TLS 1.3 server using LibreSSL by having determine_optimal_proto() first test for connectivity with TLS 1.3 without checking for client authentication and then performing a separate check for client authentication using a non-TLS 1.3 protocol.

This commit only affects the flow of the program if a $URL_PATH is specified, the server supports TLS 1.3, and $OPENSSL supports TLS 1.3 but not -enable_pha.

testss.sh may still provide incorrect information about client authentication if a $URL_PATH is provided, the server is TLS 1.3-only, and LibreSSL is used.
2022-01-06 15:33:36 -05:00
David Cooper 7fb688a9d6 Improve check for client authentication
Based on initial testing, this commit improves the check for client authentication in the case that the server only requests client authentication for specific URLs. However, it does not work correctly if the server supports TLS 1.3 and $OPENSSL is a version of LibreSSL that supports TLS 1.3 in s_client. The problem is that LibreSSL does not support post-handshake authentication with TLS 1.3
2022-01-06 15:33:36 -05:00
David Cooper e41a4c361a WIP: Improve check for client authentication
As noted in #1709, some servers will only request client authentication if a specific URL is requested. This commit modifies the check for client authentication, in the case that a $URL_PATH is provided, by having testssl.sh perform a GET request on the URL provided on the command line.
2022-01-06 15:33:36 -05:00
David Cooper 9dac4592b7 Send /dev/null to s_client
As discussed in #2079, this commit adds "</dev/null" to calls "$OPENSSL s_client" that are intended to test whether a certain option is supported. This is done to prevent hanging in the case that the option is supported, a TLS server happens to be listening on the port to which s_client tries to connect, and the connection is successful.

This PR also adds a new helper function, sclient_supported(), which is called from locally_supported() and run_prototest_openssl(). The helper function makes use of the already defined variables $HAS_SSL2, $HAS_SSL3, and $HAS_TLS13 in order to avoid calling "$OPENSSL s_client" when it has already been determined whether $OPENSSL supports the specified protocol.
2022-01-05 16:26:22 -05:00
David Cooper ff8e9f49cc Fix #2053
This commit fixes #2053 by setting $FIRST_FINDING to false after a section footer is output.
2021-12-09 10:13:24 -05:00
David Cooper e1600e3f62 Fix JSON section headers
This commit fixes two issues with the headers in the structured JSON output. First, if run_cipher_match() is performed the header this is used is "pretest" rather than "singleCipher". Second, the headers for "serverPreferences" and "fs" are swapped.
2021-12-08 14:13:10 -05:00
David Cooper f2a4ee1090 Document $keyopts
Shellcheck complains on line 2234 that keyopts is referenced but not assigned and there is no explanation in the code (or in the documentation) why "$keyopts" is there. This commit adds a comment so that "$keyopts" isn't deleted as part of a code cleanup.
2021-12-08 11:50:35 -05:00
David Cooper edbc66c78d Update reset_hostdepended_vars()
This commit adds several variables to reset_hostdepended_vars() that are not currently being reset for each host being tested, but that should be reset.
2021-12-07 14:45:19 -05:00
David Cooper 019c7fa57a Simplify extracting Git information
testssl.sh currently calls "git log --format='%h %ci' -1 2>/dev/null" three times. This commits changes testssl.sh to make this call just once and then use Bash string manipulation to extract the necessary information from the result.
2021-12-07 14:38:14 -05:00
David Cooper d701e69e20 Fix some Shellcheck issues
This commit fixes a number of issues raised by Shellcheck and removes unnecessary quotation marks in a number of places.
2021-12-07 09:22:34 -05:00
David Cooper 708cc672a2 Fix #2049
This commit fixes #2049 by converting newline characters to spaces in JSON and CSV findings.

fileout() calls newline_to_spaces() on the $findings that are to be written to JSON and CSV files. However, this only affects actual newline characters in the string, not escaped newline characters (i.e., "\n"). Escaped newline characters pass through this function unchanged, but then get converted to newline characters when they are written to the JSON and/or CSV files. This commit fixes the problem by also converting escaped newline characters ("\n") to spaces.
2021-11-29 14:36:29 -05:00
David Cooper 6b7836d350 Fix sub_cipherlists()
This commit fixes a bug in sub_cipherlists() when using sockets to test whether a server supports a set of ciphers with SSLv2. Code that is supposed to extract the list of SSLv2 ciphers to test for is incorrectly reading from the list of non-SSLv2 ciphers.
2021-11-22 12:25:20 -05:00
David CooperandGitHub 64d110f19d Check file permissions on ./testssl.sh
This commit adds a check that ./testssl.sh has both read and execute permission. If ./testssl.sh is lacking execute permission, it will pass the tests in 00_testssl_help.t and 01_testssl_banner.t that run the program as `bash ./testssl.sh`, but will fail the subsequent tests that run the program as `./testssl.sh`, but the reason for the failure will not be clear.
2021-11-15 07:25:08 -05:00
David Cooper 80934c85e8 Fix some Shellcheck issues
This commit fixes a few issues found by Shellcheck.
2021-11-12 16:20:41 -05:00
David Cooper f1df111a32 Fix calls to debugme1() with redirects
As noted in https://github.com/drwetter/testssl.sh/pull/1963#issuecomment-954935175, there are two places in which debugme1() is called in which the command to be run prints something to stdout, which is then redirected to a file. Now that debugme1() includes a redirect from stdout to stderr, these two lines do not work as expected. The output appears in the terminal and an empty file is created.

This commit fixes the issue by not using the debugme1() function in these two places.
2021-11-09 15:36:30 -05:00
David Cooper 095433774d Support OpenSSL 3.0.1-dev and 3.1.0-dev
This commit changes a few lines of code that checks OpenSSL version numbers to recognize 3.0.1 and 3.1.0 in addtion to 3.0.0.

According to https://www.openssl.org/blog/blog/2018/11/28/version, API/ABI compatibility is guaranteed for the same MAJOR version number (starting with version 3), so it should be sufficient to just check that $OSSL_VER_MAJOR is 3.
2021-11-08 08:04:34 -05:00
David CooperandGitHub 3d9f109780 Fix 2030
Fix CI issue created by #2028 and by new certificate fingerprint.
2021-10-28 08:13:34 -04:00
David Cooper 43f3b507c1 Fix #1733
This commit adds PrioritzeChaCha detection, as requested in #1733. If the server (1) enforces a cipher order for a given protocol, (2) supports at least one non-ChaCha cipher for that protocol, and (3) supports at least one ChaCha cipher that would normally be less preferred than the ChaCha cipher, then a test is performed to see if the server selects the ChaCha cipher if it is listed first in the ClientHello.
2021-10-27 13:53:30 -04:00
David Cooper 15e3d61ddc Speedup cipher_pref_check()
While OpenSSL 1.0.2-chacha supports more than 128 cipher suites, other versions of OpenSSL tend to support far fewer than that.

Calling check_tls12_pref() adds to the run time of cipher_pref_check(), but is only needed if OpenSSL would otherwise send a ClientHello with more than 128 cipher suites. So, this commit adds another check and only calls check_tls12_pref() if the server has the size limit bug and OpenSSL supports more than 127 ciphers.
2021-10-26 15:56:08 -04:00
David Cooper d4606ad9f8 Remove extra colon
The code added by #2024 creates a cipher list with two consecutive colons. While this doesn't seem to be a problem, the commit removes the extra colon.
2021-10-26 15:43:01 -04:00
David Cooper 2b752feea0 Remove unnecessary quotes 2021-10-26 12:05:36 -04:00
David Cooper 4536e933f9 Improve cipher_pref_check()
Some servers are configured to prioritize ChaCha ciphers if those ciphers are preferred by the client, even if the server is generally configured to use the server's cipher preferences rather than the client's. As a result of this, if a ChaCha cipher appears in the ClientHello before a non-ChaCha cipher, the server may select the ChaCha cipher even if the server is configured to prefer the non-ChaCha cipher.

In a few cases, e.g., cloudflare.com for TLS 1.2, this affects the ordering of the ciphers presented by cipher_pref_check(). This commit fixes the problem by having cipher_pref_check() (and check_tls12_pref()) always place any ChaCha ciphers at the end of the cipher list in the ClientHello. This ensures that cipher_pref_check() presents the ciphers in the server's preference order.
2021-10-25 14:28:51 -04:00
David Cooper 00fb68f47c Fix s_client_options()
This commit fixes an error in s_client_options() when the function is called with an empty "-cipher" list and $OPENSSL supports "@SECLEVEL". This happens, for example, when ciphers_by_strength() is called for TLS 1.3.

The call to `openssl s_client` will fail is the cipher option is provided with an empty list or a list that just contains "@SECLEVEL=0". So, "@SECLEVEL=0" should only be added if the "$ciphers" list is non-empty. If "$ciphers" remains empty, then the "-cipher" option will not be added to the command line.
2021-10-25 12:15:13 -04:00
David CooperandGitHub 8b129577a7 Update testssl.1.md
testssl.1.md included '.SS "SINGLE CHECK OPTIONS"', which belongs in testssl.1, but not in testssl.1.md. This commit removes this extra line.
2021-09-30 14:09:17 -04:00
David Cooper 667de371cd Fix #1961
This commit fixes #1961 in the 3.1dev branch by leaving NODEIP set to the server's IP address rather than changing it to the DNS name in the case of STARTTLS XMPP.

In order to address the problem of $OPENSSL s_client not working with STARTTLS XMPP if an IP address is provided to -connect, the -xmpphost option is used to provide the DNS name.
2021-08-09 13:22:31 -04:00
David Cooper b4d11459a8 Use all+ in calls to tls_sockets()
get_server_certificate() includes a few calls to tls_sockets() in which the response will be TLS 1.3 and in which the response will be useless if it cannot be decrypted (since the goal is to obtain the server's certificate). So, these calls to tls_sockets() should specify "all+" rather than "all".
2021-08-05 11:36:32 -04:00
David Cooper 526d25bc1d Don't test for certificate compression if --ssl-native
This commit changes run_server_defaults() so that the test for certificate compression is not run in --ssl-native mode. This fixes an issue that was caught by 21_baseline_starttls.t.
2021-08-05 10:37:37 -04:00
David Cooper fa1ccdb565 Check for RFC 8879 certificate compression
This commit adds a check for whether the server supports certificate compression (RFC 8879). If it does, then the list of supprted compression methods is output in the server's preference order.
2021-08-04 14:39:12 -04:00
David Cooper fc310301f1 Print consecutive spaces faster
This commit adds a new function, print_n_spaces(), which prints a sequence of (up to 80) space characters.

This new function is used to replace a few places in testssl.sh in which a sequence of space characters is printed by calling 'out " "' in a loop. The new function is much faster than the current code, so it will make testssl.sh run slightly faster.
2021-07-29 15:12:27 -04:00
David Cooper 265c85a44f Specify an error code in all calls to fatal()
This commit fix a few places in which calls to fatal() do not specify an error code.
2021-05-13 11:32:56 -04:00
David Cooper 0552fdadb8 Print errors to stderr
In parse_cmd_line() error messages are usually printed to stderr, but in three places the messages are printed to stdout. This commit modifies those three lines so that they also print to stderr.

The commit also replaces a call to a non-existant function, tmln_magenta_term, with a call to tmln_magenta.
2021-05-13 11:10:01 -04:00
David Cooper 944eb1bcd9 Improve compatibility with OpenSSL 3.0
This commit addresses a few issued related to the use of testssl.sh with OpenSSL 3.0.0-alpha14.

First, when pkey is used to print a DH key that uses an unknown group, OpenSSL 3.0.0-alpha14 labels the prime and generator using "P:" and "G:" rather than "prime:" and "generator:". (In PR #1586 it was noted that OpenSSL 3.0.0-alpha1 used "prime P:" and "generator G:". The x509 command in OpenSSL 3.0.0-alpha14 still uses "prime P:" and "generator G:" when printing a DH public key in a certificate, but the pkey command just uses "P:" and "G:").

Second, when the pkey command is used to print a DH key that uses certain common primes (e.g., groups from RFC 3526 or RFC 7919), OpenSSL 3.0.0-alpha14 simply prints "GROUP: " followed by a short name for the group rather than printing the value of the prime and generator.

Finally, the "-text" option no longer works if the input is a public key. Fortunately, the "-text_pub" option provides the expected results with all versions of OpenSSL and LibreSSL.
2021-04-07 13:28:34 -04:00
David Cooper d8bec390be Reintroduce hex2ascii()
Add hex2ascii() as a function that just calls hex2binary().
2021-03-22 11:56:46 -04:00
David Cooper 3756cdcb38 Cleanup conversion from ASCII-HEX to binary
This commit makes some minor improvements to code that converts ASCII-HEX to binary.

First, testssl.sh currently has two functions that do the same thing: asciihex_to_binary() and hex2ascii(). This commit all calls to either of these functions with calls to hex2binary(), which is based on the current asciihex_to_binary().

This commit also changes direct use of printf to calls to hex2ascii() in generate-ccm-counter-blocks(), ccm-compute-tag(), and generate_gcm_counter().

Finally, this commit cleans up the implemention of hex2binary() a bit and introduces the option to use xxd, if that program is available. Using xxd rather than multiple calls to printf has a couple of advantages. xxd is a bit faster. However, the primary advantage is that when debugging (i.e., using bash -x), each call to hex2binary() only includes a few steps, regardless of how long the string is, whereas using printf the call to hex2binary() could take hundreds of steps.
2021-03-22 11:55:30 -04:00
David Cooper f829c8ebf0 Add more comments to print_dn()
This commit adds some more explanatory comments to the code in print_dn()
2021-02-05 13:35:54 -05:00
David Cooper 9dbb629154 Add printing of information about client authentication to run_server_defaults(). Minor cleanup of code to extract information about client authentication. 2021-02-05 13:11:38 -05:00
David Cooper e8a3dce5ad sclient_auth() improvements
Modify sclient_auth() to use checks similar to sclient_connect_successful() to determine whether the connection attempt was successful. Replace uses of awk and grep with Bash internals string comparisons.
2021-02-05 13:11:38 -05:00
David Cooper 44787d6bcb Extract Client Auth CA list
This commit is a first step towards addressing #1709. It attempts to determime whether certificate-based client authentication is (1) not requested, (2) optional, or (3) required. If it is either optional or required, then it extracts the list of CA names (DNs) that the server sends in its CertificateRequest message.

The code for extracting the CA list from the CertificateRequest message seems to be working correctly. However, this commit is incomplete for a couple of reasons. First, it does not produce any new output, it just collects the information. Second, sclient_auth() needs some work.

The current sclient_auth() simply returns 0 if $OPENSSL returned 0. This may be okay if only trying to determine whether certificate-based client authentication is required. However, if it is optional, then the output will include "CertificateRequest", but $OPENSSL will return 0, since the connection was successful even though the client did not provide a certificates.

If $OPENSSL does not return 0, then sclient_auth() checks whether Master-Key is present. This works for TLS 1.2 and earlier, but not for TLS 1.3. So, sclient_auth() needs to be updated to work correctly with TLS 1.3.

The modified version of sclient_auth() will set CLIENT_AUTH and CLIENT_AUTH_CA_LIST for any version of TLS, but the remaining part of the code needs work. As I am not clear on the reason for this code, I need some help with it. Why does the code only look for "CertificateRequest" if "Master-Key" is present? Why is there a check for Session-ID in a function that is supposed to just be checking for client authentication. Why is CLIENT_AUTH set to false if SESSION-ID is absent (this is a no-op since CLIENT_AUTH would already have been false)?
2021-02-05 13:11:38 -05:00
David Cooper 1de8def49f Mass testing with CSV, HTML, JSON, and/or LOG file names in mass testing file
See #1148 and #1805.

As noted in #1148, testssl.sh is not current designed to handle a mass testing file in which CSV, HTML, LOG, and/or JSON file names are provided in the mass testing file. If a child process receives a command line with one of the files, it assumes the same command-line option was provided to the parent so that the output of every test is being written to this one file. If this assumption is wrong, then either the file will not be created at all or it will be malformed since it will be missing header and/or footer information.

This PR partially addresses the problem by introducing new command-line arguments that are for internal use only. These command line arguments allow a child process to distinguish between a CSV, HTML, LOG, or JSON file that it is supposed to create itself versus one that is to be shared by all of the child processes.

There is one major limitation to this PR. The code for handle command-line arguments in the mass testing file is very simple and cannot handle whitespace characters, whether they are enclosed in quotes or are escaped. So, any file names included in the mass testing file cannot have whitespace characters.
2021-01-26 16:46:35 -05:00
David Cooper 64cca8c03a Reintroduce unused print functions
This commit adds back in the print functions (tm_*, tmln_*, pr_*, prln_*) that are defined but not used.
2020-11-13 15:32:21 -05:00
David Cooper 7d183ba8a2 This commit changes the colors that are used when generating HTML so that they comply with the minimum requirements for contrast in the W3C's Web Content Accessibility Guidelines (WCAG). 2020-11-13 14:48:14 -05:00
David Cooper 3973bc3364 Fix #1699
This commit fixes #1699 by setting FIRST_FINDING to true in fileout_banner() if $do_json_pretty is true.

When $do_json_pretty is true, fileout_banner() calls fileout_pretty_json_banner(), which starts a new sectio in the JSON file. Setting FIRST_FINDING to true ensures that a comma is not placed before the first entry in this new section. This is the same as is done in other places when a new section is stated: fileout_section_header() and fileout_insert_warning().
2020-08-31 10:35:19 -04:00
David Cooper fd5928af47 Use fewer external function calls
This commit modifies a few functions to use fewer external function calls. In most cases this involves replacing external function calls with Bash internal functions, but in one case it involves replacing multiple external function calls with one call to awk.

This commit makes a few changes to the way that some functions work.

is_ipv4addr() and is_ipv6addr() will now strictly only accept a string that is an IPv4 (or IPv6) address and nothing else.

A couple of changes were also made to match_ipv4_httpheader(). First, lines that match $excluded_header (formerly $whitelisted_header) are not processed in the while loop. This prevents the excluded header from being output in the case that $HEADERFILE includes a non-excluded header with an IPv4 address and an excluded header with a string that looks like an IPv4 address.

The list of excluded headers was also modified to exclude any line that begins "Server: " rather than just lines that begin "Server: PRTG". According to https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Server, the "Server" header describes the software used by the server, so it seems reasonable to expect that this header line will never contain an IPv4 address. Also, looking at some old test results I found cases in which Oracle software version numbers in the Server header were mistakenly matched as IPv4 addresses.
2020-08-06 07:50:01 -04:00
David Cooper 7f99ffa55d Update ETSI ETS test
The commit updates the test for the "Visibility Information" certificate extension used in the ETSI Enterprise Transport Security protocol.

The main change is to support OpenSSL 3.0.0, which prints more information about subject alternative names that are encoded as otherName. For otherName types for the OpenSSL has no information, it prints "otherName: <OID>::<unsupported>" rather than just "otherName: <unsupported>". So, testssl.sh needs to account for the possibility that the OID for the visibility information certificate extension will be printed.

This commit also updates the reference for this extension and changes the name of the function from etsi_etls_visibility_info() to etls_ets_visibility_info() since the name of the protocol was changed from Enterprise TLS (eTLS) to Enterprise Transport Security (ETS).

This commit does not change the output to the terminal or to JSON/CSV, even though those outputs use the previous name of eTLS rather than ETS.
2020-08-04 08:29:22 -04:00
David Cooper 9d62647226 Align ALPN GREASE test with RFC 8701
The ALPN GREASE test was written based on draft-ietf-tls-grease-01, which reserved all ALPN identifiers beginning with the prefix "ignore/". This commit changes the test to align with RFC 8701, which instead reserves {0x0A,0x0A}, {0x1A,0x1A}, ..., {0xFA,0xFA}.
2020-08-04 07:35:05 -04:00
David Cooper 5b17bbcf87 Add RFC 8701 to list of RFCs
This commit adds RFC 8701 to the list of RFCs in the documentation.
2020-08-03 11:14:10 -04:00
David Cooper 57c4913260 Update GREASE reference
The GEASE Internet Draft is now RFC 8701. This commit updates the references.
2020-08-03 10:43:15 -04:00
David Cooper bd856e2ada Save intermediate certificates for more use
As there as suggestions to check intermediate certificates for things such as expiration date, this commit saves the text versions of each of the intermediate certificates so that they are available to extract additional information.
2020-07-16 07:57:27 -04:00
David Cooper 17ee0245b5 Speed up intermediate certificate extraction
This commit speeds up extraction of intermediate certificates by using Bash commands rather than awk.
2020-07-15 11:56:31 -04:00
David Cooper 851cd564e6 Check for bad OCSP intermediate certificates
This commit checks whether any intermediate certificates provided by the server include an extended key usage extension that asserts the OCSP Signing key purpose.

This commit replaces #1680, which checks for such certificates by comparing the server's intermediate certificates against a fixed list of known bad certificates.
2020-07-15 11:56:20 -04:00
David Cooper 6c8df4529c Include cipher quality in JSON and CSV
run_cipherlists() checks for support for different groups of ciphers, but does not indicate which ciphers in each group are supported. So, for example, if the JSON file indicates that there is a problem with severity level "HIGH" because the "LOW" ciphers are available, there is no clear indication of which of these ciphers are supported by the server.

If run_server_preference() is run with "--color 3", then there will be a visual indication (via color) of the ciphers the server supports that are considered bad, but this information does not appear in the JSON (or CSV) output. The JSON (or CSV) output will include information about every cipher that is supported, but the severity level is always "INFO".

This commit addresses this problem by changing the fileout() calls in ciphers_by_strength() and cipher_pref_check() that output each supported cipher individually so that the "severity" argument is an indication of the quality of the cipher. With this, information about which bad ciphers are supported can easily be found in the JSON/CSV output.
2020-07-07 12:35:35 -04:00
David Cooper 45eafd239f Fix printing of unrecognized option
When testssl.sh is called with an unknown option it prints something like:

     0: unrecognized option "--option"

It should be printing the name of the program rather than "0". This commit fixes that.
2020-07-07 07:30:48 -04:00
David Cooper 919064095f Separate pr_cipher_quality() into two functions
This commit separates pr_cipher_quality() into two functions, one that returns the quality of a cipher as a numeric rating (get_cipher_quality()) and one that prints a cipher based on its quality (pr_cipher_quality()). This separation allows get_cipher_quality() to be used to determine how good a cipher is without having to print anything. Having this ability would be helpful in implementing the changes suggested in #1311.
2020-07-06 15:45:36 -04:00
David Cooper 1f2b4a3f40 Fix #1665
This commit fixes #1665 by adding the certificate number to the JSON identifier for cert_eTLS.
2020-06-25 13:18:28 -04:00
David Cooper 91ceaca1e9 Fix #1662
This commit fixes #1662 by changing the fileout to use the value of $cert_ext_keyusage rather than the string "cert_ext_keyusage".
2020-06-25 07:31:50 -04:00
David Cooper a6c2168cd9 Fix and enhance CN matching
PR #1373 changed get_cn_from_cert() to handle certificate subject names that include more than one CN attribute. It did this by converting newline characters to spaces. It seems that this resulted in a space character being added to the end of the string returned by get_cn_from_cert() even in the case that the subject name only included one CN attribute. The presence of the space character in returned value caused compare_server_name_to_cert() to determine that the CN attribute did not contain a DNS name (since DNS names cannot include spaces), and so compare_server_name_to_cert() reports that the server name does not match against the CN in the subject. This may be the reason for the problem noted in #1555.

This commit fixes the above problem and also enhances the matching of the CN in the subject name against the server's name. Currently, compare_server_name_to_cert() assumes that the subject field contains at most one CN attribute. However, as noted in #1373, some certificates include subject names with more than one CN attribute, and RFC 6125 (Section 6.2.2) indicates that the certificate subject name include more than one CN, with each specifying a different DNS name.

So, in addition to fixing the problem with the space character, this commit also enhances the CN matching to work even if the certificate includes more than one CN attribute in the subject name.
2020-06-08 13:57:00 -04:00
David Cooper fe87192a80 Fix missing spaces
In some cases when the Trust finding is printed, there is no space between the results when SNI is used and the results without SNI (which appear in paraenthesis). This commit adds the missing space.
2020-06-08 13:54:36 -04:00
David Cooper edefce5998 Fix Shellcheck SC2034 issues
This commit fixes several issues related to Shellcheck issue SC2034: unused variables.

In most cases variables are declared in a function, but are referenced later. The exceptions are:

* SESS_RESUMPTION is declared and values are assigned to it, but it us never used. (Same applies for not_new_reused in sub_seession_resumption().)

* In run_cipherlists(), there is a typo in the declaration of sslv2_tdes_ciphers.

* In get_caa_rr_record(), "hash", "len", and "line" are used but not declared.
2020-06-01 15:31:01 -04:00
David Cooper 37ffabf8d5 Remove some unnecessary quotation marks 2020-05-18 07:38:49 -04:00
David Cooper 3ae48931fb Support EdDSA
This commit adds support for EdDSA (Ed25519 and Ed448). In particular:

* It modifies prepare_tls_clienthello() to include Ed25519 and Ed448 in the signature_algorithms extension of the TLS 1.2 and earlier ClientHello (RFC 8422).

* It modifies run_server_defaults() and get_server_certificate() to check whether the server offers EdDSA certificates with TLS 1.3.

* It modifies certificate_info() to handle certificates signed with EdDSA or with EdDSA public keys, even if $OPENSSL does not support pretty printing such keys and signatures.

* It modifies read_sigalg_from_file() to recognize EdDSA signatures even if $OPENSSL does not.
2020-05-18 07:37:46 -04:00
David Cooper df42eeb8b4 Extract server's signature algorithm
PR #1519 requested that testssl.sh show the signature algorithm that the server uses during the TLS handshake. In TLS 1.3, this appears in the CertificateVerify message. In TLS 1.2 it appears in the ServerKeyExchange message when the chosen cipher suite uses an ephemeral (DH or ECDH) key, except in the case of cipher suites that provide no authentication. This information is not present in TLS 1.1 and earlier, as the hash algorithm to use in these earlier versions of the protocol is hard coded into the specification.

This commit takes a first step towards being able to show the signature algorithm by extending parse_tls_serverhello() to extract the signature algorithm when it is present. Matching the output produced by OpenSSL, it output two separate lines, the "Peer signature type" (RSA, RSA-PSS, DSA, ECDSA, Ed25519, or Ed448) and the "Peer signing digest" (MD5, SHA1, SHA224, SHA256, SHA384, or SHA512). This will allow the same function to extract the signature algorithm and digest, whether the handshake was performed using "$OPENSSL s_client" or tls_sockets().
2020-05-14 14:42:08 -04:00
David Cooper d5671a0352 Fix $SHOW_SIGALGO
This commit fixes two issues related to $SHOW_SIGALGO.

First, cipher_pref_check() does not show the signature algorithm if any of the ciphers were found using tls_sockets(), since the call to tls_sockets() does not specify that the server's certificate should be extracted.

Second, in run_beast() the call to tls_sockets() indicates that the server's certificate should be extracted if "$SHOW_SIGALGO" is true, even if "$WIDE" is false. While this does not cause any problems, extracting the certificate is a waste of effort if "$WIDE" is false, since the signature algorithm is not shown in that case.
2020-05-11 10:09:02 -04:00
David Cooper 4f802502a0 Implement $HAS_SIGALGS
The "-sigalgs" option is used in get_server_certificate() to obtain certificates the server uses with TLS 1.3. get_server_certificate() is currently designed to use $OPENSSL, if $OPENSSL supports TLS 1.3.

LibreSSL 3.1.{0,1} has added client support for TLS 1.3, but does not support the "-sigalgs" option. So, this commit determines whether the "-sigalgs" option is supported, and if it isn't, then uses tls_sockets().
2020-05-08 16:15:32 -04:00
David Cooper ec4feb52e7 Fix "local problem" output in ciher_pref_check()
When cipher_pref_check() is called in "--ssl-native" mode and the specified protocol is not supported, the message indicating a "local problem" is not properly formatted.
2020-05-08 16:13:30 -04:00
David Cooper cde2ecdc5d Rate RSA e=1 as CRITICAL
PR #1619 set the grade cap to 'F' is the server has a certificate with an RSA with e=1, however, it did not change the rating in the JSON/CSV output. This commit changes the cert_keySize rating to CRITICAL for an RSA key with e=1, regardless of the size of the modulus. It also uses pr_svrty_critical() to print the exponent in this case.
2020-05-08 08:23:14 -04:00
David Cooper 8697e3417a Fix copy and paste error
This commit fixes a bug that was introduced by an accidental copy and paste.
2020-05-07 12:33:23 -04:00
David Cooper 46bf8c90ac Improve key exchange grading
This commit makes a couple of improvements to set_key_str_score().

It rates (finite-field) DH keys the same as RSA and DSA keys.

Second, in the case of a server that has more than one certificate, the current code sets $KEY_EXCH_SCORE based on the length of the public key in the last certificate that is parsed. This commit changes set_key_str_score() so that $KEY_EXCH_SCORE is set based on the weakest public key.

Note that there is still the issue that the key exchange score does not take into account any ephemeral keys used. However, that needs to be addressed by callling set_key_str_score() from run_fs() and run_logjam(), as certificate_info() cannot provide information about ephemeral keys.
2020-05-06 14:30:44 -04:00
David Cooper a8c9133fc6 Check for RSA exponent of 1
As suggested in #1576, set the grade cap to F if the RSA key has an exponent of 1.
2020-05-06 14:25:59 -04:00
David Cooper 9dba2a8c9c Fix #1576
This commit adds additional information to the "Server key size" line for a certificate if the subject public key is RSA, ECDSA, or DH.

For RSA it show the public exponent. For ECDSA, it shows the curve. For DH, it shows the group used, if it is a common prime.
2020-05-06 12:16:15 -04:00
David Cooper 329ba95d5b Fix #1433
This commit fixes #1433 by adding "@SECLEVEL=0" to the "$OPENSSL s_client" and "$OPENSSL ciphers" command lines if that option is supported. Adding this option configures OpenSSL to support some weak ciphers that it would not use in the default configuration.
2020-05-06 08:43:13 -04:00
David Cooper 84a82dbddc tls_sockets() return value
There is one place in parse_tls_serverhello() that returns 8 if the server's response is not well-formed TLS. However, there is no code in testssl.sh that is prepared to handle this return value. Every function except run_protocols() only distinguishes between 0, 2, and everything else. run_protocols(), however, gets confused if tls_sockets() returns a value that it is not expecting. So, this commit changes parse_tls_serverhello() to return 1 whenever the server's response can not be parsed.
2020-05-06 08:31:09 -04:00
David Cooper ae8a056afe Check server's response
There is code at the beginning of parse_tls_serverhello() that checks whether the server's response appears to consist of a sequence of messages of the form <protocol><content type><content>. However, at the moment the check is only performed if "$do_starttls" is false. This commit changes parse_tls_serverhello() so that the check is always performed.
2020-05-04 14:29:13 -04:00
David Cooper a5a28d2457 Improve LibreSSL 3.1.0 compatibility
This commit addresses two compatibility issues with LibreSSL 3.1.0, which has added client support for TLS 1.3.

The first issue is that LibreSSL has named the TLS 1.3 ciphers that it supports AEAD-AES256-GCM-SHA384, AEAD-CHACHA20-POLY1305-SHA256, and AEAD-AES128-GCM-SHA256, rather than using the OpenSSL names, which are TLS_AES_256_GCM_SHA384, TLS_CHACHA20_POLY1305_SHA256, and TLS_AES_128_GCM_SHA256. (Draft versions of OpenSSL 1.1.1 names these ciphers TLS13-AES-256-GCM-SHA384, TLS13-CHACHA20-POLY1305-SHA256, TLS13-AES-128-GCM-SHA256.) There are several places where testssl.sh checks whether a cipher suite is a TLS 1.3 cipher by checking whether its OpenSSL name begins with "TLS_" (or "TLS13"). In order to work with LibreSSL 3.1.0, these checks also need to consider names that begin with "AEAD-" to be TLS 1.3 ciphers.

Second, in sub_session_resumption() there is code that adds "-no_ssl2" to the "$OPENSSL s_client" command line if that option is supported. If "-no_ssl2" is not supported, then other protocol information is added to the command line. I believe this code was written with the assumption that any version of OpenSSL that supports "-no_ssl2" does not support TLS 1.3. However, LibreSSL 3.1.0 supports both. So, this commit changes the code to add the "-no_ssl2" option only if TLS 1.3 is not supported.
2020-04-30 11:08:04 -04:00
David Cooper cb67d91417 Improve compatibility with LibreSSL 3.0.2 and earlier
This commit addresses two compatibility issues with LibreSSL.

First, with LibreSSL, "$OPENSSL s_client" does not support the "-curves" option, so the "-groups" option needs to be used instead. Note that with LibreSSL, the command line "$OPENSSL s_client -groups $curve -connect invalid." will not work, as it will complain "no port defined," but will not indicate whether the specified curve is supported. Adding a port number fixes that problem. (There does not seem to be a need to include a port number for other tests, such as whether the "-curves" option itself is supported.)

Second, including "-out -" in the command line for "$OPENSSL genpkey" causes LibreSSL to create a file with the name "-" if the algorithm is supported. This is not an issue at the moment, since LibreSSL's genpkey does not support X25519 or X448. However, both genpkey with both OpenSSL and LibreSSL uses stdout as the default output if no "-out" is specified, so the "-out -" is not necessary.
2020-04-30 10:37:12 -04:00