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 * @modules java.base/sun.misc 36 * @run main/othervm ShortRSAKeyGCM PKIX TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 37 * @run main/othervm ShortRSAKeyGCM PKIX TLS_RSA_WITH_AES_128_GCM_SHA256 38 * @run main/othervm ShortRSAKeyGCM PKIX TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 39 * @run main/othervm ShortRSAKeyGCM PKIX TLS_DH_anon_WITH_AES_128_GCM_SHA256 40 */ 41 42 /* 43 * Need additional key materials to run the following cases. 44 * 45 * @run main/othervm ShortRSAKeyGCM PKIX TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 46 * @run main/othervm ShortRSAKeyGCM PKIX TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 47 * @run main/othervm ShortRSAKeyGCM PKIX TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 48 * 49 * Need unlimited JCE Unlimited Strength Jurisdiction Policy to run the 50 * following cases. 51 * 52 * @run main/othervm ShortRSAKeyGCM PKIX TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 53 * @run main/othervm ShortRSAKeyGCM PKIX TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 54 * @run main/othervm ShortRSAKeyGCM PKIX TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 55 * @run main/othervm ShortRSAKeyGCM PKIX TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 56 * @run main/othervm ShortRSAKeyGCM PKIX TLS_RSA_WITH_AES_256_GCM_SHA384 57 * @run main/othervm ShortRSAKeyGCM PKIX TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 58 * @run main/othervm ShortRSAKeyGCM PKIX TLS_DH_anon_WITH_AES_256_GCM_SHA384 59 */ 60 61 import java.net.*; 62 import java.util.*; 63 import java.io.*; 64 import javax.net.ssl.*; 65 import java.security.Security; 66 import java.security.KeyStore; 67 import java.security.KeyFactory; 68 import java.security.cert.Certificate; 69 import java.security.cert.CertificateFactory; 70 import java.security.spec.*; 71 import java.security.interfaces.*; 72 import sun.misc.BASE64Decoder; 73 74 75 public class ShortRSAKeyGCM { 76 77 /* 78 * ============================================================= 79 * Set the various variables needed for the tests, then 80 * specify what tests to run on each side. 81 */ 82 83 /* 84 * Should we run the client or server in a separate thread? 85 * Both sides can throw exceptions, but do you have a preference 86 * as to which side should be the main thread. 87 */ 88 static boolean separateServerThread = true; 89 90 /* 91 * Where do we find the keystores? 92 */ 93 // Certificates and key used in the test. 94 static String trustedCertStr = 95 "-----BEGIN CERTIFICATE-----\n" + 96 "MIICkjCCAfugAwIBAgIBADANBgkqhkiG9w0BAQQFADA7MQswCQYDVQQGEwJVUzEN\n" + 97 "MAsGA1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2Y2UwHhcN\n" + 98 "MTEwODE5MDE1MjE5WhcNMzIwNzI5MDE1MjE5WjA7MQswCQYDVQQGEwJVUzENMAsG\n" + 99 "A1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2Y2UwgZ8wDQYJ\n" + 100 "KoZIhvcNAQEBBQADgY0AMIGJAoGBAM8orG08DtF98TMSscjGsidd1ZoN4jiDpi8U\n" + 101 "ICz+9dMm1qM1d7O2T+KH3/mxyox7Rc2ZVSCaUD0a3CkhPMnlAx8V4u0H+E9sqso6\n" + 102 "iDW3JpOyzMExvZiRgRG/3nvp55RMIUV4vEHOZ1QbhuqG4ebN0Vz2DkRft7+flthf\n" + 103 "vDld6f5JAgMBAAGjgaUwgaIwHQYDVR0OBBYEFLl81dnfp0wDrv0OJ1sxlWzH83Xh\n" + 104 "MGMGA1UdIwRcMFqAFLl81dnfp0wDrv0OJ1sxlWzH83XhoT+kPTA7MQswCQYDVQQG\n" + 105 "EwJVUzENMAsGA1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2\n" + 106 "Y2WCAQAwDwYDVR0TAQH/BAUwAwEB/zALBgNVHQ8EBAMCAQYwDQYJKoZIhvcNAQEE\n" + 107 "BQADgYEALlgaH1gWtoBZ84EW8Hu6YtGLQ/L9zIFmHonUPZwn3Pr//icR9Sqhc3/l\n" + 108 "pVTxOINuFHLRz4BBtEylzRIOPzK3tg8XwuLb1zd0db90x3KBCiAL6E6cklGEPwLe\n" + 109 "XYMHDn9eDsaq861Tzn6ZwzMgw04zotPMoZN0mVd/3Qca8UJFucE=\n" + 110 "-----END CERTIFICATE-----"; 111 112 static String targetCertStr = 113 "-----BEGIN CERTIFICATE-----\n" + 114 "MIICNDCCAZ2gAwIBAgIBDDANBgkqhkiG9w0BAQQFADA7MQswCQYDVQQGEwJVUzEN\n" + 115 "MAsGA1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2Y2UwHhcN\n" + 116 "MTExMTA3MTM1NTUyWhcNMzEwNzI1MTM1NTUyWjBPMQswCQYDVQQGEwJVUzENMAsG\n" + 117 "A1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2Y2UxEjAQBgNV\n" + 118 "BAMTCWxvY2FsaG9zdDBcMA0GCSqGSIb3DQEBAQUAA0sAMEgCQQC3Pb49OSPfOD2G\n" + 119 "HSXFCFx1GJEZfqG9ZUf7xuIi/ra5dLjPGAaoY5QF2QOa8VnOriQCXDfyXHxsuRnE\n" + 120 "OomxL7EVAgMBAAGjeDB2MAsGA1UdDwQEAwID6DAdBgNVHQ4EFgQUXNCJK3/dtCIc\n" + 121 "xb+zlA/JINlvs/MwHwYDVR0jBBgwFoAUuXzV2d+nTAOu/Q4nWzGVbMfzdeEwJwYD\n" + 122 "VR0lBCAwHgYIKwYBBQUHAwEGCCsGAQUFBwMCBggrBgEFBQcDAzANBgkqhkiG9w0B\n" + 123 "AQQFAAOBgQB2qIDUxA2caMPpGtUACZAPRUtrGssCINIfItETXJZCx/cRuZ5sP4D9\n" + 124 "N1acoNDn0hCULe3lhXAeTC9NZ97680yJzregQMV5wATjo1FGsKY30Ma+sc/nfzQW\n" + 125 "+h/7RhYtoG0OTsiaDCvyhI6swkNJzSzrAccPY4+ZgU8HiDLzZTmM3Q==\n" + 126 "-----END CERTIFICATE-----"; 127 128 // Private key in the format of PKCS#8, key size is 512 bits. 129 static String targetPrivateKey = 130 "MIIBVAIBADANBgkqhkiG9w0BAQEFAASCAT4wggE6AgEAAkEAtz2+PTkj3zg9hh0l\n" + 131 "xQhcdRiRGX6hvWVH+8biIv62uXS4zxgGqGOUBdkDmvFZzq4kAlw38lx8bLkZxDqJ\n" + 132 "sS+xFQIDAQABAkByx/5Oo2hQ/w2q4L8z+NTRlJ3vdl8iIDtC/4XPnfYfnGptnpG6\n" + 133 "ZThQRvbMZiai0xHQPQMszvAHjZVme1eDl3EBAiEA3aKJHynPVCEJhpfCLWuMwX5J\n" + 134 "1LntwJO7NTOyU5m8rPECIQDTpzn5X44r2rzWBDna/Sx7HW9IWCxNgUD2Eyi2nA7W\n" + 135 "ZQIgJerEorw4aCAuzQPxiGu57PB6GRamAihEAtoRTBQlH0ECIQDN08FgTtnesgCU\n" + 136 "DFYLLcw1CiHvc7fZw4neBDHCrC8NtQIgA8TOUkGnpCZlQ0KaI8KfKWI+vxFcgFnH\n" + 137 "3fnqsTgaUs4="; 138 139 static char passphrase[] = "passphrase".toCharArray(); 140 141 /* 142 * Is the server ready to serve? 143 */ 144 volatile static boolean serverReady = false; 145 146 /* 147 * Turn on SSL debugging? 148 */ 149 static boolean debug = false; 150 151 /* 152 * Define the server side of the test. 153 * 154 * If the server prematurely exits, serverReady will be set to true 155 * to avoid infinite hangs. 156 */ 157 void doServerSide() throws Exception { 158 SSLContext context = generateSSLContext(null, targetCertStr, 159 targetPrivateKey); 160 SSLServerSocketFactory sslssf = context.getServerSocketFactory(); 161 SSLServerSocket sslServerSocket = 162 (SSLServerSocket)sslssf.createServerSocket(serverPort); 163 serverPort = sslServerSocket.getLocalPort(); 164 165 /* 166 * Signal Client, we're ready for his connect. 167 */ 168 serverReady = true; 169 170 SSLSocket sslSocket = (SSLSocket)sslServerSocket.accept(); 171 sslSocket.setEnabledCipherSuites(sslSocket.getSupportedCipherSuites()); 172 InputStream sslIS = sslSocket.getInputStream(); 173 OutputStream sslOS = sslSocket.getOutputStream(); 174 175 sslIS.read(); 176 sslOS.write('A'); 177 sslOS.flush(); 178 179 sslSocket.close(); 180 } 181 182 /* 183 * Define the client side of the test. 184 * 185 * If the server prematurely exits, serverReady will be set to true 186 * to avoid infinite hangs. 187 */ 188 void doClientSide() throws Exception { 189 190 /* 191 * Wait for server to get started. 192 */ 193 while (!serverReady) { 194 Thread.sleep(50); 195 } 196 197 SSLContext context = generateSSLContext(trustedCertStr, null, null); 198 SSLSocketFactory sslsf = context.getSocketFactory(); 199 200 SSLSocket sslSocket = 201 (SSLSocket)sslsf.createSocket("localhost", serverPort); 202 203 // enable TLSv1.2 only 204 sslSocket.setEnabledProtocols(new String[] {"TLSv1.2"}); 205 206 // enable a block cipher 207 sslSocket.setEnabledCipherSuites(new String[] {cipherSuite}); 208 209 InputStream sslIS = sslSocket.getInputStream(); 210 OutputStream sslOS = sslSocket.getOutputStream(); 211 212 sslOS.write('B'); 213 sslOS.flush(); 214 sslIS.read(); 215 216 sslSocket.close(); 217 } 218 219 /* 220 * ============================================================= 221 * The remainder is just support stuff 222 */ 223 private static String tmAlgorithm; // trust manager 224 private static String cipherSuite; // cipher suite 225 226 private static void parseArguments(String[] args) { 227 tmAlgorithm = args[0]; 228 cipherSuite = args[1]; 229 } 230 231 private static SSLContext generateSSLContext(String trustedCertStr, 232 String keyCertStr, String keySpecStr) throws Exception { 233 234 // generate certificate from cert string 235 CertificateFactory cf = CertificateFactory.getInstance("X.509"); 236 237 // create a key store 238 KeyStore ks = KeyStore.getInstance("JKS"); 239 ks.load(null, null); 240 241 // import the trused cert 242 Certificate trusedCert = null; 243 ByteArrayInputStream is = null; 244 if (trustedCertStr != null) { 245 is = new ByteArrayInputStream(trustedCertStr.getBytes()); 246 trusedCert = cf.generateCertificate(is); 247 is.close(); 248 249 ks.setCertificateEntry("RSA Export Signer", trusedCert); 250 } 251 252 if (keyCertStr != null) { 253 // generate the private key. 254 PKCS8EncodedKeySpec priKeySpec = new PKCS8EncodedKeySpec( 255 new BASE64Decoder().decodeBuffer(keySpecStr)); 256 KeyFactory kf = KeyFactory.getInstance("RSA"); 257 RSAPrivateKey priKey = 258 (RSAPrivateKey)kf.generatePrivate(priKeySpec); 259 260 // generate certificate chain 261 is = new ByteArrayInputStream(keyCertStr.getBytes()); 262 Certificate keyCert = cf.generateCertificate(is); 263 is.close(); 264 265 Certificate[] chain = null; 266 if (trusedCert != null) { 267 chain = new Certificate[2]; 268 chain[0] = keyCert; 269 chain[1] = trusedCert; 270 } else { 271 chain = new Certificate[1]; 272 chain[0] = keyCert; 273 } 274 275 // import the key entry. 276 ks.setKeyEntry("Whatever", priKey, passphrase, chain); 277 } 278 279 // create SSL context 280 TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmAlgorithm); 281 tmf.init(ks); 282 283 SSLContext ctx = SSLContext.getInstance("TLS"); 284 if (keyCertStr != null && !keyCertStr.isEmpty()) { 285 KeyManagerFactory kmf = KeyManagerFactory.getInstance("NewSunX509"); 286 kmf.init(ks, passphrase); 287 288 ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null); 289 ks = null; 290 } else { 291 ctx.init(null, tmf.getTrustManagers(), null); 292 } 293 294 return ctx; 295 } 296 297 298 // use any free port by default 299 volatile int serverPort = 0; 300 301 volatile Exception serverException = null; 302 volatile Exception clientException = null; 303 304 public static void main(String[] args) throws Exception { 305 // reset the security property to make sure that the algorithms 306 // and keys used in this test are not disabled. 307 Security.setProperty("jdk.certpath.disabledAlgorithms", "MD2"); 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 }