1 /* 2 * @test 3 * @build TestThread Traffic Handler ServerHandler ServerThread ClientThread 4 * @run main/othervm/timeout=140 -Djsse.enableCBCProtection=false main 5 * @summary Make sure that different configurations of SSL sockets work 6 * @key randomness 7 */ 8 9 /* 10 * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. 11 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 12 * 13 * This code is free software; you can redistribute it and/or modify it 14 * under the terms of the GNU General Public License version 2 only, as 15 * published by the Free Software Foundation. 16 * 17 * This code is distributed in the hope that it will be useful, but WITHOUT 18 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 19 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 20 * version 2 for more details (a copy is included in the LICENSE file that 21 * accompanied this code). 22 * 23 * You should have received a copy of the GNU General Public License version 24 * 2 along with this work; if not, write to the Free Software Foundation, 25 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 26 * 27 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 28 * or visit www.oracle.com if you need additional information or have any 29 * questions. 30 */ 31 32 import java.io.*; 33 import java.security.SecureRandom; 34 import java.security.KeyStore; 35 import javax.security.cert.*; 36 import java.util.Date; 37 import java.util.Vector; 38 import java.util.ArrayList; 39 40 import javax.net.ssl.*; 41 42 public class main 43 { 44 // NOTE: "prng" doesn't need to be a SecureRandom 45 46 private static final SecureRandom prng 47 = new SecureRandom (); 48 private static SSLContext sslContext; 49 50 private static void usage() { 51 System.err.println ( 52 "usage: tests.ssl.main default|random|cipher_suite [nthreads]"); 53 } 54 55 /** 56 * Runs a test ... there are a variety of configurations, and the way 57 * they're invoked is subject to change. This program can support 58 * single and multiple process tests, but by default it's set up for 59 * single process testing. 60 * 61 * <P> The first commandline argument identifies a test configuration. 62 * Currently identified configurations include "default", "random". 63 * 64 * <P> The second commandline argument identifies the number of 65 * client threads to use. 66 */ 67 public static void main (String argv []) 68 { 69 String config; 70 int NTHREADS; 71 72 initContext(); 73 String supported [] = sslContext.getSocketFactory() 74 .getSupportedCipherSuites(); 75 76 // Strip out any Kerberos Suites for now. 77 ArrayList list = new ArrayList(supported.length); 78 for (int i = 0; i < supported.length; i++) { 79 if (!supported[i].startsWith("TLS_KRB5")) { 80 list.add(supported[i]); 81 } 82 } 83 supported = (String [])list.toArray(new String [0]); 84 85 if (argv.length == 2) { 86 config = argv [0]; 87 NTHREADS = Integer.parseInt (argv [1]); 88 } else if (argv.length == 1) { 89 config = argv [0]; 90 NTHREADS = 15; 91 } else { 92 /* temporaraly changed to make it run under jtreg with 93 * default configuration, when no input parameters are 94 * given 95 */ 96 //usage(); 97 //return; 98 config = "default"; 99 NTHREADS = supported.length; 100 } 101 102 // More options ... port #. different clnt/svr configs, 103 // cipher suites, etc. 104 105 ServerThread server = new ServerThread (0, NTHREADS, sslContext); 106 Vector clients = new Vector (NTHREADS); 107 108 if (!(config.equals("default") || config.equals("random"))) 109 supported = new String[] {config}; 110 111 System.out.println("Supported cipher suites are:"); 112 for(int i=0; i < supported.length; i++) { 113 System.out.println(supported[i]); 114 } 115 116 setConfig (server, config, supported); 117 118 // if (OS != Win95) 119 server.setUseMT (true); 120 121 server.start (); 122 server.waitTillReady (); 123 124 // 125 // iterate over all cipher suites 126 // 127 int next = 0; 128 int passes = 0; 129 130 if (usesRandom (config)) 131 next = nextUnsignedRandom (); 132 133 for (int i = 0; i < NTHREADS; i++, next++) { 134 ClientThread client = new ClientThread (server.getServerPort(), sslContext); 135 String cipher [] = new String [1]; 136 137 setConfig (client, config, supported); 138 next = next % supported.length; 139 cipher [0] = supported [next]; 140 client.setBasicCipherSuites (cipher); 141 142 // 143 // Win95 has been observed to choke if you throw many 144 // connections at it. So we make it easy to unthread 145 // everything; it can be handy outside Win95 too. 146 // 147 client.start (); 148 if (!server.getUseMT ()) { 149 waitForClient (client); 150 if (client.passed ()) 151 passes++; 152 } else 153 clients.addElement (client); 154 } 155 156 while (!clients.isEmpty ()) { 157 ClientThread client; 158 159 client = (ClientThread) clients.elementAt (0); 160 clients.removeElement (client); 161 waitForClient (client); 162 if (client.passed ()) 163 passes++; 164 } 165 166 System.out.println ("SUMMARY: threads = " + NTHREADS 167 + ", passes = " + passes); 168 } 169 170 171 // 172 // Rather than replicating code, a helper function! 173 // 174 private static void waitForClient (Thread client) 175 { 176 while (true) 177 try { 178 client.join (); 179 180 // System.out.println ("Joined: " + client.getName ()); 181 break; 182 } catch (InterruptedException e) { 183 continue; 184 } 185 } 186 187 private static void initContext() 188 { 189 try { 190 String testRoot = System.getProperty("test.src", "."); 191 System.setProperty("javax.net.ssl.trustStore", testRoot 192 + "/../../../../javax/net/ssl/etc/truststore"); 193 194 KeyStore ks = KeyStore.getInstance("JKS"); 195 ks.load(new FileInputStream(testRoot 196 + "/../../../../javax/net/ssl/etc/truststore"), 197 "passphrase".toCharArray()); 198 KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509"); 199 kmf.init(ks, "passphrase".toCharArray()); 200 TrustManagerFactory tmf = 201 TrustManagerFactory.getInstance("SunX509"); 202 tmf.init(ks); 203 sslContext = SSLContext.getInstance("SSL"); 204 sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null); 205 } catch (Throwable t) { 206 // oh well; ignore it, the tester presumably intends this 207 System.out.println("Failed to read keystore/truststore file... Continuing"); 208 t.printStackTrace(); 209 } 210 } 211 212 private static int nextUnsignedRandom () 213 { 214 int retval = prng.nextInt (); 215 216 if (retval < 0) 217 return -retval; 218 else 219 return retval; 220 } 221 222 223 // 224 // Randomness in testing can be good and bad ... covers more 225 // territory, but not reproducibly. 226 // 227 private static boolean usesRandom (String config) 228 { 229 return config.equalsIgnoreCase ("random"); 230 } 231 232 233 private static void setConfig ( 234 TestThread test, 235 String config, 236 String supported [] 237 ) 238 { 239 test.setBasicCipherSuites (supported); 240 test.setOutput (System.out); 241 test.setVerbosity (3); 242 243 if (test instanceof ClientThread) { 244 test.setListenHandshake (true); 245 test.setIterations (20); 246 } 247 248 // XXX role reversals !!! 249 250 // 251 // We can establish a reasonable degree of variability 252 // on the test data and configs ... expecting that the 253 // diagnostics will identify any problems that exist. 254 // Client and server must agree on these things. 255 // 256 // Unless we do this, only the SSL nonces and ephemeral 257 // keys will be unpredictable in a given test run. Those 258 // affect only the utmost innards of SSL, details which 259 // are not visible to applications. 260 // 261 if (usesRandom (config)) { 262 int rand = nextUnsignedRandom (); 263 264 if (test instanceof ClientThread) 265 test.setIterations (rand % 35); 266 267 if ((rand & 0x080) == 0) 268 test.setInitiateHandshake (true); 269 // if ((rand & 0x040) == 0) 270 // test.setDoRenegotiate (true); 271 272 test.setPRNG (new SecureRandom ()); 273 } 274 } 275 }