Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/test/javax/net/ssl/Stapling/SSLEngineWithStapling.java
38853 views
1
/*
2
* Copyright (c) 2015, 2018, 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.
8
*
9
* This code is distributed in the hope that it will be useful, but WITHOUT
10
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12
* version 2 for more details (a copy is included in the LICENSE file that
13
* accompanied this code).
14
*
15
* You should have received a copy of the GNU General Public License version
16
* 2 along with this work; if not, write to the Free Software Foundation,
17
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18
*
19
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20
* or visit www.oracle.com if you need additional information or have any
21
* questions.
22
*/
23
24
// SunJSSE does not support dynamic system properties, no way to re-use
25
// system properties in samevm/agentvm mode.
26
27
/*
28
* @test
29
* @bug 8046321 8153829
30
* @summary OCSP Stapling for TLS
31
* @library ../../../../java/security/testlibrary
32
* @build CertificateBuilder SimpleOCSPServer
33
* @run main/othervm -Djdk.tls.client.protocols="TLSv1.3,TLSv1.2,TLSv1.1,TLSv1,SSLv3" SSLEngineWithStapling
34
*/
35
36
/**
37
* A SSLEngine usage example which simplifies the presentation
38
* by removing the I/O and multi-threading concerns.
39
*
40
* The test creates two SSLEngines, simulating a client and server.
41
* The "transport" layer consists two byte buffers: think of them
42
* as directly connected pipes.
43
*
44
* Note, this is a *very* simple example: real code will be much more
45
* involved. For example, different threading and I/O models could be
46
* used, transport mechanisms could close unexpectedly, and so on.
47
*
48
* When this application runs, notice that several messages
49
* (wrap/unwrap) pass before any application data is consumed or
50
* produced. (For more information, please see the SSL/TLS
51
* specifications.) There may several steps for a successful handshake,
52
* so it's typical to see the following series of operations:
53
*
54
* client server message
55
* ====== ====== =======
56
* wrap() ... ClientHello
57
* ... unwrap() ClientHello
58
* ... wrap() ServerHello/Certificate
59
* unwrap() ... ServerHello/Certificate
60
* wrap() ... ClientKeyExchange
61
* wrap() ... ChangeCipherSpec
62
* wrap() ... Finished
63
* ... unwrap() ClientKeyExchange
64
* ... unwrap() ChangeCipherSpec
65
* ... unwrap() Finished
66
* ... wrap() ChangeCipherSpec
67
* ... wrap() Finished
68
* unwrap() ... ChangeCipherSpec
69
* unwrap() ... Finished
70
*/
71
72
import javax.net.ssl.*;
73
import javax.net.ssl.SSLEngineResult.*;
74
import java.io.*;
75
import java.math.BigInteger;
76
import java.security.*;
77
import java.nio.*;
78
import java.security.cert.CertPathValidatorException;
79
import java.security.cert.PKIXBuilderParameters;
80
import java.security.cert.X509Certificate;
81
import java.security.cert.X509CertSelector;
82
import java.util.ArrayList;
83
import java.util.Collections;
84
import java.util.Date;
85
import java.util.HashMap;
86
import java.util.List;
87
import java.util.Map;
88
import java.util.concurrent.TimeUnit;
89
90
import sun.security.testlibrary.SimpleOCSPServer;
91
import sun.security.testlibrary.CertificateBuilder;
92
93
public class SSLEngineWithStapling {
94
95
/*
96
* Enables logging of the SSLEngine operations.
97
*/
98
private static final boolean logging = true;
99
100
/*
101
* Enables the JSSE system debugging system property:
102
*
103
* -Djavax.net.debug=all
104
*
105
* This gives a lot of low-level information about operations underway,
106
* including specific handshake messages, and might be best examined
107
* after gaining some familiarity with this application.
108
*/
109
private static final boolean debug = true;
110
111
private SSLEngine clientEngine; // client Engine
112
private ByteBuffer clientOut; // write side of clientEngine
113
private ByteBuffer clientIn; // read side of clientEngine
114
115
private SSLEngine serverEngine; // server Engine
116
private ByteBuffer serverOut; // write side of serverEngine
117
private ByteBuffer serverIn; // read side of serverEngine
118
119
/*
120
* For data transport, this example uses local ByteBuffers. This
121
* isn't really useful, but the purpose of this example is to show
122
* SSLEngine concepts, not how to do network transport.
123
*/
124
private ByteBuffer cTOs; // "reliable" transport client->server
125
private ByteBuffer sTOc; // "reliable" transport server->client
126
127
/*
128
* The following is to set up the keystores.
129
*/
130
static final String passwd = "passphrase";
131
static final String ROOT_ALIAS = "root";
132
static final String INT_ALIAS = "intermediate";
133
static final String SSL_ALIAS = "ssl";
134
135
// PKI components we will need for this test
136
static KeyStore rootKeystore; // Root CA Keystore
137
static KeyStore intKeystore; // Intermediate CA Keystore
138
static KeyStore serverKeystore; // SSL Server Keystore
139
static KeyStore trustStore; // SSL Client trust store
140
static SimpleOCSPServer rootOcsp; // Root CA OCSP Responder
141
static int rootOcspPort; // Port number for root OCSP
142
static SimpleOCSPServer intOcsp; // Intermediate CA OCSP Responder
143
static int intOcspPort; // Port number for intermed. OCSP
144
145
// Extra configuration parameters and constants
146
static final String[] TLS13ONLY = new String[] { "TLSv1.3" };
147
static final String[] TLS12MAX =
148
new String[] { "TLSv1.2", "TLSv1.1", "TLSv1" };
149
150
/*
151
* Main entry point for this test.
152
*/
153
public static void main(String args[]) throws Exception {
154
if (debug) {
155
System.setProperty("javax.net.debug", "ssl:handshake");
156
}
157
158
// Create the PKI we will use for the test and start the OCSP servers
159
createPKI();
160
161
// Set the certificate entry in the intermediate OCSP responder
162
// with a revocation date of 8 hours ago.
163
X509Certificate sslCert =
164
(X509Certificate)serverKeystore.getCertificate(SSL_ALIAS);
165
Map<BigInteger, SimpleOCSPServer.CertStatusInfo> revInfo =
166
new HashMap<>();
167
revInfo.put(sslCert.getSerialNumber(),
168
new SimpleOCSPServer.CertStatusInfo(
169
SimpleOCSPServer.CertStatus.CERT_STATUS_REVOKED,
170
new Date(System.currentTimeMillis() -
171
TimeUnit.HOURS.toMillis(8))));
172
intOcsp.updateStatusDb(revInfo);
173
174
// Create a list of TLS protocol configurations we can use to
175
// drive tests with different handshaking models.
176
List<String[]> allowedProtList = new ArrayList();
177
allowedProtList.add(TLS12MAX);
178
allowedProtList.add(TLS13ONLY);
179
180
for (String[] protocols : allowedProtList) {
181
SSLEngineWithStapling test = new SSLEngineWithStapling();
182
try {
183
test.runTest(protocols);
184
throw new RuntimeException("Expected failure due to " +
185
"revocation did not occur");
186
} catch (Exception e) {
187
if (!checkClientValidationFailure(e,
188
CertPathValidatorException.BasicReason.REVOKED)) {
189
System.out.println(
190
"*** Didn't find the exception we wanted");
191
throw e;
192
}
193
}
194
}
195
196
System.out.println("Test Passed.");
197
}
198
199
/*
200
* Create an initialized SSLContext to use for these tests.
201
*/
202
public SSLEngineWithStapling() throws Exception {
203
System.setProperty("javax.net.ssl.keyStore", "");
204
System.setProperty("javax.net.ssl.keyStorePassword", "");
205
System.setProperty("javax.net.ssl.trustStore", "");
206
System.setProperty("javax.net.ssl.trustStorePassword", "");
207
208
// Enable OCSP Stapling on both client and server sides, but turn off
209
// client-side OCSP for revocation checking. This ensures that the
210
// revocation information from the test has to come via stapling.
211
System.setProperty("jdk.tls.client.enableStatusRequestExtension",
212
Boolean.toString(true));
213
System.setProperty("jdk.tls.server.enableStatusRequestExtension",
214
Boolean.toString(true));
215
Security.setProperty("ocsp.enable", "false");
216
}
217
218
/*
219
* Run the test.
220
*
221
* Sit in a tight loop, both engines calling wrap/unwrap regardless
222
* of whether data is available or not. We do this until both engines
223
* report back they are closed.
224
*
225
* The main loop handles all of the I/O phases of the SSLEngine's
226
* lifetime:
227
*
228
* initial handshaking
229
* application data transfer
230
* engine closing
231
*
232
* One could easily separate these phases into separate
233
* sections of code.
234
*/
235
private void runTest(String[] protocols) throws Exception {
236
boolean dataDone = false;
237
238
createSSLEngines(protocols);
239
createBuffers();
240
241
SSLEngineResult clientResult; // results from client's last operation
242
SSLEngineResult serverResult; // results from server's last operation
243
244
/*
245
* Examining the SSLEngineResults could be much more involved,
246
* and may alter the overall flow of the application.
247
*
248
* For example, if we received a BUFFER_OVERFLOW when trying
249
* to write to the output pipe, we could reallocate a larger
250
* pipe, but instead we wait for the peer to drain it.
251
*/
252
while (!isEngineClosed(clientEngine) ||
253
!isEngineClosed(serverEngine)) {
254
255
log("================");
256
257
clientResult = clientEngine.wrap(clientOut, cTOs);
258
log("client wrap: ", clientResult);
259
runDelegatedTasks(clientResult, clientEngine);
260
261
serverResult = serverEngine.wrap(serverOut, sTOc);
262
log("server wrap: ", serverResult);
263
runDelegatedTasks(serverResult, serverEngine);
264
265
cTOs.flip();
266
sTOc.flip();
267
268
log("----");
269
270
clientResult = clientEngine.unwrap(sTOc, clientIn);
271
log("client unwrap: ", clientResult);
272
runDelegatedTasks(clientResult, clientEngine);
273
274
serverResult = serverEngine.unwrap(cTOs, serverIn);
275
log("server unwrap: ", serverResult);
276
runDelegatedTasks(serverResult, serverEngine);
277
278
cTOs.compact();
279
sTOc.compact();
280
281
/*
282
* After we've transfered all application data between the client
283
* and server, we close the clientEngine's outbound stream.
284
* This generates a close_notify handshake message, which the
285
* server engine receives and responds by closing itself.
286
*/
287
if (!dataDone && (clientOut.limit() == serverIn.position()) &&
288
(serverOut.limit() == clientIn.position())) {
289
290
/*
291
* A sanity check to ensure we got what was sent.
292
*/
293
checkTransfer(serverOut, clientIn);
294
checkTransfer(clientOut, serverIn);
295
296
log("\tClosing clientEngine's *OUTBOUND*...");
297
clientEngine.closeOutbound();
298
dataDone = true;
299
}
300
}
301
}
302
303
/*
304
* Using the SSLContext created during object creation,
305
* create/configure the SSLEngines we'll use for this test.
306
*/
307
private void createSSLEngines(String[] protocols) throws Exception {
308
// Initialize the KeyManager and TrustManager for the server
309
KeyManagerFactory servKmf = KeyManagerFactory.getInstance("PKIX");
310
servKmf.init(serverKeystore, passwd.toCharArray());
311
TrustManagerFactory servTmf =
312
TrustManagerFactory.getInstance("PKIX");
313
servTmf.init(trustStore);
314
315
// Initialize the TrustManager for the client with revocation checking
316
PKIXBuilderParameters pkixParams = new PKIXBuilderParameters(trustStore,
317
new X509CertSelector());
318
pkixParams.setRevocationEnabled(true);
319
ManagerFactoryParameters mfp =
320
new CertPathTrustManagerParameters(pkixParams);
321
TrustManagerFactory cliTmf =
322
TrustManagerFactory.getInstance("PKIX");
323
cliTmf.init(mfp);
324
325
// Create the SSLContexts from the factories
326
SSLContext servCtx = SSLContext.getInstance("TLS");
327
servCtx.init(servKmf.getKeyManagers(), servTmf.getTrustManagers(),
328
null);
329
SSLContext cliCtx = SSLContext.getInstance("TLS");
330
cliCtx.init(null, cliTmf.getTrustManagers(), null);
331
332
333
/*
334
* Configure the serverEngine to act as a server in the SSL/TLS
335
* handshake.
336
*/
337
serverEngine = servCtx.createSSLEngine();
338
serverEngine.setEnabledProtocols(protocols);
339
serverEngine.setUseClientMode(false);
340
serverEngine.setNeedClientAuth(false);
341
342
/*
343
* Similar to above, but using client mode instead.
344
*/
345
clientEngine = cliCtx.createSSLEngine("client", 80);
346
clientEngine.setEnabledProtocols(protocols);
347
clientEngine.setUseClientMode(true);
348
}
349
350
/*
351
* Create and size the buffers appropriately.
352
*/
353
private void createBuffers() {
354
355
/*
356
* We'll assume the buffer sizes are the same
357
* between client and server.
358
*/
359
SSLSession session = clientEngine.getSession();
360
int appBufferMax = session.getApplicationBufferSize();
361
int netBufferMax = session.getPacketBufferSize();
362
363
/*
364
* We'll make the input buffers a bit bigger than the max needed
365
* size, so that unwrap()s following a successful data transfer
366
* won't generate BUFFER_OVERFLOWS.
367
*
368
* We'll use a mix of direct and indirect ByteBuffers for
369
* tutorial purposes only. In reality, only use direct
370
* ByteBuffers when they give a clear performance enhancement.
371
*/
372
clientIn = ByteBuffer.allocate(appBufferMax + 50);
373
serverIn = ByteBuffer.allocate(appBufferMax + 50);
374
375
cTOs = ByteBuffer.allocateDirect(netBufferMax);
376
sTOc = ByteBuffer.allocateDirect(netBufferMax);
377
378
clientOut = ByteBuffer.wrap("Hi Server, I'm Client".getBytes());
379
serverOut = ByteBuffer.wrap("Hello Client, I'm Server".getBytes());
380
}
381
382
/*
383
* If the result indicates that we have outstanding tasks to do,
384
* go ahead and run them in this thread.
385
*/
386
private static void runDelegatedTasks(SSLEngineResult result,
387
SSLEngine engine) throws Exception {
388
389
if (result.getHandshakeStatus() == HandshakeStatus.NEED_TASK) {
390
Runnable runnable;
391
while ((runnable = engine.getDelegatedTask()) != null) {
392
log("\trunning delegated task...");
393
runnable.run();
394
}
395
HandshakeStatus hsStatus = engine.getHandshakeStatus();
396
if (hsStatus == HandshakeStatus.NEED_TASK) {
397
throw new Exception(
398
"handshake shouldn't need additional tasks");
399
}
400
log("\tnew HandshakeStatus: " + hsStatus);
401
}
402
}
403
404
private static boolean isEngineClosed(SSLEngine engine) {
405
return (engine.isOutboundDone() && engine.isInboundDone());
406
}
407
408
/*
409
* Simple check to make sure everything came across as expected.
410
*/
411
private static void checkTransfer(ByteBuffer a, ByteBuffer b)
412
throws Exception {
413
a.flip();
414
b.flip();
415
416
if (!a.equals(b)) {
417
throw new Exception("Data didn't transfer cleanly");
418
} else {
419
log("\tData transferred cleanly");
420
}
421
422
a.position(a.limit());
423
b.position(b.limit());
424
a.limit(a.capacity());
425
b.limit(b.capacity());
426
}
427
428
/*
429
* Logging code
430
*/
431
private static boolean resultOnce = true;
432
433
private static void log(String str, SSLEngineResult result) {
434
if (!logging) {
435
return;
436
}
437
if (resultOnce) {
438
resultOnce = false;
439
System.out.println("The format of the SSLEngineResult is: \n" +
440
"\t\"getStatus() / getHandshakeStatus()\" +\n" +
441
"\t\"bytesConsumed() / bytesProduced()\"\n");
442
}
443
HandshakeStatus hsStatus = result.getHandshakeStatus();
444
log(str +
445
result.getStatus() + "/" + hsStatus + ", " +
446
result.bytesConsumed() + "/" + result.bytesProduced() +
447
" bytes");
448
if (hsStatus == HandshakeStatus.FINISHED) {
449
log("\t...ready for application data");
450
}
451
}
452
453
private static void log(String str) {
454
if (logging) {
455
System.out.println(str);
456
}
457
}
458
459
/**
460
* Creates the PKI components necessary for this test, including
461
* Root CA, Intermediate CA and SSL server certificates, the keystores
462
* for each entity, a client trust store, and starts the OCSP responders.
463
*/
464
private static void createPKI() throws Exception {
465
CertificateBuilder cbld = new CertificateBuilder();
466
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
467
keyGen.initialize(2048);
468
KeyStore.Builder keyStoreBuilder =
469
KeyStore.Builder.newInstance("PKCS12", null,
470
new KeyStore.PasswordProtection(passwd.toCharArray()));
471
472
// Generate Root, IntCA, EE keys
473
KeyPair rootCaKP = keyGen.genKeyPair();
474
log("Generated Root CA KeyPair");
475
KeyPair intCaKP = keyGen.genKeyPair();
476
log("Generated Intermediate CA KeyPair");
477
KeyPair sslKP = keyGen.genKeyPair();
478
log("Generated SSL Cert KeyPair");
479
480
// Set up the Root CA Cert
481
cbld.setSubjectName("CN=Root CA Cert, O=SomeCompany");
482
cbld.setPublicKey(rootCaKP.getPublic());
483
cbld.setSerialNumber(new BigInteger("1"));
484
// Make a 3 year validity starting from 60 days ago
485
long start = System.currentTimeMillis() - TimeUnit.DAYS.toMillis(60);
486
long end = start + TimeUnit.DAYS.toMillis(1085);
487
cbld.setValidity(new Date(start), new Date(end));
488
addCommonExts(cbld, rootCaKP.getPublic(), rootCaKP.getPublic());
489
addCommonCAExts(cbld);
490
// Make our Root CA Cert!
491
X509Certificate rootCert = cbld.build(null, rootCaKP.getPrivate(),
492
"SHA256withRSA");
493
log("Root CA Created:\n" + certInfo(rootCert));
494
495
// Now build a keystore and add the keys and cert
496
rootKeystore = keyStoreBuilder.getKeyStore();
497
java.security.cert.Certificate[] rootChain = {rootCert};
498
rootKeystore.setKeyEntry(ROOT_ALIAS, rootCaKP.getPrivate(),
499
passwd.toCharArray(), rootChain);
500
501
// Now fire up the OCSP responder
502
rootOcsp = new SimpleOCSPServer(rootKeystore, passwd, ROOT_ALIAS, null);
503
rootOcsp.enableLog(logging);
504
rootOcsp.setNextUpdateInterval(3600);
505
rootOcsp.start();
506
507
// Wait 5 seconds for server ready
508
for (int i = 0; (i < 100 && !rootOcsp.isServerReady()); i++) {
509
Thread.sleep(50);
510
}
511
if (!rootOcsp.isServerReady()) {
512
throw new RuntimeException("Server not ready yet");
513
}
514
515
rootOcspPort = rootOcsp.getPort();
516
String rootRespURI = "http://localhost:" + rootOcspPort;
517
log("Root OCSP Responder URI is " + rootRespURI);
518
519
// Now that we have the root keystore and OCSP responder we can
520
// create our intermediate CA.
521
cbld.reset();
522
cbld.setSubjectName("CN=Intermediate CA Cert, O=SomeCompany");
523
cbld.setPublicKey(intCaKP.getPublic());
524
cbld.setSerialNumber(new BigInteger("100"));
525
// Make a 2 year validity starting from 30 days ago
526
start = System.currentTimeMillis() - TimeUnit.DAYS.toMillis(30);
527
end = start + TimeUnit.DAYS.toMillis(730);
528
cbld.setValidity(new Date(start), new Date(end));
529
addCommonExts(cbld, intCaKP.getPublic(), rootCaKP.getPublic());
530
addCommonCAExts(cbld);
531
cbld.addAIAExt(Collections.singletonList(rootRespURI));
532
// Make our Intermediate CA Cert!
533
X509Certificate intCaCert = cbld.build(rootCert, rootCaKP.getPrivate(),
534
"SHA256withRSA");
535
log("Intermediate CA Created:\n" + certInfo(intCaCert));
536
537
// Provide intermediate CA cert revocation info to the Root CA
538
// OCSP responder.
539
Map<BigInteger, SimpleOCSPServer.CertStatusInfo> revInfo =
540
new HashMap<>();
541
revInfo.put(intCaCert.getSerialNumber(),
542
new SimpleOCSPServer.CertStatusInfo(
543
SimpleOCSPServer.CertStatus.CERT_STATUS_GOOD));
544
rootOcsp.updateStatusDb(revInfo);
545
546
// Now build a keystore and add the keys, chain and root cert as a TA
547
intKeystore = keyStoreBuilder.getKeyStore();
548
java.security.cert.Certificate[] intChain = {intCaCert, rootCert};
549
intKeystore.setKeyEntry(INT_ALIAS, intCaKP.getPrivate(),
550
passwd.toCharArray(), intChain);
551
intKeystore.setCertificateEntry(ROOT_ALIAS, rootCert);
552
553
// Now fire up the Intermediate CA OCSP responder
554
intOcsp = new SimpleOCSPServer(intKeystore, passwd,
555
INT_ALIAS, null);
556
intOcsp.enableLog(logging);
557
intOcsp.setNextUpdateInterval(3600);
558
intOcsp.start();
559
560
// Wait 5 seconds for server ready
561
for (int i = 0; (i < 100 && !intOcsp.isServerReady()); i++) {
562
Thread.sleep(50);
563
}
564
if (!intOcsp.isServerReady()) {
565
throw new RuntimeException("Server not ready yet");
566
}
567
568
intOcspPort = intOcsp.getPort();
569
String intCaRespURI = "http://localhost:" + intOcspPort;
570
log("Intermediate CA OCSP Responder URI is " + intCaRespURI);
571
572
// Last but not least, let's make our SSLCert and add it to its own
573
// Keystore
574
cbld.reset();
575
cbld.setSubjectName("CN=SSLCertificate, O=SomeCompany");
576
cbld.setPublicKey(sslKP.getPublic());
577
cbld.setSerialNumber(new BigInteger("4096"));
578
// Make a 1 year validity starting from 7 days ago
579
start = System.currentTimeMillis() - TimeUnit.DAYS.toMillis(7);
580
end = start + TimeUnit.DAYS.toMillis(365);
581
cbld.setValidity(new Date(start), new Date(end));
582
583
// Add extensions
584
addCommonExts(cbld, sslKP.getPublic(), intCaKP.getPublic());
585
boolean[] kuBits = {true, false, true, false, false, false,
586
false, false, false};
587
cbld.addKeyUsageExt(kuBits);
588
List<String> ekuOids = new ArrayList<>();
589
ekuOids.add("1.3.6.1.5.5.7.3.1");
590
ekuOids.add("1.3.6.1.5.5.7.3.2");
591
cbld.addExtendedKeyUsageExt(ekuOids);
592
cbld.addSubjectAltNameDNSExt(Collections.singletonList("localhost"));
593
cbld.addAIAExt(Collections.singletonList(intCaRespURI));
594
// Make our SSL Server Cert!
595
X509Certificate sslCert = cbld.build(intCaCert, intCaKP.getPrivate(),
596
"SHA256withRSA");
597
log("SSL Certificate Created:\n" + certInfo(sslCert));
598
599
// Provide SSL server cert revocation info to the Intermeidate CA
600
// OCSP responder.
601
revInfo = new HashMap<>();
602
revInfo.put(sslCert.getSerialNumber(),
603
new SimpleOCSPServer.CertStatusInfo(
604
SimpleOCSPServer.CertStatus.CERT_STATUS_GOOD));
605
intOcsp.updateStatusDb(revInfo);
606
607
// Now build a keystore and add the keys, chain and root cert as a TA
608
serverKeystore = keyStoreBuilder.getKeyStore();
609
java.security.cert.Certificate[] sslChain = {sslCert, intCaCert, rootCert};
610
serverKeystore.setKeyEntry(SSL_ALIAS, sslKP.getPrivate(),
611
passwd.toCharArray(), sslChain);
612
serverKeystore.setCertificateEntry(ROOT_ALIAS, rootCert);
613
614
// And finally a Trust Store for the client
615
trustStore = keyStoreBuilder.getKeyStore();
616
trustStore.setCertificateEntry(ROOT_ALIAS, rootCert);
617
}
618
619
private static void addCommonExts(CertificateBuilder cbld,
620
PublicKey subjKey, PublicKey authKey) throws IOException {
621
cbld.addSubjectKeyIdExt(subjKey);
622
cbld.addAuthorityKeyIdExt(authKey);
623
}
624
625
private static void addCommonCAExts(CertificateBuilder cbld)
626
throws IOException {
627
cbld.addBasicConstraintsExt(true, true, -1);
628
// Set key usage bits for digitalSignature, keyCertSign and cRLSign
629
boolean[] kuBitSettings = {true, false, false, false, false, true,
630
true, false, false};
631
cbld.addKeyUsageExt(kuBitSettings);
632
}
633
634
/**
635
* Helper routine that dumps only a few cert fields rather than
636
* the whole toString() output.
637
*
638
* @param cert an X509Certificate to be displayed
639
*
640
* @return the String output of the issuer, subject and
641
* serial number
642
*/
643
private static String certInfo(X509Certificate cert) {
644
StringBuilder sb = new StringBuilder();
645
sb.append("Issuer: ").append(cert.getIssuerX500Principal()).
646
append("\n");
647
sb.append("Subject: ").append(cert.getSubjectX500Principal()).
648
append("\n");
649
sb.append("Serial: ").append(cert.getSerialNumber()).append("\n");
650
return sb.toString();
651
}
652
653
/**
654
* Checks a validation failure to see if it failed for the reason we think
655
* it should. This comes in as an SSLException of some sort, but it
656
* encapsulates a CertPathValidatorException at some point in the
657
* exception stack.
658
*
659
* @param e the exception thrown at the top level
660
* @param reason the underlying CertPathValidatorException BasicReason
661
* we are expecting it to have.
662
*
663
* @return true if the reason matches up, false otherwise.
664
*/
665
static boolean checkClientValidationFailure(Exception e,
666
CertPathValidatorException.BasicReason reason) {
667
boolean result = false;
668
669
// Locate the CertPathValidatorException. If one
670
// Does not exist, then it's an automatic failure of
671
// the test.
672
Throwable curExc = e;
673
CertPathValidatorException cpve = null;
674
while (curExc != null) {
675
if (curExc instanceof CertPathValidatorException) {
676
cpve = (CertPathValidatorException)curExc;
677
}
678
curExc = curExc.getCause();
679
}
680
681
// If we get through the loop and cpve is null then we
682
// we didn't find CPVE and this is a failure
683
if (cpve != null) {
684
if (cpve.getReason() == reason) {
685
result = true;
686
} else {
687
System.out.println("CPVE Reason Mismatch: Expected = " +
688
reason + ", Actual = " + cpve.getReason());
689
}
690
} else {
691
System.out.println("Failed to find an expected CPVE");
692
}
693
694
return result;
695
}
696
}
697
698