The Postgres protocol uses STARTTLS with a custom start packet. This
functionality is supported by openssl s_client in the current openssl
master branch but not yet in any released version.
This patch detects whether the given openssl binary supports postgres
and runs the default tests against a postgres server.
Example of no openssl support:
~/bin/testssl$ ./testssl.sh --quiet
--openssl=/opt/openssl/openssl-1.1.0c/bin/openssl --starttls=postgres
test.postgres.server.com:5432
Start 2016-12-07 18:03:24 -->> ip.add.re.ss:5432
(test.postgres.server.com:5432) <<--
Fatal error: Your /opt/openssl/openssl-1.1.0c/bin/openssl does not
support the "-starttls postgres" option
Example of openssl support:
~/bin/testssl$ ./testssl.sh --quiet
--openssl=/opt/openssl/openssl-2016-12-07/bin/openssl --startt ls=postgres
test.postgres.server.com:5432
Start 2016-12-07 18:06:03 -->> ip.add.re.ss:5432
(test.postgres.server.com:5432) <<--
Service set: STARTTLS via POSTGRES
Testing protocols (via openssl, SSLv2 via sockets)
SSLv2 not offered (OK)
SSLv3 offered (NOT ok)
TLS 1 offered
TLS 1.1 offered
TLS 1.2 offered (OK)
SPDY/NPN (SPDY is an HTTP protocol and thus not tested here)
HTTP2/ALPN (HTTP/2 is a HTTP protocol and thus not tested
here)
...
For several elliptic curves the number of bits, as indicated by OpenSSL, is slightly different than the name implies. For example, for sect239k1 OpenSSL outputs: `Server Temp Key: ECDH, sect239k1, 238 bits`.
This PR aligns the output created by `parse_tls_serverhello()` with OpenSSL.
When the cipher-mapping.txt file is read, the contents of the "Mac=..." column is placed in `TLS_CIPHER_EXPORT` rather than the contents of the "export" column. This PR fixes that.
This PR address a problem in `run_drown()` when the server does not support SSLv2, but does support multiple certificates or doesn't have an RSA certificate.
One example of the problem can be seen with www.facebook.com. If `run_server_preferences()` is run before `run_drown()`, then the results of `run_drown()` are:
```
DROWN (2016-0800, CVE-2016-0703) not vulnerable on this port (OK)
make sure you don't use this certificate elsewhere with SSLv2 enabled services
https://censys.io/ipv4?q=A626B154CC65634181250B810B1BD4C89EC277CEA08D785EEBE7E768BDA7BB00 SHA256 A3F474FB17509AE6C5B6BA5E46B79E0DE6AF1BF1EEAA040A6114676E714C9965 could help you to find out
```
If only `run_drown()` is performed, then the result is:
```
DROWN (2016-0800, CVE-2016-0703) not vulnerable on this port (OK)
make sure you don't use this certificate elsewhere with SSLv2 enabled services
https://censys.io/ipv4?q=A626B154CC65634181250B810B1BD4C89EC277CEA08D785EEBE7E768BDA7BB00 could help you to find out
```
However, A626B154CC65634181250B810B1BD4C89EC277CEA08D785EEBE7E768BDA7BB00 is the fingerprint of Facebook's ECDSA certificate, not its RSA certificate.
In addition, as noted in the "FIXME," `run_drown()` will display the warning "make sure you don't use this certificate elsewhere with SSLv2 enabled services" even if the server doesn't have an RSA certificate, even though SSLv2 can only use RSA certificates.
This PR fixes this issue by only showing the warning if the server has an RSA certificate and by ensuring that the `$cert_fingerprint_sha2` used to construct the "https://censys.io/ipv4?q=..." URL only contains a single SHA256 fingerprint and that it is the fingerprint of the server's RSA certificate.
This PR implements `run_rc4()` in a similar manner to `run_allciphers()` and `run_cipher_per_proto()` (in PR #541). The change doesn't seem to have much of an impact on speed, but when sockets are used it can detect ciphers that aren't locally supported by OpenSSL.
This PR fixes two minor bugs in run_allciphers():
* If `$SSL_NATIVE` or `$FAST` is `true`, then the cipher mapping file will not be used (unless `$OPENSSL ciphers` does not support the `-V` option), so there is no "fallback" to openssl, even if `[[ $TLS_NR_CIPHERS == 0 ]]`.
* If `$using_sockets` is `false` and `$SHOW_EACH_C` is `true`, then `ossl_supported` should be checked to see if the cipher was tested, not `TLS_CIPHER_OSSL_SUPPORTED`.
This function reorganizes `run_server_defaults()` based on the suggestion in #515.
The current `determine_tls_extensions()` is renamed to `get_server_certificate()`, and two changes are made to it:
*it no longer includes an extra call to `$OPENSSL s_client` to check for the ALPN extension; and
* rather than setting `$TLS_EXTENSIONS` to be the extensions found during this call to the function, it adds any newly found extensions to those already in `$TLS_EXTENSIONS`.
The PR then adds a new function, `determine_tls_extensions()`, which borrows some logic from the old `determine_tls_extensions()`, but this new `determine_tls_extensions()` only looks for additional TLS extensions, including ALPN.
`run_server_defaults()` makes multiple calls to `get_server_certificate()` (as it previously did to `determine_tls_extensions()`) in order to collect all of the server's certificates, and then it makes one call to `determine_tls_extensions()`, which checks for support for extensions that were not checked for by `get_server_certificate()` (e.g., ALPN, extended master secret, signed certificate timestamps).
The new `determine_tls_extensions()` will check for most of the extensions that are checked for by
`run_server_defaults()`, including the heartbeat extension, so the call to `determine_tls_extensions()` from `run_heartbleed()` will still work.
> The dh_bits are still not shown, maybe because of #531.
This PR fixes the issue of dh_bits not being shown if the cipher-mapping.txt file is missing. The problem is that the code in `parse_tls_serverhello()` that parses the ServerKeyExchange message assumes that `$rfc_cipher_suite` has the RFC version of the name the cipher suite. However, if the cipher-mapping.txt file is missing, `$rfc_cipher_suite` will have the OpenSSL name of the cipher suite. This PR changes the code to recognize either the RFC or OpenSSL names for ciphers with ephemeral DH or ECDH keys.