Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SSL Connection Reset

Tags:

I am attempting to connect to an HTTPS endpoint in Java. Every method I have tried (more details below) ends up generating this stack trace:

java.net.SocketException: Connection reset at java.net.SocketInputStream.read(SocketInputStream.java:168) at com.sun.net.ssl.internal.ssl.InputRecord.readFully(InputRecord.java:293) at com.sun.net.ssl.internal.ssl.InputRecord.read(InputRecord.java:331) at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:798) at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1138) at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readDataRecord(SSLSocketImpl.java:753) at com.sun.net.ssl.internal.ssl.AppInputStream.read(AppInputStream.java:75) 

I have tried:

  • Connecting with the javax SOAP libs and a new URL("https://...")
  • Connecting with new URL("https://...").openConnection()
  • Creating an SSL connection by hand:

            Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());     SSLSocketFactory factory = (SSLSocketFactory) SSLSocketFactory.getDefault();      SSLSocket socket = (SSLSocket) factory.createSocket("...", 443);      Writer out = new OutputStreamWriter(socket.getOutputStream());     // https requires the full URL in the GET line     //     out.write("GET / HTTP/1.0\r\n");     out.write("\r\n");     out.flush();      // read response     BufferedReader in = new BufferedReader(                 new InputStreamReader(socket.getInputStream()));     int c;     while ((c = in.read()) != -1) {         System.out.write(c);     }      out.close();     in.close();     socket.close(); 

A few more details:

  • Every method I have tried has worked against other SSL servers, it's this particular server (I am not at liberty to discuss what server, it's a business partner)
  • I can connect to this server both with a web browser, and with a faked up SOAP request with curl; This is something Java-specific.

So, it seems pretty clear that there is some disagreement between Java and the HTTPS server over how the handshake should go down, which probably means the server has some strange SSL configuration. However, I don't have direct access to the server, and the people who do are halfway around the world, so communication is a little strained due to very different timezones.

If my assumptions there are correct, what possible SSL problems could there be? What might cause something like this? Where can I ask the people in control of the server to look for issues? When I do the request with curl, I get back these server configuration headers:

Server: Apache/2.2.9 (Debian) mod_jk/1.2.26 PHP/5.2.6-1+lenny10 with Suhosin-Patch mod_ssl/2.2.9 OpenSSL/0.9.8g mod_perl/2.0.4 Perl/v5.10.0 X-Powered-By: PHP/5.2.6-1+lenny10 X-SOAP-Server: NuSOAP/0.7.3 (1.114) 
like image 432
roguenet Avatar asked Apr 01 '11 00:04

roguenet


People also ask

What is SSL exception connection reset?

SocketException: Connection reset. This SocketException occurs on the server side when the client closed the socket connection before the response could be returned over the socket. For example, by quitting the browser before the reponse was retrieved. Connection reset simply means that a TCP RST was received.

What caused connection reset?

Summary. If you run into the “ERR_CONNECTION_RESET” error, it means that your browser can't establish a connection to the remote server. In most cases, it's due to a misconfiguration in your internet settings or something else that's blocking the connection.

How do you handle a connection reset?

Handle the connection reset by peer error Since TCP connections can be broken, there is no need to handle the connection reset by peer in any special way on the client side. You can log the error, ignore it or retry the connection when it occurs.


1 Answers

It is an SSL version problem. The server only supports SSLv3, and Java will start at v2, and attempt to negotiate upwards, but not all servers support that type of negotiation.

Forcing java to use SSLv3 only is the only solution I'm aware of.

Edit, there are two ways to do this that I'm aware of:

  • If you are creating the socket by hand, you can set the enabled protocols

    socket.setEnabledProtocols(new String[] { "SSLv3" }); 
  • If you are using a higher level library, you probably need to set all SSL requests to use v3 only, which is accomplished with the "https.protocols" system property:

    java -Dhttps.protocols=SSLv3 
like image 181
roguenet Avatar answered Sep 20 '22 13:09

roguenet