14

Due to a security scan, I was told to not use TLS1.0. I found a link that gave me commands to use to check if a specific protocol is used/enabled. The command I ran (with output is)

(Output from TLS1.0 disabled)

$ openssl s_client -connect localhost:8443 -tls1
CONNECTED(00000003)
139874418423624:error:14094410:SSL routines:SSL3_READ_BYTES:sslv3 alert handshake failure:s3_pkt.c:1275:SSL alert number 40
139874418423624:error:1409E0E5:SSL routines:SSL3_WRITE_BYTES:ssl handshake failure:s3_pkt.c:598:
---
no peer certificate available
---
No client certificate CA names sent
---
SSL handshake has read 7 bytes and written 0 bytes
---
New, (NONE), Cipher is (NONE)
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
SSL-Session:
    Protocol  : TLSv1
    Cipher    : 0000
    Session-ID: 
    Session-ID-ctx: 
    Master-Key: 
    Key-Arg   : None
    Krb5 Principal: None
    PSK identity: None
    PSK identity hint: None
    Start Time: 1505770082
    Timeout   : 7200 (sec)
    Verify return code: 0 (ok)
---

The link said if the protocol is enabled, it will say "Connected", else "handshake failure". However, as you can see the messages above, it says both even though I configured Tomcat to use TLS1.2.

My config in the server.xml file:

<Connector port="8443" protocol="HTTP/1.1"
   maxThreads="150" SSLEnabled="true" scheme="https" secure="true"
   keystoreFile="/glide/bigdata/bdapi/keys/bdapi_keystore.jks"
   keystorePass="bdapi123" clientAuth="false" sslProtocol="TLSv1.2" 
   sslEnabledProtocols="TLSv1.2"/>

If I allow Tomcat to use TLS1.0, I still see CONNECTED but I also see the certificate info.

(Output from TLS1.0 enabled)

openssl s_client -connect localhost:8443 -tls1
CONNECTED(00000003)
<snip snip>
<snip snip>
(certificate info)
verify error:num=21:unable to verify the first certificate
verify return:1
---
Certificate chain
<snip snip>
<snip snip>
(certificate info)
---
Server certificate
-----BEGIN CERTIFICATE-----
<snip snip>
<snip snip>
(public key)
-----END CERTIFICATE-----
<snip snip>
<snip snip>
(certificate info)
---
No client certificate CA names sent
Server Temp Key: ECDH, secp521r1, 521 bits
---
SSL handshake has read 2121 bytes and written 357 bytes
---
New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES256-SHA
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
SSL-Session:
    Protocol  : TLSv1
    Cipher    : ECDHE-RSA-AES256-SHA
    Session-ID: 59C0448146B0A18DE52D99C630C896E12BA9861702AB2582C2AA0658E6458B04
    Session-ID-ctx: 
    Master-Key: <some random key>
    Key-Arg   : None
    Krb5 Principal: None
    PSK identity: None
    PSK identity hint: None
    Start Time: 1505772673
    Timeout   : 7200 (sec)
    Verify return code: 21 (unable to verify the first certificate)
---
read:errno=0

How do I interpret the output from openssl? Did I successfully disable TLS1.0 with the config above or since it says "CONNECTED" in both output, I didn't disable it and I'll fail the security scan again?

peterh
  • 2,938
  • 6
  • 25
  • 31
Classified
  • 243
  • 1
  • 3
  • 7

4 Answers4

19

TL;TR: It is far from trivial to verify from the client that a server is not supporting TLS 1.0. You can be sure that the server supports TLS 1.0 if you get a successful connection with TLS 1.0. But you cannot be sure that the server does not support TLS 1.0 if this attempt fails.


As you already realized the information given in the link you cite are at least partly wrong. Also, they are incomplete. Checking if a server has really TLS 1.0 disabled is not that simple. To understand what need to be checked to be really sure it is better to have at least a basic understanding of how the TLS-Handshake works. Note that most of what I say here is also true for SSL, which is mainly the earlier name for the same protocol family now known as TLS.

Initially, the client needs to create a TCP connection to the server. This has nothing to do with TLS itself yet. And already if the TCP connection succeeds you will get CONNECTED(00000003). If you don't get this CONNECTED then the server might be down or might not be reachable from your site, for example because a firewall is blocking the access. Thus, not getting the CONNECTED says nothing about the ability of the server to support TLS 1.0.

