Sunday, April 15, 2012

Sample program to test SSL Connection with certicates

Keywords : ssl sample program, test program to test ssl, How can I check connectivity to ssl using java, test connectivity with ssl, Ssl connectivity testing programs.


I was looking for a sample program in java, using which I can test the connectivity to SSL.

Then I found http://www.herongyang.com/JDK/SSL-Socket-Server-Example-SslReverseEchoer.html

There are two programs

SslReverseEchoer.java (Running on server side)

/**
 * SslReverseEchoer.java
 * Copyright (c) 2005 by Dr. Herong Yang
 * http://www.herongyang.com/JDK/SSL-Socket-Server-Example-SslReverseEchoer.html
 */
import java.io.*;
import java.net.*;
import java.security.*;
import javax.net.ssl.*;
public class SslReverseEchoer {
public static void main(String[] args) {
      // This is the keystore generated on the server.
      String ksName = "C:\\localhostCerts\\localhost.jks";
   // Keystore Password
      char ksPass[] = "welcome".toCharArray();
      // store Password
   char ctPass[] = "welcome".toCharArray();
      try {
         KeyStore ks = KeyStore.getInstance("JKS");
         ks.load(new FileInputStream(ksName), ksPass);
         KeyManagerFactory kmf = 
         KeyManagerFactory.getInstance("SunX509");
         kmf.init(ks, ctPass);
         SSLContext sc = SSLContext.getInstance("TLS");
         sc.init(kmf.getKeyManagers(), null, null);
         SSLServerSocketFactory ssf = sc.getServerSocketFactory();
         // This is the port number that we'll be giving in the client program.
         // Please do note it down.
         SSLServerSocket s 
            = (SSLServerSocket) ssf.createServerSocket(8888);
         printServerSocketInfo(s);
         SSLSocket c = (SSLSocket) s.accept();
         printSocketInfo(c);
         BufferedWriter w = new BufferedWriter(new OutputStreamWriter(
            c.getOutputStream()));
         BufferedReader r = new BufferedReader(new InputStreamReader(
            c.getInputStream()));
         String m = "Welcome to SSL Reverse Echo Server."+
            " Please type in some words.";
         w.write(m,0,m.length());
         w.newLine();
         w.flush();
         while ((m=r.readLine())!= null) {
            if (m.equals(".")) break;
            char[] a = m.toCharArray();
            int n = a.length;
            for (int i=0; i<n/2; i++) {
               char t = a[i];
               a[i] = a[n-1-i];
               a[n-i-1] = t;
            }
            w.write(a,0,n);
            w.newLine();
            w.flush();
         }
         w.close();
         r.close();
         c.close();
         s.close();
      } catch (Exception e) {
         System.err.println(e.toString());
      }
   }
   private static void printSocketInfo(SSLSocket s) {
      System.out.println("Socket class: "+s.getClass());
      System.out.println("   Remote address = "
         +s.getInetAddress().toString());
      System.out.println("   Remote port = "+s.getPort());
      System.out.println("   Local socket address = "
         +s.getLocalSocketAddress().toString());
      System.out.println("   Local address = "
         +s.getLocalAddress().toString());
      System.out.println("   Local port = "+s.getLocalPort());
      System.out.println("   Need client authentication = "
         +s.getNeedClientAuth());
      SSLSession ss = s.getSession();
      System.out.println("   Cipher suite = "+ss.getCipherSuite());
      System.out.println("   Protocol = "+ss.getProtocol());
   }
   private static void printServerSocketInfo(SSLServerSocket s) {
      System.out.println("Server socket class: "+s.getClass());
      System.out.println("   Socker address = "
         +s.getInetAddress().toString());
      System.out.println("   Socker port = "
         +s.getLocalPort());
      System.out.println("   Need client authentication = "
         +s.getNeedClientAuth());
      System.out.println("   Want client authentication = "
         +s.getWantClientAuth());
      System.out.println("   Use client mode = "
         +s.getUseClientMode());
   }
}
Of course, to run this program, you need to have the key store file, C:\localhostCerts\localhost.jks, ready. It contains a self-signed pair of private and public keys.
If you want to create certificates using keytool, you can follow first 2 steps of this

SslSocketClient.java (running on client side)

