1/* 2 * Copyright (c) 2012, 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. 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 60import java.net.*; 61import java.util.*; 62import java.io.*; 63import javax.net.ssl.*; 64import java.security.Security; 65import java.security.KeyStore; 66import java.security.KeyFactory; 67import java.security.cert.Certificate; 68import java.security.cert.CertificateFactory; 69import java.security.spec.*; 70import java.security.interfaces.*; 71 72 73public 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 Security.setProperty("jdk.tls.disabledAlgorithms", 307 "SSLv3, RC4, DH keySize < 768"); 308 309 if (debug) { 310 System.setProperty("javax.net.debug", "all"); 311 } 312 313 /* 314 * Get the customized arguments. 315 */ 316 parseArguments(args); 317 318 /* 319 * Start the tests. 320 */ 321 new ShortRSAKeyGCM(); 322 } 323 324 Thread clientThread = null; 325 Thread serverThread = null; 326 327 /* 328 * Primary constructor, used to drive remainder of the test. 329 * 330 * Fork off the other side, then do your work. 331 */ 332 ShortRSAKeyGCM() throws Exception { 333 try { 334 if (separateServerThread) { 335 startServer(true); 336 startClient(false); 337 } else { 338 startClient(true); 339 startServer(false); 340 } 341 } catch (Exception e) { 342 // swallow for now. Show later 343 } 344 345 /* 346 * Wait for other side to close down. 347 */ 348 if (separateServerThread) { 349 serverThread.join(); 350 } else { 351 clientThread.join(); 352 } 353 354 /* 355 * When we get here, the test is pretty much over. 356 * Which side threw the error? 357 */ 358 Exception local; 359 Exception remote; 360 String whichRemote; 361 362 if (separateServerThread) { 363 remote = serverException; 364 local = clientException; 365 whichRemote = "server"; 366 } else { 367 remote = clientException; 368 local = serverException; 369 whichRemote = "client"; 370 } 371 372 /* 373 * If both failed, return the curthread's exception, but also 374 * print the remote side Exception 375 */ 376 if ((local != null) && (remote != null)) { 377 System.out.println(whichRemote + " also threw:"); 378 remote.printStackTrace(); 379 System.out.println(); 380 throw local; 381 } 382 383 if (remote != null) { 384 throw remote; 385 } 386 387 if (local != null) { 388 throw local; 389 } 390 } 391 392 void startServer(boolean newThread) throws Exception { 393 if (newThread) { 394 serverThread = new Thread() { 395 public void run() { 396 try { 397 doServerSide(); 398 } catch (Exception e) { 399 /* 400 * Our server thread just died. 401 * 402 * Release the client, if not active already... 403 */ 404 System.err.println("Server died..." + e); 405 serverReady = true; 406 serverException = e; 407 } 408 } 409 }; 410 serverThread.start(); 411 } else { 412 try { 413 doServerSide(); 414 } catch (Exception e) { 415 serverException = e; 416 } finally { 417 serverReady = true; 418 } 419 } 420 } 421 422 void startClient(boolean newThread) throws Exception { 423 if (newThread) { 424 clientThread = new Thread() { 425 public void run() { 426 try { 427 doClientSide(); 428 } catch (Exception e) { 429 /* 430 * Our client thread just died. 431 */ 432 System.err.println("Client died..." + e); 433 clientException = e; 434 } 435 } 436 }; 437 clientThread.start(); 438 } else { 439 try { 440 doClientSide(); 441 } catch (Exception e) { 442 clientException = e; 443 } 444 } 445 } 446} 447