1 /* 2 * Copyright (c) 2001, 2015, 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 // SunJSSE does not support dynamic system properties, no way to re-use 26 // system properties in samevm/agentvm mode. 27 // 28 29 /* 30 * @test 31 * @bug 4392475 32 * @summary Calling setWantClientAuth(true) disables anonymous suites 33 * @run main/othervm/timeout=180 AnonCipherWithWantClientAuth 34 */ 35 36 import java.io.*; 37 import java.net.*; 38 import javax.net.ssl.*; 39 import java.security.Security; 40 41 public class AnonCipherWithWantClientAuth { 42 43 /* 44 * ============================================================= 45 * Set the various variables needed for the tests, then 46 * specify what tests to run on each side. 47 */ 48 49 /* 50 * Should we run the client or server in a separate thread? 51 * Both sides can throw exceptions, but do you have a preference 52 * as to which side should be the main thread. 53 */ 54 static boolean separateServerThread = false; 55 56 /* 57 * Where do we find the keystores? 58 */ 59 static String pathToStores = "../../../../javax/net/ssl/etc"; 60 static String keyStoreFile = "keystore"; 61 static String trustStoreFile = "truststore"; 62 static String passwd = "passphrase"; 63 64 /* 65 * Is the server ready to serve? 66 */ 67 volatile static boolean serverReady = false; 68 69 /* 70 * Turn on SSL debugging? 71 */ 72 static boolean debug = false; 73 74 /* 75 * If the client or server is doing some kind of object creation 76 * that the other side depends on, and that thread prematurely 77 * exits, you may experience a hang. The test harness will 78 * terminate all hung threads after its timeout has expired, 79 * currently 3 minutes by default, but you might try to be 80 * smart about it.... 81 */ 82 83 /* 84 * Define the server side of the test. 85 * 86 * If the server prematurely exits, serverReady will be set to true 87 * to avoid infinite hangs. 88 */ 89 void doServerSide() throws Exception { 90 SSLServerSocketFactory sslssf = 91 (SSLServerSocketFactory) SSLServerSocketFactory.getDefault(); 92 SSLServerSocket sslServerSocket = 93 (SSLServerSocket) sslssf.createServerSocket(serverPort); 94 serverPort = sslServerSocket.getLocalPort(); 95 String ciphers[]={"SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA", 96 "SSL_DH_anon_EXPORT_WITH_RC4_40_MD5", 97 "SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA"}; 98 sslServerSocket.setEnabledCipherSuites(ciphers); 99 sslServerSocket.setWantClientAuth(true); 100 /* 101 * Signal Client, we're ready for his connect. 102 */ 103 serverReady = true; 104 105 SSLSocket sslSocket = (SSLSocket) sslServerSocket.accept(); 106 InputStream sslIS = sslSocket.getInputStream(); 107 OutputStream sslOS = sslSocket.getOutputStream(); 108 109 sslIS.read(); 110 sslOS.write(85); 111 sslOS.flush(); 112 113 sslSocket.close(); 114 } 115 116 /* 117 * Define the client side of the test. 118 * 119 * If the server prematurely exits, serverReady will be set to true 120 * to avoid infinite hangs. 121 */ 122 void doClientSide() throws Exception { 123 124 /* 125 * Wait for server to get started. 126 */ 127 while (!serverReady) { 128 Thread.sleep(50); 129 } 130 131 SSLSocketFactory sslsf = 132 (SSLSocketFactory) SSLSocketFactory.getDefault(); 133 SSLSocket sslSocket = (SSLSocket) 134 sslsf.createSocket("localhost", serverPort); 135 String ciphers[] = {"SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA", 136 "SSL_DH_anon_EXPORT_WITH_RC4_40_MD5"}; 137 sslSocket.setEnabledCipherSuites(ciphers); 138 sslSocket.setUseClientMode(true); 139 140 InputStream sslIS = sslSocket.getInputStream(); 141 OutputStream sslOS = sslSocket.getOutputStream(); 142 143 sslOS.write(280); 144 sslOS.flush(); 145 sslIS.read(); 146 147 sslSocket.close(); 148 } 149 150 /* 151 * ============================================================= 152 * The remainder is just support stuff 153 */ 154 155 // use any free port by default 156 volatile int serverPort = 0; 157 158 volatile Exception serverException = null; 159 volatile Exception clientException = null; 160 161 public static void main(String[] args) throws Exception { 162 // reset security properties to make sure that the algorithms 163 // and keys used in this test are not disabled. 164 Security.setProperty("jdk.tls.disabledAlgorithms", ""); 165 Security.setProperty("jdk.certpath.disabledAlgorithms", ""); 166 167 String keyFilename = 168 System.getProperty("test.src", "./") + "/" + pathToStores + 169 "/" + keyStoreFile; 170 String trustFilename = 171 System.getProperty("test.src", "./") + "/" + pathToStores + 172 "/" + trustStoreFile; 173 174 System.setProperty("javax.net.ssl.keyStore", keyFilename); 175 System.setProperty("javax.net.ssl.keyStorePassword", passwd); 176 System.setProperty("javax.net.ssl.trustStore", trustFilename); 177 System.setProperty("javax.net.ssl.trustStorePassword", passwd); 178 179 if (debug) 180 System.setProperty("javax.net.debug", "all"); 181 182 /* 183 * Start the tests. 184 */ 185 new AnonCipherWithWantClientAuth(); 186 } 187 188 Thread clientThread = null; 189 Thread serverThread = null; 190 191 /* 192 * Primary constructor, used to drive remainder of the test. 193 * 194 * Fork off the other side, then do your work. 195 */ 196 AnonCipherWithWantClientAuth () throws Exception { 197 if (separateServerThread) { 198 startServer(true); 199 startClient(false); 200 } else { 201 startClient(true); 202 startServer(false); 203 } 204 205 /* 206 * Wait for other side to close down. 207 */ 208 if (separateServerThread) { 209 serverThread.join(); 210 } else { 211 clientThread.join(); 212 } 213 214 /* 215 * When we get here, the test is pretty much over. 216 * 217 * If the main thread excepted, that propagates back 218 * immediately. If the other thread threw an exception, we 219 * should report back. 220 */ 221 if (serverException != null) 222 throw serverException; 223 if (clientException != null) 224 throw clientException; 225 } 226 227 void startServer(boolean newThread) throws Exception { 228 if (newThread) { 229 serverThread = new Thread() { 230 public void run() { 231 try { 232 doServerSide(); 233 } catch (Exception e) { 234 /* 235 * Our server thread just died. 236 */ 237 System.err.println("Server died..."); 238 serverReady = true; 239 serverException = e; 240 } 241 } 242 }; 243 serverThread.start(); 244 } else { 245 doServerSide(); 246 } 247 } 248 249 void startClient(boolean newThread) throws Exception { 250 if (newThread) { 251 clientThread = new Thread() { 252 public void run() { 253 try { 254 doClientSide(); 255 } catch (Exception e) { 256 /* 257 * Our client thread just died. 258 */ 259 System.err.println("Client died..."); 260 clientException = e; 261 } 262 } 263 }; 264 clientThread.start(); 265 } else { 266 doClientSide(); 267 } 268 } 269 } | 1 /* 2 * Copyright (c) 2001, 2016, 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 // SunJSSE does not support dynamic system properties, no way to re-use 26 // system properties in samevm/agentvm mode. 27 // 28 29 /* 30 * @test 31 * @bug 4392475 32 * @summary Calling setWantClientAuth(true) disables anonymous suites 33 * @run main/othervm/timeout=180 AnonCipherWithWantClientAuth 34 */ 35 36 import java.io.*; 37 import java.net.InetSocketAddress; 38 import java.net.SocketTimeoutException; 39 40 import javax.net.ssl.*; 41 import java.security.Security; 42 import java.util.concurrent.CountDownLatch; 43 import java.util.concurrent.TimeUnit; 44 45 public class AnonCipherWithWantClientAuth { 46 47 /* 48 * ============================================================= 49 * Set the various variables needed for the tests, then 50 * specify what tests to run on each side. 51 */ 52 53 /* 54 * Should we run the client or server in a separate thread? 55 * Both sides can throw exceptions, but do you have a preference 56 * as to which side should be the main thread. 57 */ 58 static boolean separateServerThread = false; 59 60 /* 61 * Where do we find the keystores? 62 */ 63 static String pathToStores = "../../../../javax/net/ssl/etc"; 64 static String keyStoreFile = "keystore"; 65 static String trustStoreFile = "truststore"; 66 static String passwd = "passphrase"; 67 68 /* 69 * Turn on SSL debugging? 70 */ 71 static boolean debug = false; 72 73 /* 74 * Is the server ready to serve? 75 */ 76 private static final CountDownLatch serverCondition = new CountDownLatch(1); 77 78 /* 79 * Is the client ready to handshake? 80 */ 81 private static final CountDownLatch clientCondition = new CountDownLatch(1); 82 83 /* 84 * use any free port by default 85 */ 86 private volatile int serverPort = 0; 87 88 /* 89 * If the client or server is doing some kind of object creation 90 * that the other side depends on, and that thread prematurely 91 * exits, you may experience a hang. The test harness will 92 * terminate all hung threads after its timeout has expired, 93 * currently 3 minutes by default, but you might try to be 94 * smart about it.... 95 */ 96 97 /* 98 * Define the server side of the test. 99 * 100 * If the server prematurely exits, serverReady will be set to true 101 * to avoid infinite hangs. 102 */ 103 void doServerSide() throws Exception { 104 SSLServerSocketFactory sslssf = 105 (SSLServerSocketFactory) SSLServerSocketFactory.getDefault(); 106 SSLServerSocket sslServerSocket = 107 (SSLServerSocket) sslssf.createServerSocket(serverPort); 108 serverPort = sslServerSocket.getLocalPort(); 109 String ciphers[]={"SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA", 110 "SSL_DH_anon_EXPORT_WITH_RC4_40_MD5", 111 "SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA"}; 112 sslServerSocket.setEnabledCipherSuites(ciphers); 113 sslServerSocket.setWantClientAuth(true); 114 115 // Signal the client, the server is ready to accept connection. 116 serverCondition.countDown(); 117 118 // Try to accept a connection in 30 seconds. 119 SSLSocket sslSocket; 120 try { 121 sslServerSocket.setSoTimeout(30000); 122 sslSocket = (SSLSocket)sslServerSocket.accept(); 123 } catch (SocketTimeoutException ste) { 124 sslServerSocket.close(); 125 126 // Ignore the test case if no connection within 30 seconds. 127 System.out.println( 128 "No incoming client connection in 30 seconds. " + 129 "Ignore in server side."); 130 return; 131 } 132 133 try { 134 boolean clientIsReady = clientCondition.await(30L, 135 TimeUnit.SECONDS); 136 if (clientIsReady) { 137 InputStream sslIS = sslSocket.getInputStream(); 138 OutputStream sslOS = sslSocket.getOutputStream(); 139 140 sslIS.read(); 141 sslOS.write(85); 142 sslOS.flush(); 143 } else { 144 System.out.println( 145 "The client is not the expected one or timeout. " 146 + "Ignore in server side."); 147 } 148 } finally { 149 sslSocket.close(); 150 sslServerSocket.close(); 151 } 152 } 153 154 /* 155 * Define the client side of the test. 156 * 157 * If the server prematurely exits, serverReady will be set to true 158 * to avoid infinite hangs. 159 */ 160 void doClientSide() throws Exception { 161 162 /* 163 * Wait for server to get started. 164 */ 165 boolean serverIsReady = 166 serverCondition.await(90L, TimeUnit.SECONDS); 167 if (!serverIsReady) { 168 System.out.println( 169 "The server is not ready yet in 90 seconds. " + 170 "Ignore in client side."); 171 return; 172 } 173 174 SSLSocketFactory sslsf = 175 (SSLSocketFactory) SSLSocketFactory.getDefault(); 176 try (SSLSocket sslSocket = (SSLSocket) sslsf.createSocket("localhost", 177 serverPort)) { 178 try { 179 sslSocket.connect( 180 new InetSocketAddress("localhost", serverPort), 15000); 181 } catch (IOException ioe) { 182 // The server side may be impacted by naughty test cases or 183 // third party routines, and cannot accept connections. 184 // 185 // Just ignore the test if the connection cannot be 186 // established. 187 System.out.println( 188 "Cannot make a connection in 15 seconds. " + 189 "Ignore in client side."); 190 return; 191 } 192 193 String ciphers[] = { "SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA", 194 "SSL_DH_anon_EXPORT_WITH_RC4_40_MD5" }; 195 sslSocket.setEnabledCipherSuites(ciphers); 196 sslSocket.setUseClientMode(true); 197 198 // Signal the server, the client is ready to communicate. 199 clientCondition.countDown(); 200 201 InputStream sslIS = sslSocket.getInputStream(); 202 OutputStream sslOS = sslSocket.getOutputStream(); 203 204 sslOS.write(280); 205 sslOS.flush(); 206 sslIS.read(); 207 } 208 } 209 210 /* 211 * ============================================================= 212 * The remainder is just support stuff 213 */ 214 215 volatile Exception serverException = null; 216 volatile Exception clientException = null; 217 218 public static void main(String[] args) throws Exception { 219 // reset security properties to make sure that the algorithms 220 // and keys used in this test are not disabled. 221 Security.setProperty("jdk.tls.disabledAlgorithms", ""); 222 Security.setProperty("jdk.certpath.disabledAlgorithms", ""); 223 224 String keyFilename = 225 System.getProperty("test.src", "./") + "/" + pathToStores + 226 "/" + keyStoreFile; 227 String trustFilename = 228 System.getProperty("test.src", "./") + "/" + pathToStores + 229 "/" + trustStoreFile; 230 231 System.setProperty("javax.net.ssl.keyStore", keyFilename); 232 System.setProperty("javax.net.ssl.keyStorePassword", passwd); 233 System.setProperty("javax.net.ssl.trustStore", trustFilename); 234 System.setProperty("javax.net.ssl.trustStorePassword", passwd); 235 236 if (debug) 237 System.setProperty("javax.net.debug", "all"); 238 239 /* 240 * Start the tests. 241 */ 242 new AnonCipherWithWantClientAuth(); 243 } 244 245 Thread clientThread = null; 246 Thread serverThread = null; 247 248 /* 249 * Primary constructor, used to drive remainder of the test. 250 * 251 * Fork off the other side, then do your work. 252 */ 253 AnonCipherWithWantClientAuth() throws Exception { 254 Exception startException = null; 255 try { 256 if (separateServerThread) { 257 startServer(true); 258 startClient(false); 259 } else { 260 startClient(true); 261 startServer(false); 262 } 263 } catch (Exception e) { 264 startException = e; 265 } 266 267 /* 268 * Wait for other side to close down. 269 */ 270 if (separateServerThread) { 271 if (serverThread != null) { 272 serverThread.join(); 273 } 274 } else { 275 if (clientThread != null) { 276 clientThread.join(); 277 } 278 } 279 280 /* 281 * When we get here, the test is pretty much over. 282 * Which side threw the error? 283 */ 284 Exception local; 285 Exception remote; 286 287 if (separateServerThread) { 288 remote = serverException; 289 local = clientException; 290 } else { 291 remote = clientException; 292 local = serverException; 293 } 294 295 Exception exception = null; 296 297 /* 298 * Check various exception conditions. 299 */ 300 if ((local != null) && (remote != null)) { 301 // If both failed, return the curthread's exception. 302 local.initCause(remote); 303 exception = local; 304 } else if (local != null) { 305 exception = local; 306 } else if (remote != null) { 307 exception = remote; 308 } else if (startException != null) { 309 exception = startException; 310 } 311 312 /* 313 * If there was an exception *AND* a startException, 314 * output it. 315 */ 316 if (exception != null) { 317 if (exception != startException && startException != null) { 318 exception.addSuppressed(startException); 319 } 320 throw exception; 321 } 322 323 // Fall-through: no exception to throw! 324 } 325 326 void startServer(boolean newThread) throws Exception { 327 if (newThread) { 328 serverThread = new Thread() { 329 public void run() { 330 try { 331 doServerSide(); 332 } catch (Exception e) { 333 /* 334 * Our server thread just died. 335 */ 336 System.err.println("Server died..."); 337 serverException = e; 338 } 339 } 340 }; 341 serverThread.start(); 342 } else { 343 try { 344 doServerSide(); 345 } catch (Exception e) { 346 System.out.println("Server failed: " + e); 347 serverException = e; 348 } 349 } 350 } 351 352 void startClient(boolean newThread) throws Exception { 353 if (newThread) { 354 clientThread = new Thread() { 355 public void run() { 356 try { 357 doClientSide(); 358 } catch (Exception e) { 359 /* 360 * Our client thread just died. 361 */ 362 System.err.println("Client died..."); 363 clientException = e; 364 } 365 } 366 }; 367 clientThread.start(); 368 } else { 369 try { 370 doClientSide(); 371 } catch (Exception e) { 372 System.out.println("Client failed: " + e); 373 clientException = e; 374 } 375 } 376 } 377 } 378 |