1 /** 2 * Copyright (c) 2010, 2014, 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 under 6 * the terms of the GNU General Public License version 2 only, as published by 7 * the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT ANY 10 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR 11 * A PARTICULAR PURPOSE. See the GNU General Public License version 2 for more 12 * details (a copy is included in the LICENSE file that accompanied this code). 13 * 14 * You should have received a copy of the GNU General Public License version 2 15 * along with this work; if not, write to the Free Software Foundation, Inc., 51 16 * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 17 * 18 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA or 19 * visit www.oracle.com if you need additional information or have any 20 * questions. 21 */ 22 23 import java.io.ByteArrayInputStream; 24 import java.io.EOFException; 25 import java.io.File; 26 import java.io.FileInputStream; 27 import java.io.FileNotFoundException; 28 import java.io.IOException; 29 import java.io.InputStream; 30 import java.io.OutputStream; 31 import java.net.Socket; 32 import java.security.KeyFactory; 33 import java.security.KeyStore; 34 import java.security.KeyStoreException; 35 import java.security.NoSuchAlgorithmException; 36 import java.security.Principal; 37 import java.security.PrivateKey; 38 import java.security.SecureRandom; 39 import java.security.UnrecoverableKeyException; 40 import java.security.cert.Certificate; 41 import java.security.cert.CertificateException; 42 import java.security.cert.CertificateFactory; 43 import java.security.cert.X509Certificate; 44 import java.security.interfaces.RSAPrivateKey; 45 import java.security.spec.InvalidKeySpecException; 46 import java.security.spec.PKCS8EncodedKeySpec; 47 import java.util.ArrayList; 48 import java.util.Arrays; 49 import java.util.Base64; 50 import java.util.List; 51 import javax.net.ssl.KeyManagerFactory; 52 import javax.net.ssl.SSLEngine; 53 import javax.net.ssl.SSLServerSocket; 54 import javax.net.ssl.SSLSocket; 55 import javax.net.ssl.SSLSocketFactory; 56 import javax.net.ssl.TrustManager; 57 import javax.net.ssl.TrustManagerFactory; 58 import javax.net.ssl.X509ExtendedKeyManager; 59 import javax.net.ssl.X509TrustManager; 60 61 /** 62 * Test that all ciphersuites work in all versions and all client authentication 63 * types. The way this is setup the server is stateless and all checking is done 64 * on the client side. 65 */ 66 67 public class CipherTestUtils { 68 69 public static final int TIMEOUT = 20 * 1000; 70 public static final SecureRandom secureRandom = new SecureRandom(); 71 public static char[] PASSWORD = "passphrase".toCharArray(); 72 private static final List<TestParameters> TESTS = new ArrayList<>(3); 73 private static final List<Exception> EXCEPTIONS = new ArrayList<>(1); 74 private static final String CLIENT_PUBLIC_KEY 75 = "-----BEGIN CERTIFICATE-----\n" 76 + "MIICtTCCAh4CCQDkYJ46DMcGRjANBgkqhkiG9w0BAQUFADCBnDELMAkGA1UEBhMC\n" 77 + "VVMxCzAJBgNVBAgMAkNBMRYwFAYDVQQHDA1Nb3VudGFpbiBWaWV3MR8wHQYDVQQK\n" 78 + "DBZTdW4gTWljcm9zeXN0ZW1zLCBJbmMuMSYwJAYDVQQLDB1TdW4gTWljcm9zeXN0\n" 79 + "ZW1zIExhYm9yYXRvcmllczEfMB0GA1UEAwwWVGVzdCBDQSAoMTAyNCBiaXQgUlNB\n" 80 + "KTAeFw0wOTA0MjcwNDA0MDhaFw0xMzA2MDUwNDA0MDhaMIGgMQswCQYDVQQGEwJV\n" 81 + "UzELMAkGA1UECAwCQ0ExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxHzAdBgNVBAoM\n" 82 + "FlN1biBNaWNyb3N5c3RlbXMsIEluYy4xJjAkBgNVBAsMHVN1biBNaWNyb3N5c3Rl\n" 83 + "bXMgTGFib3JhdG9yaWVzMSMwIQYDVQQDDBpUZXN0IENsaWVudCAoMTAyNCBiaXQg\n" 84 + "UlNBKTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAm5rwjmhO7Nwd5GWs+KvQ\n" 85 + "UnDiqpRDvRriOUFdF0rCI2Op24C+iwUMDGxPsgP7VkUpOdJhw3c72aP0CAWcZ5dN\n" 86 + "UCW7WVDAxnogCahLCir1jjoGdEjiNGOy0L9sypsM9UvBzJN8uvXsxsTZX4Z88cKU\n" 87 + "G7RUvN8LQ88zDljk5zr3c2MCAwEAATANBgkqhkiG9w0BAQUFAAOBgQA7LUDrzHln\n" 88 + "EXuGmwZeeroACB6DVtkClMskF/Pj5GnTxoeNN9DggycX/eOeIDKRloHuMpBeZPJH\n" 89 + "NUwFu4LB6HBDeldQD9iRp8zD/fPakOdN+1Gk5hciIZZJ5hQmeCl7Va2Gr64vUqZG\n" 90 + "MkVU755t+7ByLgzWuhPhhsX9QCuPR5FjvQ==\n" 91 + "-----END CERTIFICATE-----"; 92 93 private static final String CLIENT_PRIVATE_KEY 94 = "-----BEGIN PRIVATE KEY-----\n" 95 + "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAJua8I5oTuzcHeRl\n" 96 + "rPir0FJw4qqUQ70a4jlBXRdKwiNjqduAvosFDAxsT7ID+1ZFKTnSYcN3O9mj9AgF\n" 97 + "nGeXTVAlu1lQwMZ6IAmoSwoq9Y46BnRI4jRjstC/bMqbDPVLwcyTfLr17MbE2V+G\n" 98 + "fPHClBu0VLzfC0PPMw5Y5Oc693NjAgMBAAECgYA5w73zj8Nk6J3sMNaShe3S/PcY\n" 99 + "TewLopRCnwI46FbDnnbq9pNFtnzvi7HWKuY983THc1M5peTA+b1Y0QRr7F4Vg4x9\n" 100 + "9UM0B/tZcIIcJJ3LS+9fXKCbYLQWq5F05JqeZu+i+QLmJFO5+2p7laeQ4oQfW7QE\n" 101 + "YR4u2mSaLe0SsqHvOQJBAMhgcye9C6pJO0eo2/VtRxAXI7zxNAIjHwKo1cva7bhu\n" 102 + "GdrMaEAJBAsMJ1GEk7/WDI+3KEbTjQdfIJuAvOR4FXUCQQDGzNn/tl2k93v/ugyM\n" 103 + "/tBhCKDipYDIbyJMoG2AOtOGmCsiGo5L7idO4OAcm/QiHBQMXjFIVgTUcH8MhGj4\n" 104 + "blJ3AkA5fUqsxRV6tuYWKkFpif/QgwMS65VDY7Y6+hvVECwSNSyf1PO4I54QWV1S\n" 105 + "ixok+RHDjgY1Q+77hXSCiQ4o8rcdAkBHvjfR+5sx5IpgUGElJPRIgFenU3j1XH3x\n" 106 + "T1gVFaWuhg3S4eiGaGzRH4BhcrqY8K8fg4Kfi0N08yA2gTZsqUujAkEAjuNPTuKx\n" 107 + "ti0LXI09kbGUqOpRMm1zW5TD6LFeEaUN6oxrSZI2YUvu7VyotAqsxX5O0u0f3VQw\n" 108 + "ySF0Q1oZ6qu7cg==\n" 109 + "-----END PRIVATE KEY-----"; 110 private static final String SERVER_PUBLIC_KEY 111 = "-----BEGIN CERTIFICATE-----\n" 112 + "MIICtTCCAh4CCQDkYJ46DMcGRTANBgkqhkiG9w0BAQUFADCBnDELMAkGA1UEBhMC\n" 113 + "VVMxCzAJBgNVBAgMAkNBMRYwFAYDVQQHDA1Nb3VudGFpbiBWaWV3MR8wHQYDVQQK\n" 114 + "DBZTdW4gTWljcm9zeXN0ZW1zLCBJbmMuMSYwJAYDVQQLDB1TdW4gTWljcm9zeXN0\n" 115 + "ZW1zIExhYm9yYXRvcmllczEfMB0GA1UEAwwWVGVzdCBDQSAoMTAyNCBiaXQgUlNB\n" 116 + "KTAeFw0wOTA0MjcwNDA0MDhaFw0xMzA2MDUwNDA0MDhaMIGgMQswCQYDVQQGEwJV\n" 117 + "UzELMAkGA1UECAwCQ0ExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxHzAdBgNVBAoM\n" 118 + "FlN1biBNaWNyb3N5c3RlbXMsIEluYy4xJjAkBgNVBAsMHVN1biBNaWNyb3N5c3Rl\n" 119 + "bXMgTGFib3JhdG9yaWVzMSMwIQYDVQQDDBpUZXN0IFNlcnZlciAoMTAyNCBiaXQg\n" 120 + "UlNBKTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEArsHHeZ1O67yuxQKDSAOC\n" 121 + "Xm271ViwBrXkxe5cvhG8MCCem6Z3XeZ/m6c2ucRwLaQxnmG1m0G6/OYaUXTivjcG\n" 122 + "/K4bc1I+yjghAWQNLBtsOiP9w0LKibg3TSDehpeuuz/lmB5A4HMqQr8KkY4K7peD\n" 123 + "1QkJ2Dn3zhbwQ/0d8f5CCbkCAwEAATANBgkqhkiG9w0BAQUFAAOBgQBOd8XojEnu\n" 124 + "eTUHBwqfmnvRQvbICFDNbbL4KuX/JNPSy1WMGAEbNCTLZ+5yP69js8aUYqAk5vVf\n" 125 + "dWRLU3MDiEzW7zxE1ubuKWjVuyGbG8Me0G01Hw+evBcZqB64Fz3OFISVfQh7MqE/\n" 126 + "O0AeakRMH350FRLNl4o6KBSXmF/AADfqQQ==\n" 127 + "-----END CERTIFICATE-----"; 128 129 private static final String SERVER_PRIVATE_KEY 130 = "-----BEGIN PRIVATE KEY-----\n" 131 + "MIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBAK7Bx3mdTuu8rsUC\n" 132 + "g0gDgl5tu9VYsAa15MXuXL4RvDAgnpumd13mf5unNrnEcC2kMZ5htZtBuvzmGlF0\n" 133 + "4r43BvyuG3NSPso4IQFkDSwbbDoj/cNCyom4N00g3oaXrrs/5ZgeQOBzKkK/CpGO\n" 134 + "Cu6Xg9UJCdg5984W8EP9HfH+Qgm5AgMBAAECgYAXUv+3qJo+9mjxHHu/IdDFn6nB\n" 135 + "ONwNmTtWe5DfQWi3l7LznU0zOC9x6+hu9NvwC4kf1XSyqxw04tVCZ/JXZurEmEBz\n" 136 + "YtcQ5idRQDkKYXEDOeVUfvtHO6xilzrhPKxxd0GG/sei2pozikkqnYF3OcP0qL+a\n" 137 + "3nWixZQBRoF2nIRLcQJBAN97TJBr0XTRmE7OCKLUy1+ws7vZB9uQ2efHMsgwOpsY\n" 138 + "3cEW5qd95hrxLU72sBeu9loHQgBrT2Q3OAxnsPXmgO0CQQDIL3u9kS/O3Ukx+n1H\n" 139 + "JdPFQCRxrDm/vtJpQEmq+mLqxxnxCFRIYQ2ieAPokBxWeMDtdWJGD3VxhahjPfZm\n" 140 + "5K59AkEAuDVl0tVMfUIWjT5/F9jXGjUIsZofQ/iN5OLpFOHMLPO+Nd6umPjJpwON\n" 141 + "GT11wM/S+DprSPUrJ6vsYy1FTCuHsQJBAMXtnO07xgdE6AAQaRmVnyMiXmY+IQMj\n" 142 + "CyuhsrToyDDWFyIoWB0QSMjg3QxuoHYnAqpGK5qV4ksSGgG13BCz/okCQQCRHTgn\n" 143 + "DuFG2f7GYLFjI4NaTEzHGp+J9LiNYY1kYYLonpwAC3Z5hzJVanYT3/g23AUZ/fdF\n" 144 + "v5PDIViuPo5ZB1eD\n" 145 + "-----END PRIVATE KEY-----"; 146 147 private static final String CA_PUBLIC_KEY 148 = "-----BEGIN CERTIFICATE-----\n" 149 + "MIIDCDCCAnGgAwIBAgIJAIYlGfwNBY6NMA0GCSqGSIb3DQEBBQUAMIGcMQswCQYD\n" 150 + "VQQGEwJVUzELMAkGA1UECAwCQ0ExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxHzAd\n" 151 + "BgNVBAoMFlN1biBNaWNyb3N5c3RlbXMsIEluYy4xJjAkBgNVBAsMHVN1biBNaWNy\n" 152 + "b3N5c3RlbXMgTGFib3JhdG9yaWVzMR8wHQYDVQQDDBZUZXN0IENBICgxMDI0IGJp\n" 153 + "dCBSU0EpMB4XDTA5MDQyNzA0MDQwOFoXDTEzMDYwNTA0MDQwOFowgZwxCzAJBgNV\n" 154 + "BAYTAlVTMQswCQYDVQQIDAJDQTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzEfMB0G\n" 155 + "A1UECgwWU3VuIE1pY3Jvc3lzdGVtcywgSW5jLjEmMCQGA1UECwwdU3VuIE1pY3Jv\n" 156 + "c3lzdGVtcyBMYWJvcmF0b3JpZXMxHzAdBgNVBAMMFlRlc3QgQ0EgKDEwMjQgYml0\n" 157 + "IFJTQSkwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAOK4DJxxb0XX6MJ1CVjp\n" 158 + "9Gmr/Ua8MS12R58F9lDpSKuq8cFexA4W7OdZ4jtbKv0tRHX5YxmbnXedwS+gdcOA\n" 159 + "GRgXMoeXlgTFGpdL+TR8xKIlMGRSjnR7MpR2tRyIYI2p+UTEiD6LTlIm5Wh4z1q8\n" 160 + "LYbxyMVD1XNNNymvPM44OjsBAgMBAAGjUDBOMB0GA1UdDgQWBBT27BLUflmfdtbi\n" 161 + "WTgjwWnoxop2MTAfBgNVHSMEGDAWgBT27BLUflmfdtbiWTgjwWnoxop2MTAMBgNV\n" 162 + "HRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4GBAEQELNzhZpjnSgigd+QJ6I/3CPDo\n" 163 + "SDkMLdP1BHlT/DkMIZvABm+M09ePNlWiLYCNCsL9nWmX0gw0rFDKsTklZyKTUzaM\n" 164 + "oy/AZCrAaoIc6SO5m1xE1RMyVxd/Y/kg6cbfWxxCJFlMeU5rsSdC97HTE/lDyuoh\n" 165 + "BmlOBB7SdR+1ScjA\n" 166 + "-----END CERTIFICATE-----"; 167 168 private static final String CA_PRIVATE_KEY 169 = "-----BEGIN PRIVATE KEY-----\n" 170 + "MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAOK4DJxxb0XX6MJ1\n" 171 + "CVjp9Gmr/Ua8MS12R58F9lDpSKuq8cFexA4W7OdZ4jtbKv0tRHX5YxmbnXedwS+g\n" 172 + "dcOAGRgXMoeXlgTFGpdL+TR8xKIlMGRSjnR7MpR2tRyIYI2p+UTEiD6LTlIm5Wh4\n" 173 + "z1q8LYbxyMVD1XNNNymvPM44OjsBAgMBAAECgYEApmMOlk3FrQtsvjGof4GLp3Xa\n" 174 + "tmvs54FzxKhagj0C4UHelNyYpAJ9MLjNiGQ7I31yTeaNrUCAi0XSfsKTSrwbLSnJ\n" 175 + "qsUPKMBrnzcWrOyui2+cupHZXaTlNeYB97teLJYpa6Ql9CZLoTHoim1+//s7diBh\n" 176 + "03Vls+M6Poi5PMvv59UCQQD+k/BiokmbBgWHfBY5cZSlx3Z4VTwSHJmHDTO3Tjso\n" 177 + "EVErXUSVvqD/KHX6eM4VPM8lySV5djWV8lDsESCWMtiLAkEA4/xFNsiOLMQpxW/O\n" 178 + "bt2tukxJkAxldD4lPoFZR+zbXtMtt8OjERtX2wD+nj6h7jfIeSyVuBEcBN8Uj8xe\n" 179 + "kgfgIwJAPbKG4LCqHAsCjgpRrIxNVTwZByLJEy6hOqzFathn19cSj+rjs1Lm28/n\n" 180 + "f9OFRnpdTbAJB/3REM0QNZYVCrG57wJBAN0KuTytZJNouaswhPCew5Kt5mDgc/kp\n" 181 + "S8j3dk2zCto8W8Ygy1iJrzuqEjPxO+UQdrFtlde51vWuKGxnVIW3VwsCQEldqk7r\n" 182 + "8y7PgquPP+k3L0OXno5wGBrPcW1+U0mhIZGnwSzE4SPX2ddqUSEUA/Av4RjAckL/\n" 183 + "fpqmCkpTanyYW9U=\n" 184 + "-----END PRIVATE KEY-----"; 185 186 private final SSLSocketFactory factory; 187 private final X509ExtendedKeyManager clientKeyManager; 188 private final X509ExtendedKeyManager serverKeyManager; 189 private final X509TrustManager clientTrustManager; 190 private final X509TrustManager serverTrustManager; 191 192 static abstract class Server implements Runnable { 193 194 final CipherTestUtils cipherTest; 195 196 Server(CipherTestUtils cipherTest) throws Exception { 197 this.cipherTest = cipherTest; 198 } 199 200 @Override 201 public abstract void run(); 202 203 void handleRequest(InputStream in, OutputStream out) 204 throws IOException { 205 boolean newline = false; 206 StringBuilder sb = new StringBuilder(); 207 while (true) { 208 int ch = in.read(); 209 if (ch < 0) { 210 throw new EOFException(); 211 } 212 sb.append((char) ch); 213 if (ch == '\r') { 214 // empty 215 } else if (ch == '\n') { 216 if (newline) { 217 // 2nd newline in a row, end of request 218 break; 219 } 220 newline = true; 221 } else { 222 newline = false; 223 } 224 } 225 String request = sb.toString(); 226 if (request.startsWith("GET / HTTP/1.") == false) { 227 throw new IOException("Invalid request: " + request); 228 } 229 out.write("HTTP/1.0 200 OK\r\n\r\n".getBytes()); 230 out.write("Tested Scenario: ".getBytes()); 231 TestParameters tp = (TestParameters) CipherTestUtils.TESTS.get(0); 232 out.write(tp.toString().getBytes()); 233 out.write(" Test PASSED.".getBytes()); 234 } 235 } 236 237 public static class TestParameters { 238 239 String cipherSuite; 240 String protocol; 241 String clientAuth; 242 243 TestParameters(String cipherSuite, String protocol, 244 String clientAuth) { 245 this.cipherSuite = cipherSuite; 246 this.protocol = protocol; 247 this.clientAuth = clientAuth; 248 } 249 250 boolean isEnabled() { 251 return true; 252 } 253 254 @Override 255 public String toString() { 256 String s = cipherSuite + " in " + protocol + " mode"; 257 if (clientAuth != null) { 258 s += " with " + clientAuth + " client authentication"; 259 } 260 return s; 261 } 262 } 263 264 private static volatile CipherTestUtils instance = null; 265 266 public static CipherTestUtils getInstance() throws IOException, 267 FileNotFoundException, KeyStoreException, 268 NoSuchAlgorithmException, CertificateException, 269 UnrecoverableKeyException, InvalidKeySpecException { 270 if (instance == null) { 271 synchronized (CipherTestUtils.class) { 272 if (instance == null) { 273 instance = new CipherTestUtils(); 274 } 275 } 276 } 277 return instance; 278 } 279 280 public static void setTestedArguments(String testedProtocol, 281 String testedCipherSuite) { 282 283 TestParameters testedParams; 284 285 String cipherSuite = testedCipherSuite.trim(); 286 if (cipherSuite.startsWith("SSL_")) { 287 testedParams = 288 new TestParameters(cipherSuite, testedProtocol, null); 289 TESTS.add(testedParams); 290 291 } else { 292 System.out.println("Your input Cipher suites is not correct, " 293 + "please try another one ."); 294 } 295 } 296 297 public X509ExtendedKeyManager getClientKeyManager() { 298 return clientKeyManager; 299 } 300 301 public X509TrustManager getClientTrustManager() { 302 return clientTrustManager; 303 } 304 305 public X509ExtendedKeyManager getServerKeyManager() { 306 return serverKeyManager; 307 } 308 309 public X509TrustManager getServerTrustManager() { 310 return serverTrustManager; 311 } 312 313 public static void addFailure(Exception e) { 314 EXCEPTIONS.add(e); 315 } 316 317 private CipherTestUtils() 318 throws IOException, FileNotFoundException, KeyStoreException, 319 NoSuchAlgorithmException, CertificateException, 320 UnrecoverableKeyException, InvalidKeySpecException { 321 factory = (SSLSocketFactory) SSLSocketFactory.getDefault(); 322 KeyStore serverKeyStore = createServerKeyStore(SERVER_PUBLIC_KEY, 323 SERVER_PRIVATE_KEY); 324 KeyStore serverTrustStore = createServerKeyStore(CA_PUBLIC_KEY, 325 CA_PRIVATE_KEY); 326 327 if (serverKeyStore != null) { 328 KeyManagerFactory keyFactory1 329 = KeyManagerFactory.getInstance( 330 KeyManagerFactory.getDefaultAlgorithm()); 331 keyFactory1.init(serverKeyStore, PASSWORD); 332 serverKeyManager = (X509ExtendedKeyManager) keyFactory1. 333 getKeyManagers()[0]; 334 } else { 335 serverKeyManager = null; 336 } 337 serverTrustManager = serverTrustStore != null 338 ? new AlwaysTrustManager(serverTrustStore) : null; 339 340 KeyStore clientKeyStore, clientTrustStore; 341 clientTrustStore = serverTrustStore; 342 clientKeyStore = 343 createServerKeyStore(CLIENT_PUBLIC_KEY,CLIENT_PRIVATE_KEY); 344 if (clientKeyStore != null) { 345 KeyManagerFactory keyFactory 346 = KeyManagerFactory.getInstance( 347 KeyManagerFactory.getDefaultAlgorithm()); 348 keyFactory.init(clientKeyStore, PASSWORD); 349 clientKeyManager = (X509ExtendedKeyManager) keyFactory. 350 getKeyManagers()[0]; 351 } else { 352 clientKeyManager = null; 353 } 354 clientTrustManager = (clientTrustStore != null) 355 ? new AlwaysTrustManager(clientTrustStore) : null; 356 } 357 358 void checkResult(String exception) throws Exception { 359 if (EXCEPTIONS.size() >= 1) { 360 Exception actualException = EXCEPTIONS.get(0); 361 if (exception == null) { 362 throw new RuntimeException("FAILED: got unexpected exception: " 363 + actualException); 364 } 365 if (!exception.equals(actualException.getClass().getName())) { 366 throw new RuntimeException("FAILED: got unexpected exception: " 367 + actualException); 368 } 369 370 System.out.println("PASSED: got expected exception: " 371 + actualException); 372 } else { 373 if (exception != null) { 374 throw new RuntimeException("FAILED: " + exception 375 + " was expected"); 376 } 377 System.out.println("PASSED"); 378 } 379 } 380 381 SSLSocketFactory getFactory() { 382 return factory; 383 } 384 385 static abstract class Client implements Runnable { 386 387 final CipherTestUtils cipherTest; 388 TestParameters testedParams; 389 390 Client(CipherTestUtils cipherTest) throws Exception { 391 this.cipherTest = cipherTest; 392 } 393 394 Client(CipherTestUtils cipherTest, 395 String testedCipherSuite) throws Exception { 396 this.cipherTest = cipherTest; 397 } 398 399 @Override 400 public final void run() { 401 402 TESTS.stream().map((params) -> { 403 if (!params.isEnabled()) { 404 System.out.println("Skipping disabled test " + params); 405 } 406 return params; 407 }).forEach((params) -> { 408 try { 409 runTest(params); 410 System.out.println("Passed " + params); 411 } catch (Exception e) { 412 CipherTestUtils.addFailure(e); 413 System.out.println("** Failed " + params 414 + "**, got exception:"); 415 e.printStackTrace(System.err); 416 } 417 }); 418 } 419 420 abstract void runTest(TestParameters params) throws Exception; 421 422 void sendRequest(InputStream in, OutputStream out) throws IOException { 423 out.write("GET / HTTP/1.0\r\n\r\n".getBytes()); 424 out.flush(); 425 StringBuilder sb = new StringBuilder(); 426 while (true) { 427 int ch = in.read(); 428 if (ch < 0) { 429 break; 430 } 431 sb.append((char) ch); 432 } 433 String response = sb.toString(); 434 if (response.startsWith("HTTP/1.0 200 ") == false) { 435 throw new IOException("Invalid response: " + response); 436 } else { 437 System.out.println(); 438 System.out.println("--- Response --- "); 439 System.out.println(response); 440 System.out.println("---------------- "); 441 } 442 } 443 } 444 445 public static void printStringArray(String[] stringArray) { 446 System.out.print(stringArray.length + " : "); 447 for (String stringArray1 : stringArray) { 448 System.out.print(stringArray1); 449 System.out.print(","); 450 } 451 System.out.println(); 452 } 453 454 public static void printInfo(SSLServerSocket socket) { 455 System.out.println(); 456 System.out.println("--- SSL ServerSocket Info ---"); 457 System.out.print("SupportedProtocols : "); 458 printStringArray(socket.getSupportedProtocols()); 459 System.out.print("SupportedCipherSuites : "); 460 printStringArray(socket.getSupportedCipherSuites()); 461 System.out.print("EnabledProtocols : "); 462 printStringArray(socket.getEnabledProtocols()); 463 System.out.print("EnabledCipherSuites : "); 464 String[] supportedCipherSuites = socket.getEnabledCipherSuites(); 465 Arrays.sort(supportedCipherSuites); 466 printStringArray(supportedCipherSuites); 467 System.out.println("NeedClientAuth : " 468 + socket.getNeedClientAuth()); 469 System.out.println("WantClientAuth : " 470 + socket.getWantClientAuth()); 471 System.out.println("-----------------------"); 472 } 473 474 public static void printInfo(SSLSocket socket) { 475 System.out.println(); 476 System.out.println("--- SSL Socket Info ---"); 477 System.out.print(" SupportedProtocols : "); 478 printStringArray(socket.getSupportedProtocols()); 479 System.out.println(" EnabledProtocols : " 480 + socket.getEnabledProtocols()[0]); 481 System.out.print(" SupportedCipherSuites : "); 482 String[] supportedCipherSuites = socket.getEnabledCipherSuites(); 483 Arrays.sort(supportedCipherSuites); 484 printStringArray(supportedCipherSuites); 485 System.out.println(" EnabledCipherSuites : " 486 + socket.getEnabledCipherSuites()[0]); 487 System.out.println(" NeedClientAuth : " 488 + socket.getNeedClientAuth()); 489 System.out.println(" WantClientAuth : " 490 + socket.getWantClientAuth()); 491 System.out.println("-----------------------"); 492 } 493 494 private static KeyStore createServerKeyStore(String publicKeyStr, 495 String keySpecStr) throws KeyStoreException, IOException, 496 NoSuchAlgorithmException, CertificateException, 497 InvalidKeySpecException { 498 499 KeyStore ks = KeyStore.getInstance("JKS"); 500 ks.load(null, null); 501 if (publicKeyStr == null || keySpecStr == null) { 502 throw new IllegalArgumentException("publicKeyStr or " 503 + "keySpecStr cannot be null"); 504 } 505 String strippedPrivateKey = keySpecStr.substring( 506 keySpecStr.indexOf("\n"), keySpecStr.lastIndexOf("\n")); 507 508 // generate the private key. 509 PKCS8EncodedKeySpec priKeySpec = new PKCS8EncodedKeySpec( 510 Base64.getMimeDecoder().decode(strippedPrivateKey)); 511 KeyFactory kf = KeyFactory.getInstance("RSA"); 512 RSAPrivateKey priKey 513 = (RSAPrivateKey) kf.generatePrivate(priKeySpec); 514 515 // generate certificate chain 516 try (InputStream is = 517 new ByteArrayInputStream(publicKeyStr.getBytes())) { 518 // generate certificate from cert string 519 CertificateFactory cf = CertificateFactory.getInstance("X.509"); 520 Certificate keyCert = cf.generateCertificate(is); 521 Certificate[] chain = {keyCert}; 522 ks.setKeyEntry("TestEntry", priKey, PASSWORD, chain); 523 } 524 525 return ks; 526 } 527 528 public static void main(PeerFactory peerFactory, String mode, 529 String expectedException) 530 throws Exception { 531 long time = System.currentTimeMillis(); 532 setTestedArguments(peerFactory.getTestedProtocol(), 533 peerFactory.getTestedCipher()); 534 535 System.out.print( 536 " Initializing test '" + peerFactory.getName() + "'..."); 537 secureRandom.nextInt(); 538 539 CipherTestUtils cipherTest = CipherTestUtils.getInstance(); 540 if (mode.equalsIgnoreCase("Server")) { // server mode 541 Thread serverThread = new Thread(peerFactory.newServer(cipherTest), 542 "Server"); 543 serverThread.start(); 544 } else if (mode.equalsIgnoreCase("Client")) { 545 peerFactory.newClient(cipherTest).run(); 546 cipherTest.checkResult(expectedException); 547 JSSEServer.closeServer = true; 548 } else { 549 throw new RuntimeException("unsupported mode"); 550 } 551 time = System.currentTimeMillis() - time; 552 System.out.println("Elapsed time " + time); 553 554 } 555 556 public static abstract class PeerFactory { 557 558 abstract String getName(); 559 560 abstract String getTestedProtocol(); 561 562 abstract String getTestedCipher(); 563 564 abstract Client newClient(CipherTestUtils cipherTest) throws Exception; 565 566 abstract Server newServer(CipherTestUtils cipherTest) throws Exception; 567 568 boolean isSupported(String cipherSuite) { 569 return true; 570 } 571 } 572 } 573 574 class AlwaysTrustManager implements X509TrustManager { 575 576 X509TrustManager trustManager; 577 578 public AlwaysTrustManager(KeyStore keyStore) 579 throws NoSuchAlgorithmException, KeyStoreException { 580 581 TrustManagerFactory tmf 582 = TrustManagerFactory.getInstance(TrustManagerFactory. 583 getDefaultAlgorithm()); 584 tmf.init(keyStore); 585 586 TrustManager tms[] = tmf.getTrustManagers(); 587 for (TrustManager tm : tms) { 588 trustManager = (X509TrustManager) tm; 589 return; 590 } 591 592 } 593 594 @Override 595 public void checkClientTrusted(X509Certificate[] chain, String authType) 596 throws CertificateException { 597 try { 598 trustManager.checkClientTrusted(chain, authType); 599 } catch (CertificateException excep) { 600 System.out.println("ERROR in client trust manager"); 601 } 602 } 603 604 @Override 605 public void checkServerTrusted(X509Certificate[] chain, String authType) 606 throws CertificateException { 607 try { 608 trustManager.checkServerTrusted(chain, authType); 609 } catch (CertificateException excep) { 610 System.out.println("ERROR in server Trust manger"); 611 } 612 } 613 614 @Override 615 public X509Certificate[] getAcceptedIssuers() { 616 return trustManager.getAcceptedIssuers(); 617 } 618 } 619 620 class MyX509KeyManager extends X509ExtendedKeyManager { 621 622 private final X509ExtendedKeyManager keyManager; 623 private String authType; 624 625 MyX509KeyManager(X509ExtendedKeyManager keyManager) { 626 this.keyManager = keyManager; 627 } 628 629 void setAuthType(String authType) { 630 this.authType = "ECDSA".equals(authType) ? "EC" : authType; 631 } 632 633 @Override 634 public String[] getClientAliases(String keyType, Principal[] issuers) { 635 if (authType == null) { 636 return null; 637 } 638 return keyManager.getClientAliases(authType, issuers); 639 } 640 641 @Override 642 public String chooseClientAlias(String[] keyType, Principal[] issuers, 643 Socket socket) { 644 if (authType == null) { 645 return null; 646 } 647 return keyManager.chooseClientAlias(new String[]{authType}, 648 issuers, socket); 649 } 650 651 @Override 652 public String chooseEngineClientAlias(String[] keyType, 653 Principal[] issuers, SSLEngine engine) { 654 if (authType == null) { 655 return null; 656 } 657 return keyManager.chooseEngineClientAlias(new String[]{authType}, 658 issuers, engine); 659 } 660 661 @Override 662 public String[] getServerAliases(String keyType, Principal[] issuers) { 663 throw new UnsupportedOperationException("Servers not supported"); 664 } 665 666 @Override 667 public String chooseServerAlias(String keyType, Principal[] issuers, 668 Socket socket) { 669 throw new UnsupportedOperationException("Servers not supported"); 670 } 671 672 @Override 673 public String chooseEngineServerAlias(String keyType, Principal[] issuers, 674 SSLEngine engine) { 675 throw new UnsupportedOperationException("Servers not supported"); 676 } 677 678 @Override 679 public X509Certificate[] getCertificateChain(String alias) { 680 return keyManager.getCertificateChain(alias); 681 } 682 683 @Override 684 public PrivateKey getPrivateKey(String alias) { 685 return keyManager.getPrivateKey(alias); 686 } 687 }