/**
 * SslSocketClient.java
 * Copyright (c) 2005 by Dr. Herong Yang
 * Before you execute this program, you have to prepare a jks file which will be trusted
 * by the client program. To make the trusted key store file you can use keytool -import command
 * You can read http://www.herongyang.com/JDK/SSL-Socket-Make-Self-Signed-Certificates-Trusted.html for more information.
 * This is also a good URL to study : http://docs.oracle.com/javaee/1.4/tutorial/doc/Security6.html
 */
import java.io.*;
import java.net.*;
import javax.net.ssl.*;
public class SslSocketClient {
   public static void main(String[] args) {
      BufferedReader in = new BufferedReader(
         new InputStreamReader(System.in));
      PrintStream out = System.out;
      SSLSocketFactory f = 
         (SSLSocketFactory) SSLSocketFactory.getDefault();
      try {
   // This is the port number of the server on which server is listening
         SSLSocket c =
           (SSLSocket) f.createSocket("localhost", 8888);
         printSocketInfo(c);
         c.startHandshake();
         BufferedWriter w = new BufferedWriter(
            new OutputStreamWriter(c.getOutputStream()));
         BufferedReader r = new BufferedReader(
            new InputStreamReader(c.getInputStream()));
         String m = null;
         while ((m=r.readLine())!= null) {
            out.println(m);
            m = in.readLine();
            w.write(m,0,m.length());
            w.newLine();
            w.flush();
         }
         w.close();
         r.close();
         c.close();
      } catch (IOException e) {
         System.err.println(e.toString());
      }
   }
   private static void printSocketInfo(SSLSocket s) {
      System.out.println("Socket class: "+s.getClass());
      System.out.println("   Remote address = "
         +s.getInetAddress().toString());
      System.out.println("   Remote port = "+s.getPort());
      System.out.println("   Local socket address = "
         +s.getLocalSocketAddress().toString());
      System.out.println("   Local address = "
         +s.getLocalAddress().toString());
      System.out.println("   Local port = "+s.getLocalPort());
      System.out.println("   Need client authentication = "
         +s.getNeedClientAuth());
      SSLSession ss = s.getSession();
      System.out.println("   Cipher suite = "+ss.getCipherSuite());
      System.out.println("   Protocol = "+ss.getProtocol());
   }
}

How to test these programs

After you have created certificates on the server side, you can start the server as follows.
C:\>java SslReverseEchoer
Server socket class: class com.sun.net.ssl.internal.ssl.SSLServerSocketImpl
   Socker address = 0.0.0.0/0.0.0.0
   Socker port = 8888
   Need client authentication = false
   Want client authentication = false
   Use client mode = false
Socket class: class com.sun.net.ssl.internal.ssl.SSLSocketImpl
   Remote address = /127.0.0.1
   Remote port = 53298
   Local socket address = /127.0.0.1:8888
   Local address = /127.0.0.1
   Local port = 8888
   Need client authentication = false
   Cipher suite = SSL_RSA_WITH_RC4_128_MD5
   Protocol = TLSv1
While the server program is running, go to the client machine and execute the following

C:\>java SslSocketClient
Socket class: class com.sun.net.ssl.internal.ssl.SSLSocketImpl
   Remote address = localhost/127.0.0.1
   Remote port = 8888
   Local socket address = /127.0.0.1:52814
   Local address = /127.0.0.1
   Local port = 52814
   Need client authentication = false
   Cipher suite = SSL_NULL_WITH_NULL_NULL
   Protocol = NONE
javax.net.ssl.SSLException: Connection has been shutdown: javax.net.ssl.SSLHands
hakeException: sun.security.validator.ValidatorException: PKIX path building fai
led: sun.security.provider.certpath.SunCertPathBuilderException: unable to find
valid certification path to requested target

// Please note that the above command will terminate the server process. You need to restart it.
// In the above command, we didn't provide the certiciates, so as expected, it should not be 
// able to connect.


// Before running the following command, you have to import the server side certificate
// into cacerts.jks using the keytool -import command.

C:\>java -Djavax.net.ssl.trustStore=localhostCerts\cacerts.jks SslSocketClient
Socket class: class com.sun.net.ssl.internal.ssl.SSLSocketImpl
   Remote address = localhost/127.0.0.1
   Remote port = 8888
   Local socket address = /127.0.0.1:52816
   Local address = /127.0.0.1
   Local port = 52816
   Need client authentication = false
   Cipher suite = SSL_RSA_WITH_RC4_128_MD5
   Protocol = TLSv1
Welcome to SSL Reverse Echo Server. Please type in some words.
How are you?
?uoy era woH

1 comment: