1/* 2 * Copyright (c) 2012, 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. 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 40import java.net.*; 41import java.util.*; 42import java.io.*; 43import javax.net.ssl.*; 44import java.security.Security; 45import java.security.KeyStore; 46import java.security.KeyFactory; 47import java.security.cert.Certificate; 48import java.security.cert.CertificateFactory; 49import java.security.spec.*; 50import java.security.interfaces.*; 51import java.util.Base64; 52 53 54public 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 = true; 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 try (SSLServerSocket sslServerSocket = 141 (SSLServerSocket) sslssf.createServerSocket(serverPort)) { 142 143 serverPort = sslServerSocket.getLocalPort(); 144 System.out.println("Start server on port " + serverPort); 145 146 /* 147 * Signal Client, we're ready for his connect. 148 */ 149 serverReady = true; 150 151 try (SSLSocket sslSocket = (SSLSocket)sslServerSocket.accept()) { 152 InputStream sslIS = sslSocket.getInputStream(); 153 OutputStream sslOS = sslSocket.getOutputStream(); 154 155 sslIS.read(); 156 sslOS.write('A'); 157 sslOS.flush(); 158 } 159 } 160 } 161 162 /* 163 * Define the client side of the test. 164 * 165 * If the server prematurely exits, serverReady will be set to true 166 * to avoid infinite hangs. 167 */ 168 void doClientSide() throws Exception { 169 170 /* 171 * Wait for server to get started. 172 */ 173 while (!serverReady) { 174 Thread.sleep(50); 175 } 176 177 SSLContext context = generateSSLContext(trustedCertStr, null, null); 178 SSLSocketFactory sslsf = context.getSocketFactory(); 179 180 System.out.println("Client connects to port " + serverPort); 181 try (SSLSocket sslSocket = 182 (SSLSocket) sslsf.createSocket("localhost", serverPort)) { 183 184 // enable TLSv1.2 only 185 sslSocket.setEnabledProtocols(new String[] {"TLSv1.2"}); 186 187 // enable a block cipher 188 sslSocket.setEnabledCipherSuites( 189 new String[] {"TLS_DHE_RSA_WITH_AES_128_CBC_SHA"}); 190 191 InputStream sslIS = sslSocket.getInputStream(); 192 OutputStream sslOS = sslSocket.getOutputStream(); 193 194 sslOS.write('B'); 195 sslOS.flush(); 196 sslIS.read(); 197 } 198 } 199 200 /* 201 * ============================================================= 202 * The remainder is just support stuff 203 */ 204 private static String tmAlgorithm; // trust manager 205 206 private static void parseArguments(String[] args) { 207 tmAlgorithm = args[0]; 208 } 209 210 private static SSLContext generateSSLContext(String trustedCertStr, 211 String keyCertStr, String keySpecStr) throws Exception { 212 213 // generate certificate from cert string 214 CertificateFactory cf = CertificateFactory.getInstance("X.509"); 215 216 // create a key store 217 KeyStore ks = KeyStore.getInstance("JKS"); 218 ks.load(null, null); 219 220 // import the trused cert 221 Certificate trusedCert = null; 222 ByteArrayInputStream is = null; 223 if (trustedCertStr != null) { 224 is = new ByteArrayInputStream(trustedCertStr.getBytes()); 225 trusedCert = cf.generateCertificate(is); 226 is.close(); 227 228 ks.setCertificateEntry("RSA Export Signer", trusedCert); 229 } 230 231 if (keyCertStr != null) { 232 // generate the private key. 233 PKCS8EncodedKeySpec priKeySpec = new PKCS8EncodedKeySpec( 234 Base64.getMimeDecoder().decode(keySpecStr)); 235 KeyFactory kf = KeyFactory.getInstance("RSA"); 236 RSAPrivateKey priKey = 237 (RSAPrivateKey)kf.generatePrivate(priKeySpec); 238 239 // generate certificate chain 240 is = new ByteArrayInputStream(keyCertStr.getBytes()); 241 Certificate keyCert = cf.generateCertificate(is); 242 is.close(); 243 244 Certificate[] chain = null; 245 if (trusedCert != null) { 246 chain = new Certificate[2]; 247 chain[0] = keyCert; 248 chain[1] = trusedCert; 249 } else { 250 chain = new Certificate[1]; 251 chain[0] = keyCert; 252 } 253 254 // import the key entry. 255 ks.setKeyEntry("Whatever", priKey, passphrase, chain); 256 } 257 258 // create SSL context 259 TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmAlgorithm); 260 tmf.init(ks); 261 262 SSLContext ctx = SSLContext.getInstance("TLS"); 263 if (keyCertStr != null && !keyCertStr.isEmpty()) { 264 KeyManagerFactory kmf = KeyManagerFactory.getInstance("NewSunX509"); 265 kmf.init(ks, passphrase); 266 267 ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null); 268 ks = null; 269 } else { 270 ctx.init(null, tmf.getTrustManagers(), null); 271 } 272 273 return ctx; 274 } 275 276 277 // use any free port by default 278 volatile int serverPort = 0; 279 280 volatile Exception serverException = null; 281 volatile Exception clientException = null; 282 283 public static void main(String[] args) throws Exception { 284 // reset the security property to make sure that the algorithms 285 // and keys used in this test are not disabled. 286 Security.setProperty("jdk.certpath.disabledAlgorithms", "MD2"); 287 Security.setProperty("jdk.tls.disabledAlgorithms", 288 "SSLv3, RC4, DH keySize < 768"); 289 290 if (debug) 291 System.setProperty("javax.net.debug", "all"); 292 293 /* 294 * Get the customized arguments. 295 */ 296 parseArguments(args); 297 298 /* 299 * Start the tests. 300 */ 301 new ShortRSAKey512(); 302 } 303 304 Thread clientThread = null; 305 Thread serverThread = null; 306 307 /* 308 * Primary constructor, used to drive remainder of the test. 309 * 310 * Fork off the other side, then do your work. 311 */ 312 ShortRSAKey512() throws Exception { 313 if (separateServerThread) { 314 startServer(true); 315 startClient(false); 316 } else { 317 startClient(true); 318 startServer(false); 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 337 if (separateServerThread) { 338 remote = serverException; 339 local = clientException; 340 } else { 341 remote = clientException; 342 local = serverException; 343 } 344 345 /* 346 * If both failed, return the curthread's exception, but also 347 * print the remote side Exception 348 */ 349 if ((local != null) && (remote != null)) { 350 throw local; 351 } 352 353 if (remote != null) { 354 throw remote; 355 } 356 357 if (local != null) { 358 throw local; 359 } 360 } 361 362 void startServer(boolean newThread) { 363 if (newThread) { 364 serverThread = new Thread() { 365 public void run() { 366 try { 367 doServerSide(); 368 } catch (Exception e) { 369 /* 370 * Our server thread just died. 371 * 372 * Release the client, if not active already... 373 */ 374 System.err.println("Server died..."); 375 e.printStackTrace(System.err); 376 serverReady = true; 377 serverException = e; 378 } 379 } 380 }; 381 serverThread.setDaemon(true); 382 serverThread.start(); 383 } else { 384 try { 385 doServerSide(); 386 } catch (Exception e) { 387 serverException = e; 388 } finally { 389 serverReady = true; 390 } 391 } 392 } 393 394 void startClient(boolean newThread) { 395 if (newThread) { 396 clientThread = new Thread() { 397 public void run() { 398 try { 399 doClientSide(); 400 } catch (Exception e) { 401 /* 402 * Our client thread just died. 403 */ 404 System.err.println("Client died..."); 405 e.printStackTrace(System.err); 406 clientException = e; 407 } 408 } 409 }; 410 clientThread.setDaemon(true); 411 clientThread.start(); 412 } else { 413 try { 414 doClientSide(); 415 } catch (Exception e) { 416 clientException = e; 417 } 418 } 419 } 420} 421