Test SSL protocols availability using openssl s_client

3 min read | by Jordi Prats

To make sure we don't publish an SSL service with vulnerable protocols enabled we can check which protocols the server has enabled using openssl s_client

Depending on the OpenSSL version we have we will have different procotols available. For example, if we are using OpenSSL 1.0.2j we will have the following options for s_client:

 -ssl2 - just use SSLv2 -ssl3 - just use SSLv3 -tls1_2 - just use TLSv1.2 -tls1_1 - just use TLSv1.1 -tls1 - just use TLSv1 -dtls1 - just use DTLSv1 

On the other hand, if we are using OpenSSL 1.1.1f we will only have:

 -tls1 Just use TLSv1 -tls1_1 Just use TLSv1.1 -tls1_2 Just use TLSv1.2 -tls1_3 Just use TLSv1.3 

To be able to test a connection for a specific protocol we just need to look at it's output:

$ echo | openssl s_client -connect pet2cattle.com:443 -tls1_1 CONNECTED(00000003) 140063618889024:error:141E70BF:SSL routines:tls_construct_client_hello:no protocols available:../ssl/statem/statem_clnt.c:1112: --- no peer certificate available --- No client certificate CA names sent --- SSL handshake has read 0 bytes and written 7 bytes Verification: OK --- New, (NONE), Cipher is (NONE) Secure Renegotiation IS NOT supported Compression: NONE Expansion: NONE No ALPN negotiated Early data was not sent Verify return code: 0 (ok) --- 

If we are receiving the server's certificate means that the protocol is enabled

$ echo | openssl s_client -connect pet2cattle.com:443 -tls1_2 CONNECTED(00000003) depth=2 C = US, O = Internet Security Research Group, CN = ISRG Root X1 verify return:1 depth=1 C = US, O = Let's Encrypt, CN = R3 verify return:1 depth=0 CN = pet2cattle.com verify return:1 --- Certificate chain  0 s:CN = pet2cattle.com  i:C = US, O = Let's Encrypt, CN = R3  1 s:C = US, O = Let's Encrypt, CN = R3  i:C = US, O = Internet Security Research Group, CN = ISRG Root X1  2 s:C = US, O = Internet Security Research Group, CN = ISRG Root X1  i:O = Digital Signature Trust Co., CN = DST Root CA X3 --- Server certificate -----BEGIN CERTIFICATE----- MIIFTDCCBDSgAwIBAgISAwXD7VJX4nuT0D36AAaBjuTBMA0GCSqGSIb3DQEBCwUA MDIxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MQswCQYDVQQD EwJSMzAeFw0yMTA2MTIxNzQyNDRaFw0yMTA5MTAxNzQyNDNaMBkxFzAVBgNVBAMT DnBldDJjYXR0bGUuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA (...) 

So, we can check for the s_clients output looking for the Server certificate string to tell if the protocol is enabled. We can even make a small oneliner to list all status of the available protocols:

$ for i in $(openssl s_client --help 2>&1 | grep -i "just use" | awk '{ print $1 }' | grep -v dtls); do echo | openssl s_client -connect pet2cattle.com:443 $i 2>&1 | grep "Server certificate" > /dev/null; if [ $? -eq 0 ]; then echo $i ENABLED; else echo $i DISABLED; fi; done -tls1 DISABLED -tls1_1 DISABLED -tls1_2 ENABLED -tls1_3 DISABLED 

Just by changing the -connect string we can test any server we like:

$ for i in $(openssl s_client --help 2>&1 | grep -i "just use" | awk '{ print $1 }' | grep -v dtls); do echo | openssl s_client -connect google.com:443 $i 2>&1 | grep "Server certificate" > /dev/null; if [ $? -eq 0 ]; then echo $i ENABLED; else echo $i DISABLED; fi; done -tls1 DISABLED -tls1_1 DISABLED -tls1_2 ENABLED -tls1_3 ENABLED 

Posted on 06/07/2021