/* * @test * @build TestThread Traffic Handler ServerHandler ServerThread ClientThread * @run main/othervm/timeout=140 -Djsse.enableCBCProtection=false main * @summary Make sure that different configurations of SSL sockets work * @key randomness */ /* * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ import java.io.*; import java.security.SecureRandom; import java.security.KeyStore; import javax.security.cert.*; import java.util.Date; import java.util.Vector; import java.util.ArrayList; import javax.net.ssl.*; public class main { // NOTE: "prng" doesn't need to be a SecureRandom private static final SecureRandom prng = new SecureRandom (); private static SSLContext sslContext; private static void usage() { System.err.println ( "usage: tests.ssl.main default|random|cipher_suite [nthreads]"); } /** * Runs a test ... there are a variety of configurations, and the way * they're invoked is subject to change. This program can support * single and multiple process tests, but by default it's set up for * single process testing. * *

The first commandline argument identifies a test configuration. * Currently identified configurations include "default", "random". * *

The second commandline argument identifies the number of * client threads to use. */ public static void main (String argv []) { String config; int NTHREADS; initContext(); String supported [] = sslContext.getSocketFactory() .getSupportedCipherSuites(); // Strip out any Kerberos Suites for now. ArrayList list = new ArrayList(supported.length); for (int i = 0; i < supported.length; i++) { if (!supported[i].startsWith("TLS_KRB5")) { list.add(supported[i]); } } supported = (String [])list.toArray(new String [0]); if (argv.length == 2) { config = argv [0]; NTHREADS = Integer.parseInt (argv [1]); } else if (argv.length == 1) { config = argv [0]; NTHREADS = 15; } else { /* temporaraly changed to make it run under jtreg with * default configuration, when no input parameters are * given */ //usage(); //return; config = "default"; NTHREADS = supported.length; } // More options ... port #. different clnt/svr configs, // cipher suites, etc. ServerThread server = new ServerThread (0, NTHREADS, sslContext); Vector clients = new Vector (NTHREADS); if (!(config.equals("default") || config.equals("random"))) supported = new String[] {config}; System.out.println("Supported cipher suites are:"); for(int i=0; i < supported.length; i++) { System.out.println(supported[i]); } setConfig (server, config, supported); // if (OS != Win95) server.setUseMT (true); server.start (); server.waitTillReady (); // // iterate over all cipher suites // int next = 0; int passes = 0; if (usesRandom (config)) next = nextUnsignedRandom (); for (int i = 0; i < NTHREADS; i++, next++) { ClientThread client = new ClientThread (server.getServerPort(), sslContext); String cipher [] = new String [1]; setConfig (client, config, supported); next = next % supported.length; cipher [0] = supported [next]; client.setBasicCipherSuites (cipher); // // Win95 has been observed to choke if you throw many // connections at it. So we make it easy to unthread // everything; it can be handy outside Win95 too. // client.start (); if (!server.getUseMT ()) { waitForClient (client); if (client.passed ()) passes++; } else clients.addElement (client); } while (!clients.isEmpty ()) { ClientThread client; client = (ClientThread) clients.elementAt (0); clients.removeElement (client); waitForClient (client); if (client.passed ()) passes++; } System.out.println ("SUMMARY: threads = " + NTHREADS + ", passes = " + passes); } // // Rather than replicating code, a helper function! // private static void waitForClient (Thread client) { while (true) try { client.join (); // System.out.println ("Joined: " + client.getName ()); break; } catch (InterruptedException e) { continue; } } private static void initContext() { try { String testRoot = System.getProperty("test.src", "."); System.setProperty("javax.net.ssl.trustStore", testRoot + "/../../../../javax/net/ssl/etc/truststore"); KeyStore ks = KeyStore.getInstance("JKS"); ks.load(new FileInputStream(testRoot + "/../../../../javax/net/ssl/etc/truststore"), "passphrase".toCharArray()); KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509"); kmf.init(ks, "passphrase".toCharArray()); TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509"); tmf.init(ks); sslContext = SSLContext.getInstance("SSL"); sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null); } catch (Throwable t) { // oh well; ignore it, the tester presumably intends this System.out.println("Failed to read keystore/truststore file... Continuing"); t.printStackTrace(); } } private static int nextUnsignedRandom () { int retval = prng.nextInt (); if (retval < 0) return -retval; else return retval; } // // Randomness in testing can be good and bad ... covers more // territory, but not reproducibly. // private static boolean usesRandom (String config) { return config.equalsIgnoreCase ("random"); } private static void setConfig ( TestThread test, String config, String supported [] ) { test.setBasicCipherSuites (supported); test.setOutput (System.out); test.setVerbosity (3); if (test instanceof ClientThread) { test.setListenHandshake (true); test.setIterations (20); } // XXX role reversals !!! // // We can establish a reasonable degree of variability // on the test data and configs ... expecting that the // diagnostics will identify any problems that exist. // Client and server must agree on these things. // // Unless we do this, only the SSL nonces and ephemeral // keys will be unpredictable in a given test run. Those // affect only the utmost innards of SSL, details which // are not visible to applications. // if (usesRandom (config)) { int rand = nextUnsignedRandom (); if (test instanceof ClientThread) test.setIterations (rand % 35); if ((rand & 0x080) == 0) test.setInitiateHandshake (true); // if ((rand & 0x040) == 0) // test.setDoRenegotiate (true); test.setPRNG (new SecureRandom ()); } } }