Our CXF call with JDK 7 against www1.ecall.ch
started failing after the provider disabled SSLv3 and I don't understand why. The issue is resolved by setting -Dhttps.protocols=TLSv1
but I'm surprised this is even necessary.
JDK 7/8 support all of SSLv2Hello(2), SSLv3, TLSv1, TLSv1.1 and TLSv1.2 and I'd expect
Here's the relevant part of the SSL debug log prior to setting -Dhttps.protocols=TLSv1
i.e. using the JVM defaults (I cut off the listing of all certs at the beginning):
trigger seeding of SecureRandom
done seeding SecureRandom
trigger seeding of SecureRandom
done seeding SecureRandom
Ignoring unavailable cipher suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
Ignoring unavailable cipher suite: TLS_DHE_RSA_WITH_AES_256_CBC_SHA
Ignoring unavailable cipher suite: TLS_ECDH_RSA_WITH_AES_256_CBC_SHA
Ignoring unavailable cipher suite: TLS_DHE_DSS_WITH_AES_256_CBC_SHA256
Ignoring unavailable cipher suite: TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
Ignoring unavailable cipher suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
Ignoring unavailable cipher suite: TLS_ECDH_anon_WITH_AES_256_CBC_SHA
Ignoring unavailable cipher suite: TLS_DH_anon_WITH_AES_256_CBC_SHA
Ignoring unavailable cipher suite: TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384
Ignoring unavailable cipher suite: TLS_DH_anon_WITH_AES_256_CBC_SHA256
Ignoring unavailable cipher suite: TLS_RSA_WITH_AES_256_CBC_SHA256
Ignoring unavailable cipher suite: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
Ignoring unavailable cipher suite: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
Ignoring unavailable cipher suite: TLS_DHE_DSS_WITH_AES_256_CBC_SHA
Ignoring unavailable cipher suite: TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384
Ignoring unavailable cipher suite: TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA
Ignoring unavailable cipher suite: TLS_RSA_WITH_AES_256_CBC_SHA
Ignoring unavailable cipher suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
Ignoring unavailable cipher suite: TLS_DHE_RSA_WITH_AES_256_CBC_SHA
Ignoring unavailable cipher suite: TLS_ECDH_RSA_WITH_AES_256_CBC_SHA
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 unavailable cipher suite: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
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 unavailable cipher suite: TLS_DHE_DSS_WITH_AES_256_CBC_SHA
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 unavailable cipher suite: TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA
Ignoring unavailable cipher suite: TLS_RSA_WITH_AES_256_CBC_SHA
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
main, setSoTimeout(180000) called
Ignoring unsupported cipher suite: TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 for SSLv2Hello
Ignoring unsupported cipher suite: TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 for SSLv2Hello
Ignoring unsupported cipher suite: TLS_RSA_WITH_AES_128_CBC_SHA256 for SSLv2Hello
Ignoring unsupported cipher suite: TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 for SSLv2Hello
Ignoring unsupported cipher suite: TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 for SSLv2Hello
Ignoring unsupported cipher suite: TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 for SSLv2Hello
Ignoring unsupported cipher suite: TLS_DHE_DSS_WITH_AES_128_CBC_SHA256 for SSLv2Hello
Ignoring unsupported cipher suite: TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 for SSLv3
Ignoring unsupported cipher suite: TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 for SSLv3
Ignoring unsupported cipher suite: TLS_RSA_WITH_AES_128_CBC_SHA256 for SSLv3
Ignoring unsupported cipher suite: TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 for SSLv3
Ignoring unsupported cipher suite: TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 for SSLv3
Ignoring unsupported cipher suite: TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 for SSLv3
Ignoring unsupported cipher suite: TLS_DHE_DSS_WITH_AES_128_CBC_SHA256 for SSLv3
Ignoring unsupported cipher suite: TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
Ignoring unsupported cipher suite: TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
Ignoring unsupported cipher suite: TLS_RSA_WITH_AES_128_CBC_SHA256
Ignoring unsupported cipher suite: TLS_ECDH_ECDSA_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_128_CBC_SHA256
Ignoring unsupported cipher suite: TLS_DHE_DSS_WITH_AES_128_CBC_SHA256
%% No cached client session
*** ClientHello, SSLv3
RandomCookie: GMT: 1403944475 bytes = { 12, 68, 193, 229, 85, 79, 86, 211, 209, 34, 251, 218, 184, 7, 51, 93, 180, 144, 114, 70, 105, 252, 31, 61, 151, 188, 165, 177 }
Session ID: {}
Cipher Suites: [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_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, 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, SSL_RSA_WITH_RC4_128_MD5, TLS_EMPTY_RENEGOTIATION_INFO_SCSV, SSL_RSA_WITH_DES_CBC_SHA, SSL_DHE_RSA_WITH_DES_CBC_SHA, SSL_DHE_DSS_WITH_DES_CBC_SHA, SSL_RSA_EXPORT_WITH_RC4_40_MD5, SSL_RSA_EXPORT_WITH_DES40_CBC_SHA, SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA, SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA, TLS_KRB5_WITH_RC4_128_SHA, TLS_KRB5_WITH_RC4_128_MD5, TLS_KRB5_WITH_3DES_EDE_CBC_SHA, TLS_KRB5_WITH_3DES_EDE_CBC_MD5, TLS_KRB5_WITH_DES_CBC_SHA, TLS_KRB5_WITH_DES_CBC_MD5, TLS_KRB5_EXPORT_WITH_RC4_40_SHA, TLS_KRB5_EXPORT_WITH_RC4_40_MD5, TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHA, TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5]
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: www1.ecall.ch]
***
[write] MD5 and SHA1 hashes: len = 205
0000: 01 00 00 C9 03 00 54 AE 7E 1B 0C 44 C1 E5 55 4F ......T....D..UO
0010: 56 D3 D1 22 FB DA B8 07 33 5D B4 90 72 46 69 FC V.."....3]..rFi.
0020: 1F 3D 97 BC A5 B1 00 00 4C C0 09 C0 13 00 2F C0 .=......L...../.
0030: 04 C0 0E 00 33 00 32 C0 07 C0 11 00 05 C0 02 C0 ....3.2.........
0040: 0C C0 08 C0 12 00 0A C0 03 C0 0D 00 16 00 13 00 ................
0050: 04 00 FF 00 09 00 15 00 12 00 03 00 08 00 14 00 ................
0060: 11 00 20 00 24 00 1F 00 23 00 1E 00 22 00 28 00 .. .$...#...".(.
0070: 2B 00 26 00 29 01 00 00 54 00 0A 00 34 00 32 00 +.&.)...T...4.2.
0080: 17 00 01 00 03 00 13 00 15 00 06 00 07 00 09 00 ................
0090: 0A 00 18 00 0B 00 0C 00 19 00 0D 00 0E 00 0F 00 ................
00A0: 10 00 11 00 02 00 12 00 04 00 05 00 14 00 08 00 ................
00B0: 16 00 0B 00 02 01 00 00 00 00 12 00 10 00 00 0D ................
00C0: 77 77 77 31 2E 65 63 61 6C 6C 2E 63 68 www1.ecall.ch
main, WRITE: SSLv3 Handshake, length = 205
[write] MD5 and SHA1 hashes: len = 179
0000: 01 03 00 00 8A 00 00 00 20 00 C0 09 06 00 40 00 ........ .....@.
0010: C0 13 00 00 2F 00 C0 04 01 00 80 00 C0 0E 00 00 ..../...........
0020: 33 00 00 32 00 C0 07 05 00 80 00 C0 11 00 00 05 3..2............
0030: 00 C0 02 00 C0 0C 00 C0 08 00 C0 12 00 00 0A 07 ................
0040: 00 C0 00 C0 03 02 00 80 00 C0 0D 00 00 16 00 00 ................
0050: 13 00 00 04 01 00 80 00 00 FF 00 00 09 06 00 40 ...............@
0060: 00 00 15 00 00 12 00 00 03 02 00 80 00 00 08 00 ................
0070: 00 14 00 00 11 00 00 20 00 00 24 00 00 1F 00 00 ....... ..$.....
0080: 23 00 00 1E 00 00 22 00 00 28 00 00 2B 00 00 26 #....."..(..+..&
0090: 00 00 29 54 AE 7E 1B 0C 44 C1 E5 55 4F 56 D3 D1 ..)T....D..UOV..
00A0: 22 FB DA B8 07 33 5D B4 90 72 46 69 FC 1F 3D 97 "....3]..rFi..=.
00B0: BC A5 B1 ...
main, WRITE: SSLv2 client hello message, length = 179
[Raw write]: length = 181
0000: 80 B3 01 03 00 00 8A 00 00 00 20 00 C0 09 06 00 .......... .....
0010: 40 00 C0 13 00 00 2F 00 C0 04 01 00 80 00 C0 0E @...../.........
0020: 00 00 33 00 00 32 00 C0 07 05 00 80 00 C0 11 00 ..3..2..........
0030: 00 05 00 C0 02 00 C0 0C 00 C0 08 00 C0 12 00 00 ................
0040: 0A 07 00 C0 00 C0 03 02 00 80 00 C0 0D 00 00 16 ................
0050: 00 00 13 00 00 04 01 00 80 00 00 FF 00 00 09 06 ................
0060: 00 40 00 00 15 00 00 12 00 00 03 02 00 80 00 00 .@..............
0070: 08 00 00 14 00 00 11 00 00 20 00 00 24 00 00 1F ......... ..$...
0080: 00 00 23 00 00 1E 00 00 22 00 00 28 00 00 2B 00 ..#....."..(..+.
0090: 00 26 00 00 29 54 AE 7E 1B 0C 44 C1 E5 55 4F 56 .&..)T....D..UOV
00A0: D3 D1 22 FB DA B8 07 33 5D B4 90 72 46 69 FC 1F .."....3]..rFi..
00B0: 3D 97 BC A5 B1 =....
main, handling exception: java.net.SocketException: Connection reset
main, SEND TLSv1 ALERT: fatal, description = unexpected_message
main, WRITE: TLSv1 Alert, length = 2
main, Exception sending alert: java.net.SocketException: Broken pipe
main, called closeSocket()
main, called close()
main, called closeInternal(true)
[...upper part of stacktrace...]
Caused by: java.net.SocketException: Connection reset
at java.net.SocketInputStream.read(SocketInputStream.java:196)
at java.net.SocketInputStream.read(SocketInputStream.java:122)
at sun.security.ssl.InputRecord.readFully(InputRecord.java:442)
at sun.security.ssl.InputRecord.read(InputRecord.java:480)
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:927)
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1312)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1339)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1323)
[...remaining part of stacktrace...]
If I got that right the JVM first tries a SSLv3 Handshake
then a SSLv2 client hello message
before resorting to TLSv1.
But why does it fail after it tries TLSv1 yet when I enable TLS as the only supported protocol it works? Does the server (IIS 8.5) attempt some unconventional handshake on which the socket connection trips over?
JVM (more exactly JSSE) does not try top-down. It follows the RFCs (including the appendix for SSLv2 ClientHello) and sends one ClientHello stating the highest version supported, and the server can reply with any version less than or equal to that. If the server considers our highest too low, it rejects the handshake outright. If the server (tentatively) accepts a version we consider too low (or want to skip, but that's silly) we abort the handshake. It was the common browser behavior of "falling back" to a lower protocol that caused POODLE (see many questions about which).
The javax.net.debug
trace appears is misleading in this case. If SSLv2Hello is enabled -- which it is was in Java6 by default but not in Java7, did you change it somewhere? -- JSSE apparently displays and says "WRITE" for both the SSLv3+ (new format) hello and the SSLv2 (mapped old format) hello, but it actually sends only the latter, (@Steffen) confirmed by openssl s_server
.
It is thus apparent that without the https.protocol
change your client is sending SSLv2 format hello and the server is rejecting it. This isn't strictly necessary: it is technically possible to use SSLv2 format to negotiate TLSv1.0 and even higher, OpenSSL for example can do so, but it's not a good idea; SSLv2 protocol has been spurned as known insecure since about 2001, and was belatedly officially prohibited by RFC 6176 in 2011, and SSLv2 format hello can't support extensions including those semi-required for ECC, sigalgs in 1.2, and (as @Steffen notes) SNI which many webservers today need or want. It is quite possible that the configuration of the server to prohibit SSLv3 also has the effect of prohibiting SSLv2 format, and that would be my bet, and if so it's for the best.
Also: it appears something in your code (or maybe a library) is enabling all or nearly all supported ciphers. This is a BAD IDEA. Your hello offers the single-DES suites which have been insecure for years, the export suites which were insecure forever, and the Kerberos suites which are totally useless on the Internet including the Kerberos export suites which are useless and totally insecure. A decent server will not agree to these, but if you happen to connect to a misconfigured or perverse server you will get an apparently successful connection and not notice it is insecure unless you monitor very closely.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With