Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 9 additions & 5 deletions jdk/src/share/classes/sun/security/provider/certpath/OCSP.java
Original file line number Diff line number Diff line change
Expand Up @@ -225,20 +225,24 @@ public static byte[] getOCSPBytes(List<CertId> certIds, URI responderURI,
List<Extension> extensions) throws IOException {
OCSPRequest request = new OCSPRequest(certIds, extensions);
byte[] bytes = request.encodeBytes();
String responder = responderURI.toString();

if (debug != null) {
debug.println("connecting to OCSP service at: " + responderURI);
debug.println("connecting to OCSP service at: " + responder);
}

HttpURLConnection con = null;

try {
String encodedGetReq = responderURI.toString() + "/" +
URLEncoder.encode(Base64.getEncoder().encodeToString(bytes),
"UTF-8");
StringBuilder encodedGetReq = new StringBuilder(responder);
if (!responder.endsWith("/")) {
encodedGetReq.append("/");
}
encodedGetReq.append(URLEncoder.encode(
Base64.getEncoder().encodeToString(bytes), "UTF-8"));

if (encodedGetReq.length() <= 255) {
URL url = new URL(encodedGetReq);
URL url = new URL(encodedGetReq.toString());
con = (HttpURLConnection)url.openConnection();
con.setDoOutput(true);
con.setDoInput(true);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -639,7 +639,10 @@ private boolean verifySignature(X509Certificate cert)

try {
Signature respSignature = Signature.getInstance(sigAlgId.getName());
respSignature.initVerify(cert.getPublicKey());
SignatureUtil.initVerifyWithParam(respSignature,
cert.getPublicKey(),
SignatureUtil.getParamSpec(sigAlgId.getName(),
sigAlgId.getEncodedParams()));
respSignature.update(tbsResponseData);

if (respSignature.verify(signature)) {
Expand All @@ -655,8 +658,8 @@ private boolean verifySignature(X509Certificate cert)
}
return false;
}
} catch (InvalidKeyException | NoSuchAlgorithmException |
SignatureException e)
} catch (InvalidAlgorithmParameterException | InvalidKeyException
| NoSuchAlgorithmException | SignatureException e)
{
throw new CertPathValidatorException(e);
}
Expand Down
88 changes: 81 additions & 7 deletions jdk/src/share/classes/sun/security/util/SignatureUtil.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018, 2021, 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
Expand Down Expand Up @@ -30,6 +30,7 @@
import java.security.spec.*;
import java.util.Locale;
import sun.security.rsa.RSAUtil;
import sun.security.x509.AlgorithmId;
import sun.misc.SharedSecrets;

/**
Expand Down Expand Up @@ -145,8 +146,7 @@ public static AlgorithmParameterSpec getParamSpec(String sigName,
// for verification with the specified key and params (may be null)
public static void initVerifyWithParam(Signature s, PublicKey key,
AlgorithmParameterSpec params)
throws ProviderException, InvalidAlgorithmParameterException,
InvalidKeyException {
throws InvalidAlgorithmParameterException, InvalidKeyException {
SharedSecrets.getJavaSecuritySignatureAccess().initVerify(s, key, params);
}

Expand All @@ -155,17 +155,91 @@ public static void initVerifyWithParam(Signature s, PublicKey key,
public static void initVerifyWithParam(Signature s,
java.security.cert.Certificate cert,
AlgorithmParameterSpec params)
throws ProviderException, InvalidAlgorithmParameterException,
InvalidKeyException {
throws InvalidAlgorithmParameterException, InvalidKeyException {
SharedSecrets.getJavaSecuritySignatureAccess().initVerify(s, cert, params);
}

// Utility method for initializing the specified Signature object
// for signing with the specified key and params (may be null)
public static void initSignWithParam(Signature s, PrivateKey key,
AlgorithmParameterSpec params, SecureRandom sr)
throws ProviderException, InvalidAlgorithmParameterException,
InvalidKeyException {
throws InvalidAlgorithmParameterException, InvalidKeyException {
SharedSecrets.getJavaSecuritySignatureAccess().initSign(s, key, params, sr);
}

/**
* Create a Signature that has been initialized with proper key and params.
*
* @param sigAlg signature algorithms
* @param key private key
* @param provider (optional) provider
*/
public static Signature fromKey(String sigAlg, PrivateKey key, String provider)
throws NoSuchAlgorithmException, NoSuchProviderException,
InvalidKeyException{
Signature sigEngine = (provider == null || provider.isEmpty())
? Signature.getInstance(sigAlg)
: Signature.getInstance(sigAlg, provider);
return autoInitInternal(sigAlg, key, sigEngine);
}

/**
* Create a Signature that has been initialized with proper key and params.
*
* @param sigAlg signature algorithms
* @param key private key
* @param provider (optional) provider
*/
public static Signature fromKey(String sigAlg, PrivateKey key, Provider provider)
throws NoSuchAlgorithmException, InvalidKeyException{
Signature sigEngine = (provider == null)
? Signature.getInstance(sigAlg)
: Signature.getInstance(sigAlg, provider);
return autoInitInternal(sigAlg, key, sigEngine);
}

private static Signature autoInitInternal(String alg, PrivateKey key, Signature s)
throws InvalidKeyException {
AlgorithmParameterSpec params = AlgorithmId
.getDefaultAlgorithmParameterSpec(alg, key);
try {
SignatureUtil.initSignWithParam(s, key, params, null);
} catch (InvalidAlgorithmParameterException e) {
throw new AssertionError("Should not happen", e);
}
return s;
}

/**
* Derives AlgorithmId from a signature object and a key.
* @param sigEngine the signature object
* @param key the private key
* @return the AlgorithmId, not null
* @throws SignatureException if cannot find one
*/
public static AlgorithmId fromSignature(Signature sigEngine, PrivateKey key)
throws SignatureException {
try {
AlgorithmParameters params = null;
try {
params = sigEngine.getParameters();
} catch (UnsupportedOperationException e) {
// some provider does not support it
}
if (params != null) {
return AlgorithmId.get(sigEngine.getParameters());
} else {
String sigAlg = sigEngine.getAlgorithm();
if (sigAlg.equalsIgnoreCase("EdDSA")) {
// Hopefully key knows if it's Ed25519 or Ed448
sigAlg = key.getAlgorithm();
}
return AlgorithmId.get(sigAlg);
}
} catch (NoSuchAlgorithmException e) {
// This could happen if both sig alg and key alg is EdDSA,
// we don't know which provider does this.
throw new SignatureException("Cannot derive AlgorithmIdentifier", e);
}
}
}
40 changes: 39 additions & 1 deletion jdk/src/share/classes/sun/security/x509/AlgorithmId.java
Original file line number Diff line number Diff line change
Expand Up @@ -291,7 +291,7 @@ public AlgorithmParameters getParameters() {
*
* @return DER encoded parameters, or null not present.
*/
public byte[] getEncodedParams() throws IOException {
public byte[] getEncodedParams() {
return (encodedParams == null || algid.equals(specifiedWithECDSA_oid))
? null
: encodedParams.clone();
Expand Down Expand Up @@ -1070,6 +1070,33 @@ public static String getDigAlgFromSigAlg(String signatureAlgorithm) {
return null;
}

/**
* Returns the default signature algorithm for a private key. The digest
* part might evolve with time. Remember to update the spec of
* {@link jdk.security.jarsigner.JarSigner.Builder#getDefaultSignatureAlgorithm(PrivateKey)}
* if updated.
*
* @param k cannot be null
* @return the default alg, might be null if unsupported
*/
public static String getDefaultSigAlgForKey(PrivateKey k) {
switch (k.getAlgorithm().toUpperCase(Locale.ENGLISH)) {
case "EC":
return ecStrength(KeyUtil.getKeySize(k))
+ "withECDSA";
case "DSA":
return ifcFfcStrength(KeyUtil.getKeySize(k))
+ "withDSA";
case "RSA":
return ifcFfcStrength(KeyUtil.getKeySize(k))
+ "withRSA";
case "RSASSA-PSS":
return "RSASSA-PSS";
default:
return null;
}
}

// Most commonly used PSSParameterSpec and AlgorithmId
private static class PSSParamsHolder {

Expand Down Expand Up @@ -1145,6 +1172,17 @@ public static PSSParameterSpec getDefaultAlgorithmParameterSpec(
}
}

// Values from SP800-57 part 1 rev 4 tables 2 and 3
private static String ecStrength (int bitLength) {
if (bitLength >= 512) { // 256 bits of strength
return "SHA512";
} else if (bitLength >= 384) { // 192 bits of strength
return "SHA384";
} else { // 128 bits of strength and less
return "SHA256";
}
}

// Same values for RSA and DSA (from 8056174)
private static String ifcFfcStrength(int bitLength) {
if (bitLength > 7680) { // 256 bits
Expand Down
10 changes: 2 additions & 8 deletions jdk/src/share/classes/sun/security/x509/X509CRLImpl.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2021, 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
Expand Down Expand Up @@ -809,13 +809,7 @@ public String getSigAlgOID() {
* null if no parameters are present.
*/
public byte[] getSigAlgParams() {
if (sigAlgId == null)
return null;
try {
return sigAlgId.getEncodedParams();
} catch (IOException e) {
return null;
}
return sigAlgId == null ? null : sigAlgId.getEncodedParams();
}

/**
Expand Down
8 changes: 1 addition & 7 deletions jdk/src/share/classes/sun/security/x509/X509CertImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -1095,13 +1095,7 @@ public String getSigAlgOID() {
* null if no parameters are present.
*/
public byte[] getSigAlgParams() {
if (algId == null)
return null;
try {
return algId.getEncodedParams();
} catch (IOException e) {
return null;
}
return algId == null ? null : algId.getEncodedParams();
}

/**
Expand Down
41 changes: 14 additions & 27 deletions jdk/test/java/security/testlibrary/CertificateBuilder.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 2021, 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
Expand Down Expand Up @@ -38,6 +38,7 @@
import sun.security.util.DerOutputStream;
import sun.security.util.DerValue;
import sun.security.util.ObjectIdentifier;
import sun.security.util.SignatureUtil;
import sun.security.x509.AccessDescription;
import sun.security.x509.AlgorithmId;
import sun.security.x509.AuthorityInfoAccessExtension;
Expand Down Expand Up @@ -364,8 +365,7 @@ public X509Certificate build(X509Certificate issuerCert,
throws IOException, CertificateException, NoSuchAlgorithmException {
// TODO: add some basic checks (key usage, basic constraints maybe)

AlgorithmId signAlg = AlgorithmId.get(algName);
byte[] encodedCert = encodeTopLevel(issuerCert, issuerKey, signAlg);
byte[] encodedCert = encodeTopLevel(issuerCert, issuerKey, algName);
ByteArrayInputStream bais = new ByteArrayInputStream(encodedCert);
return (X509Certificate)factory.generateCertificate(bais);
}
Expand All @@ -392,18 +392,24 @@ public X509Certificate build(X509Certificate issuerCert,
* @throws IOException if an encoding error occurs.
*/
private byte[] encodeTopLevel(X509Certificate issuerCert,
PrivateKey issuerKey, AlgorithmId signAlg)
throws CertificateException, IOException {
PrivateKey issuerKey, String algName)
throws CertificateException, IOException, NoSuchAlgorithmException {

AlgorithmId signAlg = AlgorithmId.get(algName);
DerOutputStream outerSeq = new DerOutputStream();
DerOutputStream topLevelItems = new DerOutputStream();

tbsCertBytes = encodeTbsCert(issuerCert, signAlg);
topLevelItems.write(tbsCertBytes);
try {
signatureBytes = signCert(issuerKey, signAlg);
Signature sig = SignatureUtil.fromKey(signAlg.getName(), issuerKey, (Provider)null);
// Rewrite signAlg, RSASSA-PSS needs some parameters.
signAlg = SignatureUtil.fromSignature(sig, issuerKey);
tbsCertBytes = encodeTbsCert(issuerCert, signAlg);
sig.update(tbsCertBytes);
signatureBytes = sig.sign();
} catch (GeneralSecurityException ge) {
throw new CertificateException(ge);
}
topLevelItems.write(tbsCertBytes);
signAlg.derEncode(topLevelItems);
topLevelItems.putBitString(signatureBytes);
outerSeq.write(DerValue.tag_Sequence, topLevelItems);
Expand Down Expand Up @@ -517,23 +523,4 @@ private void encodeExtensions(DerOutputStream tbsStream)
tbsStream.write(DerValue.createTag(DerValue.TAG_CONTEXT, true,
(byte)3), extSequence);
}

/**
* Digitally sign the X.509 certificate.
*
* @param issuerKey The private key of the issuing authority
* @param signAlg The signature algorithm object
*
* @return The digital signature bytes.
*
* @throws GeneralSecurityException If any errors occur during the
* digital signature process.
*/
private byte[] signCert(PrivateKey issuerKey, AlgorithmId signAlg)
throws GeneralSecurityException {
Signature sig = Signature.getInstance(signAlg.getName());
sig.initSign(issuerKey);
sig.update(tbsCertBytes);
return sig.sign();
}
}
14 changes: 8 additions & 6 deletions jdk/test/java/security/testlibrary/SimpleOCSPServer.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 2021, 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
Expand Down Expand Up @@ -50,6 +50,7 @@
import sun.security.util.DerOutputStream;
import sun.security.util.DerValue;
import sun.security.util.ObjectIdentifier;
import sun.security.util.SignatureUtil;


/**
Expand Down Expand Up @@ -179,7 +180,7 @@ public SimpleOCSPServer(InetAddress addr, int port, KeyStore ks,
}
}

sigAlgId = AlgorithmId.get("Sha256withRSA");
sigAlgId = AlgorithmId.get(AlgorithmId.getDefaultSigAlgForKey(signerKey));
respId = new ResponderId(signerCert.getSubjectX500Principal());
listenAddress = addr;
listenPort = port;
Expand Down Expand Up @@ -1352,13 +1353,14 @@ private byte[] encodeBasicOcspResponse() throws IOException {
basicORItemStream.write(tbsResponseBytes);

try {
sigAlgId.derEncode(basicORItemStream);

// Create the signature
Signature sig = Signature.getInstance(sigAlgId.getName());
sig.initSign(signerKey);
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);
sigAlgId.derEncode(basicORItemStream);
basicORItemStream.putBitString(signature);
} catch (GeneralSecurityException exc) {
err(exc);
Expand Down
Loading