Skip to content

Commit 32fda32

Browse files
Alexey PavlyutkinYuri Nesterenko
Alexey Pavlyutkin
authored and
Yuri Nesterenko
committedMay 23, 2023
8296343: CPVE thrown on missing content-length in OCSP response
Backport-of: 1a3cb8c5018bc016c2ad6b078e4abe13b39d151c
1 parent 6b362e4 commit 32fda32

File tree

9 files changed

+362
-116
lines changed

9 files changed

+362
-116
lines changed
 

‎src/java.base/share/classes/sun/security/provider/certpath/OCSP.java

+15-12
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2009, 2022, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2009, 2023, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -267,20 +267,23 @@ public static byte[] getOCSPBytes(List<CertId> certIds, URI responderURI,
267267
out.flush();
268268
}
269269

270-
// Check the response
271-
if (debug != null &&
272-
con.getResponseCode() != HttpURLConnection.HTTP_OK) {
273-
debug.println("Received HTTP error: " + con.getResponseCode()
274-
+ " - " + con.getResponseMessage());
270+
// Check the response. Non-200 codes will generate an exception
271+
// but path validation may complete successfully if revocation info
272+
// can be obtained elsewhere (e.g. CRL).
273+
int respCode = con.getResponseCode();
274+
if (respCode != HttpURLConnection.HTTP_OK) {
275+
String msg = "Received HTTP error: " + respCode + " - " +
276+
con.getResponseMessage();
277+
if (debug != null) {
278+
debug.println(msg);
279+
}
280+
throw new IOException(msg);
275281
}
276282

277283
int contentLength = con.getContentLength();
278-
if (contentLength == -1) {
279-
contentLength = Integer.MAX_VALUE;
280-
}
281-
282-
return IOUtils.readExactlyNBytes(con.getInputStream(),
283-
contentLength);
284+
return (contentLength == -1) ? con.getInputStream().readAllBytes() :
285+
IOUtils.readExactlyNBytes(con.getInputStream(),
286+
contentLength);
284287
} finally {
285288
if (con != null) {
286289
con.disconnect();

‎test/jdk/java/security/cert/CertPathValidator/OCSP/GetAndPostTests.java

+7-6
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -60,6 +60,8 @@
6060
import java.util.Map;
6161
import java.util.Objects;
6262
import java.util.Set;
63+
import java.util.concurrent.TimeUnit;
64+
6365
import sun.security.testlibrary.SimpleOCSPServer;
6466
import sun.security.testlibrary.SimpleOCSPServer;
6567
import sun.security.testlibrary.SimpleOCSPServer;
@@ -114,11 +116,10 @@ public static void main(String args[]) throws Exception {
114116
SimpleOCSPServer.CertStatus.CERT_STATUS_GOOD)));
115117
ocspResponder.start();
116118
// Wait 5 seconds for server ready
117-
for (int i = 0; (i < 100 && !ocspResponder.isServerReady()); i++) {
118-
Thread.sleep(50);
119-
}
120-
if (!ocspResponder.isServerReady()) {
121-
throw new RuntimeException("Server not ready yet");
119+
boolean readyStatus =
120+
ocspResponder.awaitServerReady(5, TimeUnit.SECONDS);
121+
if (!readyStatus) {
122+
throw new RuntimeException("Server not ready");
122123
}
123124

124125
int ocspPort = ocspResponder.getPort();

‎test/jdk/java/security/testlibrary/SimpleOCSPServer.java

+40-13
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2015, 2021, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -84,10 +84,11 @@ public static enum CertStatus {
8484
private boolean logEnabled = false;
8585
private ExecutorService threadPool;
8686
private volatile boolean started = false;
87-
private volatile boolean serverReady = false;
87+
private CountDownLatch serverReady = new CountDownLatch(1);
8888
private volatile boolean receivedShutdown = false;
8989
private volatile boolean acceptConnections = true;
9090
private volatile long delayMsec = 0;
91+
private boolean omitContentLength = false;
9192

9293
// Fields used in the generation of responses
9394
private long nextUpdateInterval = -1;
@@ -216,14 +217,15 @@ public void run() {
216217
listenPort), 128);
217218
log("Listening on " + servSocket.getLocalSocketAddress());
218219

219-
// Singal ready
220-
serverReady = true;
221-
222220
// Update the listenPort with the new port number. If
223221
// the server is restarted, it will bind to the same
224222
// port rather than picking a new one.
225223
listenPort = servSocket.getLocalPort();
226224

225+
// Decrement the latch, allowing any waiting entities
226+
// to proceed with their requests.
227+
serverReady.countDown();
228+
227229
// Main dispatch loop
228230
while (!receivedShutdown) {
229231
try {
@@ -257,7 +259,7 @@ public void run() {
257259
// Reset state variables so the server can be restarted
258260
receivedShutdown = false;
259261
started = false;
260-
serverReady = false;
262+
serverReady = new CountDownLatch(1);
261263
}
262264
}
263265
});
@@ -497,7 +499,7 @@ public void setSignatureAlgorithm(String algName)
497499
* server has not yet been bound to a port.
498500
*/
499501
public int getPort() {
500-
if (serverReady) {
502+
if (serverReady.getCount() == 0) {
501503
InetSocketAddress inetSock =
502504
(InetSocketAddress)servSocket.getLocalSocketAddress();
503505
return inetSock.getPort();
@@ -507,12 +509,21 @@ public int getPort() {
507509
}
508510

509511
/**
510-
* Use to check if OCSP server is ready to accept connection.
512+
* Allow SimpleOCSPServer consumers to wait for the server to be in
513+
* the ready state before sending requests.
514+
*
515+
* @param timeout the length of time to wait for the server to be ready
516+
* @param unit the unit of time applied to the timeout parameter
511517
*
512-
* @return true if server ready, false otherwise
518+
* @return true if the server enters the ready state, false if the
519+
* timeout period elapses while the caller is waiting for the server
520+
* to become ready.
521+
*
522+
* @throws InterruptedException if the current thread is interrupted.
513523
*/
514-
public boolean isServerReady() {
515-
return serverReady;
524+
public boolean awaitServerReady(long timeout, TimeUnit unit)
525+
throws InterruptedException {
526+
return serverReady.await(timeout, unit);
516527
}
517528

518529
/**
@@ -531,6 +542,19 @@ public void setDelay(long delayMillis) {
531542
}
532543
}
533544

545+
/**
546+
* Setting to control whether HTTP responses have the Content-Length
547+
* field asserted or not.
548+
*
549+
* @param isDisabled true if the Content-Length field should not be
550+
* asserted, false otherwise.
551+
*/
552+
public void setDisableContentLength(boolean isDisabled) {
553+
if (!started) {
554+
omitContentLength = isDisabled;
555+
}
556+
}
557+
534558
/**
535559
* Log a message to stdout.
536560
*
@@ -776,8 +800,11 @@ public void sendResponse(OutputStream out, LocalOcspResponse resp)
776800

777801
sb.append("HTTP/1.0 200 OK\r\n");
778802
sb.append("Content-Type: application/ocsp-response\r\n");
779-
sb.append("Content-Length: ").append(respBytes.length);
780-
sb.append("\r\n\r\n");
803+
if (!omitContentLength) {
804+
sb.append("Content-Length: ").append(respBytes.length).
805+
append("\r\n");
806+
}
807+
sb.append("\r\n");
781808

782809
out.write(sb.toString().getBytes("UTF-8"));
783810
out.write(respBytes);

‎test/jdk/javax/net/ssl/Stapling/HttpsUrlConnClient.java

+7-11
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2015, 2021, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -562,11 +562,9 @@ private static void createPKI() throws Exception {
562562
rootOcsp.start();
563563

564564
// Wait 5 seconds for server ready
565-
for (int i = 0; (i < 100 && !rootOcsp.isServerReady()); i++) {
566-
Thread.sleep(50);
567-
}
568-
if (!rootOcsp.isServerReady()) {
569-
throw new RuntimeException("Server not ready yet");
565+
boolean readyStatus = rootOcsp.awaitServerReady(5, TimeUnit.SECONDS);
566+
if (!readyStatus) {
567+
throw new RuntimeException("Server not ready");
570568
}
571569

572570
rootOcspPort = rootOcsp.getPort();
@@ -615,11 +613,9 @@ private static void createPKI() throws Exception {
615613
intOcsp.start();
616614

617615
// Wait 5 seconds for server ready
618-
for (int i = 0; (i < 100 && !intOcsp.isServerReady()); i++) {
619-
Thread.sleep(50);
620-
}
621-
if (!intOcsp.isServerReady()) {
622-
throw new RuntimeException("Server not ready yet");
616+
readyStatus = intOcsp.awaitServerReady(5, TimeUnit.SECONDS);
617+
if (!readyStatus) {
618+
throw new RuntimeException("Server not ready");
623619
}
624620

625621
intOcspPort = intOcsp.getPort();

‎test/jdk/javax/net/ssl/Stapling/SSLEngineWithStapling.java

+7-11
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -503,11 +503,9 @@ private static void createPKI() throws Exception {
503503
rootOcsp.start();
504504

505505
// Wait 5 seconds for server ready
506-
for (int i = 0; (i < 100 && !rootOcsp.isServerReady()); i++) {
507-
Thread.sleep(50);
508-
}
509-
if (!rootOcsp.isServerReady()) {
510-
throw new RuntimeException("Server not ready yet");
506+
boolean readyStatus = rootOcsp.awaitServerReady(5, TimeUnit.SECONDS);
507+
if (!readyStatus) {
508+
throw new RuntimeException("Server not ready");
511509
}
512510

513511
rootOcspPort = rootOcsp.getPort();
@@ -556,11 +554,9 @@ private static void createPKI() throws Exception {
556554
intOcsp.start();
557555

558556
// Wait 5 seconds for server ready
559-
for (int i = 0; (i < 100 && !intOcsp.isServerReady()); i++) {
560-
Thread.sleep(50);
561-
}
562-
if (!intOcsp.isServerReady()) {
563-
throw new RuntimeException("Server not ready yet");
557+
readyStatus = intOcsp.awaitServerReady(5, TimeUnit.SECONDS);
558+
if (!readyStatus) {
559+
throw new RuntimeException("Server not ready");
564560
}
565561

566562
intOcspPort = intOcsp.getPort();

‎test/jdk/javax/net/ssl/Stapling/SSLSocketWithStapling.java

+27-41
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -432,11 +432,9 @@ static void testMissingIntermediate(boolean isTls13) throws Exception {
432432
rootOcsp.acceptConnections();
433433

434434
// 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");
435+
boolean rootOcspReady = rootOcsp.awaitServerReady(5, TimeUnit.SECONDS);
436+
if (!rootOcspReady) {
437+
throw new RuntimeException("Server not ready");
440438
}
441439
}
442440

@@ -493,13 +491,11 @@ static void testHardFailFallback(boolean isTls13) throws Exception {
493491
intOcsp.acceptConnections();
494492
rootOcsp.acceptConnections();
495493

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");
494+
// Wait up to 5 seconds for each server
495+
boolean rootOcspReady = rootOcsp.awaitServerReady(5, TimeUnit.SECONDS);
496+
boolean intOcspReady = intOcsp.awaitServerReady(5, TimeUnit.SECONDS);
497+
if (!rootOcspReady || !intOcspReady) {
498+
throw new RuntimeException("Server not ready");
503499
}
504500
}
505501

@@ -563,12 +559,10 @@ static void testSoftFailFallback(boolean isTls13) throws Exception {
563559
rootOcsp.acceptConnections();
564560

565561
// 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");
562+
boolean rootOcspReady = rootOcsp.awaitServerReady(5, TimeUnit.SECONDS);
563+
boolean intOcspReady = intOcsp.awaitServerReady(5, TimeUnit.SECONDS);
564+
if (!rootOcspReady || !intOcspReady) {
565+
throw new RuntimeException("Server not ready");
572566
}
573567
}
574568

@@ -602,12 +596,10 @@ static void testLatencyNoStaple(Boolean fallback, boolean isTls13)
602596
Thread.sleep(1000);
603597

604598
// 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");
599+
boolean rootOcspReady = rootOcsp.awaitServerReady(5, TimeUnit.SECONDS);
600+
boolean intOcspReady = intOcsp.awaitServerReady(5, TimeUnit.SECONDS);
601+
if (!rootOcspReady || !intOcspReady) {
602+
throw new RuntimeException("Server not ready");
611603
}
612604

613605
System.out.println("========================================");
@@ -654,12 +646,10 @@ static void testLatencyNoStaple(Boolean fallback, boolean isTls13)
654646
Thread.sleep(1000);
655647

656648
// 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");
649+
rootOcspReady = rootOcsp.awaitServerReady(5, TimeUnit.SECONDS);
650+
intOcspReady = intOcsp.awaitServerReady(5, TimeUnit.SECONDS);
651+
if (!rootOcspReady || !intOcspReady) {
652+
throw new RuntimeException("Server not ready");
663653
}
664654
}
665655

@@ -959,11 +949,9 @@ private static void createPKI() throws Exception {
959949
rootOcsp.start();
960950

961951
// 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");
952+
boolean readyStatus = rootOcsp.awaitServerReady(5, TimeUnit.SECONDS);
953+
if (!readyStatus) {
954+
throw new RuntimeException("Server not ready");
967955
}
968956

969957
rootOcspPort = rootOcsp.getPort();
@@ -1012,11 +1000,9 @@ private static void createPKI() throws Exception {
10121000
intOcsp.start();
10131001

10141002
// 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");
1003+
readyStatus = intOcsp.awaitServerReady(5, TimeUnit.SECONDS);
1004+
if (!readyStatus) {
1005+
throw new RuntimeException("Server not ready");
10201006
}
10211007

10221008
intOcspPort = intOcsp.getPort();

‎test/jdk/javax/net/ssl/Stapling/StapleEnableProps.java

+7-11
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -696,11 +696,9 @@ private static void createPKI() throws Exception {
696696
rootOcsp.start();
697697

698698
// Wait 5 seconds for server ready
699-
for (int i = 0; (i < 100 && !rootOcsp.isServerReady()); i++) {
700-
Thread.sleep(50);
701-
}
702-
if (!rootOcsp.isServerReady()) {
703-
throw new RuntimeException("Server not ready yet");
699+
boolean readyStatus = rootOcsp.awaitServerReady(5, TimeUnit.SECONDS);
700+
if (!readyStatus) {
701+
throw new RuntimeException("Server not ready");
704702
}
705703

706704
rootOcspPort = rootOcsp.getPort();
@@ -749,11 +747,9 @@ private static void createPKI() throws Exception {
749747
intOcsp.start();
750748

751749
// Wait 5 seconds for server ready
752-
for (int i = 0; (i < 100 && !intOcsp.isServerReady()); i++) {
753-
Thread.sleep(50);
754-
}
755-
if (!intOcsp.isServerReady()) {
756-
throw new RuntimeException("Server not ready yet");
750+
readyStatus = intOcsp.awaitServerReady(5, TimeUnit.SECONDS);
751+
if (!readyStatus) {
752+
throw new RuntimeException("Server not ready");
757753
}
758754

759755
intOcspPort = intOcsp.getPort();
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,245 @@
1+
/*
2+
* Copyright (c) 2023, 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+
/*
25+
* @test
26+
* @bug 8296343
27+
* @summary CPVE thrown on missing content-length in OCSP response
28+
* @modules java.base/sun.security.x509
29+
* java.base/sun.security.provider.certpath
30+
* java.base/sun.security.util
31+
* @library ../../../../../java/security/testlibrary
32+
* @build CertificateBuilder SimpleOCSPServer
33+
* @run main/othervm OCSPNoContentLength
34+
*/
35+
36+
import java.io.IOException;
37+
import java.math.BigInteger;
38+
import java.security.KeyPair;
39+
import java.security.KeyPairGenerator;
40+
import java.security.KeyStore;
41+
import java.security.PublicKey;
42+
import java.security.cert.*;
43+
import java.security.cert.X509Certificate;
44+
import java.security.spec.ECGenParameterSpec;
45+
import java.util.*;
46+
import java.util.concurrent.TimeUnit;
47+
48+
49+
import sun.security.testlibrary.SimpleOCSPServer;
50+
import sun.security.testlibrary.CertificateBuilder;
51+
52+
public class OCSPNoContentLength {
53+
54+
static String passwd = "passphrase";
55+
static String ROOT_ALIAS = "root";
56+
static String EE_ALIAS = "endentity";
57+
58+
// Enable debugging for additional output
59+
static final boolean debug = false;
60+
61+
// PKI components we will need for this test
62+
static X509Certificate rootCert; // The root CA certificate
63+
static X509Certificate eeCert; // The end entity certificate
64+
static KeyStore rootKeystore; // Root CA Keystore
65+
static KeyStore eeKeystore; // End Entity Keystore
66+
static KeyStore trustStore; // SSL Client trust store
67+
static SimpleOCSPServer rootOcsp; // Root CA OCSP Responder
68+
static int rootOcspPort; // Port number for root OCSP
69+
70+
71+
public static void main(String[] args) throws Exception {
72+
73+
try {
74+
createPKI();
75+
76+
CertificateFactory cf = CertificateFactory.getInstance("X.509");
77+
CertPath path = cf.generateCertPath(List.of(eeCert));
78+
log("%s", path);
79+
80+
TrustAnchor anchor = new TrustAnchor(rootCert, null);
81+
log("%s", anchor);
82+
Set<TrustAnchor> anchors = Set.of(anchor);
83+
84+
CertPathValidator validator = CertPathValidator.getInstance("PKIX");
85+
PKIXParameters params = new PKIXParameters(anchors);
86+
PKIXRevocationChecker prc =
87+
(PKIXRevocationChecker)validator.getRevocationChecker();
88+
params.addCertPathChecker(prc);
89+
90+
validator.validate(path, params);
91+
} finally {
92+
rootOcsp.stop();
93+
}
94+
}
95+
96+
97+
/**
98+
* Creates the PKI components necessary for this test, including
99+
* Root CA, Intermediate CA and SSL server certificates, the keystores
100+
* for each entity, a client trust store, and starts the OCSP responders.
101+
*/
102+
private static void createPKI() throws Exception {
103+
CertificateBuilder cbld = new CertificateBuilder();
104+
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("EC");
105+
keyGen.initialize(new ECGenParameterSpec("secp256r1"));
106+
KeyStore.Builder keyStoreBuilder =
107+
KeyStore.Builder.newInstance("PKCS12", null,
108+
new KeyStore.PasswordProtection(passwd.toCharArray()));
109+
110+
// Generate Root and EE keys
111+
KeyPair rootCaKP = keyGen.genKeyPair();
112+
log("Generated Root CA KeyPair");
113+
KeyPair eeKP = keyGen.genKeyPair();
114+
log("Generated End Entity KeyPair");
115+
116+
// Set up the Root CA Cert
117+
cbld.setSubjectName("CN=Root CA Cert, O=SomeCompany");
118+
cbld.setPublicKey(rootCaKP.getPublic());
119+
cbld.setSerialNumber(new BigInteger("1"));
120+
// Make a 3 year validity starting from 60 days ago
121+
long start = System.currentTimeMillis() - TimeUnit.DAYS.toMillis(60);
122+
long end = start + TimeUnit.DAYS.toMillis(1085);
123+
cbld.setValidity(new Date(start), new Date(end));
124+
addCommonExts(cbld, rootCaKP.getPublic(), rootCaKP.getPublic());
125+
addCommonCAExts(cbld);
126+
// Make our Root CA Cert!
127+
rootCert = cbld.build(null, rootCaKP.getPrivate(),
128+
"SHA256withECDSA");
129+
log("Root CA Created:\n%s", certInfo(rootCert));
130+
131+
// Now build a keystore and add the keys and cert
132+
rootKeystore = keyStoreBuilder.getKeyStore();
133+
Certificate[] rootChain = {rootCert};
134+
rootKeystore.setKeyEntry(ROOT_ALIAS, rootCaKP.getPrivate(),
135+
passwd.toCharArray(), rootChain);
136+
137+
// Now fire up the OCSP responder
138+
rootOcsp = new SimpleOCSPServer(rootKeystore, passwd, ROOT_ALIAS, null);
139+
rootOcsp.enableLog(debug);
140+
rootOcsp.setNextUpdateInterval(3600);
141+
rootOcsp.setDisableContentLength(true);
142+
rootOcsp.start();
143+
144+
// Wait 5 seconds for server ready
145+
boolean readyStatus = rootOcsp.awaitServerReady(5, TimeUnit.SECONDS);
146+
if (!readyStatus) {
147+
throw new RuntimeException("Server not ready");
148+
}
149+
150+
rootOcspPort = rootOcsp.getPort();
151+
String rootRespURI = "http://localhost:" + rootOcspPort;
152+
log("Root OCSP Responder URI is %s", rootRespURI);
153+
154+
// Now that we have the root keystore and OCSP responder we can
155+
// create our end entity certificate
156+
cbld.reset();
157+
cbld.setSubjectName("CN=SSLCertificate, O=SomeCompany");
158+
cbld.setPublicKey(eeKP.getPublic());
159+
cbld.setSerialNumber(new BigInteger("4096"));
160+
// Make a 1 year validity starting from 7 days ago
161+
start = System.currentTimeMillis() - TimeUnit.DAYS.toMillis(7);
162+
end = start + TimeUnit.DAYS.toMillis(365);
163+
cbld.setValidity(new Date(start), new Date(end));
164+
165+
// Add extensions
166+
addCommonExts(cbld, eeKP.getPublic(), rootCaKP.getPublic());
167+
boolean[] kuBits = {true, false, false, false, false, false,
168+
false, false, false};
169+
cbld.addKeyUsageExt(kuBits);
170+
List<String> ekuOids = new ArrayList<>();
171+
ekuOids.add("1.3.6.1.5.5.7.3.1");
172+
ekuOids.add("1.3.6.1.5.5.7.3.2");
173+
cbld.addExtendedKeyUsageExt(ekuOids);
174+
cbld.addSubjectAltNameDNSExt(Collections.singletonList("localhost"));
175+
cbld.addAIAExt(Collections.singletonList(rootRespURI));
176+
// Make our End Entity Cert!
177+
eeCert = cbld.build(rootCert, rootCaKP.getPrivate(),
178+
"SHA256withECDSA");
179+
log("SSL Certificate Created:\n%s", certInfo(eeCert));
180+
181+
// Provide end entity cert revocation info to the Root CA
182+
// OCSP responder.
183+
Map<BigInteger, SimpleOCSPServer.CertStatusInfo> revInfo =
184+
new HashMap<>();
185+
revInfo.put(eeCert.getSerialNumber(),
186+
new SimpleOCSPServer.CertStatusInfo(
187+
SimpleOCSPServer.CertStatus.CERT_STATUS_GOOD));
188+
rootOcsp.updateStatusDb(revInfo);
189+
190+
// Now build a keystore and add the keys, chain and root cert as a TA
191+
eeKeystore = keyStoreBuilder.getKeyStore();
192+
Certificate[] eeChain = {eeCert, rootCert};
193+
eeKeystore.setKeyEntry(EE_ALIAS, eeKP.getPrivate(),
194+
passwd.toCharArray(), eeChain);
195+
eeKeystore.setCertificateEntry(ROOT_ALIAS, rootCert);
196+
197+
// And finally a Trust Store for the client
198+
trustStore = keyStoreBuilder.getKeyStore();
199+
trustStore.setCertificateEntry(ROOT_ALIAS, rootCert);
200+
}
201+
202+
private static void addCommonExts(CertificateBuilder cbld,
203+
PublicKey subjKey, PublicKey authKey) throws IOException {
204+
cbld.addSubjectKeyIdExt(subjKey);
205+
cbld.addAuthorityKeyIdExt(authKey);
206+
}
207+
208+
private static void addCommonCAExts(CertificateBuilder cbld)
209+
throws IOException {
210+
cbld.addBasicConstraintsExt(true, true, -1);
211+
// Set key usage bits for digitalSignature, keyCertSign and cRLSign
212+
boolean[] kuBitSettings = {true, false, false, false, false, true,
213+
true, false, false};
214+
cbld.addKeyUsageExt(kuBitSettings);
215+
}
216+
217+
/**
218+
* Helper routine that dumps only a few cert fields rather than
219+
* the whole toString() output.
220+
*
221+
* @param cert an X509Certificate to be displayed
222+
*
223+
* @return the String output of the issuer, subject and
224+
* serial number
225+
*/
226+
private static String certInfo(X509Certificate cert) {
227+
StringBuilder sb = new StringBuilder();
228+
sb.append("Issuer: ").append(cert.getIssuerX500Principal()).
229+
append("\n");
230+
sb.append("Subject: ").append(cert.getSubjectX500Principal()).
231+
append("\n");
232+
sb.append("Serial: ").append(cert.getSerialNumber()).append("\n");
233+
return sb.toString();
234+
}
235+
236+
/**
237+
* Log a message on stdout
238+
*
239+
* @param format the format string for the log entry
240+
* @param args zero or more arguments corresponding to the format string
241+
*/
242+
private static void log(String format, Object ... args) {
243+
System.out.format(format + "\n", args);
244+
}
245+
}

‎test/jdk/sun/security/ssl/Stapling/java.base/sun/security/ssl/StatusResponseManagerTests.java

+7-11
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -304,11 +304,9 @@ private static void createPKI() throws Exception {
304304
rootOcsp.start();
305305

306306
// Wait 5 seconds for server ready
307-
for (int i = 0; (i < 100 && !rootOcsp.isServerReady()); i++) {
308-
Thread.sleep(50);
309-
}
310-
if (!rootOcsp.isServerReady()) {
311-
throw new RuntimeException("Server not ready yet");
307+
boolean readyStatus = rootOcsp.awaitServerReady(5, TimeUnit.SECONDS);
308+
if (!readyStatus) {
309+
throw new RuntimeException("Server not ready");
312310
}
313311

314312
rootOcspPort = rootOcsp.getPort();
@@ -357,11 +355,9 @@ private static void createPKI() throws Exception {
357355
intOcsp.start();
358356

359357
// Wait 5 seconds for server ready
360-
for (int i = 0; (i < 100 && !intOcsp.isServerReady()); i++) {
361-
Thread.sleep(50);
362-
}
363-
if (!intOcsp.isServerReady()) {
364-
throw new RuntimeException("Server not ready yet");
358+
readyStatus = intOcsp.awaitServerReady(5, TimeUnit.SECONDS);
359+
if (!readyStatus) {
360+
throw new RuntimeException("Server not ready");
365361
}
366362

367363
intOcspPort = intOcsp.getPort();

0 commit comments

Comments
 (0)
Please sign in to comment.