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