Reputation: 107
I am using JAVA 8. I am trying to connect a Socket Server using client certificates and certificate tree.
I have followings provided by client:
I have created keystore.jks using following steps:
Combining client cert and CA tree in a single pem file using cat
Crested PKCS12 file from combined file encrypted using private key(OpenSSL Command)
Generated JKS keystore file using keytool
I have created trustore.jks using following steps:
My Sample code is as following :
package com.tutorial.exception.customize;
import javax.net.ssl.SSLHandshakeException;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
import java.io.*;
import java.security.cert.CertPathValidatorException;
import java.security.cert.CertificateException;
import java.util.Scanner;
/**
* Created by SomnathG on 12/1/2016.
*/
public class Client {
public Client() {
System.setProperty("javax.net.ssl.keyStore", {keystore Location});
System.setProperty("javax.net.ssl.keyStorePassword", {password});
System.setProperty("javax.net.ssl.trustStore", {trustore location});
System.setProperty("javax.net.ssl.trustStorePassword", {password});
System.setProperty("javax.net.debug", "all");
System.setProperty( "sun.security.ssl.allowUnsafeRenegotiation", "true" );
}
public void connectHost(){
SSLSocketFactory sslSocketFactory = (SSLSocketFactory) SSLSocketFactory.getDefault();
SSLSocket sslSocket = null;
try {
sslSocket = (SSLSocket) sslSocketFactory.createSocket(host, port);
sslSocket.setEnabledProtocols(new String[] {"TLSv1.2"});
sslSocket.startHandshake();
InputStream inputStream = sslSocket.getInputStream();
OutputStream outputStream = sslSocket.getOutputStream();
System.out.println("Sending request to Socket Server");
outputStream.write("Hello".getBytes());
outputStream.write("exit".getBytes());
byte[] messageByte = new byte[1000];
boolean end = false;
String dataString = "";
int bytesRead = 0;
String messageString = "";
DataInputStream in = new DataInputStream(sslSocket.getInputStream());
while(!end)
{
bytesRead = in.read(messageByte);
messageString += new String(messageByte, 0, bytesRead);
if (messageString.length() == 100)
{
end = true;
}
}
System.out.println("MESSAGE: " + messageString);
// byte[] read = (byte[]) ois.readObject();
//String s2 = new String(read);
//System.out.println("" + s2);
//System.out.println("Message: " + message);
//close resources
//System.out.println(receive(inputStream));
}catch (IOException e) {
e.printStackTrace();
System.out.println("=====");
System.out.println(e.getMessage());
System.out.println("=====");
CertPathValidatorException ce = new CertPathValidatorException(e);
System.out.println("******");
System.out.println(ce.getIndex());
System.out.println(ce.getReason());
System.out.println("******");
//e.printStackTrace();
}
}
public static void main(String[] args){
new Client().connectHost();
}
}
I am getting following exception after executing the code:
javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path validation failed: java.security.cert.CertPathValidatorException: basic constraints check failed: this is not a CA certificate
at sun.security.ssl.Alerts.getSSLException(Alerts.java:192)
at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1949)
at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:302)
at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:296)
at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1509)
at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:216)
at sun.security.ssl.Handshaker.processLoop(Handshaker.java:979)
at sun.security.ssl.Handshaker.process_record(Handshaker.java:914)
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 com.tutorial.exception.customize.Client.connectHost(Client.java:33)
at com.tutorial.exception.customize.Client.main(Client.java:82)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)
After analyzing the log I have found "clientHello" and "serverHello" messages but after that application is throwing above mentioned exception.
What am I doing wrong? Please advice.
Thanks, Somnath Guha
Upvotes: 0
Views: 3694
Reputation: 107
I have figured out the issue after analyzing the debug lo.
"BasicConstraints" was missing from the server V3 certificates and thus java was failing to recognize the certificate as a valid certificate. Once that constraint has been added then the client was able to handshake with the server and able to communicate with server.
BasicConstraints:[ CA:true PathLen:2147483647 ]
Upvotes: 1