Issue when connecting to TLSv1 server

Bradford Wetmore bradford.wetmore at oracle.com
Tue Feb 9 20:37:06 UTC 2016


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-bounces at openjdk.java.net] On Behalf Of Bradford Wetmore
> Sent: Montag, 8. Februar 2016 20:13
> To: Xuelei Fan <xuelei.fan at oracle.com>; security-dev at 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
>>>
>>>
>>>
>>



More information about the security-dev mailing list