Example: JSSE client servlet
/* * * This material contains programming source code for your * consideration. These examples have not been thoroughly * tested under all conditions. IBM, therefore, cannot * guarantee or imply reliability, serviceability, or function * of these program. All programs contained herein are * provided to you "AS IS". THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * ARE EXPRESSLY DISCLAIMED. IBM provides no program services for * these programs and files. * */ import java.io.*; import java.net.ServerSocket; import java.net.Socket; import java.security.Security; import java.security.KeyStore; import javax.net.ssl.SSLServerSocketFactory; import javax.net.ssl.SSLSocketFactory; import javax.net.ssl.SSLServerSocket; import javax.net.ssl.SSLSocket; import javax.net.ssl.SSLSession; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.ibm.net.ssl.SSLContext; import com.ibm.net.ssl.TrustManagerFactory; import com.ibm.net.ssl.TrustManager; import com.ibm.net.ssl.KeyManagerFactory; /* * ServerJsse and ClientJsse * * Sample applications to demonstrate a simple client/server interaction using JSSE. * They communicate using all enabled cipher suites. * * The ServerJsse and ClientJsse use different KeyStore files called * "clientAppKeys.jks" and "serverAppKeys.jks" protected by a password and assumed * to be in the current working directory. In a real application, the client and * server should also have their own KeyStore files. * * You can build these sample program classes by issuing the following command but * first make sure that the ibmjsse.jar file shipped in the * "WAS_PRODUCT_ROOT/java/ext" is in your CLASSPATH or extensions directory. * This is a servlet, so you also need "WAS_PRODUCT_ROOT/lib/j2ee.jar to compile. * * javac ServerJsse.java * javac ClientJsse.java * * * Running the client/server application requires that the Server is started first * and then the Client application. * * To start the ServerJsse, run the following command: * * java ServerJsse * * The ServerJsse uses port 8050 by default. Once ServerJsse has started it waits * for the ClientJsse connection. * * To start the client, issue the following command: * * java ClientJsse hostname:port * * where hostname:port is the optional host:port running SeverJsse. * The default is localhost:8050. * */ public class ClientJsse extends HttpServlet { static int N = 50, L = 100, R = 2; static PrintWriter out = new PrintWriter(System.out); static SSLContext sslContext; // Open the KeyStore to obtain the Trusted Certificates. // KeyStore is of type "JKS". Filename is "clientAppKeys.jks" // and password is "myKeys". public static void initContext() { try { Security.addProvider(new com.ibm.jsse.JSSEProvider()); KeyStore ks = KeyStore.getInstance("JKS"); ks.load(new FileInputStream("clientAppKeys.jks"), "myKeys".toCharArray()); KeyManagerFactory kmf = KeyManagerFactory.getInstance("IbmX509"); kmf.init(ks, "myKeys".toCharArray()); TrustManager[] tm; TrustManagerFactory tmf = TrustManagerFactory.getInstance("IbmX509"); tmf.init(ks); tm = tmf.getTrustManagers(); sslContext = SSLContext.getInstance("SSL"); sslContext.init(kmf.getKeyManagers(), tm, null); } catch (Throwable t) { out.println("Failed to read clientAppKeys.jks file."); t.printStackTrace(); } } public void doGet(HttpServletRequest q, HttpServletResponse r) { r.setContentType("text/html"); String[] args = new String[1]; args[0] = getInitParameter("hostname"); // send result to the caller try { out = r.getWriter(); out.println("<html>"); out.println("<head>title>Client JSSE Session</title></head>"); out.println("<body>"); out.println("<h1>Client JSSE Session (starting)</h1>"); out.flush(); out.println("<pre>"); main(args); out.println("</pre>"); out.println("</body></html>"); out.flush(); out.close(); } catch (Exception e) { out.println("Exception in ClientJsse Servlet: " + e.getMessage()); e.printStackTrace(); } }//end public void doGet(...) /** Starts the ClientJsse application as stand alone application. * @param args the name of the host the ClientJsse should connect to */ public static void main(String args[]) throws Exception { int i, j, len, ci_nonanon; String host = "127.0.0.1"; int port = 8050; if ((args != null) && (args.length > 0)) { host = args[0]; i = host.indexOf(':'); if (i != -1) { try { port = Integer.parseInt(host.substring(i+1)); host = host.substring(0,i); } catch (Exception e) { System.err.println("ClientJsse: wrong address format"); e.printStackTrace(); throw e; } } } if (args.length > 1) N = Integer.parseInt(args[1]); if (args.length > 2) L = Integer.parseInt(args[2]); byte buffer[] = new byte[L]; out.println("ClientJsse: started."); initContext(); try { if (sslContext == null) { out.println ("ClientJsse: SSL client context NOT created."); return; } out.println("ClientJsse: SSL client context created."); SSLSocketFactory factory = sslContext.getSocketFactory(); String[] cipher_suites = sslContext.getSocketFactory().getSupportedCipherSuites(); out.println("ClientJsse: enabled cipher suites"); for (i=0, ci_nonanon=0; i < cipher_suites.length; i++) { if (cipher_suites[i].indexOf("_anon_") < 0) { ci_nonanon++; } out.println(" " + cipher_suites[i]); } out.flush(); SSLSocket ssl_sock; OutputStream ostr; InputStream istr; long t; String[] ecs = new String[1]; out.println("\n "); for (int csi = 0; csi < ci_nonanon; csi++) { // Remove anonymous cipher suites. // TrustManager requires a personal certificate. ecs[0] = cipher_suites[csi]; if (ecs[0].indexOf("_anon_") >= 0) { continue; } for (int n = 0; n < R; n++) { t = System.currentTimeMillis(); try { ssl_sock = (SSLSocket) factory.createSocket(host, port); ssl_sock.setEnabledCipherSuites(ecs); ssl_sock.startHandshake(); SSLSession session = ssl_sock.getSession(); out.println(" "); out.println("\nClientJsse: SSL connection established"); out.println(" cipher suite: " + session.getCipherSuite()); } catch (Exception se) { out.println(" "); out.println("\nClientJsse: can't connect using: " + cipher_suites[csi] + "\n" + se); break; } if (L > 0) { istr = ssl_sock.getInputStream(); ostr = ssl_sock.getOutputStream(); for (j=0; j < N; j++) { if ((j==N-1) && (n == R-1) && (csi == ci_nonanon - 1)) buffer[0] = (byte)-1; ostr.write(buffer, 0, L); for (len = 0;;) { try { if ((i = istr.read(buffer, len, L-len)) == -1) { out.println("ClientJsse: SSL connection dropped by partner."); istr.close(); return; } // out.println("ClientJsse: " + i + " bytes received."); if ((len+=i) == L) break; } catch (InterruptedIOException e) { // out.println("ClientJsse: timeout.\n"); } } } } out.println("Messages = " + N*2 + "; Time = " + (System.currentTimeMillis() - t)); ssl_sock.close(); out.println("ClientJsse: SSL connection closed."); out.flush(); } } Thread.sleep(1500); // Example using plain sockets if (L > 0) { Socket sock = new Socket(host, port); out.println(" "); out.println("\nClientJsse: Plain Socket connection established."); istr = sock.getInputStream(); ostr = sock.getOutputStream(); t = System.currentTimeMillis(); for (j=0; j < N; j++) { ostr.write(buffer, 0, L); for (len = 0;;) { if ((i = istr.read(buffer, len, L-len)) == -1) { out.println("ClientJsse: connection dropped by partner."); return; } if ((len+=i) == L) break; } } out.println("Messages = " + N*2 + "; Time = " + (System.currentTimeMillis() - t)); sock.close(); out.println("ClientJsse: Plain Socket connection closed."); Thread.sleep(1500); } } catch (Exception e) { out.println(e); } out.println(" "); out.println("ClientJsse: terminated."); out.flush(); }//end main(...) }//end class