| /* |
| * @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. |
| * |
| * <P> The first commandline argument identifies a test configuration. |
| * Currently identified configurations include "default", "random". |
| * |
| * <P> 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 ()); |
| } |
| } |
| } |