Question

I am trying to do client server based ssl,

here is my server code:

 public static void main(String arg[]){

 try {
 KeyStore keyStore = KeyStore.getInstance("jks");

 InputStream inputStream;
 try {
 inputStream = new FileInputStream(ITestEncryptionConstants.SSLKEYSTORE);
 keyStore.load(inputStream,
 ITestEncryptionConstants.SSLPASSWORD.toCharArray());
 TrustManagerFactory trustManagerFactory =
 TrustManagerFactory.getInstance("PKIX", "SunJSSE");
 trustManagerFactory.init(keyStore);

 X509TrustManager x509TrustManager = null;
 for (TrustManager trustManager : trustManagerFactory.getTrustManagers())
 {
 if (trustManager instanceof X509TrustManager) {
 x509TrustManager = (X509TrustManager) trustManager;
 break;
 }
 }

 KeyManagerFactory keyManagerFactory =
 KeyManagerFactory.getInstance("SunX509", "SunJSSE");
 keyManagerFactory.init(keyStore,
 ITestEncryptionConstants.SSLPASSWORD.toCharArray());

 X509KeyManager x509KeyManager = null;
 for (KeyManager keyManager : keyManagerFactory.getKeyManagers()) {
 if (keyManager instanceof X509KeyManager) {
 x509KeyManager = (X509KeyManager) keyManager;
 break;
 }
 }

 SSLContext sslContext = SSLContext.getInstance("TLS");

 sslContext.init(new KeyManager[]{x509KeyManager},
 new TrustManager[]{x509TrustManager}, null);

 SSLServerSocketFactory factory =
 sslContext.getServerSocketFactory();//(SSLServerSocketFactory )
 SSLServerSocketFactory .getDefault();

 SSLServerSocket sslSock =
 (SSLServerSocket)factory.createServerSocket(8096);
 SSLSocket c = (SSLSocket)sslSock.accept();
 PrintWriter out =new PrintWriter(c.getOutputStream(),true);
 InputStream in = c.getInputStream();
in.close();
 out.close();


 } catch (FileNotFoundException e) {
 // TODO Auto-generated catch block
 e.printStackTrace();
 } catch (NoSuchAlgorithmException e) {
 // TODO Auto-generated catch block
 e.printStackTrace();
 } catch (CertificateException e) {
 // TODO Auto-generated catch block
 e.printStackTrace();
 } catch (IOException e) {
 // TODO Auto-generated catch block
 e.printStackTrace();
 } catch (NoSuchProviderException e) {
 // TODO Auto-generated catch block
 e.printStackTrace();
 } catch (UnrecoverableKeyException e) {
 // TODO Auto-generated catch block
 e.printStackTrace();
 } catch (KeyManagementException e) {
 // TODO Auto-generated catch block
 e.printStackTrace();
 }

 } catch (KeyStoreException e1) {
 // TODO Auto-generated catch block
 e1.printStackTrace();
 }



 }

And this is my client code:

 public static void main(String[] args) {

 try{
 // // register a https protocol handler - this may be required for previous JDK versions
 //
 System.setProperty("java.protocol.handler.pkgs","com.sun.net.ssl.internal.www.protocol");



 System.out.println("Ok passed.");
 //connect to google
 SSLSocketFactory factory = (SSLSocketFactory)
 SSLSocketFactory.getDefault();
 SSLSocket sslSock = (SSLSocket) factory.createSocket("localhost",8096);

 //send HTTP get request
 PrintWriter out = new PrintWriter(sslSock.getOutputStream(), true);
 BufferedReader in = new BufferedReader(new
 InputStreamReader(sslSock.getInputStream()));

 out.println("--------------------------> It works!!!");
 System.out.println("Written to server.");

 // read response
 StringBuffer buf = new StringBuffer();
 String line = "";
 while ((line = in.readLine()) != null) {
 System.out.println("Received : " + line);
 buf.append(line);
 }
 System.out.println("Read from server: " + buf.toString());

 in.close();
 out.close();
 // Close connection.
 sslSock.close();

 }catch(Exception ex){
 ex.printStackTrace();
 }
 }

But I am getting the following error in client side:

javax.net.ssl.SSLException: Connection has been shutdown: javax.net.ssl.SSLException: java.net.SocketException: Connection reset

Can someone help what's going wrong in my code?

javax.net.ssl.SSLException: Connection has been shutdown: javax.net.ssl.SSLException: java.net.SocketException: Connection reset
    at sun.security.ssl.SSLSocketImpl.checkEOF(Unknown Source)
    at sun.security.ssl.AppInputStream.read(Unknown Source)
    at sun.nio.cs.StreamDecoder.readBytes(Unknown Source)
    at sun.nio.cs.StreamDecoder.implRead(Unknown Source)
    at sun.nio.cs.StreamDecoder.read(Unknown Source)
    at java.io.InputStreamReader.read(Unknown Source)
    at java.io.BufferedReader.fill(Unknown Source)
    at java.io.BufferedReader.readLine(Unknown Source)
    at java.io.BufferedReader.readLine(Unknown Source)
    at ripl.jing.security.encryptor.tlsservice.TestJingClient.main(TestJingClient.java:85)
Caused by: javax.net.ssl.SSLException: java.net.SocketException: Connection reset
Was it helpful?

Solution

(Sorry, I was just going to comment on EJP's now-deleted answer.)

The server code says:

SSLSocket c = (SSLSocket)sslSock.accept();
PrintWriter out =new PrintWriter(c.getOutputStream(),true);
InputStream in = c.getInputStream();
in.close();
out.close();

That is, the I/O streams (and thus the socket) are closed immediately after the socket is accepted. Hence, an error message appearing on the client saying that the connection has been closed by the remote party shouldn't really come as a surprise.

This more or less the same problem as in this question: just getting the I/O streams, without trying to read/write from them, and without trying any other action that triggers the handshake implicitly (reading from the streams or trying to get the SSLSession) or explicitly (calling startHandshake) means that the handshake won't have started on the server. Therefore, the client throws this exception because the connection is interrupted in the middle of the handshake it has started.

OTHER TIPS

I don't know what certificate you're talking about, or what change, but the only issue here is that you're sending a line from the client that is never read, and you're reading a line in the client that is never sent. Sending data that is never read when the peer has already closed the connection causes a connection reset.

NB You haven't need to set java.protocol.handler.pkgs since Java 1.4 which is over ten years ago. You could accomplish all that setup in the server code via

System.setProperty("javax.net.ssl.keyStore", ITestEncryptionConstants.SSLKEYSTORE);
System.setProperty("javax.net.ssl.keyStorePassword", ITestEncryptionConstants.SSLPASSWORD);
SSLContext sslContext = SSLContext.getDefault();
SSLServerSocketFactory factory =
    sslContext.getServerSocketFactory();//(SSLServerSocketFactory )

The line:

SSLServerSocketFactory .getDefault();

does nothing.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top