diff --git a/src/java.base/share/classes/sun/security/provider/certpath/OCSP.java b/src/java.base/share/classes/sun/security/provider/certpath/OCSP.java index eaef53598b7..825bb427589 100644 --- a/src/java.base/share/classes/sun/security/provider/certpath/OCSP.java +++ b/src/java.base/share/classes/sun/security/provider/certpath/OCSP.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -206,20 +206,23 @@ public final class OCSP { out.flush(); } - // Check the response - if (debug != null && - con.getResponseCode() != HttpURLConnection.HTTP_OK) { - debug.println("Received HTTP error: " + con.getResponseCode() - + " - " + con.getResponseMessage()); + // Check the response. Non-200 codes will generate an exception + // but path validation may complete successfully if revocation info + // can be obtained elsewhere (e.g. CRL). + int respCode = con.getResponseCode(); + if (respCode != HttpURLConnection.HTTP_OK) { + String msg = "Received HTTP error: " + respCode + " - " + + con.getResponseMessage(); + if (debug != null) { + debug.println(msg); + } + throw new IOException(msg); } int contentLength = con.getContentLength(); - if (contentLength == -1) { - contentLength = Integer.MAX_VALUE; - } - - return IOUtils.readExactlyNBytes(con.getInputStream(), - contentLength); + return (contentLength == -1) ? con.getInputStream().readAllBytes() : + IOUtils.readExactlyNBytes(con.getInputStream(), + contentLength); } finally { if (con != null) { con.disconnect(); diff --git a/test/jdk/java/security/cert/CertPathValidator/OCSP/GetAndPostTests.java b/test/jdk/java/security/cert/CertPathValidator/OCSP/GetAndPostTests.java index d9cf7a5294e..1dc8cba5cc5 100644 --- a/test/jdk/java/security/cert/CertPathValidator/OCSP/GetAndPostTests.java +++ b/test/jdk/java/security/cert/CertPathValidator/OCSP/GetAndPostTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -60,6 +60,8 @@ import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Set; +import java.util.concurrent.TimeUnit; + import sun.security.testlibrary.SimpleOCSPServer; import sun.security.testlibrary.SimpleOCSPServer; import sun.security.testlibrary.SimpleOCSPServer; @@ -114,11 +116,10 @@ public class GetAndPostTests { SimpleOCSPServer.CertStatus.CERT_STATUS_GOOD))); ocspResponder.start(); // Wait 5 seconds for server ready - for (int i = 0; (i < 100 && !ocspResponder.isServerReady()); i++) { - Thread.sleep(50); - } - if (!ocspResponder.isServerReady()) { - throw new RuntimeException("Server not ready yet"); + boolean readyStatus = + ocspResponder.awaitServerReady(5, TimeUnit.SECONDS); + if (!readyStatus) { + throw new RuntimeException("Server not ready"); } int ocspPort = ocspResponder.getPort(); diff --git a/test/jdk/java/security/testlibrary/SimpleOCSPServer.java b/test/jdk/java/security/testlibrary/SimpleOCSPServer.java index 1518e643ce6..d6ee9419ed9 100644 --- a/test/jdk/java/security/testlibrary/SimpleOCSPServer.java +++ b/test/jdk/java/security/testlibrary/SimpleOCSPServer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -84,10 +84,11 @@ public class SimpleOCSPServer { private boolean logEnabled = false; private ExecutorService threadPool; private volatile boolean started = false; - private volatile boolean serverReady = false; + private CountDownLatch serverReady = new CountDownLatch(1); private volatile boolean receivedShutdown = false; private volatile boolean acceptConnections = true; private volatile long delayMsec = 0; + private boolean omitContentLength = false; // Fields used in the generation of responses private long nextUpdateInterval = -1; @@ -216,14 +217,15 @@ public class SimpleOCSPServer { listenPort), 128); log("Listening on " + servSocket.getLocalSocketAddress()); - // Singal ready - serverReady = true; - // Update the listenPort with the new port number. If // the server is restarted, it will bind to the same // port rather than picking a new one. listenPort = servSocket.getLocalPort(); + // Decrement the latch, allowing any waiting entities + // to proceed with their requests. + serverReady.countDown(); + // Main dispatch loop while (!receivedShutdown) { try { @@ -257,7 +259,7 @@ public class SimpleOCSPServer { // Reset state variables so the server can be restarted receivedShutdown = false; started = false; - serverReady = false; + serverReady = new CountDownLatch(1); } } }); @@ -497,7 +499,7 @@ public class SimpleOCSPServer { * server has not yet been bound to a port. */ public int getPort() { - if (serverReady) { + if (serverReady.getCount() == 0) { InetSocketAddress inetSock = (InetSocketAddress)servSocket.getLocalSocketAddress(); return inetSock.getPort(); @@ -507,12 +509,21 @@ public class SimpleOCSPServer { } /** - * Use to check if OCSP server is ready to accept connection. + * Allow SimpleOCSPServer consumers to wait for the server to be in + * the ready state before sending requests. * - * @return true if server ready, false otherwise + * @param timeout the length of time to wait for the server to be ready + * @param unit the unit of time applied to the timeout parameter + * + * @return true if the server enters the ready state, false if the + * timeout period elapses while the caller is waiting for the server + * to become ready. + * + * @throws InterruptedException if the current thread is interrupted. */ - public boolean isServerReady() { - return serverReady; + public boolean awaitServerReady(long timeout, TimeUnit unit) + throws InterruptedException { + return serverReady.await(timeout, unit); } /** @@ -531,6 +542,19 @@ public class SimpleOCSPServer { } } + /** + * Setting to control whether HTTP responses have the Content-Length + * field asserted or not. + * + * @param isDisabled true if the Content-Length field should not be + * asserted, false otherwise. + */ + public void setDisableContentLength(boolean isDisabled) { + if (!started) { + omitContentLength = isDisabled; + } + } + /** * Log a message to stdout. * @@ -776,8 +800,11 @@ public class SimpleOCSPServer { sb.append("HTTP/1.0 200 OK\r\n"); sb.append("Content-Type: application/ocsp-response\r\n"); - sb.append("Content-Length: ").append(respBytes.length); - sb.append("\r\n\r\n"); + if (!omitContentLength) { + sb.append("Content-Length: ").append(respBytes.length). + append("\r\n"); + } + sb.append("\r\n"); out.write(sb.toString().getBytes("UTF-8")); out.write(respBytes); diff --git a/test/jdk/javax/net/ssl/Stapling/HttpsUrlConnClient.java b/test/jdk/javax/net/ssl/Stapling/HttpsUrlConnClient.java index 8fedde9b985..72a68cdddb0 100644 --- a/test/jdk/javax/net/ssl/Stapling/HttpsUrlConnClient.java +++ b/test/jdk/javax/net/ssl/Stapling/HttpsUrlConnClient.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -562,11 +562,9 @@ public class HttpsUrlConnClient { rootOcsp.start(); // Wait 5 seconds for server ready - for (int i = 0; (i < 100 && !rootOcsp.isServerReady()); i++) { - Thread.sleep(50); - } - if (!rootOcsp.isServerReady()) { - throw new RuntimeException("Server not ready yet"); + boolean readyStatus = rootOcsp.awaitServerReady(5, TimeUnit.SECONDS); + if (!readyStatus) { + throw new RuntimeException("Server not ready"); } rootOcspPort = rootOcsp.getPort(); @@ -615,11 +613,9 @@ public class HttpsUrlConnClient { intOcsp.start(); // Wait 5 seconds for server ready - for (int i = 0; (i < 100 && !intOcsp.isServerReady()); i++) { - Thread.sleep(50); - } - if (!intOcsp.isServerReady()) { - throw new RuntimeException("Server not ready yet"); + readyStatus = intOcsp.awaitServerReady(5, TimeUnit.SECONDS); + if (!readyStatus) { + throw new RuntimeException("Server not ready"); } intOcspPort = intOcsp.getPort(); diff --git a/test/jdk/javax/net/ssl/Stapling/SSLEngineWithStapling.java b/test/jdk/javax/net/ssl/Stapling/SSLEngineWithStapling.java index 47f796a1974..ec869f83431 100644 --- a/test/jdk/javax/net/ssl/Stapling/SSLEngineWithStapling.java +++ b/test/jdk/javax/net/ssl/Stapling/SSLEngineWithStapling.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -503,11 +503,9 @@ public class SSLEngineWithStapling { rootOcsp.start(); // Wait 5 seconds for server ready - for (int i = 0; (i < 100 && !rootOcsp.isServerReady()); i++) { - Thread.sleep(50); - } - if (!rootOcsp.isServerReady()) { - throw new RuntimeException("Server not ready yet"); + boolean readyStatus = rootOcsp.awaitServerReady(5, TimeUnit.SECONDS); + if (!readyStatus) { + throw new RuntimeException("Server not ready"); } rootOcspPort = rootOcsp.getPort(); @@ -556,11 +554,9 @@ public class SSLEngineWithStapling { intOcsp.start(); // Wait 5 seconds for server ready - for (int i = 0; (i < 100 && !intOcsp.isServerReady()); i++) { - Thread.sleep(50); - } - if (!intOcsp.isServerReady()) { - throw new RuntimeException("Server not ready yet"); + readyStatus = intOcsp.awaitServerReady(5, TimeUnit.SECONDS); + if (!readyStatus) { + throw new RuntimeException("Server not ready"); } intOcspPort = intOcsp.getPort(); diff --git a/test/jdk/javax/net/ssl/Stapling/SSLSocketWithStapling.java b/test/jdk/javax/net/ssl/Stapling/SSLSocketWithStapling.java index eb0dcaf67d7..7e1473c2828 100644 --- a/test/jdk/javax/net/ssl/Stapling/SSLSocketWithStapling.java +++ b/test/jdk/javax/net/ssl/Stapling/SSLSocketWithStapling.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -432,11 +432,9 @@ public class SSLSocketWithStapling { rootOcsp.acceptConnections(); // Wait 5 seconds for server ready - for (int i = 0; (i < 100 && !rootOcsp.isServerReady()); i++) { - Thread.sleep(50); - } - if (!rootOcsp.isServerReady()) { - throw new RuntimeException("Root OCSP responder not ready yet"); + boolean rootOcspReady = rootOcsp.awaitServerReady(5, TimeUnit.SECONDS); + if (!rootOcspReady) { + throw new RuntimeException("Server not ready"); } } @@ -493,13 +491,11 @@ public class SSLSocketWithStapling { intOcsp.acceptConnections(); rootOcsp.acceptConnections(); - // Wait 5 seconds for server ready - for (int i = 0; (i < 100 && (!intOcsp.isServerReady() || - !rootOcsp.isServerReady())); i++) { - Thread.sleep(50); - } - if (!intOcsp.isServerReady() || !rootOcsp.isServerReady()) { - throw new RuntimeException("Server not ready yet"); + // Wait up to 5 seconds for each server + boolean rootOcspReady = rootOcsp.awaitServerReady(5, TimeUnit.SECONDS); + boolean intOcspReady = intOcsp.awaitServerReady(5, TimeUnit.SECONDS); + if (!rootOcspReady || !intOcspReady) { + throw new RuntimeException("Server not ready"); } } @@ -563,12 +559,10 @@ public class SSLSocketWithStapling { rootOcsp.acceptConnections(); // Wait 5 seconds for server ready - for (int i = 0; (i < 100 && (!intOcsp.isServerReady() || - !rootOcsp.isServerReady())); i++) { - Thread.sleep(50); - } - if (!intOcsp.isServerReady() || !rootOcsp.isServerReady()) { - throw new RuntimeException("Server not ready yet"); + boolean rootOcspReady = rootOcsp.awaitServerReady(5, TimeUnit.SECONDS); + boolean intOcspReady = intOcsp.awaitServerReady(5, TimeUnit.SECONDS); + if (!rootOcspReady || !intOcspReady) { + throw new RuntimeException("Server not ready"); } } @@ -602,12 +596,10 @@ public class SSLSocketWithStapling { Thread.sleep(1000); // Wait 5 seconds for server ready - for (int i = 0; (i < 100 && (!intOcsp.isServerReady() || - !rootOcsp.isServerReady())); i++) { - Thread.sleep(50); - } - if (!intOcsp.isServerReady() || !rootOcsp.isServerReady()) { - throw new RuntimeException("Server not ready yet"); + boolean rootOcspReady = rootOcsp.awaitServerReady(5, TimeUnit.SECONDS); + boolean intOcspReady = intOcsp.awaitServerReady(5, TimeUnit.SECONDS); + if (!rootOcspReady || !intOcspReady) { + throw new RuntimeException("Server not ready"); } System.out.println("========================================"); @@ -654,12 +646,10 @@ public class SSLSocketWithStapling { Thread.sleep(1000); // Wait 5 seconds for server ready - for (int i = 0; (i < 100 && (!intOcsp.isServerReady() || - !rootOcsp.isServerReady())); i++) { - Thread.sleep(50); - } - if (!intOcsp.isServerReady() || !rootOcsp.isServerReady()) { - throw new RuntimeException("Server not ready yet"); + rootOcspReady = rootOcsp.awaitServerReady(5, TimeUnit.SECONDS); + intOcspReady = intOcsp.awaitServerReady(5, TimeUnit.SECONDS); + if (!rootOcspReady || !intOcspReady) { + throw new RuntimeException("Server not ready"); } } @@ -959,11 +949,9 @@ public class SSLSocketWithStapling { rootOcsp.start(); // Wait 5 seconds for server ready - for (int i = 0; (i < 100 && !rootOcsp.isServerReady()); i++) { - Thread.sleep(50); - } - if (!rootOcsp.isServerReady()) { - throw new RuntimeException("Server not ready yet"); + boolean readyStatus = rootOcsp.awaitServerReady(5, TimeUnit.SECONDS); + if (!readyStatus) { + throw new RuntimeException("Server not ready"); } rootOcspPort = rootOcsp.getPort(); @@ -1012,11 +1000,9 @@ public class SSLSocketWithStapling { intOcsp.start(); // Wait 5 seconds for server ready - for (int i = 0; (i < 100 && !intOcsp.isServerReady()); i++) { - Thread.sleep(50); - } - if (!intOcsp.isServerReady()) { - throw new RuntimeException("Server not ready yet"); + readyStatus = intOcsp.awaitServerReady(5, TimeUnit.SECONDS); + if (!readyStatus) { + throw new RuntimeException("Server not ready"); } intOcspPort = intOcsp.getPort(); diff --git a/test/jdk/javax/net/ssl/Stapling/StapleEnableProps.java b/test/jdk/javax/net/ssl/Stapling/StapleEnableProps.java index 11cd6b090ec..14651cf3db9 100644 --- a/test/jdk/javax/net/ssl/Stapling/StapleEnableProps.java +++ b/test/jdk/javax/net/ssl/Stapling/StapleEnableProps.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -696,11 +696,9 @@ public class StapleEnableProps { rootOcsp.start(); // Wait 5 seconds for server ready - for (int i = 0; (i < 100 && !rootOcsp.isServerReady()); i++) { - Thread.sleep(50); - } - if (!rootOcsp.isServerReady()) { - throw new RuntimeException("Server not ready yet"); + boolean readyStatus = rootOcsp.awaitServerReady(5, TimeUnit.SECONDS); + if (!readyStatus) { + throw new RuntimeException("Server not ready"); } rootOcspPort = rootOcsp.getPort(); @@ -749,11 +747,9 @@ public class StapleEnableProps { intOcsp.start(); // Wait 5 seconds for server ready - for (int i = 0; (i < 100 && !intOcsp.isServerReady()); i++) { - Thread.sleep(50); - } - if (!intOcsp.isServerReady()) { - throw new RuntimeException("Server not ready yet"); + readyStatus = intOcsp.awaitServerReady(5, TimeUnit.SECONDS); + if (!readyStatus) { + throw new RuntimeException("Server not ready"); } intOcspPort = intOcsp.getPort(); diff --git a/test/jdk/sun/security/provider/certpath/OCSP/OCSPNoContentLength.java b/test/jdk/sun/security/provider/certpath/OCSP/OCSPNoContentLength.java new file mode 100644 index 00000000000..bddde507d1c --- /dev/null +++ b/test/jdk/sun/security/provider/certpath/OCSP/OCSPNoContentLength.java @@ -0,0 +1,245 @@ +/* + * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8296343 + * @summary CPVE thrown on missing content-length in OCSP response + * @modules java.base/sun.security.x509 + * java.base/sun.security.provider.certpath + * java.base/sun.security.util + * @library ../../../../../java/security/testlibrary + * @build CertificateBuilder SimpleOCSPServer + * @run main/othervm OCSPNoContentLength + */ + +import java.io.IOException; +import java.math.BigInteger; +import java.security.KeyPair; +import java.security.KeyPairGenerator; +import java.security.KeyStore; +import java.security.PublicKey; +import java.security.cert.*; +import java.security.cert.X509Certificate; +import java.security.spec.ECGenParameterSpec; +import java.util.*; +import java.util.concurrent.TimeUnit; + + +import sun.security.testlibrary.SimpleOCSPServer; +import sun.security.testlibrary.CertificateBuilder; + +public class OCSPNoContentLength { + + static String passwd = "passphrase"; + static String ROOT_ALIAS = "root"; + static String EE_ALIAS = "endentity"; + + // Enable debugging for additional output + static final boolean debug = false; + + // PKI components we will need for this test + static X509Certificate rootCert; // The root CA certificate + static X509Certificate eeCert; // The end entity certificate + static KeyStore rootKeystore; // Root CA Keystore + static KeyStore eeKeystore; // End Entity Keystore + static KeyStore trustStore; // SSL Client trust store + static SimpleOCSPServer rootOcsp; // Root CA OCSP Responder + static int rootOcspPort; // Port number for root OCSP + + + public static void main(String[] args) throws Exception { + + try { + createPKI(); + + CertificateFactory cf = CertificateFactory.getInstance("X.509"); + CertPath path = cf.generateCertPath(List.of(eeCert)); + log("%s", path); + + TrustAnchor anchor = new TrustAnchor(rootCert, null); + log("%s", anchor); + Set anchors = Set.of(anchor); + + CertPathValidator validator = CertPathValidator.getInstance("PKIX"); + PKIXParameters params = new PKIXParameters(anchors); + PKIXRevocationChecker prc = + (PKIXRevocationChecker)validator.getRevocationChecker(); + params.addCertPathChecker(prc); + + validator.validate(path, params); + } finally { + rootOcsp.stop(); + } + } + + + /** + * Creates the PKI components necessary for this test, including + * Root CA, Intermediate CA and SSL server certificates, the keystores + * for each entity, a client trust store, and starts the OCSP responders. + */ + private static void createPKI() throws Exception { + CertificateBuilder cbld = new CertificateBuilder(); + KeyPairGenerator keyGen = KeyPairGenerator.getInstance("EC"); + keyGen.initialize(new ECGenParameterSpec("secp256r1")); + KeyStore.Builder keyStoreBuilder = + KeyStore.Builder.newInstance("PKCS12", null, + new KeyStore.PasswordProtection(passwd.toCharArray())); + + // Generate Root and EE keys + KeyPair rootCaKP = keyGen.genKeyPair(); + log("Generated Root CA KeyPair"); + KeyPair eeKP = keyGen.genKeyPair(); + log("Generated End Entity KeyPair"); + + // Set up the Root CA Cert + cbld.setSubjectName("CN=Root CA Cert, O=SomeCompany"); + cbld.setPublicKey(rootCaKP.getPublic()); + cbld.setSerialNumber(new BigInteger("1")); + // Make a 3 year validity starting from 60 days ago + long start = System.currentTimeMillis() - TimeUnit.DAYS.toMillis(60); + long end = start + TimeUnit.DAYS.toMillis(1085); + cbld.setValidity(new Date(start), new Date(end)); + addCommonExts(cbld, rootCaKP.getPublic(), rootCaKP.getPublic()); + addCommonCAExts(cbld); + // Make our Root CA Cert! + rootCert = cbld.build(null, rootCaKP.getPrivate(), + "SHA256withECDSA"); + log("Root CA Created:\n%s", certInfo(rootCert)); + + // Now build a keystore and add the keys and cert + rootKeystore = keyStoreBuilder.getKeyStore(); + Certificate[] rootChain = {rootCert}; + rootKeystore.setKeyEntry(ROOT_ALIAS, rootCaKP.getPrivate(), + passwd.toCharArray(), rootChain); + + // Now fire up the OCSP responder + rootOcsp = new SimpleOCSPServer(rootKeystore, passwd, ROOT_ALIAS, null); + rootOcsp.enableLog(debug); + rootOcsp.setNextUpdateInterval(3600); + rootOcsp.setDisableContentLength(true); + rootOcsp.start(); + + // Wait 5 seconds for server ready + boolean readyStatus = rootOcsp.awaitServerReady(5, TimeUnit.SECONDS); + if (!readyStatus) { + throw new RuntimeException("Server not ready"); + } + + rootOcspPort = rootOcsp.getPort(); + String rootRespURI = "http://localhost:" + rootOcspPort; + log("Root OCSP Responder URI is %s", rootRespURI); + + // Now that we have the root keystore and OCSP responder we can + // create our end entity certificate + cbld.reset(); + cbld.setSubjectName("CN=SSLCertificate, O=SomeCompany"); + cbld.setPublicKey(eeKP.getPublic()); + cbld.setSerialNumber(new BigInteger("4096")); + // Make a 1 year validity starting from 7 days ago + start = System.currentTimeMillis() - TimeUnit.DAYS.toMillis(7); + end = start + TimeUnit.DAYS.toMillis(365); + cbld.setValidity(new Date(start), new Date(end)); + + // Add extensions + addCommonExts(cbld, eeKP.getPublic(), rootCaKP.getPublic()); + boolean[] kuBits = {true, false, false, false, false, false, + false, false, false}; + cbld.addKeyUsageExt(kuBits); + List ekuOids = new ArrayList<>(); + ekuOids.add("1.3.6.1.5.5.7.3.1"); + ekuOids.add("1.3.6.1.5.5.7.3.2"); + cbld.addExtendedKeyUsageExt(ekuOids); + cbld.addSubjectAltNameDNSExt(Collections.singletonList("localhost")); + cbld.addAIAExt(Collections.singletonList(rootRespURI)); + // Make our End Entity Cert! + eeCert = cbld.build(rootCert, rootCaKP.getPrivate(), + "SHA256withECDSA"); + log("SSL Certificate Created:\n%s", certInfo(eeCert)); + + // Provide end entity cert revocation info to the Root CA + // OCSP responder. + Map revInfo = + new HashMap<>(); + revInfo.put(eeCert.getSerialNumber(), + new SimpleOCSPServer.CertStatusInfo( + SimpleOCSPServer.CertStatus.CERT_STATUS_GOOD)); + rootOcsp.updateStatusDb(revInfo); + + // Now build a keystore and add the keys, chain and root cert as a TA + eeKeystore = keyStoreBuilder.getKeyStore(); + Certificate[] eeChain = {eeCert, rootCert}; + eeKeystore.setKeyEntry(EE_ALIAS, eeKP.getPrivate(), + passwd.toCharArray(), eeChain); + eeKeystore.setCertificateEntry(ROOT_ALIAS, rootCert); + + // And finally a Trust Store for the client + trustStore = keyStoreBuilder.getKeyStore(); + trustStore.setCertificateEntry(ROOT_ALIAS, rootCert); + } + + private static void addCommonExts(CertificateBuilder cbld, + PublicKey subjKey, PublicKey authKey) throws IOException { + cbld.addSubjectKeyIdExt(subjKey); + cbld.addAuthorityKeyIdExt(authKey); + } + + private static void addCommonCAExts(CertificateBuilder cbld) + throws IOException { + cbld.addBasicConstraintsExt(true, true, -1); + // Set key usage bits for digitalSignature, keyCertSign and cRLSign + boolean[] kuBitSettings = {true, false, false, false, false, true, + true, false, false}; + cbld.addKeyUsageExt(kuBitSettings); + } + + /** + * Helper routine that dumps only a few cert fields rather than + * the whole toString() output. + * + * @param cert an X509Certificate to be displayed + * + * @return the String output of the issuer, subject and + * serial number + */ + private static String certInfo(X509Certificate cert) { + StringBuilder sb = new StringBuilder(); + sb.append("Issuer: ").append(cert.getIssuerX500Principal()). + append("\n"); + sb.append("Subject: ").append(cert.getSubjectX500Principal()). + append("\n"); + sb.append("Serial: ").append(cert.getSerialNumber()).append("\n"); + return sb.toString(); + } + + /** + * Log a message on stdout + * + * @param format the format string for the log entry + * @param args zero or more arguments corresponding to the format string + */ + private static void log(String format, Object ... args) { + System.out.format(format + "\n", args); + } +} \ No newline at end of file diff --git a/test/jdk/sun/security/ssl/Stapling/java.base/sun/security/ssl/StatusResponseManagerTests.java b/test/jdk/sun/security/ssl/Stapling/java.base/sun/security/ssl/StatusResponseManagerTests.java index 8b1647a312d..07058a29c25 100644 --- a/test/jdk/sun/security/ssl/Stapling/java.base/sun/security/ssl/StatusResponseManagerTests.java +++ b/test/jdk/sun/security/ssl/Stapling/java.base/sun/security/ssl/StatusResponseManagerTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -304,11 +304,9 @@ public class StatusResponseManagerTests { rootOcsp.start(); // Wait 5 seconds for server ready - for (int i = 0; (i < 100 && !rootOcsp.isServerReady()); i++) { - Thread.sleep(50); - } - if (!rootOcsp.isServerReady()) { - throw new RuntimeException("Server not ready yet"); + boolean readyStatus = rootOcsp.awaitServerReady(5, TimeUnit.SECONDS); + if (!readyStatus) { + throw new RuntimeException("Server not ready"); } rootOcspPort = rootOcsp.getPort(); @@ -357,11 +355,9 @@ public class StatusResponseManagerTests { intOcsp.start(); // Wait 5 seconds for server ready - for (int i = 0; (i < 100 && !intOcsp.isServerReady()); i++) { - Thread.sleep(50); - } - if (!intOcsp.isServerReady()) { - throw new RuntimeException("Server not ready yet"); + readyStatus = intOcsp.awaitServerReady(5, TimeUnit.SECONDS); + if (!readyStatus) { + throw new RuntimeException("Server not ready"); } intOcspPort = intOcsp.getPort();