Sunny
Sunny

Reputation: 1239

How to force TLS1.2 with SSLPoke

We suspect that the host is terminating the connection due to it not supporting TLS1, but how do we force the SSLPoke utility to use TLS1.2?

Alternatively, is there another utility like SSLPoke to debug SSL issues?

Note that we are using both -Djdk.tls.client.protocols=TLSv1.2 and -Dhttps.protocols=TLSv1.2

/usr/java/jre1.7.0_79/bin/java -Djavax.net.debug=ssl:handshake:verbose -Djdk.tls.client.protocols=TLSv1.2 -Dhttps.protocols=TLSv1.2 -Djavax.net.ssl.trustStore=/usr/java/jre1.7.0_79/lib/security/cacerts SSLPoke hostname.com 443

Here is the output:

trigger seeding of SecureRandom
done seeding SecureRandom
Ignoring unsupported cipher suite: TLS_DHE_DSS_WITH_AES_128_CBC_SHA256
Ignoring unsupported cipher suite: TLS_DHE_DSS_WITH_AES_256_CBC_SHA256
Ignoring unsupported cipher suite: TLS_DHE_RSA_WITH_AES_128_CBC_SHA256
Ignoring unsupported cipher suite: TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256
Ignoring unsupported cipher suite: TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
Ignoring unsupported cipher suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
Ignoring unsupported cipher suite: TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384
Ignoring unsupported cipher suite: TLS_RSA_WITH_AES_256_CBC_SHA256
Ignoring unsupported cipher suite: TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
Ignoring unsupported cipher suite: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
Ignoring unsupported cipher suite: TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384
Ignoring unsupported cipher suite: TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
Ignoring unsupported cipher suite: TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256
Ignoring unsupported cipher suite: TLS_RSA_WITH_AES_128_CBC_SHA256
Allow unsafe renegotiation: false
Allow legacy hello messages: true
Is initial handshake: true
Is secure renegotiation: false
%% No cached client session
*** ClientHello, TLSv1
RandomCookie:  GMT: 1552588154 bytes = { 73, 65, 219, 139, 69, 186, 117, 96, 143, 111, 176, 121, 23, 183, 218, 92, 16, 61, 9, 162, 243, 215, 95, 23, 255, 24, 12, 2 }
Session ID:  {}
Cipher Suites: [TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, TLS_RSA_WITH_AES_256_CBC_SHA, TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA, TLS_ECDH_RSA_WITH_AES_256_CBC_SHA, TLS_DHE_RSA_WITH_AES_256_CBC_SHA, TLS_DHE_DSS_WITH_AES_256_CBC_SHA, TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, TLS_RSA_WITH_AES_128_CBC_SHA, TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_DSS_WITH_AES_128_CBC_SHA, TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_RSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA, TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, TLS_ECDHE_RSA_WITH_RC4_128_SHA, SSL_RSA_WITH_RC4_128_SHA, TLS_ECDH_ECDSA_WITH_RC4_128_SHA, TLS_ECDH_RSA_WITH_RC4_128_SHA, SSL_RSA_WITH_RC4_128_MD5, TLS_EMPTY_RENEGOTIATION_INFO_SCSV]
Compression Methods:  { 0 }
Extension elliptic_curves, curve names: {secp256r1, sect163k1, sect163r2, secp192r1, secp224r1, sect233k1, sect233r1, sect283k1, sect283r1, secp384r1, sect409k1, sect409r1, secp521r1, sect571k1, sect571r1, secp160k1, secp160r1, secp160r2, sect163r1, secp192k1, sect193r1, sect193r2, secp224k1, sect239k1, secp256k1}
Extension ec_point_formats, formats: [uncompressed]
Extension server_name, server_name: [host_name: hostname.com]
***
main, WRITE: TLSv1 Handshake, length = 194
main, READ: TLSv1 Alert, length = 2
main, RECV TLSv1 ALERT:  fatal, protocol_version
main, called closeSocket()
main, handling exception: javax.net.ssl.SSLException: Received fatal alert: protocol_version
javax.net.ssl.SSLException: Received fatal alert: protocol_version
    at sun.security.ssl.Alerts.getSSLException(Unknown Source)
    at sun.security.ssl.Alerts.getSSLException(Unknown Source)
    at sun.security.ssl.SSLSocketImpl.recvAlert(Unknown Source)
    at sun.security.ssl.SSLSocketImpl.readRecord(Unknown Source)
    at sun.security.ssl.SSLSocketImpl.performInitialHandshake(Unknown Source)
    at sun.security.ssl.SSLSocketImpl.writeRecord(Unknown Source)
    at sun.security.ssl.AppOutputStream.write(Unknown Source)
    at sun.security.ssl.AppOutputStream.write(Unknown Source)
    at SSLPoke.main(SSLPoke.java:43)

Upvotes: 0

Views: 1217

Answers (1)

dave_thompson_085
dave_thompson_085

Reputation: 38990

You can do this with very simple changes to the code, assuming you have a JDK or equivalent installed. Because TLS negotiates over a range of versions (until TLS1.3 and Java11, neither applicable here) there are two possibilities:

  • you want to support or allow 1.2 (because the server requires it) but don't care about lower versions

  • you want to require 1.2 only (and fail if the server supports lower)

For case 1 there are two choices:

SSLContext sslctx = SSLContext.getInstance("TLSv1.2"); // could use user input
sslctx.init (null, null, null); // no keymgr, default truststore and RNG
SSLSocket sslsocket = (SSLSocket) sslctx.getSocketFactory() .createSocket(host,port);
// continue as for SSLPoke to do some I/O, or just .startHandshake is enough
// (in spite of its name, startHandshake does all of (completes) the handshake)

or

SSLSocket sslsocket = (SSLSocket) SSLSocketFactory.getDefault() .createSocket(host,port);
sslsocket.setEnabledProtocols (new String[]{"TLSv1","TLSv1.1","TLSv1.2"});
// again could use user input; String.split(String) can be handy to create the array
// ditto

whereas for case 2 you need

SSLSocket sslsocket = (SSLSocket) SSLSocketFactory.getDefault() .createSocket(host,port);
sslsocket.setEnabledProtocols (new String[]{"TLSv1.2"});
// ditto both

Although as Robert comments, getting onto a supported (LTS) version, 8 or 11, is a good idea in general.


Also, for server-side issues like protocol and certificate compatibility on a public HTTPS (web) server only, https://www.ssllabs.com/ssltest is IMO excellent. Outside those limits it doesn't work though.

Upvotes: 1

Related Questions