Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/test/jdk/javax/net/ssl/Stapling/SSLSocketWithStapling.java
41152 views
1
/*
2
* Copyright (c) 2015, 2017, 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 SSLSocketWithStapling
34
*/
35
36
import java.io.*;
37
import java.math.BigInteger;
38
import java.net.InetAddress;
39
import java.net.Socket;
40
import java.net.ServerSocket;
41
import java.security.GeneralSecurityException;
42
import java.security.KeyPair;
43
import java.security.KeyPairGenerator;
44
import javax.net.ssl.*;
45
import java.security.KeyStore;
46
import java.security.PublicKey;
47
import java.security.Security;
48
import java.security.cert.CertPathValidator;
49
import java.security.cert.CertPathValidatorException;
50
import java.security.cert.CertPathValidatorException.BasicReason;
51
import java.security.cert.Certificate;
52
import java.security.cert.PKIXBuilderParameters;
53
import java.security.cert.X509CertSelector;
54
import java.security.cert.X509Certificate;
55
import java.security.cert.PKIXRevocationChecker;
56
import java.security.cert.PKIXRevocationChecker.Option;
57
import java.util.ArrayList;
58
import java.util.Collections;
59
import java.util.Date;
60
import java.util.EnumSet;
61
import java.util.List;
62
import java.util.Map;
63
import java.util.HashMap;
64
import java.util.concurrent.TimeUnit;
65
66
import sun.security.testlibrary.SimpleOCSPServer;
67
import sun.security.testlibrary.CertificateBuilder;
68
69
public class SSLSocketWithStapling {
70
71
/*
72
* =============================================================
73
* Set the various variables needed for the tests, then
74
* specify what tests to run on each side.
75
*/
76
77
// Turn on TLS debugging
78
static final boolean debug = false;
79
80
/*
81
* Should we run the client or server in a separate thread?
82
* Both sides can throw exceptions, but do you have a preference
83
* as to which side should be the main thread.
84
*/
85
static boolean separateServerThread = true;
86
Thread clientThread = null;
87
Thread serverThread = null;
88
89
static String passwd = "passphrase";
90
static String ROOT_ALIAS = "root";
91
static String INT_ALIAS = "intermediate";
92
static String SSL_ALIAS = "ssl";
93
94
/*
95
* Is the server ready to serve?
96
*/
97
volatile static boolean serverReady = false;
98
volatile int serverPort = 0;
99
100
volatile Exception serverException = null;
101
volatile Exception clientException = null;
102
103
// PKI components we will need for this test
104
static KeyStore rootKeystore; // Root CA Keystore
105
static KeyStore intKeystore; // Intermediate CA Keystore
106
static KeyStore serverKeystore; // SSL Server Keystore
107
static KeyStore trustStore; // SSL Client trust store
108
static SimpleOCSPServer rootOcsp; // Root CA OCSP Responder
109
static int rootOcspPort; // Port number for root OCSP
110
static SimpleOCSPServer intOcsp; // Intermediate CA OCSP Responder
111
static int intOcspPort; // Port number for intermed. OCSP
112
113
// Extra configuration parameters and constants
114
static final String[] TLS13ONLY = new String[] { "TLSv1.3" };
115
static final String[] TLS12MAX =
116
new String[] { "TLSv1.2", "TLSv1.1", "TLSv1" };
117
118
/*
119
* If the client or server is doing some kind of object creation
120
* that the other side depends on, and that thread prematurely
121
* exits, you may experience a hang. The test harness will
122
* terminate all hung threads after its timeout has expired,
123
* currently 3 minutes by default, but you might try to be
124
* smart about it....
125
*/
126
public static void main(String[] args) throws Exception {
127
if (debug) {
128
System.setProperty("javax.net.debug", "ssl:handshake");
129
}
130
131
try {
132
// Create the PKI we will use for the test and start the OCSP servers
133
createPKI();
134
135
testAllDefault(false);
136
testAllDefault(true);
137
testPKIXParametersRevEnabled(false);
138
testPKIXParametersRevEnabled(true);
139
testRevokedCertificate(false);
140
testRevokedCertificate(true);
141
testRevokedIntermediate(false);
142
testRevokedIntermediate(true);
143
testMissingIntermediate(false);
144
testMissingIntermediate(true);
145
testHardFailFallback(false);
146
testHardFailFallback(true);
147
testSoftFailFallback(false);
148
testSoftFailFallback(true);
149
testLatencyNoStaple(false, false);
150
testLatencyNoStaple(false, true);
151
testLatencyNoStaple(true, false);
152
testLatencyNoStaple(true, true);
153
} finally {
154
// shut down the OCSP responders before finishing the test
155
intOcsp.stop();
156
rootOcsp.stop();
157
}
158
}
159
160
/**
161
* Default test using no externally-configured PKIXBuilderParameters
162
*/
163
static void testAllDefault(boolean isTls13) throws Exception {
164
ClientParameters cliParams = new ClientParameters();
165
ServerParameters servParams = new ServerParameters();
166
if (isTls13) {
167
cliParams.protocols = TLS13ONLY;
168
servParams.protocols = TLS13ONLY;
169
} else {
170
cliParams.protocols = TLS12MAX;
171
servParams.protocols = TLS12MAX;
172
}
173
serverReady = false;
174
Map<BigInteger, SimpleOCSPServer.CertStatusInfo> revInfo =
175
new HashMap<>();
176
177
// We will prove revocation checking is disabled by marking the SSL
178
// certificate as revoked. The test would only pass if revocation
179
// checking did not happen.
180
X509Certificate sslCert =
181
(X509Certificate)serverKeystore.getCertificate(SSL_ALIAS);
182
Date fiveMinsAgo = new Date(System.currentTimeMillis() -
183
TimeUnit.MINUTES.toMillis(5));
184
revInfo.put(sslCert.getSerialNumber(),
185
new SimpleOCSPServer.CertStatusInfo(
186
SimpleOCSPServer.CertStatus.CERT_STATUS_REVOKED,
187
fiveMinsAgo));
188
intOcsp.updateStatusDb(revInfo);
189
190
System.out.println("=======================================");
191
System.out.println("Stapling enabled, default configuration");
192
System.out.println("=======================================");
193
194
SSLSocketWithStapling sslTest = new SSLSocketWithStapling(cliParams,
195
servParams);
196
TestResult tr = sslTest.getResult();
197
if (tr.clientExc != null) {
198
throw tr.clientExc;
199
} else if (tr.serverExc != null) {
200
throw tr.serverExc;
201
}
202
203
// Return the ssl certificate to non-revoked status
204
revInfo.put(sslCert.getSerialNumber(),
205
new SimpleOCSPServer.CertStatusInfo(
206
SimpleOCSPServer.CertStatus.CERT_STATUS_GOOD));
207
intOcsp.updateStatusDb(revInfo);
208
209
System.out.println(" PASS");
210
System.out.println("=======================================\n");
211
}
212
213
/**
214
* Do a basic connection using PKIXParameters with revocation checking
215
* enabled and client-side OCSP disabled. It will only pass if all
216
* stapled responses are present, valid and have a GOOD status.
217
*/
218
static void testPKIXParametersRevEnabled(boolean isTls13) throws Exception {
219
ClientParameters cliParams = new ClientParameters();
220
ServerParameters servParams = new ServerParameters();
221
if (isTls13) {
222
cliParams.protocols = TLS13ONLY;
223
servParams.protocols = TLS13ONLY;
224
} else {
225
cliParams.protocols = TLS12MAX;
226
servParams.protocols = TLS12MAX;
227
}
228
serverReady = false;
229
230
System.out.println("=====================================");
231
System.out.println("Stapling enabled, PKIXParameters with");
232
System.out.println("Revocation checking enabled ");
233
System.out.println("=====================================");
234
235
cliParams.pkixParams = new PKIXBuilderParameters(trustStore,
236
new X509CertSelector());
237
cliParams.pkixParams.setRevocationEnabled(true);
238
Security.setProperty("ocsp.enable", "false");
239
240
SSLSocketWithStapling sslTest = new SSLSocketWithStapling(cliParams,
241
servParams);
242
TestResult tr = sslTest.getResult();
243
if (tr.clientExc != null) {
244
throw tr.clientExc;
245
} else if (tr.serverExc != null) {
246
throw tr.serverExc;
247
}
248
249
System.out.println(" PASS");
250
System.out.println("=====================================\n");
251
}
252
253
/**
254
* Perform a test where the certificate is revoked and placed in the
255
* TLS handshake. Client-side OCSP is disabled, so this test will only
256
* pass if the OCSP response is found, since we will check the
257
* CertPathValidatorException reason for revoked status.
258
*/
259
static void testRevokedCertificate(boolean isTls13) throws Exception {
260
ClientParameters cliParams = new ClientParameters();
261
ServerParameters servParams = new ServerParameters();
262
if (isTls13) {
263
cliParams.protocols = TLS13ONLY;
264
servParams.protocols = TLS13ONLY;
265
} else {
266
cliParams.protocols = TLS12MAX;
267
servParams.protocols = TLS12MAX;
268
}
269
serverReady = false;
270
Map<BigInteger, SimpleOCSPServer.CertStatusInfo> revInfo =
271
new HashMap<>();
272
273
// We will prove revocation checking is disabled by marking the SSL
274
// certificate as revoked. The test would only pass if revocation
275
// checking did not happen.
276
X509Certificate sslCert =
277
(X509Certificate)serverKeystore.getCertificate(SSL_ALIAS);
278
Date fiveMinsAgo = new Date(System.currentTimeMillis() -
279
TimeUnit.MINUTES.toMillis(5));
280
revInfo.put(sslCert.getSerialNumber(),
281
new SimpleOCSPServer.CertStatusInfo(
282
SimpleOCSPServer.CertStatus.CERT_STATUS_REVOKED,
283
fiveMinsAgo));
284
intOcsp.updateStatusDb(revInfo);
285
286
System.out.println("============================================");
287
System.out.println("Stapling enabled, detect revoked certificate");
288
System.out.println("============================================");
289
290
cliParams.pkixParams = new PKIXBuilderParameters(trustStore,
291
new X509CertSelector());
292
cliParams.pkixParams.setRevocationEnabled(true);
293
Security.setProperty("ocsp.enable", "false");
294
295
SSLSocketWithStapling sslTest = new SSLSocketWithStapling(cliParams,
296
servParams);
297
TestResult tr = sslTest.getResult();
298
if (!checkClientValidationFailure(tr.clientExc, BasicReason.REVOKED)) {
299
if (tr.clientExc != null) {
300
throw tr.clientExc;
301
} else {
302
throw new RuntimeException(
303
"Expected client failure, but the client succeeded");
304
}
305
}
306
307
// Return the ssl certificate to non-revoked status
308
revInfo.put(sslCert.getSerialNumber(),
309
new SimpleOCSPServer.CertStatusInfo(
310
SimpleOCSPServer.CertStatus.CERT_STATUS_GOOD));
311
intOcsp.updateStatusDb(revInfo);
312
313
System.out.println(" PASS");
314
System.out.println("=======================================\n");
315
}
316
317
/**
318
* Perform a test where the intermediate CA certificate is revoked and
319
* placed in the TLS handshake. Client-side OCSP is disabled, so this
320
* test will only pass if the OCSP response for the intermediate CA is
321
* found and placed into the CertificateStatus or Certificate message
322
* (depending on the protocol version) since we will check
323
* the CertPathValidatorException reason for revoked status.
324
*/
325
static void testRevokedIntermediate(boolean isTls13) throws Exception {
326
ClientParameters cliParams = new ClientParameters();
327
ServerParameters servParams = new ServerParameters();
328
if (isTls13) {
329
cliParams.protocols = TLS13ONLY;
330
servParams.protocols = TLS13ONLY;
331
} else {
332
cliParams.protocols = TLS12MAX;
333
servParams.protocols = TLS12MAX;
334
}
335
serverReady = false;
336
Map<BigInteger, SimpleOCSPServer.CertStatusInfo> revInfo =
337
new HashMap<>();
338
339
// We will prove revocation checking is disabled by marking the SSL
340
// certificate as revoked. The test would only pass if revocation
341
// checking did not happen.
342
X509Certificate intCACert =
343
(X509Certificate)intKeystore.getCertificate(INT_ALIAS);
344
Date fiveMinsAgo = new Date(System.currentTimeMillis() -
345
TimeUnit.MINUTES.toMillis(5));
346
revInfo.put(intCACert.getSerialNumber(),
347
new SimpleOCSPServer.CertStatusInfo(
348
SimpleOCSPServer.CertStatus.CERT_STATUS_REVOKED,
349
fiveMinsAgo));
350
rootOcsp.updateStatusDb(revInfo);
351
352
System.out.println("===============================================");
353
System.out.println("Stapling enabled, detect revoked CA certificate");
354
System.out.println("===============================================");
355
356
cliParams.pkixParams = new PKIXBuilderParameters(trustStore,
357
new X509CertSelector());
358
cliParams.pkixParams.setRevocationEnabled(true);
359
Security.setProperty("ocsp.enable", "false");
360
361
SSLSocketWithStapling sslTest = new SSLSocketWithStapling(cliParams,
362
servParams);
363
TestResult tr = sslTest.getResult();
364
if (!checkClientValidationFailure(tr.clientExc, BasicReason.REVOKED)) {
365
if (tr.clientExc != null) {
366
throw tr.clientExc;
367
} else {
368
throw new RuntimeException(
369
"Expected client failure, but the client succeeded");
370
}
371
}
372
373
// Return the ssl certificate to non-revoked status
374
revInfo.put(intCACert.getSerialNumber(),
375
new SimpleOCSPServer.CertStatusInfo(
376
SimpleOCSPServer.CertStatus.CERT_STATUS_GOOD));
377
rootOcsp.updateStatusDb(revInfo);
378
379
System.out.println(" PASS");
380
System.out.println("=======================================\n");
381
}
382
383
/**
384
* Test a case where OCSP stapling is attempted, but partially occurs
385
* because the root OCSP responder is unreachable. This should use a
386
* default hard-fail behavior.
387
*/
388
static void testMissingIntermediate(boolean isTls13) throws Exception {
389
ClientParameters cliParams = new ClientParameters();
390
ServerParameters servParams = new ServerParameters();
391
if (isTls13) {
392
cliParams.protocols = TLS13ONLY;
393
servParams.protocols = TLS13ONLY;
394
} else {
395
cliParams.protocols = TLS12MAX;
396
servParams.protocols = TLS12MAX;
397
}
398
serverReady = false;
399
400
// Make the OCSP responder reject connections
401
rootOcsp.rejectConnections();
402
403
System.out.println("=======================================");
404
System.out.println("Stapling enbled in client and server,");
405
System.out.println("but root OCSP responder disabled.");
406
System.out.println("PKIXParameters with Revocation checking");
407
System.out.println("enabled.");
408
System.out.println("=======================================");
409
410
Security.setProperty("ocsp.enable", "false");
411
cliParams.pkixParams = new PKIXBuilderParameters(trustStore,
412
new X509CertSelector());
413
cliParams.pkixParams.setRevocationEnabled(true);
414
415
SSLSocketWithStapling sslTest = new SSLSocketWithStapling(cliParams,
416
servParams);
417
TestResult tr = sslTest.getResult();
418
if (!checkClientValidationFailure(tr.clientExc,
419
BasicReason.UNDETERMINED_REVOCATION_STATUS)) {
420
if (tr.clientExc != null) {
421
throw tr.clientExc;
422
} else {
423
throw new RuntimeException(
424
"Expected client failure, but the client succeeded");
425
}
426
}
427
428
System.out.println(" PASS");
429
System.out.println("=======================================\n");
430
431
// Make root OCSP responder accept connections
432
rootOcsp.acceptConnections();
433
434
// Wait 5 seconds for server ready
435
for (int i = 0; (i < 100 && !rootOcsp.isServerReady()); i++) {
436
Thread.sleep(50);
437
}
438
if (!rootOcsp.isServerReady()) {
439
throw new RuntimeException("Root OCSP responder not ready yet");
440
}
441
}
442
443
/**
444
* Test a case where client-side stapling is attempted, but does not
445
* occur because OCSP responders are unreachable. This should use a
446
* default hard-fail behavior.
447
*/
448
static void testHardFailFallback(boolean isTls13) throws Exception {
449
ClientParameters cliParams = new ClientParameters();
450
ServerParameters servParams = new ServerParameters();
451
if (isTls13) {
452
cliParams.protocols = TLS13ONLY;
453
servParams.protocols = TLS13ONLY;
454
} else {
455
cliParams.protocols = TLS12MAX;
456
servParams.protocols = TLS12MAX;
457
}
458
serverReady = false;
459
460
// make OCSP responders reject connections
461
intOcsp.rejectConnections();
462
rootOcsp.rejectConnections();
463
464
System.out.println("=======================================");
465
System.out.println("Stapling enbled in client and server,");
466
System.out.println("but OCSP responders disabled.");
467
System.out.println("PKIXParameters with Revocation checking");
468
System.out.println("enabled.");
469
System.out.println("=======================================");
470
471
Security.setProperty("ocsp.enable", "true");
472
cliParams.pkixParams = new PKIXBuilderParameters(trustStore,
473
new X509CertSelector());
474
cliParams.pkixParams.setRevocationEnabled(true);
475
476
SSLSocketWithStapling sslTest = new SSLSocketWithStapling(cliParams,
477
servParams);
478
TestResult tr = sslTest.getResult();
479
if (!checkClientValidationFailure(tr.clientExc,
480
BasicReason.UNDETERMINED_REVOCATION_STATUS)) {
481
if (tr.clientExc != null) {
482
throw tr.clientExc;
483
} else {
484
throw new RuntimeException(
485
"Expected client failure, but the client succeeded");
486
}
487
}
488
489
System.out.println(" PASS");
490
System.out.println("=======================================\n");
491
492
// Make OCSP responders accept connections
493
intOcsp.acceptConnections();
494
rootOcsp.acceptConnections();
495
496
// Wait 5 seconds for server ready
497
for (int i = 0; (i < 100 && (!intOcsp.isServerReady() ||
498
!rootOcsp.isServerReady())); i++) {
499
Thread.sleep(50);
500
}
501
if (!intOcsp.isServerReady() || !rootOcsp.isServerReady()) {
502
throw new RuntimeException("Server not ready yet");
503
}
504
}
505
506
/**
507
* Test a case where client-side stapling is attempted, but does not
508
* occur because OCSP responders are unreachable. Client-side OCSP
509
* checking is enabled for this, with SOFT_FAIL.
510
*/
511
static void testSoftFailFallback(boolean isTls13) throws Exception {
512
ClientParameters cliParams = new ClientParameters();
513
ServerParameters servParams = new ServerParameters();
514
if (isTls13) {
515
cliParams.protocols = TLS13ONLY;
516
servParams.protocols = TLS13ONLY;
517
} else {
518
cliParams.protocols = TLS12MAX;
519
servParams.protocols = TLS12MAX;
520
}
521
serverReady = false;
522
523
// make OCSP responders reject connections
524
intOcsp.rejectConnections();
525
rootOcsp.rejectConnections();
526
527
System.out.println("=======================================");
528
System.out.println("Stapling enbled in client and server,");
529
System.out.println("but OCSP responders disabled.");
530
System.out.println("PKIXParameters with Revocation checking");
531
System.out.println("enabled and SOFT_FAIL.");
532
System.out.println("=======================================");
533
534
Security.setProperty("ocsp.enable", "true");
535
cliParams.pkixParams = new PKIXBuilderParameters(trustStore,
536
new X509CertSelector());
537
cliParams.pkixParams.setRevocationEnabled(true);
538
CertPathValidator cpv = CertPathValidator.getInstance("PKIX");
539
cliParams.revChecker =
540
(PKIXRevocationChecker)cpv.getRevocationChecker();
541
cliParams.revChecker.setOptions(EnumSet.of(Option.SOFT_FAIL));
542
543
SSLSocketWithStapling sslTest = new SSLSocketWithStapling(cliParams,
544
servParams);
545
TestResult tr = sslTest.getResult();
546
if (tr.clientExc != null) {
547
throw tr.clientExc;
548
} else if (tr.serverExc != null) {
549
throw tr.serverExc;
550
}
551
552
// make sure getSoftFailExceptions is not empty
553
if (cliParams.revChecker.getSoftFailExceptions().isEmpty()) {
554
throw new Exception("No soft fail exceptions");
555
}
556
557
System.out.println(" PASS");
558
System.out.println("=======================================\n");
559
560
561
// Make OCSP responders accept connections
562
intOcsp.acceptConnections();
563
rootOcsp.acceptConnections();
564
565
// Wait 5 seconds for server ready
566
for (int i = 0; (i < 100 && (!intOcsp.isServerReady() ||
567
!rootOcsp.isServerReady())); i++) {
568
Thread.sleep(50);
569
}
570
if (!intOcsp.isServerReady() || !rootOcsp.isServerReady()) {
571
throw new RuntimeException("Server not ready yet");
572
}
573
}
574
575
/**
576
* This test initiates stapling from the client, but the server does not
577
* support OCSP stapling for this connection. In this case it happens
578
* because the latency of the OCSP responders is longer than the server
579
* is willing to wait. To keep the test streamlined, we will set the server
580
* latency to a 1 second wait, and set the responder latency to 3 seconds.
581
*
582
* @param fallback if we allow client-side OCSP fallback, which
583
* will change the result from the client failing with CPVE (no fallback)
584
* to a pass (fallback active).
585
*/
586
static void testLatencyNoStaple(Boolean fallback, boolean isTls13)
587
throws Exception {
588
ClientParameters cliParams = new ClientParameters();
589
ServerParameters servParams = new ServerParameters();
590
if (isTls13) {
591
cliParams.protocols = TLS13ONLY;
592
servParams.protocols = TLS13ONLY;
593
} else {
594
cliParams.protocols = TLS12MAX;
595
servParams.protocols = TLS12MAX;
596
}
597
serverReady = false;
598
599
// Give a 1 second delay before running the test.
600
intOcsp.setDelay(3000);
601
rootOcsp.setDelay(3000);
602
Thread.sleep(1000);
603
604
// Wait 5 seconds for server ready
605
for (int i = 0; (i < 100 && (!intOcsp.isServerReady() ||
606
!rootOcsp.isServerReady())); i++) {
607
Thread.sleep(50);
608
}
609
if (!intOcsp.isServerReady() || !rootOcsp.isServerReady()) {
610
throw new RuntimeException("Server not ready yet");
611
}
612
613
System.out.println("========================================");
614
System.out.println("Stapling enbled in client. Server does");
615
System.out.println("not support stapling due to OCSP latency.");
616
System.out.println("PKIXParameters with Revocation checking");
617
System.out.println("enabled, client-side OCSP checking is.");
618
System.out.println(fallback ? "enabled" : "disabled");
619
System.out.println("========================================");
620
621
Security.setProperty("ocsp.enable", fallback.toString());
622
cliParams.pkixParams = new PKIXBuilderParameters(trustStore,
623
new X509CertSelector());
624
cliParams.pkixParams.setRevocationEnabled(true);
625
servParams.respTimeout = 1000;
626
627
SSLSocketWithStapling sslTest = new SSLSocketWithStapling(cliParams,
628
servParams);
629
TestResult tr = sslTest.getResult();
630
631
if (fallback) {
632
if (tr.clientExc != null) {
633
throw tr.clientExc;
634
} else if (tr.serverExc != null) {
635
throw tr.serverExc;
636
}
637
} else {
638
if (!checkClientValidationFailure(tr.clientExc,
639
BasicReason.UNDETERMINED_REVOCATION_STATUS)) {
640
if (tr.clientExc != null) {
641
throw tr.clientExc;
642
} else {
643
throw new RuntimeException(
644
"Expected client failure, but the client succeeded");
645
}
646
}
647
}
648
System.out.println(" PASS");
649
System.out.println("========================================\n");
650
651
// Remove the OCSP responder latency
652
intOcsp.setDelay(0);
653
rootOcsp.setDelay(0);
654
Thread.sleep(1000);
655
656
// Wait 5 seconds for server ready
657
for (int i = 0; (i < 100 && (!intOcsp.isServerReady() ||
658
!rootOcsp.isServerReady())); i++) {
659
Thread.sleep(50);
660
}
661
if (!intOcsp.isServerReady() || !rootOcsp.isServerReady()) {
662
throw new RuntimeException("Server not ready yet");
663
}
664
}
665
666
/*
667
* Define the server side of the test.
668
*
669
* If the server prematurely exits, serverReady will be set to true
670
* to avoid infinite hangs.
671
*/
672
void doServerSide(ServerParameters servParams) throws Exception {
673
674
// Selectively enable or disable the feature
675
System.setProperty("jdk.tls.server.enableStatusRequestExtension",
676
Boolean.toString(servParams.enabled));
677
678
// Set all the other operating parameters
679
System.setProperty("jdk.tls.stapling.cacheSize",
680
Integer.toString(servParams.cacheSize));
681
System.setProperty("jdk.tls.stapling.cacheLifetime",
682
Integer.toString(servParams.cacheLifetime));
683
System.setProperty("jdk.tls.stapling.responseTimeout",
684
Integer.toString(servParams.respTimeout));
685
System.setProperty("jdk.tls.stapling.responderURI", servParams.respUri);
686
System.setProperty("jdk.tls.stapling.responderOverride",
687
Boolean.toString(servParams.respOverride));
688
System.setProperty("jdk.tls.stapling.ignoreExtensions",
689
Boolean.toString(servParams.ignoreExts));
690
691
// Set keystores and trust stores for the server
692
KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
693
kmf.init(serverKeystore, passwd.toCharArray());
694
TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
695
tmf.init(trustStore);
696
697
SSLContext sslc = SSLContext.getInstance("TLS");
698
sslc.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
699
700
SSLServerSocketFactory sslssf = new CustomizedServerSocketFactory(sslc,
701
servParams.protocols, servParams.ciphers);
702
703
try (SSLServerSocket sslServerSocket =
704
(SSLServerSocket) sslssf.createServerSocket(serverPort)) {
705
706
serverPort = sslServerSocket.getLocalPort();
707
708
/*
709
* Signal Client, we're ready for his connect.
710
*/
711
serverReady = true;
712
713
try (SSLSocket sslSocket = (SSLSocket) sslServerSocket.accept();
714
InputStream sslIS = sslSocket.getInputStream();
715
OutputStream sslOS = sslSocket.getOutputStream()) {
716
int numberIn = sslIS.read();
717
int numberSent = 85;
718
log("Server received number: " + numberIn);
719
sslOS.write(numberSent);
720
sslOS.flush();
721
log("Server sent number: " + numberSent);
722
}
723
}
724
}
725
726
/*
727
* Define the client side of the test.
728
*
729
* If the server prematurely exits, serverReady will be set to true
730
* to avoid infinite hangs.
731
*/
732
void doClientSide(ClientParameters cliParams) throws Exception {
733
734
// Wait 5 seconds for server ready
735
for (int i = 0; (i < 100 && !serverReady); i++) {
736
Thread.sleep(50);
737
}
738
if (!serverReady) {
739
throw new RuntimeException("Server not ready yet");
740
}
741
742
// Selectively enable or disable the feature
743
System.setProperty("jdk.tls.client.enableStatusRequestExtension",
744
Boolean.toString(cliParams.enabled));
745
746
// Create the Trust Manager Factory using the PKIX variant
747
TrustManagerFactory tmf = TrustManagerFactory.getInstance("PKIX");
748
749
// If we have a customized pkixParameters then use it
750
if (cliParams.pkixParams != null) {
751
// LIf we have a customized PKIXRevocationChecker, add
752
// it to the PKIXBuilderParameters.
753
if (cliParams.revChecker != null) {
754
cliParams.pkixParams.addCertPathChecker(cliParams.revChecker);
755
}
756
757
ManagerFactoryParameters trustParams =
758
new CertPathTrustManagerParameters(cliParams.pkixParams);
759
tmf.init(trustParams);
760
} else {
761
tmf.init(trustStore);
762
}
763
764
SSLContext sslc = SSLContext.getInstance("TLS");
765
sslc.init(null, tmf.getTrustManagers(), null);
766
767
SSLSocketFactory sslsf = new CustomizedSocketFactory(sslc,
768
cliParams.protocols, cliParams.ciphers);
769
try (SSLSocket sslSocket = (SSLSocket)sslsf.createSocket("localhost",
770
serverPort);
771
InputStream sslIS = sslSocket.getInputStream();
772
OutputStream sslOS = sslSocket.getOutputStream()) {
773
int numberSent = 80;
774
sslOS.write(numberSent);
775
sslOS.flush();
776
log("Client sent number: " + numberSent);
777
int numberIn = sslIS.read();
778
log("Client received number:" + numberIn);
779
}
780
}
781
782
/*
783
* Primary constructor, used to drive remainder of the test.
784
*
785
* Fork off the other side, then do your work.
786
*/
787
SSLSocketWithStapling(ClientParameters cliParams,
788
ServerParameters servParams) throws Exception {
789
Exception startException = null;
790
try {
791
if (separateServerThread) {
792
startServer(servParams, true);
793
startClient(cliParams, false);
794
} else {
795
startClient(cliParams, true);
796
startServer(servParams, false);
797
}
798
} catch (Exception e) {
799
startException = e;
800
}
801
802
/*
803
* Wait for other side to close down.
804
*/
805
if (separateServerThread) {
806
if (serverThread != null) {
807
serverThread.join();
808
}
809
} else {
810
if (clientThread != null) {
811
clientThread.join();
812
}
813
}
814
}
815
816
/**
817
* Checks a validation failure to see if it failed for the reason we think
818
* it should. This comes in as an SSLException of some sort, but it
819
* encapsulates a ValidatorException which in turn encapsulates the
820
* CertPathValidatorException we are interested in.
821
*
822
* @param e the exception thrown at the top level
823
* @param reason the underlying CertPathValidatorException BasicReason
824
* we are expecting it to have.
825
*
826
* @return true if the reason matches up, false otherwise.
827
*/
828
static boolean checkClientValidationFailure(Exception e,
829
BasicReason reason) {
830
boolean result = false;
831
832
if (e instanceof SSLException) {
833
Throwable valExc = e.getCause();
834
if (valExc instanceof sun.security.validator.ValidatorException) {
835
Throwable cause = valExc.getCause();
836
if (cause instanceof CertPathValidatorException) {
837
CertPathValidatorException cpve =
838
(CertPathValidatorException)cause;
839
if (cpve.getReason() == reason) {
840
result = true;
841
}
842
}
843
}
844
}
845
return result;
846
}
847
848
TestResult getResult() {
849
TestResult tr = new TestResult();
850
tr.clientExc = clientException;
851
tr.serverExc = serverException;
852
return tr;
853
}
854
855
void startServer(ServerParameters servParams, boolean newThread)
856
throws Exception {
857
if (newThread) {
858
serverThread = new Thread() {
859
public void run() {
860
try {
861
doServerSide(servParams);
862
} catch (Exception e) {
863
/*
864
* Our server thread just died.
865
*
866
* Release the client, if not active already...
867
*/
868
System.err.println("Server died...");
869
e.printStackTrace(System.err);
870
serverReady = true;
871
serverException = e;
872
}
873
}
874
};
875
serverThread.start();
876
} else {
877
try {
878
doServerSide(servParams);
879
} catch (Exception e) {
880
serverException = e;
881
} finally {
882
serverReady = true;
883
}
884
}
885
}
886
887
void startClient(ClientParameters cliParams, boolean newThread)
888
throws Exception {
889
if (newThread) {
890
clientThread = new Thread() {
891
public void run() {
892
try {
893
doClientSide(cliParams);
894
} catch (Exception e) {
895
/*
896
* Our client thread just died.
897
*/
898
System.err.println("Client died...");
899
clientException = e;
900
}
901
}
902
};
903
clientThread.start();
904
} else {
905
try {
906
doClientSide(cliParams);
907
} catch (Exception e) {
908
clientException = e;
909
}
910
}
911
}
912
913
/**
914
* Creates the PKI components necessary for this test, including
915
* Root CA, Intermediate CA and SSL server certificates, the keystores
916
* for each entity, a client trust store, and starts the OCSP responders.
917
*/
918
private static void createPKI() throws Exception {
919
CertificateBuilder cbld = new CertificateBuilder();
920
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
921
keyGen.initialize(2048);
922
KeyStore.Builder keyStoreBuilder =
923
KeyStore.Builder.newInstance("PKCS12", null,
924
new KeyStore.PasswordProtection(passwd.toCharArray()));
925
926
// Generate Root, IntCA, EE keys
927
KeyPair rootCaKP = keyGen.genKeyPair();
928
log("Generated Root CA KeyPair");
929
KeyPair intCaKP = keyGen.genKeyPair();
930
log("Generated Intermediate CA KeyPair");
931
KeyPair sslKP = keyGen.genKeyPair();
932
log("Generated SSL Cert KeyPair");
933
934
// Set up the Root CA Cert
935
cbld.setSubjectName("CN=Root CA Cert, O=SomeCompany");
936
cbld.setPublicKey(rootCaKP.getPublic());
937
cbld.setSerialNumber(new BigInteger("1"));
938
// Make a 3 year validity starting from 60 days ago
939
long start = System.currentTimeMillis() - TimeUnit.DAYS.toMillis(60);
940
long end = start + TimeUnit.DAYS.toMillis(1085);
941
cbld.setValidity(new Date(start), new Date(end));
942
addCommonExts(cbld, rootCaKP.getPublic(), rootCaKP.getPublic());
943
addCommonCAExts(cbld);
944
// Make our Root CA Cert!
945
X509Certificate rootCert = cbld.build(null, rootCaKP.getPrivate(),
946
"SHA256withRSA");
947
log("Root CA Created:\n" + certInfo(rootCert));
948
949
// Now build a keystore and add the keys and cert
950
rootKeystore = keyStoreBuilder.getKeyStore();
951
Certificate[] rootChain = {rootCert};
952
rootKeystore.setKeyEntry(ROOT_ALIAS, rootCaKP.getPrivate(),
953
passwd.toCharArray(), rootChain);
954
955
// Now fire up the OCSP responder
956
rootOcsp = new SimpleOCSPServer(rootKeystore, passwd, ROOT_ALIAS, null);
957
rootOcsp.enableLog(debug);
958
rootOcsp.setNextUpdateInterval(3600);
959
rootOcsp.start();
960
961
// Wait 5 seconds for server ready
962
for (int i = 0; (i < 100 && !rootOcsp.isServerReady()); i++) {
963
Thread.sleep(50);
964
}
965
if (!rootOcsp.isServerReady()) {
966
throw new RuntimeException("Server not ready yet");
967
}
968
969
rootOcspPort = rootOcsp.getPort();
970
String rootRespURI = "http://localhost:" + rootOcspPort;
971
log("Root OCSP Responder URI is " + rootRespURI);
972
973
// Now that we have the root keystore and OCSP responder we can
974
// create our intermediate CA.
975
cbld.reset();
976
cbld.setSubjectName("CN=Intermediate CA Cert, O=SomeCompany");
977
cbld.setPublicKey(intCaKP.getPublic());
978
cbld.setSerialNumber(new BigInteger("100"));
979
// Make a 2 year validity starting from 30 days ago
980
start = System.currentTimeMillis() - TimeUnit.DAYS.toMillis(30);
981
end = start + TimeUnit.DAYS.toMillis(730);
982
cbld.setValidity(new Date(start), new Date(end));
983
addCommonExts(cbld, intCaKP.getPublic(), rootCaKP.getPublic());
984
addCommonCAExts(cbld);
985
cbld.addAIAExt(Collections.singletonList(rootRespURI));
986
// Make our Intermediate CA Cert!
987
X509Certificate intCaCert = cbld.build(rootCert, rootCaKP.getPrivate(),
988
"SHA256withRSA");
989
log("Intermediate CA Created:\n" + certInfo(intCaCert));
990
991
// Provide intermediate CA cert revocation info to the Root CA
992
// OCSP responder.
993
Map<BigInteger, SimpleOCSPServer.CertStatusInfo> revInfo =
994
new HashMap<>();
995
revInfo.put(intCaCert.getSerialNumber(),
996
new SimpleOCSPServer.CertStatusInfo(
997
SimpleOCSPServer.CertStatus.CERT_STATUS_GOOD));
998
rootOcsp.updateStatusDb(revInfo);
999
1000
// Now build a keystore and add the keys, chain and root cert as a TA
1001
intKeystore = keyStoreBuilder.getKeyStore();
1002
Certificate[] intChain = {intCaCert, rootCert};
1003
intKeystore.setKeyEntry(INT_ALIAS, intCaKP.getPrivate(),
1004
passwd.toCharArray(), intChain);
1005
intKeystore.setCertificateEntry(ROOT_ALIAS, rootCert);
1006
1007
// Now fire up the Intermediate CA OCSP responder
1008
intOcsp = new SimpleOCSPServer(intKeystore, passwd,
1009
INT_ALIAS, null);
1010
intOcsp.enableLog(debug);
1011
intOcsp.setNextUpdateInterval(3600);
1012
intOcsp.start();
1013
1014
// Wait 5 seconds for server ready
1015
for (int i = 0; (i < 100 && !intOcsp.isServerReady()); i++) {
1016
Thread.sleep(50);
1017
}
1018
if (!intOcsp.isServerReady()) {
1019
throw new RuntimeException("Server not ready yet");
1020
}
1021
1022
intOcspPort = intOcsp.getPort();
1023
String intCaRespURI = "http://localhost:" + intOcspPort;
1024
log("Intermediate CA OCSP Responder URI is " + intCaRespURI);
1025
1026
// Last but not least, let's make our SSLCert and add it to its own
1027
// Keystore
1028
cbld.reset();
1029
cbld.setSubjectName("CN=SSLCertificate, O=SomeCompany");
1030
cbld.setPublicKey(sslKP.getPublic());
1031
cbld.setSerialNumber(new BigInteger("4096"));
1032
// Make a 1 year validity starting from 7 days ago
1033
start = System.currentTimeMillis() - TimeUnit.DAYS.toMillis(7);
1034
end = start + TimeUnit.DAYS.toMillis(365);
1035
cbld.setValidity(new Date(start), new Date(end));
1036
1037
// Add extensions
1038
addCommonExts(cbld, sslKP.getPublic(), intCaKP.getPublic());
1039
boolean[] kuBits = {true, false, true, false, false, false,
1040
false, false, false};
1041
cbld.addKeyUsageExt(kuBits);
1042
List<String> ekuOids = new ArrayList<>();
1043
ekuOids.add("1.3.6.1.5.5.7.3.1");
1044
ekuOids.add("1.3.6.1.5.5.7.3.2");
1045
cbld.addExtendedKeyUsageExt(ekuOids);
1046
cbld.addSubjectAltNameDNSExt(Collections.singletonList("localhost"));
1047
cbld.addAIAExt(Collections.singletonList(intCaRespURI));
1048
// Make our SSL Server Cert!
1049
X509Certificate sslCert = cbld.build(intCaCert, intCaKP.getPrivate(),
1050
"SHA256withRSA");
1051
log("SSL Certificate Created:\n" + certInfo(sslCert));
1052
1053
// Provide SSL server cert revocation info to the Intermeidate CA
1054
// OCSP responder.
1055
revInfo = new HashMap<>();
1056
revInfo.put(sslCert.getSerialNumber(),
1057
new SimpleOCSPServer.CertStatusInfo(
1058
SimpleOCSPServer.CertStatus.CERT_STATUS_GOOD));
1059
intOcsp.updateStatusDb(revInfo);
1060
1061
// Now build a keystore and add the keys, chain and root cert as a TA
1062
serverKeystore = keyStoreBuilder.getKeyStore();
1063
Certificate[] sslChain = {sslCert, intCaCert, rootCert};
1064
serverKeystore.setKeyEntry(SSL_ALIAS, sslKP.getPrivate(),
1065
passwd.toCharArray(), sslChain);
1066
serverKeystore.setCertificateEntry(ROOT_ALIAS, rootCert);
1067
1068
// And finally a Trust Store for the client
1069
trustStore = keyStoreBuilder.getKeyStore();
1070
trustStore.setCertificateEntry(ROOT_ALIAS, rootCert);
1071
}
1072
1073
private static void addCommonExts(CertificateBuilder cbld,
1074
PublicKey subjKey, PublicKey authKey) throws IOException {
1075
cbld.addSubjectKeyIdExt(subjKey);
1076
cbld.addAuthorityKeyIdExt(authKey);
1077
}
1078
1079
private static void addCommonCAExts(CertificateBuilder cbld)
1080
throws IOException {
1081
cbld.addBasicConstraintsExt(true, true, -1);
1082
// Set key usage bits for digitalSignature, keyCertSign and cRLSign
1083
boolean[] kuBitSettings = {true, false, false, false, false, true,
1084
true, false, false};
1085
cbld.addKeyUsageExt(kuBitSettings);
1086
}
1087
1088
/**
1089
* Helper routine that dumps only a few cert fields rather than
1090
* the whole toString() output.
1091
*
1092
* @param cert an X509Certificate to be displayed
1093
*
1094
* @return the String output of the issuer, subject and
1095
* serial number
1096
*/
1097
private static String certInfo(X509Certificate cert) {
1098
StringBuilder sb = new StringBuilder();
1099
sb.append("Issuer: ").append(cert.getIssuerX500Principal()).
1100
append("\n");
1101
sb.append("Subject: ").append(cert.getSubjectX500Principal()).
1102
append("\n");
1103
sb.append("Serial: ").append(cert.getSerialNumber()).append("\n");
1104
return sb.toString();
1105
}
1106
1107
/**
1108
* Log a message on stdout
1109
*
1110
* @param message The message to log
1111
*/
1112
private static void log(String message) {
1113
if (debug) {
1114
System.out.println(message);
1115
}
1116
}
1117
1118
// The following two classes are Simple nested class to group a handful
1119
// of configuration parameters used before starting a client or server.
1120
// We'll just access the data members directly for convenience.
1121
static class ClientParameters {
1122
boolean enabled = true;
1123
PKIXBuilderParameters pkixParams = null;
1124
PKIXRevocationChecker revChecker = null;
1125
String[] protocols = null;
1126
String[] ciphers = null;
1127
1128
ClientParameters() { }
1129
}
1130
1131
static class ServerParameters {
1132
boolean enabled = true;
1133
int cacheSize = 256;
1134
int cacheLifetime = 3600;
1135
int respTimeout = 5000;
1136
String respUri = "";
1137
boolean respOverride = false;
1138
boolean ignoreExts = false;
1139
String[] protocols = null;
1140
String[] ciphers = null;
1141
1142
ServerParameters() { }
1143
}
1144
1145
static class CustomizedSocketFactory extends SSLSocketFactory {
1146
final SSLContext sslc;
1147
final String[] protocols;
1148
final String[] cipherSuites;
1149
1150
CustomizedSocketFactory(SSLContext ctx, String[] prots, String[] suites)
1151
throws GeneralSecurityException {
1152
super();
1153
sslc = (ctx != null) ? ctx : SSLContext.getDefault();
1154
protocols = prots;
1155
cipherSuites = suites;
1156
1157
// Create the Trust Manager Factory using the PKIX variant
1158
TrustManagerFactory tmf = TrustManagerFactory.getInstance("PKIX");
1159
}
1160
1161
@Override
1162
public Socket createSocket(Socket s, String host, int port,
1163
boolean autoClose) throws IOException {
1164
Socket sock = sslc.getSocketFactory().createSocket(s, host, port,
1165
autoClose);
1166
customizeSocket(sock);
1167
return sock;
1168
}
1169
1170
@Override
1171
public Socket createSocket(InetAddress host, int port)
1172
throws IOException {
1173
Socket sock = sslc.getSocketFactory().createSocket(host, port);
1174
customizeSocket(sock);
1175
return sock;
1176
}
1177
1178
@Override
1179
public Socket createSocket(InetAddress host, int port,
1180
InetAddress localAddress, int localPort) throws IOException {
1181
Socket sock = sslc.getSocketFactory().createSocket(host, port,
1182
localAddress, localPort);
1183
customizeSocket(sock);
1184
return sock;
1185
}
1186
1187
@Override
1188
public Socket createSocket(String host, int port)
1189
throws IOException {
1190
Socket sock = sslc.getSocketFactory().createSocket(host, port);
1191
customizeSocket(sock);
1192
return sock;
1193
}
1194
1195
@Override
1196
public Socket createSocket(String host, int port,
1197
InetAddress localAddress, int localPort)
1198
throws IOException {
1199
Socket sock = sslc.getSocketFactory().createSocket(host, port,
1200
localAddress, localPort);
1201
customizeSocket(sock);
1202
return sock;
1203
}
1204
1205
@Override
1206
public String[] getDefaultCipherSuites() {
1207
return sslc.getDefaultSSLParameters().getCipherSuites();
1208
}
1209
1210
@Override
1211
public String[] getSupportedCipherSuites() {
1212
return sslc.getSupportedSSLParameters().getCipherSuites();
1213
}
1214
1215
private void customizeSocket(Socket sock) {
1216
if (sock instanceof SSLSocket) {
1217
if (protocols != null) {
1218
((SSLSocket)sock).setEnabledProtocols(protocols);
1219
}
1220
if (cipherSuites != null) {
1221
((SSLSocket)sock).setEnabledCipherSuites(cipherSuites);
1222
}
1223
}
1224
}
1225
}
1226
1227
static class CustomizedServerSocketFactory extends SSLServerSocketFactory {
1228
final SSLContext sslc;
1229
final String[] protocols;
1230
final String[] cipherSuites;
1231
1232
CustomizedServerSocketFactory(SSLContext ctx, String[] prots, String[] suites)
1233
throws GeneralSecurityException {
1234
super();
1235
sslc = (ctx != null) ? ctx : SSLContext.getDefault();
1236
protocols = prots;
1237
cipherSuites = suites;
1238
1239
// Create the Trust Manager Factory using the PKIX variant
1240
TrustManagerFactory tmf = TrustManagerFactory.getInstance("PKIX");
1241
}
1242
1243
@Override
1244
public ServerSocket createServerSocket(int port) throws IOException {
1245
ServerSocket sock =
1246
sslc.getServerSocketFactory().createServerSocket(port);
1247
customizeSocket(sock);
1248
return sock;
1249
}
1250
1251
@Override
1252
public ServerSocket createServerSocket(int port, int backlog)
1253
throws IOException {
1254
ServerSocket sock =
1255
sslc.getServerSocketFactory().createServerSocket(port,
1256
backlog);
1257
customizeSocket(sock);
1258
return sock;
1259
}
1260
1261
@Override
1262
public ServerSocket createServerSocket(int port, int backlog,
1263
InetAddress ifAddress) throws IOException {
1264
ServerSocket sock =
1265
sslc.getServerSocketFactory().createServerSocket(port,
1266
backlog, ifAddress);
1267
customizeSocket(sock);
1268
return sock;
1269
}
1270
1271
@Override
1272
public String[] getDefaultCipherSuites() {
1273
return sslc.getDefaultSSLParameters().getCipherSuites();
1274
}
1275
1276
@Override
1277
public String[] getSupportedCipherSuites() {
1278
return sslc.getSupportedSSLParameters().getCipherSuites();
1279
}
1280
1281
private void customizeSocket(ServerSocket sock) {
1282
if (sock instanceof SSLServerSocket) {
1283
if (protocols != null) {
1284
((SSLServerSocket)sock).setEnabledProtocols(protocols);
1285
}
1286
if (cipherSuites != null) {
1287
((SSLServerSocket)sock).setEnabledCipherSuites(cipherSuites);
1288
}
1289
}
1290
}
1291
}
1292
1293
1294
static class TestResult {
1295
Exception serverExc = null;
1296
Exception clientExc = null;
1297
}
1298
1299
}
1300
1301