1 /* 2 * Copyright (c) 2012, 2013, 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. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 // 27 // SunJSSE does not support dynamic system properties, no way to re-use 28 // system properties in samevm/agentvm mode. 29 // 30 31 /* 32 * @test 33 * @bug 7030966 34 * @summary Support AEAD CipherSuites 35 * @run main/othervm ShortRSAKeyGCM PKIX TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 36 * @run main/othervm ShortRSAKeyGCM PKIX TLS_RSA_WITH_AES_128_GCM_SHA256 37 * @run main/othervm ShortRSAKeyGCM PKIX TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 38 * @run main/othervm ShortRSAKeyGCM PKIX TLS_DH_anon_WITH_AES_128_GCM_SHA256 39 */ 40 41 /* 42 * Need additional key materials to run the following cases. 43 * 44 * @run main/othervm ShortRSAKeyGCM PKIX TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 45 * @run main/othervm ShortRSAKeyGCM PKIX TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 46 * @run main/othervm ShortRSAKeyGCM PKIX TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 47 * 48 * Need unlimited JCE Unlimited Strength Jurisdiction Policy to run the 49 * following cases. 50 * 51 * @run main/othervm ShortRSAKeyGCM PKIX TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 52 * @run main/othervm ShortRSAKeyGCM PKIX TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 53 * @run main/othervm ShortRSAKeyGCM PKIX TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 54 * @run main/othervm ShortRSAKeyGCM PKIX TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 55 * @run main/othervm ShortRSAKeyGCM PKIX TLS_RSA_WITH_AES_256_GCM_SHA384 56 * @run main/othervm ShortRSAKeyGCM PKIX TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 57 * @run main/othervm ShortRSAKeyGCM PKIX TLS_DH_anon_WITH_AES_256_GCM_SHA384 58 */ 59 60 import java.net.*; 61 import java.util.*; 62 import java.io.*; 63 import javax.net.ssl.*; 64 import java.security.Security; 65 import java.security.KeyStore; 66 import java.security.KeyFactory; 67 import java.security.cert.Certificate; 68 import java.security.cert.CertificateFactory; 69 import java.security.spec.*; 70 import java.security.interfaces.*; 71 72 73 public class ShortRSAKeyGCM { 74 75 /* 76 * ============================================================= 77 * Set the various variables needed for the tests, then 78 * specify what tests to run on each side. 79 */ 80 81 /* 82 * Should we run the client or server in a separate thread? 83 * Both sides can throw exceptions, but do you have a preference 84 * as to which side should be the main thread. 85 */ 86 static boolean separateServerThread = true; 87 88 /* 89 * Where do we find the keystores? 90 */ 91 // Certificates and key used in the test. 92 static String trustedCertStr = 93 "-----BEGIN CERTIFICATE-----\n" + 94 "MIICkjCCAfugAwIBAgIBADANBgkqhkiG9w0BAQQFADA7MQswCQYDVQQGEwJVUzEN\n" + 95 "MAsGA1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2Y2UwHhcN\n" + 96 "MTEwODE5MDE1MjE5WhcNMzIwNzI5MDE1MjE5WjA7MQswCQYDVQQGEwJVUzENMAsG\n" + 97 "A1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2Y2UwgZ8wDQYJ\n" + 98 "KoZIhvcNAQEBBQADgY0AMIGJAoGBAM8orG08DtF98TMSscjGsidd1ZoN4jiDpi8U\n" + 99 "ICz+9dMm1qM1d7O2T+KH3/mxyox7Rc2ZVSCaUD0a3CkhPMnlAx8V4u0H+E9sqso6\n" + 100 "iDW3JpOyzMExvZiRgRG/3nvp55RMIUV4vEHOZ1QbhuqG4ebN0Vz2DkRft7+flthf\n" + 101 "vDld6f5JAgMBAAGjgaUwgaIwHQYDVR0OBBYEFLl81dnfp0wDrv0OJ1sxlWzH83Xh\n" + 102 "MGMGA1UdIwRcMFqAFLl81dnfp0wDrv0OJ1sxlWzH83XhoT+kPTA7MQswCQYDVQQG\n" + 103 "EwJVUzENMAsGA1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2\n" + 104 "Y2WCAQAwDwYDVR0TAQH/BAUwAwEB/zALBgNVHQ8EBAMCAQYwDQYJKoZIhvcNAQEE\n" + 105 "BQADgYEALlgaH1gWtoBZ84EW8Hu6YtGLQ/L9zIFmHonUPZwn3Pr//icR9Sqhc3/l\n" + 106 "pVTxOINuFHLRz4BBtEylzRIOPzK3tg8XwuLb1zd0db90x3KBCiAL6E6cklGEPwLe\n" + 107 "XYMHDn9eDsaq861Tzn6ZwzMgw04zotPMoZN0mVd/3Qca8UJFucE=\n" + 108 "-----END CERTIFICATE-----"; 109 110 static String targetCertStr = 111 "-----BEGIN CERTIFICATE-----\n" + 112 "MIICNDCCAZ2gAwIBAgIBDDANBgkqhkiG9w0BAQQFADA7MQswCQYDVQQGEwJVUzEN\n" + 113 "MAsGA1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2Y2UwHhcN\n" + 114 "MTExMTA3MTM1NTUyWhcNMzEwNzI1MTM1NTUyWjBPMQswCQYDVQQGEwJVUzENMAsG\n" + 115 "A1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2Y2UxEjAQBgNV\n" + 116 "BAMTCWxvY2FsaG9zdDBcMA0GCSqGSIb3DQEBAQUAA0sAMEgCQQC3Pb49OSPfOD2G\n" + 117 "HSXFCFx1GJEZfqG9ZUf7xuIi/ra5dLjPGAaoY5QF2QOa8VnOriQCXDfyXHxsuRnE\n" + 118 "OomxL7EVAgMBAAGjeDB2MAsGA1UdDwQEAwID6DAdBgNVHQ4EFgQUXNCJK3/dtCIc\n" + 119 "xb+zlA/JINlvs/MwHwYDVR0jBBgwFoAUuXzV2d+nTAOu/Q4nWzGVbMfzdeEwJwYD\n" + 120 "VR0lBCAwHgYIKwYBBQUHAwEGCCsGAQUFBwMCBggrBgEFBQcDAzANBgkqhkiG9w0B\n" + 121 "AQQFAAOBgQB2qIDUxA2caMPpGtUACZAPRUtrGssCINIfItETXJZCx/cRuZ5sP4D9\n" + 122 "N1acoNDn0hCULe3lhXAeTC9NZ97680yJzregQMV5wATjo1FGsKY30Ma+sc/nfzQW\n" + 123 "+h/7RhYtoG0OTsiaDCvyhI6swkNJzSzrAccPY4+ZgU8HiDLzZTmM3Q==\n" + 124 "-----END CERTIFICATE-----"; 125 126 // Private key in the format of PKCS#8, key size is 512 bits. 127 static String targetPrivateKey = 128 "MIIBVAIBADANBgkqhkiG9w0BAQEFAASCAT4wggE6AgEAAkEAtz2+PTkj3zg9hh0l\n" + 129 "xQhcdRiRGX6hvWVH+8biIv62uXS4zxgGqGOUBdkDmvFZzq4kAlw38lx8bLkZxDqJ\n" + 130 "sS+xFQIDAQABAkByx/5Oo2hQ/w2q4L8z+NTRlJ3vdl8iIDtC/4XPnfYfnGptnpG6\n" + 131 "ZThQRvbMZiai0xHQPQMszvAHjZVme1eDl3EBAiEA3aKJHynPVCEJhpfCLWuMwX5J\n" + 132 "1LntwJO7NTOyU5m8rPECIQDTpzn5X44r2rzWBDna/Sx7HW9IWCxNgUD2Eyi2nA7W\n" + 133 "ZQIgJerEorw4aCAuzQPxiGu57PB6GRamAihEAtoRTBQlH0ECIQDN08FgTtnesgCU\n" + 134 "DFYLLcw1CiHvc7fZw4neBDHCrC8NtQIgA8TOUkGnpCZlQ0KaI8KfKWI+vxFcgFnH\n" + 135 "3fnqsTgaUs4="; 136 137 static char passphrase[] = "passphrase".toCharArray(); 138 139 /* 140 * Is the server ready to serve? 141 */ 142 volatile static boolean serverReady = false; 143 144 /* 145 * Turn on SSL debugging? 146 */ 147 static boolean debug = false; 148 149 /* 150 * Define the server side of the test. 151 * 152 * If the server prematurely exits, serverReady will be set to true 153 * to avoid infinite hangs. 154 */ 155 void doServerSide() throws Exception { 156 SSLContext context = generateSSLContext(null, targetCertStr, 157 targetPrivateKey); 158 SSLServerSocketFactory sslssf = context.getServerSocketFactory(); 159 SSLServerSocket sslServerSocket = 160 (SSLServerSocket)sslssf.createServerSocket(serverPort); 161 serverPort = sslServerSocket.getLocalPort(); 162 163 /* 164 * Signal Client, we're ready for his connect. 165 */ 166 serverReady = true; 167 168 SSLSocket sslSocket = (SSLSocket)sslServerSocket.accept(); 169 sslSocket.setEnabledCipherSuites(sslSocket.getSupportedCipherSuites()); 170 InputStream sslIS = sslSocket.getInputStream(); 171 OutputStream sslOS = sslSocket.getOutputStream(); 172 173 sslIS.read(); 174 sslOS.write('A'); 175 sslOS.flush(); 176 177 sslSocket.close(); 178 } 179 180 /* 181 * Define the client side of the test. 182 * 183 * If the server prematurely exits, serverReady will be set to true 184 * to avoid infinite hangs. 185 */ 186 void doClientSide() throws Exception { 187 188 /* 189 * Wait for server to get started. 190 */ 191 while (!serverReady) { 192 Thread.sleep(50); 193 } 194 195 SSLContext context = generateSSLContext(trustedCertStr, null, null); 196 SSLSocketFactory sslsf = context.getSocketFactory(); 197 198 SSLSocket sslSocket = 199 (SSLSocket)sslsf.createSocket("localhost", serverPort); 200 201 // enable TLSv1.2 only 202 sslSocket.setEnabledProtocols(new String[] {"TLSv1.2"}); 203 204 // enable a block cipher 205 sslSocket.setEnabledCipherSuites(new String[] {cipherSuite}); 206 207 InputStream sslIS = sslSocket.getInputStream(); 208 OutputStream sslOS = sslSocket.getOutputStream(); 209 210 sslOS.write('B'); 211 sslOS.flush(); 212 sslIS.read(); 213 214 sslSocket.close(); 215 } 216 217 /* 218 * ============================================================= 219 * The remainder is just support stuff 220 */ 221 private static String tmAlgorithm; // trust manager 222 private static String cipherSuite; // cipher suite 223 224 private static void parseArguments(String[] args) { 225 tmAlgorithm = args[0]; 226 cipherSuite = args[1]; 227 } 228 229 private static SSLContext generateSSLContext(String trustedCertStr, 230 String keyCertStr, String keySpecStr) throws Exception { 231 232 // generate certificate from cert string 233 CertificateFactory cf = CertificateFactory.getInstance("X.509"); 234 235 // create a key store 236 KeyStore ks = KeyStore.getInstance("JKS"); 237 ks.load(null, null); 238 239 // import the trused cert 240 Certificate trusedCert = null; 241 ByteArrayInputStream is = null; 242 if (trustedCertStr != null) { 243 is = new ByteArrayInputStream(trustedCertStr.getBytes()); 244 trusedCert = cf.generateCertificate(is); 245 is.close(); 246 247 ks.setCertificateEntry("RSA Export Signer", trusedCert); 248 } 249 250 if (keyCertStr != null) { 251 // generate the private key. 252 PKCS8EncodedKeySpec priKeySpec = new PKCS8EncodedKeySpec( 253 Base64.getMimeDecoder().decode(keySpecStr)); 254 KeyFactory kf = KeyFactory.getInstance("RSA"); 255 RSAPrivateKey priKey = 256 (RSAPrivateKey)kf.generatePrivate(priKeySpec); 257 258 // generate certificate chain 259 is = new ByteArrayInputStream(keyCertStr.getBytes()); 260 Certificate keyCert = cf.generateCertificate(is); 261 is.close(); 262 263 Certificate[] chain = null; 264 if (trusedCert != null) { 265 chain = new Certificate[2]; 266 chain[0] = keyCert; 267 chain[1] = trusedCert; 268 } else { 269 chain = new Certificate[1]; 270 chain[0] = keyCert; 271 } 272 273 // import the key entry. 274 ks.setKeyEntry("Whatever", priKey, passphrase, chain); 275 } 276 277 // create SSL context 278 TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmAlgorithm); 279 tmf.init(ks); 280 281 SSLContext ctx = SSLContext.getInstance("TLS"); 282 if (keyCertStr != null && !keyCertStr.isEmpty()) { 283 KeyManagerFactory kmf = KeyManagerFactory.getInstance("NewSunX509"); 284 kmf.init(ks, passphrase); 285 286 ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null); 287 ks = null; 288 } else { 289 ctx.init(null, tmf.getTrustManagers(), null); 290 } 291 292 return ctx; 293 } 294 295 296 // use any free port by default 297 volatile int serverPort = 0; 298 299 volatile Exception serverException = null; 300 volatile Exception clientException = null; 301 302 public static void main(String[] args) throws Exception { 303 // reset the security property to make sure that the algorithms 304 // and keys used in this test are not disabled. 305 Security.setProperty("jdk.certpath.disabledAlgorithms", "MD2"); 306 307 if (debug) { 308 System.setProperty("javax.net.debug", "all"); 309 } 310 311 /* 312 * Get the customized arguments. 313 */ 314 parseArguments(args); 315 316 /* 317 * Start the tests. 318 */ 319 new ShortRSAKeyGCM(); 320 } 321 322 Thread clientThread = null; 323 Thread serverThread = null; 324 325 /* 326 * Primary constructor, used to drive remainder of the test. 327 * 328 * Fork off the other side, then do your work. 329 */ 330 ShortRSAKeyGCM() throws Exception { 331 try { 332 if (separateServerThread) { 333 startServer(true); 334 startClient(false); 335 } else { 336 startClient(true); 337 startServer(false); 338 } 339 } catch (Exception e) { 340 // swallow for now. Show later 341 } 342 343 /* 344 * Wait for other side to close down. 345 */ 346 if (separateServerThread) { 347 serverThread.join(); 348 } else { 349 clientThread.join(); 350 } 351 352 /* 353 * When we get here, the test is pretty much over. 354 * Which side threw the error? 355 */ 356 Exception local; 357 Exception remote; 358 String whichRemote; 359 360 if (separateServerThread) { 361 remote = serverException; 362 local = clientException; 363 whichRemote = "server"; 364 } else { 365 remote = clientException; 366 local = serverException; 367 whichRemote = "client"; 368 } 369 370 /* 371 * If both failed, return the curthread's exception, but also 372 * print the remote side Exception 373 */ 374 if ((local != null) && (remote != null)) { 375 System.out.println(whichRemote + " also threw:"); 376 remote.printStackTrace(); 377 System.out.println(); 378 throw local; 379 } 380 381 if (remote != null) { 382 throw remote; 383 } 384 385 if (local != null) { 386 throw local; 387 } 388 } 389 390 void startServer(boolean newThread) throws Exception { 391 if (newThread) { 392 serverThread = new Thread() { 393 public void run() { 394 try { 395 doServerSide(); 396 } catch (Exception e) { 397 /* 398 * Our server thread just died. 399 * 400 * Release the client, if not active already... 401 */ 402 System.err.println("Server died..." + e); 403 serverReady = true; 404 serverException = e; 405 } 406 } 407 }; 408 serverThread.start(); 409 } else { 410 try { 411 doServerSide(); 412 } catch (Exception e) { 413 serverException = e; 414 } finally { 415 serverReady = true; 416 } 417 } 418 } 419 420 void startClient(boolean newThread) throws Exception { 421 if (newThread) { 422 clientThread = new Thread() { 423 public void run() { 424 try { 425 doClientSide(); 426 } catch (Exception e) { 427 /* 428 * Our client thread just died. 429 */ 430 System.err.println("Client died..." + e); 431 clientException = e; 432 } 433 } 434 }; 435 clientThread.start(); 436 } else { 437 try { 438 doClientSide(); 439 } catch (Exception e) { 440 clientException = e; 441 } 442 } 443 } 444 }