mirror of
https://github.com/openjdk/jdk.git
synced 2026-01-28 03:58:21 +00:00
8349759: Add unit test for CertificateBuilder and SimpleOCSPServer test utilities
Reviewed-by: mullan
This commit is contained in:
parent
b45c32cd4f
commit
9d9d7a17d3
230
test/lib-test/jdk/test/lib/security/CPVAlgTestWithOCSP.java
Normal file
230
test/lib-test/jdk/test/lib/security/CPVAlgTestWithOCSP.java
Normal file
@ -0,0 +1,230 @@
|
||||
/*
|
||||
* Copyright (c) 2025, 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 8349759
|
||||
* @summary Test the CertificateBuilder and SimpleOCSPServer test utility
|
||||
* classes using a range of signature algorithms and parameters.
|
||||
* The goal is to test with both no-parameter and parameterized
|
||||
* signature algorithms and use the CertPathValidator to validate
|
||||
* the correctness of the certificate and OCSP server-side structures.
|
||||
* @modules java.base/sun.security.x509
|
||||
* java.base/sun.security.provider.certpath
|
||||
* java.base/sun.security.util
|
||||
* @library /test/lib
|
||||
* @run main/othervm CPVAlgTestWithOCSP RSA
|
||||
* @run main/othervm CPVAlgTestWithOCSP RSA:3072
|
||||
* @run main/othervm CPVAlgTestWithOCSP DSA
|
||||
* @run main/othervm CPVAlgTestWithOCSP DSA:3072
|
||||
* @run main/othervm CPVAlgTestWithOCSP RSASSA-PSS
|
||||
* @run main/othervm CPVAlgTestWithOCSP RSASSA-PSS:3072
|
||||
* @run main/othervm CPVAlgTestWithOCSP RSASSA-PSS:4096:SHA-512:SHA3-384:128:1
|
||||
* @run main/othervm CPVAlgTestWithOCSP EC
|
||||
* @run main/othervm CPVAlgTestWithOCSP EC:secp521r1
|
||||
* @run main/othervm CPVAlgTestWithOCSP Ed25519
|
||||
* @run main/othervm CPVAlgTestWithOCSP ML-DSA-65
|
||||
*/
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.security.*;
|
||||
import java.security.cert.*;
|
||||
import java.security.cert.Certificate;
|
||||
import java.security.spec.*;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import jdk.test.lib.security.SimpleOCSPServer;
|
||||
import jdk.test.lib.security.CertificateBuilder;
|
||||
|
||||
import static java.security.cert.PKIXRevocationChecker.Option.NO_FALLBACK;
|
||||
|
||||
public class CPVAlgTestWithOCSP {
|
||||
|
||||
static final String passwd = "passphrase";
|
||||
static final String ROOT_ALIAS = "root";
|
||||
static final boolean[] CA_KU_FLAGS = {true, false, false, false, false,
|
||||
true, true, false, false};
|
||||
static final boolean[] EE_KU_FLAGS = {true, false, false, false, false,
|
||||
false, false, false, false};
|
||||
static final List<String> EE_EKU_OIDS = List.of("1.3.6.1.5.5.7.3.1",
|
||||
"1.3.6.1.5.5.7.3.2");
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
if (args == null || args.length < 1) {
|
||||
throw new RuntimeException(
|
||||
"Usage: CPVAlgTestWithOCSP <IssKeyAlg>");
|
||||
}
|
||||
String keyGenAlg = args[0];
|
||||
|
||||
// Generate Root and EE keys
|
||||
KeyPairGenerator keyGen = getKpGen(keyGenAlg);
|
||||
KeyPair rootCaKP = keyGen.genKeyPair();
|
||||
KeyPair eeKp = keyGen.genKeyPair();
|
||||
|
||||
// Set up the Root CA Cert
|
||||
// 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);
|
||||
CertificateBuilder cbld = new CertificateBuilder();
|
||||
cbld.setSubjectName("CN=Root CA Cert, O=SomeCompany").
|
||||
setPublicKey(rootCaKP.getPublic()).
|
||||
setSerialNumber(new BigInteger("1")).
|
||||
setValidity(new Date(start), new Date(end)).
|
||||
addSubjectKeyIdExt(rootCaKP.getPublic()).
|
||||
addAuthorityKeyIdExt(rootCaKP.getPublic()).
|
||||
addBasicConstraintsExt(true, true, -1).
|
||||
addKeyUsageExt(CA_KU_FLAGS);
|
||||
|
||||
// Make our Root CA Cert!
|
||||
X509Certificate rootCert = cbld.build(null, rootCaKP.getPrivate());
|
||||
log("Root CA Created:\n%s", rootCert);
|
||||
|
||||
// Now build a keystore and add the keys and cert
|
||||
KeyStore.Builder keyStoreBuilder =
|
||||
KeyStore.Builder.newInstance("PKCS12", null,
|
||||
new KeyStore.PasswordProtection("adminadmin0".toCharArray()));
|
||||
KeyStore rootKeystore = keyStoreBuilder.getKeyStore();
|
||||
Certificate[] rootChain = {rootCert};
|
||||
rootKeystore.setKeyEntry(ROOT_ALIAS, rootCaKP.getPrivate(),
|
||||
passwd.toCharArray(), rootChain);
|
||||
|
||||
// Now fire up the OCSP responder
|
||||
SimpleOCSPServer rootOcsp = new SimpleOCSPServer(rootKeystore,
|
||||
passwd, ROOT_ALIAS, null);
|
||||
rootOcsp.enableLog(true);
|
||||
rootOcsp.setNextUpdateInterval(3600);
|
||||
rootOcsp.start();
|
||||
|
||||
// Wait 60 seconds for server ready
|
||||
boolean readyStatus = rootOcsp.awaitServerReady(60, TimeUnit.SECONDS);
|
||||
if (!readyStatus) {
|
||||
throw new RuntimeException("Server not ready");
|
||||
}
|
||||
int rootOcspPort = rootOcsp.getPort();
|
||||
String rootRespURI = "http://localhost:" + rootOcspPort;
|
||||
log("Root OCSP Responder URI is %s", rootRespURI);
|
||||
|
||||
// Let's make an EE cert
|
||||
// Make a 1 year validity starting from 60 days ago
|
||||
start = System.currentTimeMillis() - TimeUnit.DAYS.toMillis(60);
|
||||
end = start + TimeUnit.DAYS.toMillis(365);
|
||||
cbld.reset().setSubjectName("CN=Brave Sir Robin, O=SomeCompany").
|
||||
setPublicKey(eeKp.getPublic()).
|
||||
setValidity(new Date(start), new Date(end)).
|
||||
addSubjectKeyIdExt(eeKp.getPublic()).
|
||||
addAuthorityKeyIdExt(rootCaKP.getPublic()).
|
||||
addKeyUsageExt(EE_KU_FLAGS).
|
||||
addExtendedKeyUsageExt(EE_EKU_OIDS).
|
||||
addSubjectAltNameDNSExt(Collections.singletonList("localhost")).
|
||||
addAIAExt(Collections.singletonList(rootRespURI));
|
||||
X509Certificate eeCert = cbld.build(rootCert, rootCaKP.getPrivate());
|
||||
log("EE CA Created:\n%s", eeCert);
|
||||
|
||||
// Provide end entity cert revocation info to the Root CA
|
||||
// OCSP responder.
|
||||
Map<BigInteger, SimpleOCSPServer.CertStatusInfo> revInfo =
|
||||
new HashMap<>();
|
||||
revInfo.put(eeCert.getSerialNumber(),
|
||||
new SimpleOCSPServer.CertStatusInfo(
|
||||
SimpleOCSPServer.CertStatus.CERT_STATUS_GOOD));
|
||||
rootOcsp.updateStatusDb(revInfo);
|
||||
|
||||
// validate chain
|
||||
CertPathValidator cpv = CertPathValidator.getInstance("PKIX");
|
||||
PKIXRevocationChecker prc =
|
||||
(PKIXRevocationChecker) cpv.getRevocationChecker();
|
||||
prc.setOptions(EnumSet.of(NO_FALLBACK));
|
||||
PKIXParameters params =
|
||||
new PKIXParameters(Set.of(new TrustAnchor(rootCert, null)));
|
||||
params.addCertPathChecker(prc);
|
||||
CertificateFactory cf = CertificateFactory.getInstance("X.509");
|
||||
CertPath cp = cf.generateCertPath(List.of(eeCert));
|
||||
cpv.validate(cp, params);
|
||||
}
|
||||
|
||||
private static KeyPairGenerator getKpGen(String keyGenAlg)
|
||||
throws GeneralSecurityException {
|
||||
String[] algComps = keyGenAlg.split(":");
|
||||
KeyPairGenerator kpg = KeyPairGenerator.getInstance(algComps[0]);
|
||||
int bitLen;
|
||||
|
||||
// Handle any parameters in additional tokenized fields
|
||||
switch (algComps[0].toUpperCase()) {
|
||||
case "EC":
|
||||
// The curve name will be the second token, or secp256r1
|
||||
// if not provided.
|
||||
String curveName = (algComps.length >= 2) ? algComps[1] :
|
||||
"secp256r1";
|
||||
kpg.initialize(new ECGenParameterSpec(curveName));
|
||||
break;
|
||||
case "RSA":
|
||||
case "DSA":
|
||||
// Form is RSA|DSA[:<KeyBitLen>]
|
||||
bitLen = (algComps.length >= 2) ?
|
||||
Integer.parseInt(algComps[1]) : 2048;
|
||||
kpg.initialize(bitLen);
|
||||
break;
|
||||
case "RSASSA-PSS":
|
||||
// Form is RSASSA-PSS[:<KeyBitLen>[:HASH:MGFHASH:SALTLEN:TR]]
|
||||
switch (algComps.length) {
|
||||
case 1: // Default key length and parameters
|
||||
kpg.initialize(2048);
|
||||
break;
|
||||
case 2: // Specified key length, default params
|
||||
kpg.initialize(Integer.parseInt(algComps[1]));
|
||||
break;
|
||||
default: // len > 2, key length and specified parameters
|
||||
bitLen = Integer.parseInt(algComps[1]);
|
||||
String hashAlg = algComps[2];
|
||||
MGF1ParameterSpec mSpec = (algComps.length >= 4) ?
|
||||
new MGF1ParameterSpec(algComps[3]) :
|
||||
MGF1ParameterSpec.SHA256;
|
||||
int saltLen = (algComps.length >= 5) ?
|
||||
Integer.parseInt(algComps[4]) : 32;
|
||||
int trail = (algComps.length >= 6) ?
|
||||
Integer.parseInt(algComps[5]) :
|
||||
PSSParameterSpec.TRAILER_FIELD_BC;
|
||||
PSSParameterSpec pSpec = new PSSParameterSpec(hashAlg,
|
||||
"MGF1", mSpec, saltLen, trail);
|
||||
kpg.initialize(new RSAKeyGenParameterSpec(bitLen,
|
||||
RSAKeyGenParameterSpec.F4, pSpec));
|
||||
break;
|
||||
}
|
||||
|
||||
// Default: just use the KPG as-is, no additional init needed.
|
||||
}
|
||||
|
||||
return kpg;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
}
|
||||
@ -51,7 +51,6 @@ import sun.security.x509.DNSName;
|
||||
import sun.security.x509.GeneralName;
|
||||
import sun.security.x509.GeneralNames;
|
||||
import sun.security.x509.KeyUsageExtension;
|
||||
import sun.security.x509.SerialNumber;
|
||||
import sun.security.x509.SubjectAlternativeNameExtension;
|
||||
import sun.security.x509.URIName;
|
||||
import sun.security.x509.KeyIdentifier;
|
||||
@ -288,11 +287,8 @@ public class CertificateBuilder {
|
||||
*
|
||||
* @param bitSettings Boolean array for all nine bit settings in the order
|
||||
* documented in RFC 5280 section 4.2.1.3.
|
||||
*
|
||||
* @throws IOException if an encoding error occurs.
|
||||
*/
|
||||
public CertificateBuilder addKeyUsageExt(boolean[] bitSettings)
|
||||
throws IOException {
|
||||
public CertificateBuilder addKeyUsageExt(boolean[] bitSettings) {
|
||||
return addExtension(new KeyUsageExtension(bitSettings));
|
||||
}
|
||||
|
||||
@ -305,11 +301,9 @@ public class CertificateBuilder {
|
||||
* @param maxPathLen The maximum path length issued by this CA. Values
|
||||
* less than zero will omit this field from the resulting extension and
|
||||
* no path length constraint will be asserted.
|
||||
*
|
||||
* @throws IOException if an encoding error occurs.
|
||||
*/
|
||||
public CertificateBuilder addBasicConstraintsExt(boolean crit, boolean isCA,
|
||||
int maxPathLen) throws IOException {
|
||||
int maxPathLen) {
|
||||
return addExtension(new BasicConstraintsExtension(crit, isCA,
|
||||
maxPathLen));
|
||||
}
|
||||
@ -389,7 +383,27 @@ public class CertificateBuilder {
|
||||
}
|
||||
|
||||
/**
|
||||
* Build the certificate.
|
||||
* Build the certificate using the default algorithm for the provided
|
||||
* signing key.
|
||||
*
|
||||
* @param issuerCert The certificate of the issuing authority, or
|
||||
* {@code null} if the resulting certificate is self-signed.
|
||||
* @param issuerKey The private key of the issuing authority
|
||||
*
|
||||
* @return The resulting {@link X509Certificate}
|
||||
*
|
||||
* @throws IOException if an encoding error occurs.
|
||||
* @throws CertificateException If the certificate cannot be generated
|
||||
* by the underlying {@link CertificateFactory}
|
||||
*/
|
||||
public X509Certificate build(X509Certificate issuerCert,
|
||||
PrivateKey issuerKey) throws IOException, CertificateException {
|
||||
return build(issuerCert, issuerKey,
|
||||
SignatureUtil.getDefaultSigAlgForKey(issuerKey));
|
||||
}
|
||||
|
||||
/**
|
||||
* Build the certificate using the key and specified signing algorithm.
|
||||
*
|
||||
* @param issuerCert The certificate of the issuing authority, or
|
||||
* {@code null} if the resulting certificate is self-signed.
|
||||
@ -401,14 +415,10 @@ public class CertificateBuilder {
|
||||
* @throws IOException if an encoding error occurs.
|
||||
* @throws CertificateException If the certificate cannot be generated
|
||||
* by the underlying {@link CertificateFactory}
|
||||
* @throws NoSuchAlgorithmException If an invalid signature algorithm
|
||||
* is provided.
|
||||
*/
|
||||
public X509Certificate build(X509Certificate issuerCert,
|
||||
PrivateKey issuerKey, String algName)
|
||||
throws IOException, CertificateException, NoSuchAlgorithmException {
|
||||
// TODO: add some basic checks (key usage, basic constraints maybe)
|
||||
|
||||
throws IOException, CertificateException {
|
||||
byte[] encodedCert = encodeTopLevel(issuerCert, issuerKey, algName);
|
||||
ByteArrayInputStream bais = new ByteArrayInputStream(encodedCert);
|
||||
return (X509Certificate)factory.generateCertificate(bais);
|
||||
@ -437,15 +447,14 @@ public class CertificateBuilder {
|
||||
*/
|
||||
private byte[] encodeTopLevel(X509Certificate issuerCert,
|
||||
PrivateKey issuerKey, String algName)
|
||||
throws CertificateException, IOException, NoSuchAlgorithmException {
|
||||
throws CertificateException, IOException {
|
||||
|
||||
AlgorithmId signAlg = AlgorithmId.get(algName);
|
||||
AlgorithmId signAlg;
|
||||
DerOutputStream outerSeq = new DerOutputStream();
|
||||
DerOutputStream topLevelItems = new DerOutputStream();
|
||||
|
||||
try {
|
||||
Signature sig = SignatureUtil.fromKey(signAlg.getName(), issuerKey, (Provider)null);
|
||||
// Rewrite signAlg, RSASSA-PSS needs some parameters.
|
||||
Signature sig = SignatureUtil.fromKey(algName, issuerKey, "");
|
||||
signAlg = SignatureUtil.fromSignature(sig, issuerKey);
|
||||
tbsCertBytes = encodeTbsCert(issuerCert, signAlg);
|
||||
sig.update(tbsCertBytes);
|
||||
@ -566,7 +575,6 @@ public class CertificateBuilder {
|
||||
*/
|
||||
private void encodeExtensions(DerOutputStream tbsStream)
|
||||
throws IOException {
|
||||
|
||||
if (extensions.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -25,6 +25,7 @@ package jdk.test.lib.security;
|
||||
|
||||
import java.io.*;
|
||||
import java.net.*;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.*;
|
||||
import java.security.cert.CRLReason;
|
||||
import java.security.cert.X509Certificate;
|
||||
@ -61,7 +62,7 @@ public class SimpleOCSPServer {
|
||||
static final int FREE_PORT = 0;
|
||||
|
||||
// CertStatus values
|
||||
public static enum CertStatus {
|
||||
public enum CertStatus {
|
||||
CERT_STATUS_GOOD,
|
||||
CERT_STATUS_REVOKED,
|
||||
CERT_STATUS_UNKNOWN,
|
||||
@ -69,14 +70,14 @@ public class SimpleOCSPServer {
|
||||
|
||||
// Fields used for the networking portion of the responder
|
||||
private ServerSocket servSocket;
|
||||
private InetAddress listenAddress;
|
||||
private final InetAddress listenAddress;
|
||||
private int listenPort;
|
||||
|
||||
// Keystore information (certs, keys, etc.)
|
||||
private KeyStore keystore;
|
||||
private X509Certificate issuerCert;
|
||||
private X509Certificate signerCert;
|
||||
private PrivateKey signerKey;
|
||||
private final KeyStore keystore;
|
||||
private final X509Certificate issuerCert;
|
||||
private final X509Certificate signerCert;
|
||||
private final PrivateKey signerKey;
|
||||
|
||||
// Fields used for the operational portions of the server
|
||||
private boolean logEnabled = false;
|
||||
@ -91,9 +92,9 @@ public class SimpleOCSPServer {
|
||||
// Fields used in the generation of responses
|
||||
private long nextUpdateInterval = -1;
|
||||
private Date nextUpdate = null;
|
||||
private ResponderId respId;
|
||||
private AlgorithmId sigAlgId;
|
||||
private Map<CertId, CertStatusInfo> statusDb =
|
||||
private final ResponderId respId;
|
||||
private String sigAlgName;
|
||||
private final Map<CertId, CertStatusInfo> statusDb =
|
||||
Collections.synchronizedMap(new HashMap<>());
|
||||
|
||||
/**
|
||||
@ -140,25 +141,24 @@ public class SimpleOCSPServer {
|
||||
public SimpleOCSPServer(InetAddress addr, int port, KeyStore ks,
|
||||
String password, String issuerAlias, String signerAlias)
|
||||
throws GeneralSecurityException, IOException {
|
||||
Objects.requireNonNull(ks, "Null keystore provided");
|
||||
keystore = Objects.requireNonNull(ks, "Null keystore provided");
|
||||
Objects.requireNonNull(issuerAlias, "Null issuerName provided");
|
||||
|
||||
utcDateFmt.setTimeZone(TimeZone.getTimeZone("GMT"));
|
||||
|
||||
keystore = ks;
|
||||
issuerCert = (X509Certificate)ks.getCertificate(issuerAlias);
|
||||
issuerCert = (X509Certificate)keystore.getCertificate(issuerAlias);
|
||||
if (issuerCert == null) {
|
||||
throw new IllegalArgumentException("Certificate for alias " +
|
||||
issuerAlias + " not found");
|
||||
}
|
||||
|
||||
if (signerAlias != null) {
|
||||
signerCert = (X509Certificate)ks.getCertificate(signerAlias);
|
||||
signerCert = (X509Certificate)keystore.getCertificate(signerAlias);
|
||||
if (signerCert == null) {
|
||||
throw new IllegalArgumentException("Certificate for alias " +
|
||||
signerAlias + " not found");
|
||||
}
|
||||
signerKey = (PrivateKey)ks.getKey(signerAlias,
|
||||
signerKey = (PrivateKey)keystore.getKey(signerAlias,
|
||||
password.toCharArray());
|
||||
if (signerKey == null) {
|
||||
throw new IllegalArgumentException("PrivateKey for alias " +
|
||||
@ -166,14 +166,14 @@ public class SimpleOCSPServer {
|
||||
}
|
||||
} else {
|
||||
signerCert = issuerCert;
|
||||
signerKey = (PrivateKey)ks.getKey(issuerAlias,
|
||||
signerKey = (PrivateKey)keystore.getKey(issuerAlias,
|
||||
password.toCharArray());
|
||||
if (signerKey == null) {
|
||||
throw new IllegalArgumentException("PrivateKey for alias " +
|
||||
issuerAlias + " not found");
|
||||
}
|
||||
}
|
||||
sigAlgId = AlgorithmId.get(SignatureUtil.getDefaultSigAlgForKey(signerKey));
|
||||
sigAlgName = SignatureUtil.getDefaultSigAlgForKey(signerKey);
|
||||
respId = new ResponderId(signerCert.getSubjectX500Principal());
|
||||
listenAddress = addr;
|
||||
listenPort = port;
|
||||
@ -495,8 +495,14 @@ public class SimpleOCSPServer {
|
||||
public void setSignatureAlgorithm(String algName)
|
||||
throws NoSuchAlgorithmException {
|
||||
if (!started) {
|
||||
sigAlgId = AlgorithmId.get(algName);
|
||||
log("Signature algorithm set to " + sigAlgId.getName());
|
||||
// We don't care about the AlgorithmId object, we're just
|
||||
// using it to validate the algName parameter.
|
||||
AlgorithmId.get(algName);
|
||||
sigAlgName = algName;
|
||||
log("Signature algorithm set to " + algName);
|
||||
} else {
|
||||
log("Signature algorithm cannot be set on a running server, " +
|
||||
"stop the server first");
|
||||
}
|
||||
}
|
||||
|
||||
@ -604,9 +610,9 @@ public class SimpleOCSPServer {
|
||||
* object may be used to construct OCSP responses.
|
||||
*/
|
||||
public static class CertStatusInfo {
|
||||
private CertStatus certStatusType;
|
||||
private final CertStatus certStatusType;
|
||||
private CRLReason reason;
|
||||
private Date revocationTime;
|
||||
private final Date revocationTime;
|
||||
|
||||
/**
|
||||
* Create a Certificate status object by providing the status only.
|
||||
@ -745,7 +751,7 @@ public class SimpleOCSPServer {
|
||||
// This will be tokenized so we know if we are dealing with
|
||||
// a GET or POST.
|
||||
String[] headerTokens = readLine(in).split(" ");
|
||||
LocalOcspRequest ocspReq = null;
|
||||
LocalOcspRequest ocspReq;
|
||||
LocalOcspResponse ocspResp = null;
|
||||
ResponseStatus respStat = ResponseStatus.INTERNAL_ERROR;
|
||||
try {
|
||||
@ -794,7 +800,7 @@ public class SimpleOCSPServer {
|
||||
out.flush();
|
||||
|
||||
log("Closing " + ocspSocket);
|
||||
} catch (IOException | CertificateException exc) {
|
||||
} catch (IOException | GeneralSecurityException exc) {
|
||||
err(exc);
|
||||
}
|
||||
}
|
||||
@ -826,10 +832,10 @@ public class SimpleOCSPServer {
|
||||
append("\r\n");
|
||||
}
|
||||
sb.append("\r\n");
|
||||
|
||||
out.write(sb.toString().getBytes("UTF-8"));
|
||||
out.write(respBytes);
|
||||
log(resp.toString());
|
||||
|
||||
out.write(sb.toString().getBytes(StandardCharsets.UTF_8));
|
||||
out.write(respBytes);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -940,7 +946,7 @@ public class SimpleOCSPServer {
|
||||
// "/" off before decoding.
|
||||
return new LocalOcspRequest(Base64.getMimeDecoder().decode(
|
||||
URLDecoder.decode(headerTokens[1].replaceAll("/", ""),
|
||||
"UTF-8")));
|
||||
StandardCharsets.UTF_8)));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -974,8 +980,7 @@ public class SimpleOCSPServer {
|
||||
bos.write(b);
|
||||
}
|
||||
}
|
||||
|
||||
return new String(bos.toByteArray(), "UTF-8");
|
||||
return bos.toString(StandardCharsets.UTF_8);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1052,7 +1057,6 @@ public class SimpleOCSPServer {
|
||||
|
||||
if (sigItems[2].isContextSpecific((byte)0)) {
|
||||
DerValue[] certDerItems = sigItems[2].data.getSequence(4);
|
||||
int i = 0;
|
||||
for (DerValue dv : certDerItems) {
|
||||
X509Certificate xc = new X509CertImpl(dv);
|
||||
certificates.add(xc);
|
||||
@ -1131,7 +1135,7 @@ public class SimpleOCSPServer {
|
||||
* Return the list of X.509 Certificates in this OCSP request.
|
||||
*
|
||||
* @return an unmodifiable {@code List} of zero or more
|
||||
* {@cpde X509Certificate} objects.
|
||||
* {@code X509Certificate} objects.
|
||||
*/
|
||||
private List<X509Certificate> getCertificates() {
|
||||
return Collections.unmodifiableList(certificates);
|
||||
@ -1295,7 +1299,8 @@ public class SimpleOCSPServer {
|
||||
private final Map<String, Extension> responseExtensions;
|
||||
private byte[] signature;
|
||||
private final List<X509Certificate> certificates;
|
||||
private final byte[] encodedResponse;
|
||||
private final Signature signEngine;
|
||||
private final AlgorithmId sigAlgId;
|
||||
|
||||
/**
|
||||
* Constructor for the generation of non-successful responses
|
||||
@ -1305,9 +1310,11 @@ public class SimpleOCSPServer {
|
||||
* @throws IOException if an error happens during encoding
|
||||
* @throws NullPointerException if {@code respStat} is {@code null}
|
||||
* or {@code respStat} is successful.
|
||||
* @throws GeneralSecurityException if errors occur while obtaining
|
||||
* the signature object or any algorithm identifier parameters.
|
||||
*/
|
||||
public LocalOcspResponse(OCSPResponse.ResponseStatus respStat)
|
||||
throws IOException {
|
||||
throws IOException, GeneralSecurityException {
|
||||
this(respStat, null, null);
|
||||
}
|
||||
|
||||
@ -1324,10 +1331,13 @@ public class SimpleOCSPServer {
|
||||
* @throws NullPointerException if {@code respStat} is {@code null}
|
||||
* or {@code respStat} is successful, and a {@code null} {@code itemMap}
|
||||
* has been provided.
|
||||
* @throws GeneralSecurityException if errors occur while obtaining
|
||||
* the signature object or any algorithm identifier parameters.
|
||||
*/
|
||||
public LocalOcspResponse(OCSPResponse.ResponseStatus respStat,
|
||||
Map<CertId, CertStatusInfo> itemMap,
|
||||
Map<String, Extension> reqExtensions) throws IOException {
|
||||
Map<String, Extension> reqExtensions)
|
||||
throws IOException, GeneralSecurityException {
|
||||
responseStatus = Objects.requireNonNull(respStat,
|
||||
"Illegal null response status");
|
||||
if (responseStatus == ResponseStatus.SUCCESSFUL) {
|
||||
@ -1348,13 +1358,18 @@ public class SimpleOCSPServer {
|
||||
certificates.add(signerCert);
|
||||
}
|
||||
certificates.add(issuerCert);
|
||||
// Create the signature object and AlgorithmId that we'll use
|
||||
// later to create the signature on this response.
|
||||
signEngine = SignatureUtil.fromKey(sigAlgName, signerKey, "");
|
||||
sigAlgId = SignatureUtil.fromSignature(signEngine, signerKey);
|
||||
} else {
|
||||
respItemMap = null;
|
||||
producedAtDate = null;
|
||||
responseExtensions = null;
|
||||
certificates = null;
|
||||
signEngine = null;
|
||||
sigAlgId = null;
|
||||
}
|
||||
encodedResponse = this.getBytes();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1436,13 +1451,9 @@ public class SimpleOCSPServer {
|
||||
basicORItemStream.write(tbsResponseBytes);
|
||||
|
||||
try {
|
||||
// Create the signature
|
||||
Signature sig = SignatureUtil.fromKey(
|
||||
sigAlgId.getName(), signerKey, (Provider)null);
|
||||
sig.update(tbsResponseBytes);
|
||||
signature = sig.sign();
|
||||
// Rewrite signAlg, RSASSA-PSS needs some parameters.
|
||||
sigAlgId = SignatureUtil.fromSignature(sig, signerKey);
|
||||
// Create the signature with the initialized Signature object
|
||||
signEngine.update(tbsResponseBytes);
|
||||
signature = signEngine.sign();
|
||||
sigAlgId.encode(basicORItemStream);
|
||||
basicORItemStream.putBitString(signature);
|
||||
} catch (GeneralSecurityException exc) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user