-1

I refer to the second answer to this question:

Web Service Client (JAX-WS) in Weblogic(10.3) with 2 way SSL cannot complete the handshake

I have a client program that connects to another server A with one-way SSL. To turn off certificate chain validation, I used the solution in the second answer to the above question to install an all-trusting trust manager. It works fine.

However, when the client program connects to another server B with two-way SSL, the following exception is thrown.

java.net.SocketException: Software caused connection abort: recv failed
        at java.net.SocketInputStream.socketRead0(Native Method)
        at java.net.SocketInputStream.socketRead(SocketInputStream.java:116)
        at java.net.SocketInputStream.read(SocketInputStream.java:171)
        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.waitForClose(SSLSocketImpl.java:1769)
        at sun.security.ssl.HandshakeOutStream.flush(HandshakeOutStream.java:124
)
        at sun.security.ssl.Handshaker.sendChangeCipherSpec(Handshaker.java:1130
)
        at sun.security.ssl.ClientHandshaker.sendChangeCipherAndFinish(ClientHan
dshaker.java:1216)
        at sun.security.ssl.ClientHandshaker.serverHelloDone(ClientHandshaker.ja
va:1128)
        at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.jav
a:348)
        at sun.security.ssl.Handshaker.processLoop(Handshaker.java:1026)
        at sun.security.ssl.Handshaker.process_record(Handshaker.java:961)
        at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1062)
        at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.
java:1375)
        at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1403
)
        at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1387
)
        at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:
559)
        at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect
(AbstractDelegateHttpsURLConnection.java:185)
        at sun.net.www.protocol.http.HttpURLConnection.getOutputStream0(HttpURLC
onnection.java:1316)
        at sun.net.www.protocol.http.HttpURLConnection.getOutputStream(HttpURLCo
nnection.java:1291)
        at sun.net.www.protocol.https.HttpsURLConnectionImpl.getOutputStream(Htt
psURLConnectionImpl.java:250)

If I don't install the all-trusting trust manager, I can still make the connection to both servers work (whether one-way or two-way SSL), provided that I specify the identity store and trust store:

System.setProperty("javax.net.ssl.keyStore", "path/to/your/key");
System.setProperty("javax.net.ssl.keyStorePassword", "your-keystore-password");
System.setProperty("javax.net.ssl.keyStoreType", "JKS");
System.setProperty("javax.net.ssl.trustStore", "path/to/your/trust/keystore");
System.setProperty("javax.net.ssl.trustStorePassword", "your-truststore-password");

However, I still want to turn off certificate chain validation in two-way SSL. Installing the all-trusting trust manager does not seem to work. Why?

Thanks in advance.

Community
  • 1
  • 1
user3573403
  • 1,780
  • 5
  • 38
  • 64
  • If you don't want it secure why are you using two-way authentication? Why are you using SSL at all? – user207421 Mar 30 '17 at 10:15
  • The server is actually an internal one in the company. It serves many other clients. As a client, I don't really care whether the identity of the server is in my trust store. Security is not so much of a concern since it is an internal server. – user3573403 Mar 30 '17 at 10:37
  • That doesn't answe either of my questions. – user207421 Apr 04 '17 at 04:06
  • Firstly, did I say I didn't want it secure? I'm using SSL, so of course it is secure. All I wanted was to disable the verification of the server. It is an internal server, which we can trust. – user3573403 Apr 05 '17 at 03:37

2 Answers2

0

However, I still want to turn off certificate chain validation in two-way SSL. Installing the all-trusting trust manager does not seem to work. Why?

The server requires you to provide an identifying client certificate. If your client doesn't provide a certificate that the server is configured to accept, it drops your connection attempt.

You can't change this in the client - at all.

The SSL protocol is designed such that if a client or server requires the other side to identify itself with a certificate, that can't be modified by the side required to provide the certificate.

Andrew Henle
  • 32,625
  • 3
  • 24
  • 56
  • You don't get what I am asking. I don't want the client program to validate the server's certificate. I am not trying to prevent the server from validating the client's certificate. – user3573403 Mar 30 '17 at 14:26
0

I know where the problem is now. In the solution provided in the link, there are these lines to install the all-trusting trust manager:

// Install the all-trusting trust manager
try {
    SSLContext sc = SSLContext.getInstance("SSL");
    sc.init(null, trustAllCerts, new java.security.SecureRandom());
    HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
} catch (Exception e) {
}

The problem lies with the sc.init call. The first parameter is a list of key managers. At least one key manager is needed to return the identity of the client, so that it can be sent to the server for client authentication. In the codes above, the key managers are set to null, which means that there is no identity of the client that can be sent to server for client authentication. That's why it will fail at client authentication, but will pass the server authentication (since the all-trusting trust manager is installed).

This is how we can initialize the identity key store and set it to the SSL context:

KeyStore keyStore = KeyStore.getInstance("JKS");
FileInputStream fileInputStream = new FileInputStream("identity key store full path name");
keyStore.load(fileInputStream, "identity key store password".toCharArray());
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
keyManagerFactory.init(keyStore, "identity key store password".toCharArray());
KeyManager[] keyManagers = keyManagerFactory.getKeyManagers();
sc.init(keyManagers, trustAllCerts, new java.security.SecureRandom());
user3573403
  • 1,780
  • 5
  • 38
  • 64