ServerIdentityTest.java revision 9372:171791e63397
1/* 2 * Copyright (c) 2001, 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 4328195 27 * @summary Need to include the alternate subject DN for certs, 28 * https should check for this 29 * @run main/othervm ServerIdentityTest 30 * 31 * SunJSSE does not support dynamic system properties, no way to re-use 32 * system properties in samevm/agentvm mode. 33 * 34 * @author Yingxian Wang 35 */ 36 37import java.io.*; 38import java.net.*; 39import javax.net.ssl.*; 40import java.security.KeyStore; 41 42public class ServerIdentityTest { 43 44 /* 45 * ============================================================= 46 * Set the various variables needed for the tests, then 47 * specify what tests to run on each side. 48 */ 49 50 /* 51 * Should we run the client or server in a separate thread? 52 * Both sides can throw exceptions, but do you have a preference 53 * as to which side should be the main thread. 54 */ 55 static boolean separateServerThread = true; 56 57 /* 58 * Where do we find the keystores? 59 */ 60 static String pathToStores = "./"; 61 static String[] keyStoreFiles = {"dnsstore", "ipstore"}; 62 static String[] trustStoreFiles = {"dnsstore", "ipstore"}; 63 static String passwd = "changeit"; 64 65 /* 66 * Is the server ready to serve? 67 */ 68 boolean serverReady = false; 69 70 /* 71 * Turn on SSL debugging? 72 */ 73 static boolean debug = false; 74 75 /* 76 * If the client or server is doing some kind of object creation 77 * that the other side depends on, and that thread prematurely 78 * exits, you may experience a hang. The test harness will 79 * terminate all hung threads after its timeout has expired, 80 * currently 3 minutes by default, but you might try to be 81 * smart about it.... 82 */ 83 84 /* 85 * Define the server side of the test. 86 * 87 * If the server prematurely exits, serverReady will be set to true 88 * to avoid infinite hangs. 89 */ 90 void doServerSide() throws Exception { 91 SSLServerSocketFactory sslssf = 92 context.getServerSocketFactory(); 93 SSLServerSocket sslServerSocket = 94 (SSLServerSocket) sslssf.createServerSocket(serverPort); 95 serverPort = sslServerSocket.getLocalPort(); 96 97 /* 98 * Signal Client, we're ready for his connect. 99 */ 100 serverReady = true; 101 102 SSLSocket sslSocket = (SSLSocket) sslServerSocket.accept(); 103 OutputStream sslOS = sslSocket.getOutputStream(); 104 BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(sslOS)); 105 bw.write("HTTP/1.1 200 OK\r\n\r\n\r\n"); 106 bw.flush(); 107 Thread.sleep(2000); 108 sslSocket.getSession().invalidate(); 109 sslSocket.close(); 110 } 111 112 /* 113 * Define the client side of the test. 114 * 115 * If the server prematurely exits, serverReady will be set to true 116 * to avoid infinite hangs. 117 */ 118 void doClientSide() throws Exception { 119 /* 120 * Wait for server to get started. 121 */ 122 while (!serverReady) { 123 Thread.sleep(50); 124 } 125 String host = iphost? "127.0.0.1": "localhost"; 126 URL url = new URL("https://"+host+":"+serverPort+"/index.html"); 127 128 HttpURLConnection urlc = (HttpURLConnection)url.openConnection(); 129 InputStream is = urlc.getInputStream(); 130 is.close(); 131 } 132 133 /* 134 * ============================================================= 135 * The remainder is just support stuff 136 */ 137 138 volatile int serverPort = 0; 139 140 volatile Exception serverException = null; 141 volatile Exception clientException = null; 142 143 public static void main(String[] args) throws Exception { 144 SSLSocketFactory reservedSFactory = 145 HttpsURLConnection.getDefaultSSLSocketFactory(); 146 try { 147 for (int i = 0; i < keyStoreFiles.length; i++) { 148 String keyFilename = 149 System.getProperty("test.src", ".") + "/" + pathToStores + 150 "/" + keyStoreFiles[i]; 151 String trustFilename = 152 System.getProperty("test.src", ".") + "/" + pathToStores + 153 "/" + trustStoreFiles[i]; 154 155 System.setProperty("javax.net.ssl.keyStore", keyFilename); 156 System.setProperty("javax.net.ssl.keyStorePassword", passwd); 157 System.setProperty("javax.net.ssl.trustStore", trustFilename); 158 System.setProperty("javax.net.ssl.trustStorePassword", passwd); 159 160 if (debug) 161 System.setProperty("javax.net.debug", "all"); 162 SSLContext context = SSLContext.getInstance("SSL"); 163 164 KeyManager[] kms = new KeyManager[1]; 165 KeyStore ks = KeyStore.getInstance("JKS"); 166 FileInputStream fis = new FileInputStream(keyFilename); 167 ks.load(fis, passwd.toCharArray()); 168 fis.close(); 169 KeyManager km = new MyKeyManager(ks, passwd.toCharArray()); 170 kms[0] = km; 171 context.init(kms, null, null); 172 HttpsURLConnection.setDefaultSSLSocketFactory( 173 context.getSocketFactory()); 174 175 /* 176 * Start the tests. 177 */ 178 System.out.println("Testing " + keyFilename); 179 new ServerIdentityTest(context, keyStoreFiles[i]); 180 } 181 } finally { 182 HttpsURLConnection.setDefaultSSLSocketFactory(reservedSFactory); 183 } 184 } 185 186 Thread clientThread = null; 187 Thread serverThread = null; 188 189 /* 190 * Primary constructor, used to drive remainder of the test. 191 * 192 * Fork off the other side, then do your work. 193 */ 194 SSLContext context; 195 boolean iphost = false; 196 ServerIdentityTest(SSLContext context, String keystore) 197 throws Exception { 198 this.context = context; 199 iphost = keystore.equals("ipstore"); 200 if (separateServerThread) { 201 startServer(true); 202 startClient(false); 203 } else { 204 startClient(true); 205 startServer(false); 206 } 207 208 /* 209 * Wait for other side to close down. 210 */ 211 if (separateServerThread) { 212 serverThread.join(); 213 } else { 214 clientThread.join(); 215 } 216 217 /* 218 * When we get here, the test is pretty much over. 219 * 220 * If the main thread excepted, that propagates back 221 * immediately. If the other thread threw an exception, we 222 * should report back. 223 */ 224 if (serverException != null) 225 throw serverException; 226 if (clientException != null) 227 throw clientException; 228 } 229 230 void startServer(boolean newThread) throws Exception { 231 if (newThread) { 232 serverThread = new Thread() { 233 public void run() { 234 try { 235 doServerSide(); 236 } catch (Exception e) { 237 e.printStackTrace(); 238 /* 239 * Our server thread just died. 240 * 241 * Release the client, if not active already... 242 */ 243 System.err.println("Server died..."); 244 serverReady = true; 245 serverException = e; 246 } 247 } 248 }; 249 serverThread.start(); 250 } else { 251 doServerSide(); 252 } 253 } 254 255 void startClient(boolean newThread) throws Exception { 256 if (newThread) { 257 clientThread = new Thread() { 258 public void run() { 259 try { 260 doClientSide(); 261 } catch (Exception e) { 262 /* 263 * Our client thread just died. 264 */ 265 System.err.println("Client died..."); 266 clientException = e; 267 } 268 } 269 }; 270 clientThread.start(); 271 } else { 272 doClientSide(); 273 } 274 } 275} 276