/* * The contents of this file are subject to the Mozilla Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * The Original Code is the Netscape Security Services for Java. * * The Initial Developer of the Original Code is Netscape * Communications Corporation. Portions created by Netscape are * Copyright (C) 1998-2000 Netscape Communications Corporation. All * Rights Reserved. * * Contributor(s): * * Alternatively, the contents of this file may be used under the * terms of the GNU General Public License Version 2 or later (the * "GPL"), in which case the provisions of the GPL are applicable * instead of those above. If you wish to allow use of your * version of this file only under the terms of the GPL and not to * allow others to use your version of this file under the MPL, * indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by * the GPL. If you do not delete the provisions above, a recipient * may use your version of this file under either the MPL or the * GPL. */ // This demonstrates the SSL client-side support // import org.mozilla.jss.ssl.*; import java.io.*; import java.util.*; import java.net.*; import org.mozilla.jss.*; import org.mozilla.jss.crypto.AlreadyInitializedException; /** * Parameters supported by this socket test: * SSLClient * * */ public class SSLClient implements SSLCertificateApprovalCallback, SSLClientCertificateSelectionCallback { boolean handshakeEventHappened = false; boolean doClientAuth = false; PrintStream results; Hashtable args; // command line arguments are store here public static Hashtable initArgs() { Hashtable args = new Hashtable(); args.put("hostname","localhost"); args.put("port","10443"); return args; } public String getArgument(String key) { return (String)args.get(key); } public void run() { try { SSLHandshakeCompletedListener listener = null; SSLSocket s; String hostname; int port; String msg = "GET /index.html"; String portstr = getArgument("port"); if (portstr == null) { port = 443; } else { port = Integer.valueOf(portstr).intValue(); } /* the argument 'cert' specifies the nickname of a client-auth-cert to use if asked by the server */ String nickname = getArgument("cert"); hostname = getArgument("hostname"); results.println("Connecting to " + hostname + " on port " + port ); s = new SSLSocket(InetAddress.getByName(hostname), port, null, /* local addr */ 0, /* local port */ true, /* stream */ this, /* approvalCallback */ this /* certSelectionCallback */ ); results.println("Connected."); // If you pass null for the certSelectionCallback argument // above, you can provide the name of the client-auth- // cert ahead of time, by using the setClientCertNickname // API // select the cert for client auth // s.setClientCertNickname("cert"); // Setup a handshake callback. This listener will get invoked // When the SSL handshake is completed on this socket. listener = new ClientHandshakeCB(this); s.addHandshakeCompletedListener(listener); OutputStream o = s.getOutputStream(); PrintOutputStreamWriter out = new PrintOutputStreamWriter(o); results.println("Sending: " + msg + " to " + hostname + ", " + port ); // send HTTP GET message across SSL connection out.println(msg + "\r"); InputStream in = s.getInputStream(); byte[] bytes = new byte[4096]; int totalBytes = 0; int numReads = 0; String lastBytes = null; // now try to read data back from the SSL connection try { for(;;) { results.println("Calling Read."); int n = in.read(bytes, 0, bytes.length); if(n == -1) { results.println("EOF found."); break; } if (n == 0) { results.println("Zero bytes read?"); break; } numReads++; if(totalBytes == 0) { // don't print forever... String data = new String(bytes, 0, 30, "8859_1"); results.println("Read " + n + " bytes of data"); results.println("First 30 bytes: " + escapeHTML(data)); } totalBytes += n; lastBytes = new String(bytes, n-31, 30, "8859_1"); } } catch (IOException e) { results.println("IOException while reading from pipe? "+ "Actually got "+ totalBytes + " bytes total"); e.printStackTrace(results); results.println(""); throw e; } finally { results.println("Last 30 bytes: " + lastBytes); results.println("Number of read() calls: " + numReads ); results.println("\nDiagnostics"); results.println("Total bytes read: " + totalBytes ); results.println("Security status of session:"); SSLSecurityStatus status = s.getStatus(); results.println(status.toString()); } // Got here, so no exception thrown above. // Try to clean up. o.close(); o = null; in.close(); in = null; if (listener != null) { s.removeHandshakeCompletedListener(listener); listener = null; } s.close(); s = null; } catch(Exception e) { results.println("***** TEST FAILED *****"); e.printStackTrace(results); } results.println("END OF TEST"); } /** * given an input string, convert less-than, greater-than, and ampersand * from raw characters to escaped characters * (< becomes `&lt;', etc.) */ private String escapeHTML(String s) { StringBuffer result = new StringBuffer(); for(int i=0; i': result.append(">"); break; case '&': result.append("&"); break; default: result.append(c); break; } } return result.toString(); } /* CONSTRUCTOR */ public SSLClient( PrintStream ps, String verStr, Hashtable myargs) throws Exception { this.args = myargs; this.results = ps; int i; String ocsp = (String)myargs.get("ocsp_on"); boolean ocsp_on = false; if (ocsp != null) { if (ocsp.equals("on") ) { ocsp_on = true; } else if (ocsp.equals("off")) { ocsp_on = false; } else { throw new Exception("Error: invalid argument '"+ ocsp+ "' must be 'on' or 'off'"); } } try { CryptoManager.InitializationValues vals = new CryptoManager.InitializationValues ("secmod.db", "key3.db", "cert7.db"); vals.ocspCheckingEnabled = ocsp_on; vals.ocspResponderURL = (String)myargs.get("ocsp_url"); vals.ocspResponderCertNickname = (String)myargs.get( "ocsp_nickname"); CryptoManager.initialize(vals); } catch (KeyDatabaseException kdbe) { System.out.println("Couldn't open the key database"); return; } catch (CertDatabaseException cdbe) { System.out.println("Couldn't open the certificate database"); return; } catch (AlreadyInitializedException aie) { System.out.println("CryptoManager already initialized???"); return; } /* enable all the SSL2 cipher suites */ for (i = SSLSocket.SSL2_RC4_128_WITH_MD5; i <= SSLSocket.SSL2_DES_192_EDE3_CBC_WITH_MD5; ++i) { SSLSocket.setCipherPreference( i, true); } /* enable all the SSL3 cipher suites */ for (i = 0; cipherSuites[i] != 0; ++i) { SSLSocket.setCipherPreference( cipherSuites[i], true); } } static final int cipherSuites[] = { SSLSocket.SSL3_RSA_WITH_RC4_128_MD5, SSLSocket.SSL3_RSA_WITH_3DES_EDE_CBC_SHA, SSLSocket.SSL3_RSA_WITH_DES_CBC_SHA, SSLSocket.SSL3_RSA_EXPORT_WITH_RC4_40_MD5, SSLSocket.SSL3_RSA_EXPORT_WITH_RC2_CBC_40_MD5, SSLSocket.SSL3_RSA_WITH_NULL_MD5, 0 }; public static void main(String argv[]) { Hashtable myargs = initArgs(); int i; for (i=0;i