Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does the Java SSL socket connection fail hard if server does not support SSLv3

Tags:

java

ssl

sockets

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

  1. the JVM to try top-down during handshake i.e. starting with TLSv1.2 first and
  2. to be able to establish a connection even if the server does not support SSLv3

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?

like image 939
Marcel Stör Avatar asked Jan 10 '15 14:01

Marcel Stör


1 Answers

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.

like image 140
dave_thompson_085 Avatar answered Nov 02 '22 17:11

dave_thompson_085