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