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 instnace = null;
265
266 public static CipherTestUtils getInstance() throws IOException,
267 FileNotFoundException, KeyStoreException,
268 NoSuchAlgorithmException, CertificateException,
269 UnrecoverableKeyException, InvalidKeySpecException {
270 if (instnace == null) {
271 synchronized (CipherTestUtils.class) {
272 if (instnace == null) {
273 instnace = new CipherTestUtils();
274 }
275 }
276 }
277 return instnace;
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 }