After the TCP connection is created the TLS part begins. In the simplest case the client sends at the beginning of the TLS handshake inside the ClientHello message the best TLS version it can and the ciphers it supports. The server replies with the best SSL/TLS protocol it supports which is equal or lower to the protocol version offered by the client. And the server picks the common cipher based on what the client offers and and what is configured to be acceptable for the server. In your specific case the client offers TLS 1.0 as the best protocol (due to the -tls1 option) and the default cipher set. The handshake will fail if the server does not support TLS 1.0 or lower OR if the server does not support any of the ciphers offered by the client. Because of the last part it is possible that the server fails with your specific client even if the server has TLS 1.0 enabled because the server does not like the ciphers offered by the client.

And it gets more complex. It is common that servers support multiple certificates on the same IP address today. This is done by including the target hostname using the SNI TLS extension inside the ClientHello at the start of the TLS handshake. If there is no SNI extension or if the extension does not match any configured hostname the server will usually either send some default certificate or abort the handshake. Because of the last part it is possible that the server fails with your specific client even if the server has TLS 1.0 enabled because no SNI extension was used or it was used with the wrong hostname. openssl s_client will not use SNI by default so your attempt might simply have failed just because of a missing SNI extension. You have to use the -servername option for this and of course you need to use a hostname properly configured at the server with this option.

And so far we dealt only with sane TLS stacks and a direct connection to the server. If the TLS stack is broken or if there is some broken middlebox in between (like load balancers, firewalls etc) they might make the handshake fail accidentally or on purpose even though the server supports TLS 1.0. And if you have some SSL termination in front of your server (some firewalls, load balancers or a CDN) you will not even test the properties of the server but of the system in front of it.

In other words: if you get a successful TLS 1.0 connection to the server you can be sure that the server or some SSL terminator in front of it supports TLS 1.0. If the TLS 1.0 connection fails instead it does not mean for sure that the server does not support TLS 1.0.

Steffen Ullrich
  • 184,332
  • 29
  • 363
  • 424
  • 3
    Since this Q was revived (unnecessarily) I'll add that as of OpenSSL 1.1.1 (2018-09) `s_client` does do SNI by default (unless you specify `-noservername`) – dave_thompson_085 Mar 23 '19 at 13:36
4

Although these tools do not directly answer your specific question, they may provide the results you are looking for. If you have an Internet connection, try some of these:

If no Internet Connection try:

jwilleke
  • 221
  • 1
  • 6
2

Yes that website is wrong; CONNECTED means the TCP connection succeeded but says nothing about the TLS (or hopefully not SSL) handshake. If you don't get CONNECTED but get a few lines ending with connect: errno=$n (even if the number is 0!) it means we weren't even able to attempt a handshake and thus have no information either way what the server supports.

Although you could learn to read the error messages and other info openssl puts out, the key indicator is the line beginning New, at the beginning of the last block of output (after the --- a few lines before SSL-Session:); if it shows a real protocol version and cipher the handshake succeeded, if it has (NONE) the handshake failed -- as yours does.

Note the handshake can fail for reasons other than the protocol version. If this test succeeds for 1.0, you can be sure the server does support 1.0, but if this test fails it doesn't definitely prove the server doesn't support 1.0. You'll need to actually learn about TLS to distinguish those. As Steffen posted at much greater length while I was writing this -- but I decided my paras 2 and 4 may still help.

FWIW also note testing for SSLv2 using only s_client -ssl2 is not valid on releases 1.0.0 up where the default cipherlist prevents SSLv2 connection even on servers that support SSLv2. However, anyone still worrying today about SSLv2 on a real (not test-lab or museum) server is in deep trouble.

dave_thompson_085
  • 9,759
  • 1
  • 24
  • 28
1

This output means we have successfully disabled TLS 1.0:

CONNECTED(00000003)
140089425225616:error:1409442E:SSL routines:ssl3_read_bytes:tlsv1 alert protocol version:s3_pkt.c:1493:SSL alert number 70
140089425225616:error:1409E0E5:SSL routines:ssl3_write_bytes:ssl handshake failure:s3_pkt.c:659:

If it's not disabled, it will show complete certificate details.

schroeder
  • 123,438
  • 55
  • 284
  • 319