Updated my resume

It’s been a while since I had updated my resume. I feel it is a good time make sure everything is up to date.

If you know of an interesting opportunity, or project, please be sure to let me know.

IvanAlonso.Resume

javax.net.ssl.SSLHandshakeException in JMeter against some URLs

Problem

Recently I had to investigate an issue where certain JMeter tests pointing to an HTTPS end-point were resulting in this error:

javax.net.ssl.SSLHandshakeException

Initially I thought it would be an easily fix by simply using the HTTP3.x sampler, rather than the default HTTP4.x.

Solution

The solution was to upgrade JMeter to version 3.2 (we were running 2.13 for good reasons).

How it was troubleshooted

Bad Certificates

If you do a search on that error you will be led to believe it’s an issue with the validity of the certificate being issued. To address this, it is suggested to:

  1. Upgrade Java to the latest
  2. Replace the UnlimitedJCEPolicyJDK8 JARs under <java>/jre/lib/security/
  3. Download the certificates from the server and added to the trusted cacerts

It’s the SNI

Given it was not the bad certificates, I enabled SSL debugging and got the following:

Allow unsafe renegotiation: false
Allow legacy hello messages: true
Is initial handshake: true
Is secure renegotiation: false
Ignoring unsupported cipher suite: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 for TLSv1
Ignoring unsupported cipher suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 for TLSv1
Ignoring unsupported cipher suite: TLS_RSA_WITH_AES_256_CBC_SHA256 for TLSv1
Ignoring unsupported cipher suite: TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 for TLSv1
Ignoring unsupported cipher suite: TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 for TLSv1
Ignoring unsupported cipher suite: TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 for TLSv1
Ignoring unsupported cipher suite: TLS_DHE_DSS_WITH_AES_256_CBC_SHA256 for TLSv1
Ignoring unsupported cipher suite: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 for TLSv1.1
Ignoring unsupported cipher suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 for TLSv1.1
Ignoring unsupported cipher suite: TLS_RSA_WITH_AES_256_CBC_SHA256 for TLSv1.1
Ignoring unsupported cipher suite: TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 for TLSv1.1
Ignoring unsupported cipher suite: TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 for TLSv1.1
Ignoring unsupported cipher suite: TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 for TLSv1.1
Ignoring unsupported cipher suite: TLS_DHE_DSS_WITH_AES_256_CBC_SHA256 for TLSv1.1
%% No cached client session
*** ClientHello, TLSv1.2
RandomCookie:  GMT: 1495568515 bytes = { 82, 170, 89, 172, 24, 224, 26, 122, 144, 41, 158, 48, 243, 159, 93, 186, 63, 66, 119, 137, 96, 246, 218, 179, 67, 45, 163, 50 }
Session ID:  {}
Cipher Suites: [TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, TLS_RSA_WITH_AES_256_CBC_SHA256, TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384, TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384, TLS_DHE_RSA_WITH_AES_256_CBC_SHA256, TLS_DHE_DSS_WITH_AES_256_CBC_SHA256, 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_SHA256, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, TLS_RSA_WITH_AES_128_CBC_SHA256, TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256, TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256, TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, TLS_DHE_DSS_WITH_AES_128_CBC_SHA256, 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_AES_256_GCM_SHA384, TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, TLS_RSA_WITH_AES_256_GCM_SHA384, TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384, TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384, TLS_DHE_RSA_WITH_AES_256_GCM_SHA384, TLS_DHE_DSS_WITH_AES_256_GCM_SHA384, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, TLS_RSA_WITH_AES_128_GCM_SHA256, TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256, TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256, TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, TLS_DHE_DSS_WITH_AES_128_GCM_SHA256, 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_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 signature_algorithms, signature_algorithms: SHA512withECDSA, SHA512withRSA, SHA384withECDSA, SHA384withRSA, SHA256withECDSA, SHA256withRSA, SHA256withDSA, SHA224withECDSA, SHA224withRSA, SHA224withDSA, SHA1withECDSA, SHA1withRSA, SHA1withDSA
***
[write] MD5 and SHA1 hashes:  len = 239
0000: 01 00 00 EB 03 03 59 25   91 83 52 AA 59 AC 18 E0  ......Y%..R.Y...
0010: 1A 7A 90 29 9E 30 F3 9F   5D BA 3F 42 77 89 60 F6  .z.).0..].?Bw.`.
0020: DA B3 43 2D A3 32 00 00   64 C0 24 C0 28 00 3D C0  ..C-.2..d.$.(.=.
0030: 26 C0 2A 00 6B 00 6A C0   0A C0 14 00 35 C0 05 C0  &.*.k.j.....5...
0040: 0F 00 39 00 38 C0 23 C0   27 00 3C C0 25 C0 29 00  ..9.8.#.'.<.%.).
0050: 67 00 40 C0 09 C0 13 00   2F C0 04 C0 0E 00 33 00  g.@...../.....3.
0060: 32 C0 2C C0 2B C0 30 00   9D C0 2E C0 32 00 9F 00  2.,.+.0.....2...
0070: A3 C0 2F 00 9C C0 2D C0   31 00 9E 00 A2 C0 08 C0  ../...-.1.......
0080: 12 00 0A C0 03 C0 0D 00   16 00 13 00 FF 01 00 00  ................
0090: 5E 00 0A 00 34 00 32 00   17 00 01 00 03 00 13 00  ^...4.2.........
00A0: 15 00 06 00 07 00 09 00   0A 00 18 00 0B 00 0C 00  ................
00B0: 19 00 0D 00 0E 00 0F 00   10 00 11 00 02 00 12 00  ................
00C0: 04 00 05 00 14 00 08 00   16 00 0B 00 02 01 00 00  ................
00D0: 0D 00 1C 00 1A 06 03 06   01 05 03 05 01 04 03 04  ................
00E0: 01 04 02 03 03 03 01 03   02 02 03 02 01 02 02     ...............
TestPlan_ThreadGroup 1-1, RECV TLSv1.2 ALERT:  fatal, handshake_failure
TestPlan_ThreadGroup 1-1, called closeSocket()
TestPlan_ThreadGroup 1-1, handling exception: javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
TestPlan_ThreadGroup 1-1, called close()
TestPlan_ThreadGroup 1-1, called closeInternal(true)

I confirmed the cipher suites available were compatible with the cipher used in the certificate and by searching for errors around the RECV TLSv1.2 ALERT: fatal, handshake_failure error, the SNI possibility showed itself.

Remember that we could run the same test (same load, specs, etc) against some URLs that we also encrypted using TLSv1.2 so we knew the delta was in how TLS was setup (and we unfortunately didn’t have access to the server logs).

To confirm if SNI was the problem we ran this:

openssl s_client -connect <your host>:443

If you get an error, your host requires SNI. To confirm, SNI is the solution do this:

openssl s_client -connect <your host>:443 -servername '<your host>'

If you get a valid response (which you should), your server requires SNI.

Now that we knew the server required it, we just need to find out how to enable it.

And if you search for “sni jmeter” you get this post. Which basically confirms it was broken on HTTPClient4.x but later fixed. And given we used JMeter 2.13, it meant upgrading to JMeter 3.2 (at the time of this writing it was the latest)

Upgrading to JMeter 3.2 solved the issue. Good luck.