Thanks for the additional info.  I took a quick look and updated:

    https://bugs.openjdk.java.net/browse/JDK-8149169

with more details.  At a high level:

JDK9
====
I believe there is a bug introduced in the JDK 9 DTLS IO rewrite. This has been assigned an engineer at P2, and needs to be fixed for 9.

JDK8
====
I believe the server is not properly handling the highest supported version during the renegotiation. The workaround is to force TLSv1 only using:

1.  the system property (only if this is the only TLS connection in
    this JDK),

2.  requesting a TLSv1 SSLContext:

    SSLContext sslctx = SSLContext.getInstance("TLSv1");

3.  or specifically requesting that on TLSv1 be turned on a socket:

    sslSocket.setEnabledProtocols(new String[] {"TLSv1"});

Thanks,

Brad




On 2/9/2016 8:18 AM, Langer, Christoph wrote:
Hi Brad,

I've just uploaded my recreate which I ran and I gathered 
-Djavax.net.debug=ssl,handshake traces for both, OpenJDK9 and OpenJDK8, once 
with -Djdk.tls.client.protocols=TLSv1 and once without.

So, for OpenJDK8 with -Djdk.tls.client.protocols=TLSv1, I get the Response Code 
403.
If I don't restrict "jdk.tls.client.protocols", I'll see this 
java.net.SocketException: Unrecognized Windows Sockets error: 0: recv failed
For JDK9 I get javax.net.ssl.SSLException: java.nio.BufferOverflowException in 
either case.

So, as you've mentioned in the bug - maybe the second handshake for client 
authentication (without creds) could be the cause which leads to shut down. 
However, when my customer is using credentials in his test (which he can't 
disclose obviously), we observer the same behavior. So, the question for me is 
to understand why with JDK8 and -Djdk.tls.client.protocols=TLSv1 there is a 
well behaving HTTPS communication going on (as it is with older JDKs, e.g. Java 
7, Java 6 as well) but JDK8 and higher have issues. What is going different 
there?

I guess you can play around with that and look for the data that you are 
interested in.

And no discussion - the server is using outdated and insecure standards. But we 
don't have an influence on that.

Thanks
Christoph

-----Original Message-----
From: security-dev [mailto:security-dev-boun...@openjdk.java.net] On Behalf Of 
Bradford Wetmore
Sent: Montag, 8. Februar 2016 20:13
To: Xuelei Fan <xuelei....@oracle.com>; security-dev@openjdk.java.net
Subject: Re: Issue when connecting to TLSv1 server

I looked at this last week and added a few more bits of info today.

Without the debug logs, it's hard to see what's going on.

Brad


On 2/5/2016 5:05 PM, Xuelei Fan wrote:
Thanks for the report.  I filed a bug for further evaluation:

     https://bugs.openjdk.java.net/browse/JDK-8149169

Regards,
Xuelei

On 2/6/2016 7:18 AM, Langer, Christoph wrote:
Hi,



while supporting an app development team, I'm facing a tough TLS issue -
maybe you experts have an idea.



They try to open an HTTPS connection to the server URL
https://nfe-homologacao.sefazrs.rs.gov.br:443/ws/NfeAutorizacao/NFeAutorizacao.asmx.
This is a Web Service of some Brazilian financial authority. So, what
I'm basically doing is this:



--code snippet--

URL url = new
URL("https://nfe-homologacao.sefazrs.rs.gov.br:443/ws/NfeAutorizacao/NFeAutorizacao.asmx";);

HttpsURLConnection con = (HttpsURLConnection)url.openConnection();

con.setHostnameVerifier(new DefaultHostnameVerifier());



// optional default is GET

con.setRequestMethod("GET");



System.out.println("Sending 'GET' request to URL: " + url);

int responseCode = con.getResponseCode();

System.out.println("Response Code: " + responseCode);

--end code snippet-



I expect it to return "403 - not authorized".



The coding will work with JDK7. However, with JDK8, I get this type of
exception:



java.net.SocketException: Unrecognized Windows Sockets error: 0: recv failed

          at java.net.SocketInputStream.socketRead0(Native Method)

          at java.net.SocketInputStream.socketRead(SocketInputStream.java:116)

          at java.net.SocketInputStream.read(SocketInputStream.java:170)

          at java.net.SocketInputStream.read(SocketInputStream.java:141)

          at sun.security.ssl.InputRecord.readFully(InputRecord.java:465)

          at sun.security.ssl.InputRecord.read(InputRecord.java:503)

          at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:973)

          at
sun.security.ssl.SSLSocketImpl.readDataRecord(SSLSocketImpl.java:930)

          at sun.security.ssl.AppInputStream.read(AppInputStream.java:105)

          at java.io.BufferedInputStream.fill(BufferedInputStream.java:246)

          at java.io.BufferedInputStream.read1(BufferedInputStream.java:286)

          at java.io.BufferedInputStream.read(BufferedInputStream.java:345)

          at sun.net.www.http.HttpClient.parseHTTPHeader(HttpClient.java:704)

          at sun.net.www.http.HttpClient.parseHTTP(HttpClient.java:647)

          at sun.net.www.http.HttpClient.parseHTTP(HttpClient.java:675)

          at
sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1536)

          at
sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1441)

          at
java.net.HttpURLConnection.getResponseCode(HttpURLConnection.java:480)

          at
sun.net.www.protocol.https.HttpsURLConnectionImpl.getResponseCode(HttpsURLConnectionImpl.java:338)

          ...



I can get it to work in JDK8 by forcing it to TLSv1 only, e.g. by
setting property -Djdk.tls.client.protocols=TLSv1.



For JDK9 I even get a different exception:

javax.net.ssl.SSLException: java.nio.BufferOverflowException

          at sun.security.ssl.Alerts.getSSLException(Alerts.java:214)

          at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1948)

          at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1900)

          at
sun.security.ssl.SSLSocketImpl.handleException(SSLSocketImpl.java:1883)

          at
sun.security.ssl.SSLSocketImpl.handleException(SSLSocketImpl.java:1809)

          at sun.security.ssl.AppInputStream.read(AppInputStream.java:173)

          at java.io.BufferedInputStream.fill(BufferedInputStream.java:246)

          at java.io.BufferedInputStream.read1(BufferedInputStream.java:286)

          at java.io.BufferedInputStream.read(BufferedInputStream.java:345)

          at sun.net.www.http.HttpClient.parseHTTPHeader(HttpClient.java:704)

          at sun.net.www.http.HttpClient.parseHTTP(HttpClient.java:647)

          at sun.net.www.http.HttpClient.parseHTTP(HttpClient.java:675)

          at
sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1534)

          at
sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1439)

          at
java.net.HttpURLConnection.getResponseCode(HttpURLConnection.java:480)

          at
sun.net.www.protocol.https.HttpsURLConnectionImpl.getResponseCode(HttpsURLConnectionImpl.java:319)

          at
com.sap.cl.HttpsURLConnectionTest.sendGETRequest(HttpsURLConnectionTest.java:42)

          at
com.sap.cl.HttpsURLConnectionTest.main(HttpsURLConnectionTest.java:63)

Caused by: java.nio.BufferOverflowException

          at java.nio.HeapByteBuffer.put(HeapByteBuffer.java:206)

          at
sun.security.ssl.SSLSocketInputRecord.decodeInputRecord(SSLSocketInputRecord.java:226)

          at
sun.security.ssl.SSLSocketInputRecord.decode(SSLSocketInputRecord.java:178)

          at
sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1012)

          at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:957)

          at sun.security.ssl.AppInputStream.read(AppInputStream.java:159)

          ... 12 more



I've debugged a lot today and tried to get something out of the
javax.net.debug output but I didn't get any further with this - probably
due to my lack of understanding the details of TLS communication and its
implementation. I know the server is using some legacy protocol but
still I think it should work.



Maybe someone has any helpful idea? Is it a bug? You can simply try to
run my test code snippet and should see the issue immediately...



Thanks

Christoph




Reply via email to