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 // SunJSSE does not support dynamic system properties, no way to re-use 27 // system properties in samevm/agentvm mode. 28 29 /* 30 * @test 31 * @bug 7109274 32 * @summary Consider disabling support for X.509 certificates with RSA keys 33 * less than 1024 bits 34 * @library /javax/net/ssl/templates 35 * @run main/othervm DisabledShortRSAKeys PKIX TLSv1.2 36 * @run main/othervm DisabledShortRSAKeys SunX509 TLSv1.2 37 * @run main/othervm DisabledShortRSAKeys PKIX TLSv1.1 38 * @run main/othervm DisabledShortRSAKeys SunX509 TLSv1.1 39 * @run main/othervm DisabledShortRSAKeys PKIX TLSv1 40 * @run main/othervm DisabledShortRSAKeys SunX509 TLSv1 41 * @run main/othervm DisabledShortRSAKeys PKIX SSLv3 42 * @run main/othervm DisabledShortRSAKeys SunX509 SSLv3 43 */ 44 45 import java.net.*; 46 import java.util.*; 47 import java.io.*; 48 import javax.net.ssl.*; 49 import java.security.Security; 50 import java.security.KeyStore; 51 import java.security.KeyFactory; 52 import java.security.cert.Certificate; 53 import java.security.cert.CertificateFactory; 54 import java.security.spec.*; 55 import java.security.interfaces.*; 56 import java.util.Base64; 57 58 59 public class DisabledShortRSAKeys extends SSLSocketTemplate { 60 61 /* 62 * Where do we find the keystores? 63 */ 64 // Certificates and key used in the test. 65 static String trustedCertStr = 66 "-----BEGIN CERTIFICATE-----\n" + 67 "MIICkjCCAfugAwIBAgIBADANBgkqhkiG9w0BAQQFADA7MQswCQYDVQQGEwJVUzEN\n" + 68 "MAsGA1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2Y2UwHhcN\n" + 69 "MTEwODE5MDE1MjE5WhcNMzIwNzI5MDE1MjE5WjA7MQswCQYDVQQGEwJVUzENMAsG\n" + 70 "A1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2Y2UwgZ8wDQYJ\n" + 71 "KoZIhvcNAQEBBQADgY0AMIGJAoGBAM8orG08DtF98TMSscjGsidd1ZoN4jiDpi8U\n" + 72 "ICz+9dMm1qM1d7O2T+KH3/mxyox7Rc2ZVSCaUD0a3CkhPMnlAx8V4u0H+E9sqso6\n" + 73 "iDW3JpOyzMExvZiRgRG/3nvp55RMIUV4vEHOZ1QbhuqG4ebN0Vz2DkRft7+flthf\n" + 74 "vDld6f5JAgMBAAGjgaUwgaIwHQYDVR0OBBYEFLl81dnfp0wDrv0OJ1sxlWzH83Xh\n" + 75 "MGMGA1UdIwRcMFqAFLl81dnfp0wDrv0OJ1sxlWzH83XhoT+kPTA7MQswCQYDVQQG\n" + 76 "EwJVUzENMAsGA1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2\n" + 77 "Y2WCAQAwDwYDVR0TAQH/BAUwAwEB/zALBgNVHQ8EBAMCAQYwDQYJKoZIhvcNAQEE\n" + 78 "BQADgYEALlgaH1gWtoBZ84EW8Hu6YtGLQ/L9zIFmHonUPZwn3Pr//icR9Sqhc3/l\n" + 79 "pVTxOINuFHLRz4BBtEylzRIOPzK3tg8XwuLb1zd0db90x3KBCiAL6E6cklGEPwLe\n" + 80 "XYMHDn9eDsaq861Tzn6ZwzMgw04zotPMoZN0mVd/3Qca8UJFucE=\n" + 81 "-----END CERTIFICATE-----"; 82 83 static String targetCertStr = 84 "-----BEGIN CERTIFICATE-----\n" + 85 "MIICNDCCAZ2gAwIBAgIBDDANBgkqhkiG9w0BAQQFADA7MQswCQYDVQQGEwJVUzEN\n" + 86 "MAsGA1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2Y2UwHhcN\n" + 87 "MTExMTA3MTM1NTUyWhcNMzEwNzI1MTM1NTUyWjBPMQswCQYDVQQGEwJVUzENMAsG\n" + 88 "A1UEChMESmF2YTEdMBsGA1UECxMUU3VuSlNTRSBUZXN0IFNlcml2Y2UxEjAQBgNV\n" + 89 "BAMTCWxvY2FsaG9zdDBcMA0GCSqGSIb3DQEBAQUAA0sAMEgCQQC3Pb49OSPfOD2G\n" + 90 "HSXFCFx1GJEZfqG9ZUf7xuIi/ra5dLjPGAaoY5QF2QOa8VnOriQCXDfyXHxsuRnE\n" + 91 "OomxL7EVAgMBAAGjeDB2MAsGA1UdDwQEAwID6DAdBgNVHQ4EFgQUXNCJK3/dtCIc\n" + 92 "xb+zlA/JINlvs/MwHwYDVR0jBBgwFoAUuXzV2d+nTAOu/Q4nWzGVbMfzdeEwJwYD\n" + 93 "VR0lBCAwHgYIKwYBBQUHAwEGCCsGAQUFBwMCBggrBgEFBQcDAzANBgkqhkiG9w0B\n" + 94 "AQQFAAOBgQB2qIDUxA2caMPpGtUACZAPRUtrGssCINIfItETXJZCx/cRuZ5sP4D9\n" + 95 "N1acoNDn0hCULe3lhXAeTC9NZ97680yJzregQMV5wATjo1FGsKY30Ma+sc/nfzQW\n" + 96 "+h/7RhYtoG0OTsiaDCvyhI6swkNJzSzrAccPY4+ZgU8HiDLzZTmM3Q==\n" + 97 "-----END CERTIFICATE-----"; 98 99 // Private key in the format of PKCS#8, key size is 512 bits. 100 static String targetPrivateKey = 101 "MIIBVAIBADANBgkqhkiG9w0BAQEFAASCAT4wggE6AgEAAkEAtz2+PTkj3zg9hh0l\n" + 102 "xQhcdRiRGX6hvWVH+8biIv62uXS4zxgGqGOUBdkDmvFZzq4kAlw38lx8bLkZxDqJ\n" + 103 "sS+xFQIDAQABAkByx/5Oo2hQ/w2q4L8z+NTRlJ3vdl8iIDtC/4XPnfYfnGptnpG6\n" + 104 "ZThQRvbMZiai0xHQPQMszvAHjZVme1eDl3EBAiEA3aKJHynPVCEJhpfCLWuMwX5J\n" + 105 "1LntwJO7NTOyU5m8rPECIQDTpzn5X44r2rzWBDna/Sx7HW9IWCxNgUD2Eyi2nA7W\n" + 106 "ZQIgJerEorw4aCAuzQPxiGu57PB6GRamAihEAtoRTBQlH0ECIQDN08FgTtnesgCU\n" + 107 "DFYLLcw1CiHvc7fZw4neBDHCrC8NtQIgA8TOUkGnpCZlQ0KaI8KfKWI+vxFcgFnH\n" + 108 "3fnqsTgaUs4="; 109 110 static char passphrase[] = "passphrase".toCharArray(); 111 112 /* 113 * Turn on SSL debugging? 114 */ 115 static boolean debug = false; 116 117 @Override 118 protected SSLContext createClientSSLContext() throws Exception { 119 return generateSSLContext(trustedCertStr, null, null); 120 } 121 122 @Override 123 protected SSLContext createServerSSLContext() throws Exception { 124 return generateSSLContext(null, targetCertStr, targetPrivateKey); 125 } 126 127 @Override 128 protected void runServerApplication(SSLSocket socket) throws Exception { 129 try { 130 try (InputStream sslIS = socket.getInputStream()) { 131 sslIS.read(); 132 } 133 throw new Exception("RSA keys shorter than 1024 bits should be disabled"); 134 } catch (SSLHandshakeException sslhe) { 135 // the expected exception, ignore 136 } 137 138 } 139 140 @Override 141 protected void runClientApplication(SSLSocket socket) throws Exception { 142 143 try { 144 145 // only enable the target protocol 146 socket.setEnabledProtocols(new String[] { enabledProtocol }); 147 // enable a block cipher 148 socket.setEnabledCipherSuites( 149 new String[] { "TLS_DHE_RSA_WITH_AES_128_CBC_SHA" }); 150 151 try (OutputStream sslOS = socket.getOutputStream()) { 152 sslOS.write('B'); 153 sslOS.flush(); 154 } 155 throw new Exception( 156 "RSA keys shorter than 1024 bits should be disabled"); 157 } catch (SSLHandshakeException sslhe) { 158 // the expected exception, ignore 159 } 160 } 161 162 /* 163 * ============================================================= 164 * The remainder is just support stuff 165 */ 166 private static String tmAlgorithm; // trust manager 167 private static String enabledProtocol; // the target protocol 168 169 private static void parseArguments(String[] args) { 170 tmAlgorithm = args[0]; 171 enabledProtocol = args[1]; 172 } 173 174 private static SSLContext generateSSLContext(String trustedCertStr, 175 String keyCertStr, String keySpecStr) throws Exception { 176 177 // generate certificate from cert string 178 CertificateFactory cf = CertificateFactory.getInstance("X.509"); 179 180 // create a key store 181 KeyStore ks = KeyStore.getInstance("JKS"); 182 ks.load(null, null); 183 184 // import the trused cert 185 Certificate trusedCert = null; 186 ByteArrayInputStream is = null; 187 if (trustedCertStr != null) { 188 is = new ByteArrayInputStream(trustedCertStr.getBytes()); 189 trusedCert = cf.generateCertificate(is); 190 is.close(); 191 192 ks.setCertificateEntry("RSA Export Signer", trusedCert); 193 } 194 195 if (keyCertStr != null) { 196 // generate the private key. 197 PKCS8EncodedKeySpec priKeySpec = new PKCS8EncodedKeySpec( 198 Base64.getMimeDecoder().decode(keySpecStr)); 199 KeyFactory kf = KeyFactory.getInstance("RSA"); 200 RSAPrivateKey priKey = 201 (RSAPrivateKey)kf.generatePrivate(priKeySpec); 202 203 // generate certificate chain 204 is = new ByteArrayInputStream(keyCertStr.getBytes()); 205 Certificate keyCert = cf.generateCertificate(is); 206 is.close(); 207 208 Certificate[] chain = null; 209 if (trusedCert != null) { 210 chain = new Certificate[2]; 211 chain[0] = keyCert; 212 chain[1] = trusedCert; 213 } else { 214 chain = new Certificate[1]; 215 chain[0] = keyCert; 216 } 217 218 // import the key entry. 219 ks.setKeyEntry("Whatever", priKey, passphrase, chain); 220 } 221 222 // create SSL context 223 TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmAlgorithm); 224 tmf.init(ks); 225 226 SSLContext ctx = SSLContext.getInstance("TLS"); 227 if (keyCertStr != null && !keyCertStr.isEmpty()) { 228 KeyManagerFactory kmf = KeyManagerFactory.getInstance("NewSunX509"); 229 kmf.init(ks, passphrase); 230 231 ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null); 232 ks = null; 233 } else { 234 ctx.init(null, tmf.getTrustManagers(), null); 235 } 236 237 return ctx; 238 } 239 240 public static void main(String[] args) throws Exception { 241 if (debug) 242 System.setProperty("javax.net.debug", "all"); 243 244 /* 245 * Get the customized arguments. 246 */ 247 parseArguments(args); 248 249 /* 250 * Start the tests. 251 */ 252 new DisabledShortRSAKeys().run(); 253 } 254 255 }