Somnath Guha
Somnath Guha

Reputation: 107

SSL Socket Connection Error

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:

  1. Client CERT (PEM)
  2. Private Key (PEM)
  3. CA Tree (PEM) - with 4 Certificates

I have created keystore.jks using following steps:

  1. Combining client cert and CA tree in a single pem file using cat

  2. Crested PKCS12 file from combined file encrypted using private key(OpenSSL Command)

  3. Generated JKS keystore file using keytool

I have created trustore.jks using following steps:

  1. Split CA Tree (4 certificates) into 4 different files
  2. Generated trustore file using keytool by importing each file one by one

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

Answers (1)

Somnath Guha
Somnath Guha

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

Related Questions