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