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 4390659 27 * @summary setNeedClientAuth() isn't working after a handshaker is established 28 * @run main/othervm ClientModeClientAuth 29 * 30 * SunJSSE does not support dynamic system properties, no way to re-use 31 * system properties in samevm/agentvm mode. 32 * @author Brad Wetmore 33 */ 34 35import java.io.*; 36import java.net.*; 37import javax.net.ssl.*; 38import java.security.cert.*; 39 40public class ClientModeClientAuth { 41 42 /* 43 * ============================================================= 44 * Set the various variables needed for the tests, then 45 * specify what tests to run on each side. 46 */ 47 48 /* 49 * Should we run the client or server in a separate thread? 50 * Both sides can throw exceptions, but do you have a preference 51 * as to which side should be the main thread. 52 */ 53 static boolean separateServerThread = false; 54 55 /* 56 * Where do we find the keystores? 57 */ 58 static String pathToStores = "../../../../javax/net/ssl/etc"; 59 static String keyStoreFile = "keystore"; 60 static String trustStoreFile = "truststore"; 61 static String passwd = "passphrase"; 62 63 /* 64 * Is the server ready to serve? 65 */ 66 volatile static boolean serverReady = false; 67 68 /* 69 * Define the server side of the test. 70 */ 71 void doServerSide() throws Exception { 72 73 ServerSocket serverSocket = null; 74 serverSocket = new ServerSocket(serverPort); 75 serverPort = serverSocket.getLocalPort(); 76 77 /* 78 * Signal Client, we're ready for his connect. 79 */ 80 serverReady = true; 81 82 Socket socket = serverSocket.accept(); 83 OutputStream out = socket.getOutputStream(); 84 InputStream in = socket.getInputStream(); 85 86 /* 87 * send data to make sure we are ok. 88 */ 89 out.write(85); 90 out.flush(); 91 in.read(); 92 93 SSLSocketFactory sslsf = 94 (SSLSocketFactory) SSLSocketFactory.getDefault(); 95 SSLSocket sslSocket = 96 (SSLSocket) sslsf.createSocket( 97 socket, socket.getInetAddress().getHostName(), 98 socket.getPort(), true); 99 100 sslSocket.setUseClientMode(false); 101 sslSocket.setNeedClientAuth(true); 102 103 InputStream sslIS = sslSocket.getInputStream(); 104 OutputStream sslOS = sslSocket.getOutputStream(); 105 106 sslOS.write(85); 107 sslOS.flush(); 108 sslIS.read(); 109 110 System.out.println("About to get PeerCertificates"); 111 Certificate[] certs = 112 sslSocket.getSession().getPeerCertificates(); 113 if (certs[0] instanceof X509Certificate) { 114 System.out.println("Peer: " + 115 ((X509Certificate)certs[0]).getSubjectDN()); 116 } 117 118 sslIS.close(); 119 sslOS.close(); 120 sslSocket.close(); 121 } 122 123 /* 124 * Define the client side of the test. 125 */ 126 void doClientSide() throws Exception { 127 128 /* 129 * Wait for host to set up his port. 130 */ 131 while (!serverReady) { 132 Thread.sleep(50); 133 } 134 135 Socket socket = new Socket("localhost", serverPort); 136 InputStream in = socket.getInputStream(); 137 OutputStream out = socket.getOutputStream(); 138 139 in.read(); 140 out.write(280); 141 out.flush(); 142 143 SSLSocketFactory sslsf = 144 (SSLSocketFactory) SSLSocketFactory.getDefault(); 145 146 SSLSocket sslSocket = (SSLSocket) 147 sslsf.createSocket(socket, socket.getInetAddress().getHostName(), 148 socket.getPort(), true); 149 150 sslSocket.setUseClientMode(true); 151 152 InputStream sslIS = sslSocket.getInputStream(); 153 OutputStream sslOS = sslSocket.getOutputStream(); 154 155 sslIS.read(); 156 sslOS.write(280); 157 sslOS.flush(); 158 159 sslIS.close(); 160 sslOS.close(); 161 sslSocket.close(); 162 } 163 164 /* 165 * ============================================================= 166 * The remainder is just support stuff 167 */ 168 169 // use any free port by default 170 volatile int serverPort = 0; 171 172 volatile Exception serverException = null; 173 volatile Exception clientException = null; 174 175 public static void main(String[] args) throws Exception { 176 String keyFilename = 177 System.getProperty("test.src", "./") + "/" + pathToStores + 178 "/" + keyStoreFile; 179 String trustFilename = 180 System.getProperty("test.src", "./") + "/" + pathToStores + 181 "/" + trustStoreFile; 182 183 System.setProperty("javax.net.ssl.keyStore", keyFilename); 184 System.setProperty("javax.net.ssl.keyStorePassword", passwd); 185 System.setProperty("javax.net.ssl.trustStore", trustFilename); 186 System.setProperty("javax.net.ssl.trustStorePassword", passwd); 187 188 /* 189 * Start the tests. 190 */ 191 new ClientModeClientAuth(); 192 } 193 194 Thread clientThread = null; 195 Thread serverThread = null; 196 197 ClientModeClientAuth() throws Exception { 198 if (separateServerThread) { 199 startServer(true); 200 startClient(false); 201 } else { 202 startClient(true); 203 startServer(false); 204 } 205 206 /* 207 * Wait for other side to close down. 208 */ 209 if (separateServerThread) { 210 serverThread.join(); 211 } else { 212 clientThread.join(); 213 } 214 215 /* 216 * When we get here, the test is pretty much over. 217 * 218 * If the main thread excepted, that propagates back 219 * immediately. If the other thread threw an exception, we 220 * should report back. 221 */ 222 if (serverException != null) 223 throw serverException; 224 if (clientException != null) 225 throw clientException; 226 } 227 228 void startServer(boolean newThread) throws Exception { 229 if (newThread) { 230 serverThread = new Thread() { 231 public void run() { 232 try { 233 doServerSide(); 234 } catch (Exception e) { 235 /* 236 * Our server thread just died. 237 * 238 * Release the client, if not active already... 239 */ 240 System.out.println("Server died..."); 241 serverReady = true; 242 serverException = e; 243 } 244 } 245 }; 246 serverThread.start(); 247 } else { 248 doServerSide(); 249 } 250 } 251 252 void startClient(boolean newThread) throws Exception { 253 if (newThread) { 254 clientThread = new Thread() { 255 public void run() { 256 try { 257 doClientSide(); 258 } catch (Exception e) { 259 /* 260 * Our client thread just died. 261 */ 262 System.out.println("Client died..."); 263 clientException = e; 264 } 265 } 266 }; 267 clientThread.start(); 268 } else { 269 doClientSide(); 270 } 271 } 272} 273