1/* 2 * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24/* 25 * @test 26 * @bug 4919147 27 * @summary Support for token-based KeyStores 28 * @run main/othervm GoodProvider 29 * 30 * SunJSSE does not support dynamic system properties, no way to re-use 31 * system properties in samevm/agentvm mode. 32 */ 33 34import java.io.*; 35import java.net.*; 36import javax.net.ssl.*; 37 38public class GoodProvider { 39 40 /* 41 * ============================================================= 42 * Set the various variables needed for the tests, then 43 * specify what tests to run on each side. 44 */ 45 46 /* 47 * Should we run the client or server in a separate thread? 48 * Both sides can throw exceptions, but do you have a preference 49 * as to which side should be the main thread. 50 */ 51 static boolean separateServerThread = false; 52 53 /* 54 * Where do we find the keystores? 55 */ 56 static String pathToStores = "../../../../javax/net/ssl/etc"; 57 static String keyStoreFile = "keystore"; 58 static String trustStoreFile = "truststore"; 59 static String passwd = "passphrase"; 60 61 /* 62 * Is the server ready to serve? 63 */ 64 volatile static boolean serverReady = false; 65 66 /* 67 * Turn on SSL debugging? 68 */ 69 static boolean debug = false; 70 71 /* 72 * If the client or server is doing some kind of object creation 73 * that the other side depends on, and that thread prematurely 74 * exits, you may experience a hang. The test harness will 75 * terminate all hung threads after its timeout has expired, 76 * currently 3 minutes by default, but you might try to be 77 * smart about it.... 78 */ 79 80 /* 81 * Define the server side of the test. 82 * 83 * If the server prematurely exits, serverReady will be set to true 84 * to avoid infinite hangs. 85 */ 86 void doServerSide() throws Exception { 87 SSLServerSocketFactory sslssf = 88 (SSLServerSocketFactory) SSLServerSocketFactory.getDefault(); 89 SSLServerSocket sslServerSocket = 90 (SSLServerSocket) sslssf.createServerSocket(serverPort); 91 92 serverPort = sslServerSocket.getLocalPort(); 93 94 /* 95 * Signal Client, we're ready for his connect. 96 */ 97 serverReady = true; 98 99 SSLSocket sslSocket = (SSLSocket) sslServerSocket.accept(); 100 InputStream sslIS = sslSocket.getInputStream(); 101 OutputStream sslOS = sslSocket.getOutputStream(); 102 103 sslIS.read(); 104 sslOS.write(85); 105 sslOS.flush(); 106 107 sslSocket.close(); 108 } 109 110 /* 111 * Define the client side of the test. 112 * 113 * If the server prematurely exits, serverReady will be set to true 114 * to avoid infinite hangs. 115 */ 116 void doClientSide() throws Exception { 117 118 /* 119 * Wait for server to get started. 120 */ 121 while (!serverReady) { 122 Thread.sleep(50); 123 } 124 125 SSLSocketFactory sslsf = 126 (SSLSocketFactory) SSLSocketFactory.getDefault(); 127 SSLSocket sslSocket = (SSLSocket) 128 sslsf.createSocket("localhost", serverPort); 129 130 InputStream sslIS = sslSocket.getInputStream(); 131 OutputStream sslOS = sslSocket.getOutputStream(); 132 133 sslOS.write(280); 134 sslOS.flush(); 135 sslIS.read(); 136 137 sslSocket.close(); 138 } 139 140 /* 141 * ============================================================= 142 * The remainder is just support stuff 143 */ 144 145 // use any free port by default 146 volatile int serverPort = 0; 147 148 volatile Exception serverException = null; 149 volatile Exception clientException = null; 150 151 public static void main(String[] args) throws Exception { 152 String keyFilename = 153 System.getProperty("test.src", "./") + "/" + pathToStores + 154 "/" + keyStoreFile; 155 String trustFilename = 156 System.getProperty("test.src", "./") + "/" + pathToStores + 157 "/" + trustStoreFile; 158 159 // first test a good provider name 160 161 System.setProperty("javax.net.ssl.keyStore", keyFilename); 162 System.setProperty("javax.net.ssl.keyStoreProvider", "SUN"); 163 System.setProperty("javax.net.ssl.keyStorePassword", passwd); 164 System.setProperty("javax.net.ssl.trustStore", trustFilename); 165 System.setProperty("javax.net.ssl.trustStoreProvider", "SUN"); 166 System.setProperty("javax.net.ssl.trustStorePassword", passwd); 167 168 if (debug) 169 System.setProperty("javax.net.debug", "ssl,defaultctx"); 170 171 new GoodProvider(); 172 } 173 174 Thread clientThread = null; 175 Thread serverThread = null; 176 177 /* 178 * Primary constructor, used to drive remainder of the test. 179 * 180 * Fork off the other side, then do your work. 181 */ 182 GoodProvider() throws Exception { 183 try { 184 if (separateServerThread) { 185 startServer(true); 186 startClient(false); 187 } else { 188 startClient(true); 189 startServer(false); 190 } 191 } catch (Exception e) { 192 //swallow for now. Show later 193 } 194 195 /* 196 * Wait for other side to close down. 197 */ 198 if (separateServerThread) { 199 serverThread.join(); 200 } else { 201 clientThread.join(); 202 } 203 204 /* 205 * When we get here, the test is pretty much over. 206 * Which side threw the error? 207 */ 208 Exception local; 209 Exception remote; 210 String whichRemote; 211 212 if (separateServerThread) { 213 remote = serverException; 214 local = clientException; 215 whichRemote = "server"; 216 } else { 217 remote = clientException; 218 local = serverException; 219 whichRemote = "client"; 220 } 221 222 /* 223 * If both failed, return the curthread's exception, but also 224 * print the remote side Exception 225 */ 226 if ((local != null) && (remote != null)) { 227 System.out.println(whichRemote + " also threw:"); 228 remote.printStackTrace(); 229 System.out.println(); 230 throw local; 231 } 232 233 if (remote != null) { 234 throw remote; 235 } 236 237 if (local != null) { 238 throw local; 239 } 240 } 241 242 void startServer(boolean newThread) throws Exception { 243 if (newThread) { 244 serverThread = new Thread() { 245 public void run() { 246 try { 247 doServerSide(); 248 } catch (Exception e) { 249 /* 250 * Our server thread just died. 251 * 252 * Release the client, if not active already... 253 */ 254 System.err.println("Server died..."); 255 serverReady = true; 256 serverException = e; 257 } 258 } 259 }; 260 serverThread.start(); 261 } else { 262 try { 263 doServerSide(); 264 } catch (Exception e) { 265 serverException = e; 266 } finally { 267 serverReady = true; 268 } 269 } 270 } 271 272 void startClient(boolean newThread) throws Exception { 273 if (newThread) { 274 clientThread = new Thread() { 275 public void run() { 276 try { 277 doClientSide(); 278 } catch (Exception e) { 279 /* 280 * Our client thread just died. 281 */ 282 System.err.println("Client died..."); 283 clientException = e; 284 } 285 } 286 }; 287 clientThread.start(); 288 } else { 289 try { 290 doClientSide(); 291 } catch (Exception e) { 292 clientException = e; 293 } 294 } 295 } 296} 297