8160655: Fix denyAfter and usage types for security properties

Reviewed-by: mullan, xuelei
This commit is contained in:
Anthony Scarpino 2017-02-08 12:08:28 -08:00
parent 125d4ea7d0
commit ff277c8508
20 changed files with 738 additions and 456 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1996, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1996, 2017, 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
@ -37,6 +37,7 @@ import java.security.PublicKey;
import java.security.Signature;
import java.security.SignatureException;
import java.security.Timestamp;
import java.security.cert.CertPathValidatorException;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.CertPath;
@ -48,6 +49,7 @@ import java.util.EnumSet;
import java.util.Set;
import sun.security.timestamp.TimestampToken;
import sun.security.util.ConstraintsParameters;
import sun.security.util.Debug;
import sun.security.util.DerEncoder;
import sun.security.util.DerInputStream;
@ -321,6 +323,8 @@ public class SignerInfo implements DerEncoder {
data = content.getContentBytes();
}
ConstraintsParameters cparams =
new ConstraintsParameters(timestamp);
String digestAlgname = getDigestAlgorithmId().getName();
byte[] dataSigned;
@ -347,11 +351,11 @@ public class SignerInfo implements DerEncoder {
if (messageDigest == null) // fail if there is no message digest
return null;
// check that algorithm is not restricted
if (!JAR_DISABLED_CHECK.permits(DIGEST_PRIMITIVE_SET,
digestAlgname, null)) {
throw new SignatureException("Digest check failed. " +
"Disabled algorithm used: " + digestAlgname);
// check that digest algorithm is not restricted
try {
JAR_DISABLED_CHECK.permits(digestAlgname, cparams);
} catch (CertPathValidatorException e) {
throw new SignatureException(e.getMessage(), e);
}
MessageDigest md = MessageDigest.getInstance(digestAlgname);
@ -385,17 +389,18 @@ public class SignerInfo implements DerEncoder {
String algname = AlgorithmId.makeSigAlg(
digestAlgname, encryptionAlgname);
// check that algorithm is not restricted
if (!JAR_DISABLED_CHECK.permits(SIG_PRIMITIVE_SET, algname, null)) {
throw new SignatureException("Signature check failed. " +
"Disabled algorithm used: " + algname);
// check that jar signature algorithm is not restricted
try {
JAR_DISABLED_CHECK.permits(algname, cparams);
} catch (CertPathValidatorException e) {
throw new SignatureException(e.getMessage(), e);
}
X509Certificate cert = getCertificate(block);
PublicKey key = cert.getPublicKey();
if (cert == null) {
return null;
}
PublicKey key = cert.getPublicKey();
// check if the public key is restricted
if (!JAR_DISABLED_CHECK.permits(SIG_PRIMITIVE_SET, key)) {

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2009, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2009, 2017, 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
@ -28,6 +28,7 @@ package sun.security.provider.certpath;
import java.security.AlgorithmConstraints;
import java.security.CryptoPrimitive;
import java.security.Timestamp;
import java.security.cert.CertPathValidator;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
@ -53,9 +54,10 @@ import java.security.interfaces.DSAPublicKey;
import java.security.spec.DSAPublicKeySpec;
import sun.security.util.AnchorCertificates;
import sun.security.util.CertConstraintParameters;
import sun.security.util.ConstraintsParameters;
import sun.security.util.Debug;
import sun.security.util.DisabledAlgorithmConstraints;
import sun.security.validator.Validator;
import sun.security.x509.X509CertImpl;
import sun.security.x509.X509CRLImpl;
import sun.security.x509.AlgorithmId;
@ -79,6 +81,7 @@ public final class AlgorithmChecker extends PKIXCertPathChecker {
private final Date pkixdate;
private PublicKey prevPubKey;
private final Timestamp jarTimestamp;
private final String variant;
private static final Set<CryptoPrimitive> SIGNATURE_PRIMITIVE_SET =
Collections.unmodifiableSet(EnumSet.of(CryptoPrimitive.SIGNATURE));
@ -109,64 +112,36 @@ public final class AlgorithmChecker extends PKIXCertPathChecker {
*
* @param anchor the trust anchor selected to validate the target
* certificate
* @param variant is the Validator variants of the operation. A null value
* passed will set it to Validator.GENERIC.
*/
public AlgorithmChecker(TrustAnchor anchor) {
this(anchor, certPathDefaultConstraints, null);
}
/**
* Create a new {@code AlgorithmChecker} with the
* given {@code TrustAnchor} and {@code AlgorithmConstraints}.
*
* @param anchor the trust anchor selected to validate the target
* certificate
* @param constraints the algorithm constraints (or null)
*
* @throws IllegalArgumentException if the {@code anchor} is null
*/
public AlgorithmChecker(TrustAnchor anchor,
AlgorithmConstraints constraints) {
this(anchor, constraints, null);
}
/**
* Create a new {@code AlgorithmChecker} with the
* given {@code AlgorithmConstraints}.
* <p>
* Note that this constructor will be used to check a certification
* path where the trust anchor is unknown, or a certificate list which may
* contain the trust anchor. This constructor is used by SunJSSE.
*
* @param constraints the algorithm constraints (or null)
*/
public AlgorithmChecker(AlgorithmConstraints constraints) {
this.prevPubKey = null;
this.trustedPubKey = null;
this.constraints = constraints;
this.pkixdate = null;
this.jarTimestamp = null;
public AlgorithmChecker(TrustAnchor anchor, String variant) {
this(anchor, certPathDefaultConstraints, null, variant);
}
/**
* Create a new {@code AlgorithmChecker} with the given
* {@code Timestamp}.
* {@code AlgorithmConstraints}, {@code Timestamp}, and/or {@code Variant}.
* <p>
* Note that this constructor will be used to check a certification
* path for signed JAR files that are timestamped.
* Note that this constructor can initialize a variation of situations where
* the AlgorithmConstraints, Timestamp, or Variant maybe known.
*
* @param constraints the algorithm constraints (or null)
* @param jarTimestamp Timestamp passed for JAR timestamp constraint
* checking. Set to null if not applicable.
* @param variant is the Validator variants of the operation. A null value
* passed will set it to Validator.GENERIC.
*/
public AlgorithmChecker(Timestamp jarTimestamp) {
public AlgorithmChecker(AlgorithmConstraints constraints,
Timestamp jarTimestamp, String variant) {
this.prevPubKey = null;
this.trustedPubKey = null;
this.constraints = certPathDefaultConstraints;
if (jarTimestamp == null) {
throw new IllegalArgumentException(
"Timestamp cannot be null");
}
this.pkixdate = jarTimestamp.getTimestamp();
this.constraints = (constraints == null ? certPathDefaultConstraints :
constraints);
this.pkixdate = (jarTimestamp != null ? jarTimestamp.getTimestamp() :
null);
this.jarTimestamp = jarTimestamp;
this.variant = (variant == null ? Validator.VAR_GENERIC : variant);
}
/**
@ -178,12 +153,13 @@ public final class AlgorithmChecker extends PKIXCertPathChecker {
* @param constraints the algorithm constraints (or null)
* @param pkixdate Date the constraints are checked against. The value is
* either the PKIXParameter date or null for the current date.
* @param variant is the Validator variants of the operation. A null value
* passed will set it to Validator.GENERIC.
*
* @throws IllegalArgumentException if the {@code anchor} is null
*/
public AlgorithmChecker(TrustAnchor anchor,
AlgorithmConstraints constraints,
Date pkixdate) {
AlgorithmConstraints constraints, Date pkixdate, String variant) {
if (anchor != null) {
if (anchor.getTrustedCert() != null) {
@ -207,6 +183,7 @@ public final class AlgorithmChecker extends PKIXCertPathChecker {
this.constraints = constraints;
this.pkixdate = pkixdate;
this.jarTimestamp = null;
this.variant = (variant == null ? Validator.VAR_GENERIC : variant);
}
/**
@ -217,11 +194,13 @@ public final class AlgorithmChecker extends PKIXCertPathChecker {
* certificate
* @param pkixdate Date the constraints are checked against. The value is
* either the PKIXParameter date or null for the current date.
* @param variant is the Validator variants of the operation. A null value
* passed will set it to Validator.GENERIC.
*
* @throws IllegalArgumentException if the {@code anchor} is null
*/
public AlgorithmChecker(TrustAnchor anchor, Date pkixdate) {
this(anchor, certPathDefaultConstraints, pkixdate);
public AlgorithmChecker(TrustAnchor anchor, Date pkixdate, String variant) {
this(anchor, certPathDefaultConstraints, pkixdate, variant);
}
// Check this 'cert' for restrictions in the AnchorCertificates
@ -286,6 +265,28 @@ public final class AlgorithmChecker extends PKIXCertPathChecker {
null, null, -1, PKIXReason.INVALID_KEY_USAGE);
}
X509CertImpl x509Cert;
AlgorithmId algorithmId;
try {
x509Cert = X509CertImpl.toImpl((X509Certificate)cert);
algorithmId = (AlgorithmId)x509Cert.get(X509CertImpl.SIG_ALG);
} catch (CertificateException ce) {
throw new CertPathValidatorException(ce);
}
AlgorithmParameters currSigAlgParams = algorithmId.getParameters();
PublicKey currPubKey = cert.getPublicKey();
String currSigAlg = x509Cert.getSigAlgName();
// Check the signature algorithm and parameters against constraints.
if (!constraints.permits(SIGNATURE_PRIMITIVE_SET, currSigAlg,
currSigAlgParams)) {
throw new CertPathValidatorException(
"Algorithm constraints check failed on signature " +
"algorithm: " + currSigAlg, null, null, -1,
BasicReason.ALGORITHM_CONSTRAINED);
}
// Assume all key usage bits are set if key usage is not present
Set<CryptoPrimitive> primitives = KU_PRIMITIVE_SET;
@ -322,101 +323,74 @@ public final class AlgorithmChecker extends PKIXCertPathChecker {
}
}
PublicKey currPubKey = cert.getPublicKey();
ConstraintsParameters cp =
new ConstraintsParameters((X509Certificate)cert,
trustedMatch, pkixdate, jarTimestamp, variant);
// Check against local constraints if it is DisabledAlgorithmConstraints
if (constraints instanceof DisabledAlgorithmConstraints) {
// Check against DisabledAlgorithmConstraints certpath constraints.
// permits() will throw exception on failure.
((DisabledAlgorithmConstraints)constraints).permits(primitives,
new CertConstraintParameters((X509Certificate)cert,
trustedMatch, pkixdate, jarTimestamp));
// If there is no previous key, set one and exit
if (prevPubKey == null) {
prevPubKey = currPubKey;
return;
}
}
X509CertImpl x509Cert;
AlgorithmId algorithmId;
try {
x509Cert = X509CertImpl.toImpl((X509Certificate)cert);
algorithmId = (AlgorithmId)x509Cert.get(X509CertImpl.SIG_ALG);
} catch (CertificateException ce) {
throw new CertPathValidatorException(ce);
}
AlgorithmParameters currSigAlgParams = algorithmId.getParameters();
String currSigAlg = x509Cert.getSigAlgName();
// If 'constraints' is not of DisabledAlgorithmConstraints, check all
// everything individually
if (!(constraints instanceof DisabledAlgorithmConstraints)) {
// Check the current signature algorithm
if (!constraints.permits(
SIGNATURE_PRIMITIVE_SET,
currSigAlg, currSigAlgParams)) {
throw new CertPathValidatorException(
"Algorithm constraints check failed on signature " +
"algorithm: " + currSigAlg, null, null, -1,
BasicReason.ALGORITHM_CONSTRAINED);
}
((DisabledAlgorithmConstraints)constraints).permits(currSigAlg, cp);
// DisabledAlgorithmsConstraints does not check primitives, so key
// additional key check.
} else {
// Perform the default constraints checking anyway.
certPathDefaultConstraints.permits(currSigAlg, cp);
// Call locally set constraints to check key with primitives.
if (!constraints.permits(primitives, currPubKey)) {
throw new CertPathValidatorException(
"Algorithm constraints check failed on keysize: " +
sun.security.util.KeyUtil.getKeySize(currPubKey),
"Algorithm constraints check failed on key " +
currPubKey.getAlgorithm() + " with size of " +
sun.security.util.KeyUtil.getKeySize(currPubKey) +
"bits",
null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
}
}
// If there is no previous key, set one and exit
if (prevPubKey == null) {
prevPubKey = currPubKey;
return;
}
// Check with previous cert for signature algorithm and public key
if (prevPubKey != null) {
if (!constraints.permits(
SIGNATURE_PRIMITIVE_SET,
currSigAlg, prevPubKey, currSigAlgParams)) {
throw new CertPathValidatorException(
if (!constraints.permits(
SIGNATURE_PRIMITIVE_SET,
currSigAlg, prevPubKey, currSigAlgParams)) {
throw new CertPathValidatorException(
"Algorithm constraints check failed on " +
"signature algorithm: " + currSigAlg,
null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
}
// Inherit key parameters from previous key
if (PKIX.isDSAPublicKeyWithoutParams(currPubKey)) {
// Inherit DSA parameters from previous key
if (!(prevPubKey instanceof DSAPublicKey)) {
throw new CertPathValidatorException("Input key is not " +
"of a appropriate type for inheriting parameters");
}
// Inherit key parameters from previous key
if (PKIX.isDSAPublicKeyWithoutParams(currPubKey)) {
// Inherit DSA parameters from previous key
if (!(prevPubKey instanceof DSAPublicKey)) {
throw new CertPathValidatorException("Input key is not " +
"of a appropriate type for inheriting parameters");
}
DSAParams params = ((DSAPublicKey)prevPubKey).getParams();
if (params == null) {
throw new CertPathValidatorException(
DSAParams params = ((DSAPublicKey)prevPubKey).getParams();
if (params == null) {
throw new CertPathValidatorException(
"Key parameters missing from public key.");
}
}
try {
BigInteger y = ((DSAPublicKey)currPubKey).getY();
KeyFactory kf = KeyFactory.getInstance("DSA");
DSAPublicKeySpec ks = new DSAPublicKeySpec(y,
params.getP(),
params.getQ(),
params.getG());
currPubKey = kf.generatePublic(ks);
} catch (GeneralSecurityException e) {
throw new CertPathValidatorException("Unable to generate " +
try {
BigInteger y = ((DSAPublicKey)currPubKey).getY();
KeyFactory kf = KeyFactory.getInstance("DSA");
DSAPublicKeySpec ks = new DSAPublicKeySpec(y, params.getP(),
params.getQ(), params.getG());
currPubKey = kf.generatePublic(ks);
} catch (GeneralSecurityException e) {
throw new CertPathValidatorException("Unable to generate " +
"key with inherited parameters: " + e.getMessage(), e);
}
}
}
// reset the previous public key
prevPubKey = currPubKey;
// check the extended key usage, ignore the check now
// List<String> extendedKeyUsages = x509Cert.getExtendedKeyUsage();
// DO NOT remove any unresolved critical extensions
}
/**
@ -456,8 +430,10 @@ public final class AlgorithmChecker extends PKIXCertPathChecker {
*
* @param key the public key to verify the CRL signature
* @param crl the target CRL
* @param variant is the Validator variants of the operation. A null value
* passed will set it to Validator.GENERIC.
*/
static void check(PublicKey key, X509CRL crl)
static void check(PublicKey key, X509CRL crl, String variant)
throws CertPathValidatorException {
X509CRLImpl x509CRLImpl = null;
@ -468,7 +444,7 @@ public final class AlgorithmChecker extends PKIXCertPathChecker {
}
AlgorithmId algorithmId = x509CRLImpl.getSigAlgId();
check(key, algorithmId);
check(key, algorithmId, variant);
}
/**
@ -476,20 +452,16 @@ public final class AlgorithmChecker extends PKIXCertPathChecker {
*
* @param key the public key to verify the CRL signature
* @param algorithmId signature algorithm Algorithm ID
* @param variant is the Validator variants of the operation. A null value
* passed will set it to Validator.GENERIC.
*/
static void check(PublicKey key, AlgorithmId algorithmId)
static void check(PublicKey key, AlgorithmId algorithmId, String variant)
throws CertPathValidatorException {
String sigAlgName = algorithmId.getName();
AlgorithmParameters sigAlgParams = algorithmId.getParameters();
if (!certPathDefaultConstraints.permits(
SIGNATURE_PRIMITIVE_SET, sigAlgName, key, sigAlgParams)) {
throw new CertPathValidatorException(
"Algorithm constraints check failed on signature algorithm: " +
sigAlgName + " is disabled",
null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
}
certPathDefaultConstraints.permits(new ConstraintsParameters(
sigAlgName, sigAlgParams, key, variant));
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2002, 2017, 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
@ -33,6 +33,7 @@ import javax.security.auth.x500.X500Principal;
import java.util.*;
import sun.security.util.Debug;
import sun.security.validator.Validator;
import static sun.security.x509.PKIXExtensions.*;
import sun.security.x509.*;
@ -65,6 +66,20 @@ public class DistributionPointFetcher {
* Return the X509CRLs matching this selector. The selector must be
* an X509CRLSelector with certificateChecking set.
*/
public static Collection<X509CRL> getCRLs(X509CRLSelector selector,
boolean signFlag, PublicKey prevKey, String provider,
List<CertStore> certStores, boolean[] reasonsMask,
Set<TrustAnchor> trustAnchors, Date validity, String variant)
throws CertStoreException
{
return getCRLs(selector, signFlag, prevKey, null, provider, certStores,
reasonsMask, trustAnchors, validity, variant);
}
/**
* Return the X509CRLs matching this selector. The selector must be
* an X509CRLSelector with certificateChecking set.
*/
// Called by com.sun.deploy.security.RevocationChecker
public static Collection<X509CRL> getCRLs(X509CRLSelector selector,
boolean signFlag,
PublicKey prevKey,
@ -76,7 +91,7 @@ public class DistributionPointFetcher {
throws CertStoreException
{
return getCRLs(selector, signFlag, prevKey, null, provider, certStores,
reasonsMask, trustAnchors, validity);
reasonsMask, trustAnchors, validity, Validator.VAR_GENERIC);
}
/**
@ -91,7 +106,8 @@ public class DistributionPointFetcher {
List<CertStore> certStores,
boolean[] reasonsMask,
Set<TrustAnchor> trustAnchors,
Date validity)
Date validity,
String variant)
throws CertStoreException
{
X509Certificate cert = selector.getCertificateChecking();
@ -120,7 +136,7 @@ public class DistributionPointFetcher {
DistributionPoint point = t.next();
Collection<X509CRL> crls = getCRLs(selector, certImpl,
point, reasonsMask, signFlag, prevKey, prevCert, provider,
certStores, trustAnchors, validity);
certStores, trustAnchors, validity, variant);
results.addAll(crls);
}
if (debug != null) {
@ -145,7 +161,7 @@ public class DistributionPointFetcher {
X509CertImpl certImpl, DistributionPoint point, boolean[] reasonsMask,
boolean signFlag, PublicKey prevKey, X509Certificate prevCert,
String provider, List<CertStore> certStores,
Set<TrustAnchor> trustAnchors, Date validity)
Set<TrustAnchor> trustAnchors, Date validity, String variant)
throws CertStoreException {
// check for full name
@ -208,7 +224,7 @@ public class DistributionPointFetcher {
selector.setIssuerNames(null);
if (selector.match(crl) && verifyCRL(certImpl, point, crl,
reasonsMask, signFlag, prevKey, prevCert, provider,
trustAnchors, certStores, validity)) {
trustAnchors, certStores, validity, variant)) {
crls.add(crl);
}
} catch (IOException | CRLException e) {
@ -316,7 +332,7 @@ public class DistributionPointFetcher {
X509CRL crl, boolean[] reasonsMask, boolean signFlag,
PublicKey prevKey, X509Certificate prevCert, String provider,
Set<TrustAnchor> trustAnchors, List<CertStore> certStores,
Date validity) throws CRLException, IOException {
Date validity, String variant) throws CRLException, IOException {
if (debug != null) {
debug.println("DistributionPointFetcher.verifyCRL: " +
@ -663,7 +679,7 @@ public class DistributionPointFetcher {
// check the crl signature algorithm
try {
AlgorithmChecker.check(prevKey, crl);
AlgorithmChecker.check(prevKey, crl, variant);
} catch (CertPathValidatorException cpve) {
if (debug != null) {
debug.println("CRL signature algorithm check failed: " + cpve);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2009, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2009, 2017, 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
@ -45,6 +45,7 @@ import java.util.Map;
import sun.security.action.GetIntegerAction;
import sun.security.util.Debug;
import sun.security.validator.Validator;
import sun.security.x509.AccessDescription;
import sun.security.x509.AuthorityInfoAccessExtension;
import sun.security.x509.GeneralName;
@ -94,42 +95,6 @@ public final class OCSP {
private OCSP() {}
/**
* Obtains the revocation status of a certificate using OCSP using the most
* common defaults. The OCSP responder URI is retrieved from the
* certificate's AIA extension. The OCSP responder certificate is assumed
* to be the issuer's certificate (or issued by the issuer CA).
*
* @param cert the certificate to be checked
* @param issuerCert the issuer certificate
* @return the RevocationStatus
* @throws IOException if there is an exception connecting to or
* communicating with the OCSP responder
* @throws CertPathValidatorException if an exception occurs while
* encoding the OCSP Request or validating the OCSP Response
*/
public static RevocationStatus check(X509Certificate cert,
X509Certificate issuerCert)
throws IOException, CertPathValidatorException {
CertId certId = null;
URI responderURI = null;
try {
X509CertImpl certImpl = X509CertImpl.toImpl(cert);
responderURI = getResponderURI(certImpl);
if (responderURI == null) {
throw new CertPathValidatorException
("No OCSP Responder URI in certificate");
}
certId = new CertId(issuerCert, certImpl.getSerialNumberObject());
} catch (CertificateException | IOException e) {
throw new CertPathValidatorException
("Exception while encoding OCSPRequest", e);
}
OCSPResponse ocspResponse = check(Collections.singletonList(certId),
responderURI, new OCSPResponse.IssuerInfo(issuerCert), null, null,
Collections.<Extension>emptyList());
return (RevocationStatus)ocspResponse.getSingleResponse(certId);
}
/**
* Obtains the revocation status of a certificate using OCSP.
@ -146,6 +111,8 @@ public final class OCSP {
* @throws CertPathValidatorException if an exception occurs while
* encoding the OCSP Request or validating the OCSP Response
*/
// Called by com.sun.deploy.security.TrustDecider
public static RevocationStatus check(X509Certificate cert,
X509Certificate issuerCert,
URI responderURI,
@ -154,27 +121,27 @@ public final class OCSP {
throws IOException, CertPathValidatorException
{
return check(cert, issuerCert, responderURI, responderCert, date,
Collections.<Extension>emptyList());
Collections.<Extension>emptyList(), Validator.VAR_GENERIC);
}
// Called by com.sun.deploy.security.TrustDecider
public static RevocationStatus check(X509Certificate cert,
X509Certificate issuerCert,
URI responderURI,
X509Certificate responderCert,
Date date, List<Extension> extensions)
X509Certificate issuerCert, URI responderURI,
X509Certificate responderCert, Date date, List<Extension> extensions,
String variant)
throws IOException, CertPathValidatorException
{
return check(cert, responderURI, null, issuerCert, responderCert, date, extensions);
return check(cert, responderURI, null, issuerCert, responderCert, date,
extensions, variant);
}
public static RevocationStatus check(X509Certificate cert,
URI responderURI, TrustAnchor anchor, X509Certificate issuerCert,
X509Certificate responderCert, Date date,
List<Extension> extensions)
List<Extension> extensions, String variant)
throws IOException, CertPathValidatorException
{
CertId certId = null;
CertId certId;
try {
X509CertImpl certImpl = X509CertImpl.toImpl(cert);
certId = new CertId(issuerCert, certImpl.getSerialNumberObject());
@ -184,7 +151,7 @@ public final class OCSP {
}
OCSPResponse ocspResponse = check(Collections.singletonList(certId),
responderURI, new OCSPResponse.IssuerInfo(anchor, issuerCert),
responderCert, date, extensions);
responderCert, date, extensions, variant);
return (RevocationStatus) ocspResponse.getSingleResponse(certId);
}
@ -206,10 +173,10 @@ public final class OCSP {
* @throws CertPathValidatorException if an exception occurs while
* encoding the OCSP Request or validating the OCSP Response
*/
static OCSPResponse check(List<CertId> certIds, URI responderURI,
static OCSPResponse check(List<CertId> certIds, URI responderURI,
OCSPResponse.IssuerInfo issuerInfo,
X509Certificate responderCert, Date date,
List<Extension> extensions)
List<Extension> extensions, String variant)
throws IOException, CertPathValidatorException
{
byte[] nonce = null;
@ -226,7 +193,7 @@ public final class OCSP {
// verify the response
ocspResponse.verify(certIds, issuerInfo, responderCert, date,
nonce);
nonce, variant);
} catch (IOException ioe) {
throw new CertPathValidatorException(
"Unable to determine revocation status due to network error",

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 2017, 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
@ -41,7 +41,6 @@ import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import javax.security.auth.x500.X500Principal;
@ -375,7 +374,8 @@ public final class OCSPResponse {
}
void verify(List<CertId> certIds, IssuerInfo issuerInfo,
X509Certificate responderCert, Date date, byte[] nonce)
X509Certificate responderCert, Date date, byte[] nonce,
String variant)
throws CertPathValidatorException
{
switch (responseStatus) {
@ -508,7 +508,8 @@ public final class OCSPResponse {
// Check algorithm constraints specified in security property
// "jdk.certpath.disabledAlgorithms".
AlgorithmChecker algChecker =
new AlgorithmChecker(issuerInfo.getAnchor(), date);
new AlgorithmChecker(issuerInfo.getAnchor(), date,
variant);
algChecker.init(false);
algChecker.check(signerCert, Collections.<String>emptySet());
@ -568,7 +569,7 @@ public final class OCSPResponse {
if (signerCert != null) {
// Check algorithm constraints specified in security property
// "jdk.certpath.disabledAlgorithms".
AlgorithmChecker.check(signerCert.getPublicKey(), sigAlgId);
AlgorithmChecker.check(signerCert.getPublicKey(), sigAlgId, variant);
if (!verifySignature(signerCert)) {
throw new CertPathValidatorException(

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2017, 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
@ -87,6 +87,7 @@ class PKIX {
private Set<TrustAnchor> anchors;
private List<X509Certificate> certs;
private Timestamp timestamp;
private String variant;
ValidatorParams(CertPath cp, PKIXParameters params)
throws InvalidAlgorithmParameterException
@ -102,8 +103,9 @@ class PKIX {
ValidatorParams(PKIXParameters params)
throws InvalidAlgorithmParameterException
{
if (params instanceof PKIXTimestampParameters) {
timestamp = ((PKIXTimestampParameters) params).getTimestamp();
if (params instanceof PKIXExtendedParameters) {
timestamp = ((PKIXExtendedParameters) params).getTimestamp();
variant = ((PKIXExtendedParameters) params).getVariant();
}
this.anchors = params.getTrustAnchors();
@ -199,6 +201,10 @@ class PKIX {
Timestamp timestamp() {
return timestamp;
}
String variant() {
return variant;
}
}
static class BuilderParams extends ValidatorParams {

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2000, 2017, 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
@ -173,9 +173,10 @@ public final class PKIXCertPathValidator extends CertPathValidatorSpi {
// add standard checkers that we will be using
certPathCheckers.add(untrustedChecker);
if (params.timestamp() == null) {
certPathCheckers.add(new AlgorithmChecker(anchor, params.date()));
certPathCheckers.add(new AlgorithmChecker(anchor, params.date(), null));
} else {
certPathCheckers.add(new AlgorithmChecker(params.timestamp()));
certPathCheckers.add(new AlgorithmChecker(null,
params.timestamp(), params.variant()));
}
certPathCheckers.add(new KeyChecker(certPathLen,
params.targetCertConstraints()));

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2016, 2017, 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
@ -39,19 +39,23 @@ import java.util.Set;
/**
* This class is a wrapper for PKIXBuilderParameters so that a Timestamp object
* can be passed alone when PKIXCertPath is checking signed jar files.
* and a string for the variant type, can be passed when doing certpath
* checking.
*/
public class PKIXTimestampParameters extends PKIXBuilderParameters {
public class PKIXExtendedParameters extends PKIXBuilderParameters {
private final PKIXBuilderParameters p;
private Timestamp jarTimestamp;
private final String variant;
public PKIXTimestampParameters(PKIXBuilderParameters params,
Timestamp timestamp) throws InvalidAlgorithmParameterException {
public PKIXExtendedParameters(PKIXBuilderParameters params,
Timestamp timestamp, String variant)
throws InvalidAlgorithmParameterException {
super(params.getTrustAnchors(), null);
p = params;
jarTimestamp = timestamp;
this.variant = variant;
}
public Timestamp getTimestamp() {
@ -61,6 +65,10 @@ public class PKIXTimestampParameters extends PKIXBuilderParameters {
jarTimestamp = t;
}
public String getVariant() {
return variant;
}
@Override
public void setDate(Date d) {
p.setDate(d);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2017, 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
@ -579,7 +579,7 @@ class RevocationChecker extends PKIXRevocationChecker {
approvedCRLs.addAll(DistributionPointFetcher.getCRLs(
sel, signFlag, prevKey, prevCert,
params.sigProvider(), certStores,
reasonsMask, anchors, null));
reasonsMask, anchors, null, params.variant()));
}
} catch (CertStoreException e) {
if (e instanceof CertStoreTypeException) {
@ -727,7 +727,7 @@ class RevocationChecker extends PKIXRevocationChecker {
}
}
response.verify(Collections.singletonList(certId), issuerInfo,
responderCert, params.date(), nonce);
responderCert, params.date(), nonce, params.variant());
} else {
URI responderURI = (this.responderURI != null)
@ -741,7 +741,7 @@ class RevocationChecker extends PKIXRevocationChecker {
response = OCSP.check(Collections.singletonList(certId),
responderURI, issuerInfo, responderCert, null,
ocspExtensions);
ocspExtensions, params.variant());
}
} catch (IOException e) {
throw new CertPathValidatorException(
@ -853,7 +853,7 @@ class RevocationChecker extends PKIXRevocationChecker {
if (DistributionPointFetcher.verifyCRL(
certImpl, point, crl, reasonsMask, signFlag,
prevKey, null, params.sigProvider(), anchors,
certStores, params.date()))
certStores, params.date(), params.variant()))
{
results.add(crl);
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2000, 2017, 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
@ -344,7 +344,7 @@ public final class SunCertPathBuilder extends CertPathBuilderSpi {
// add the algorithm checker
checkers.add(new AlgorithmChecker(builder.trustAnchor,
buildParams.date()));
buildParams.date(), null));
BasicChecker basicChecker = null;
if (nextState.keyParamsNeeded()) {

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1999, 2017, 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
@ -37,6 +37,7 @@ import javax.net.ssl.*;
import sun.security.provider.certpath.AlgorithmChecker;
import sun.security.action.GetPropertyAction;
import sun.security.validator.Validator;
public abstract class SSLContextImpl extends SSLContextSpi {
@ -1436,7 +1437,7 @@ final class AbstractTrustManagerWrapper extends X509ExtendedTrustManager
constraints = new SSLAlgorithmConstraints(sslSocket, true);
}
checkAlgorithmConstraints(chain, constraints);
checkAlgorithmConstraints(chain, constraints, isClient);
}
}
@ -1478,12 +1479,12 @@ final class AbstractTrustManagerWrapper extends X509ExtendedTrustManager
constraints = new SSLAlgorithmConstraints(engine, true);
}
checkAlgorithmConstraints(chain, constraints);
checkAlgorithmConstraints(chain, constraints, isClient);
}
}
private void checkAlgorithmConstraints(X509Certificate[] chain,
AlgorithmConstraints constraints) throws CertificateException {
AlgorithmConstraints constraints, boolean isClient) throws CertificateException {
try {
// Does the certificate chain end with a trusted certificate?
@ -1501,7 +1502,9 @@ final class AbstractTrustManagerWrapper extends X509ExtendedTrustManager
// A forward checker, need to check from trust to target
if (checkedLength >= 0) {
AlgorithmChecker checker = new AlgorithmChecker(constraints);
AlgorithmChecker checker =
new AlgorithmChecker(constraints, null,
(isClient ? Validator.VAR_TLS_CLIENT : Validator.VAR_TLS_SERVER));
checker.init(false);
for (int i = checkedLength; i >= 0; i--) {
Certificate cert = chain[i];

View File

@ -39,6 +39,7 @@ import java.security.cert.Certificate;
import javax.net.ssl.*;
import sun.security.provider.certpath.AlgorithmChecker;
import sun.security.validator.Validator;
/**
* The new X509 key manager implementation. The main differences to the
@ -661,6 +662,15 @@ final class X509KeyManagerImpl extends X509ExtendedKeyManager
return CheckResult.OK;
}
public String getValidator() {
if (this == CLIENT) {
return Validator.VAR_TLS_CLIENT;
} else if (this == SERVER) {
return Validator.VAR_TLS_SERVER;
}
return Validator.VAR_GENERIC;
}
}
// enum for the result of the extension check
@ -774,7 +784,8 @@ final class X509KeyManagerImpl extends X509ExtendedKeyManager
// check the algorithm constraints
if (constraints != null &&
!conformsToAlgorithmConstraints(constraints, chain)) {
!conformsToAlgorithmConstraints(constraints, chain,
checkType.getValidator())) {
if (useDebug) {
debug.println("Ignoring alias " + alias +
@ -811,9 +822,10 @@ final class X509KeyManagerImpl extends X509ExtendedKeyManager
}
private static boolean conformsToAlgorithmConstraints(
AlgorithmConstraints constraints, Certificate[] chain) {
AlgorithmConstraints constraints, Certificate[] chain,
String variant) {
AlgorithmChecker checker = new AlgorithmChecker(constraints);
AlgorithmChecker checker = new AlgorithmChecker(constraints, null, variant);
try {
checker.init(false);
} catch (CertPathValidatorException cpve) {

View File

@ -1,76 +0,0 @@
/*
* Copyright (c) 2016, 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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.
*/
package sun.security.util;
import java.security.Timestamp;
import java.security.cert.X509Certificate;
import java.util.Date;
/**
* This class is a wrapper for keeping state and passing objects between PKIX,
* AlgorithmChecker, and DisabledAlgorithmConstraints.
*/
public class CertConstraintParameters {
// A certificate being passed to check against constraints.
private final X509Certificate cert;
// This is true if the trust anchor in the certificate chain matches a cert
// in AnchorCertificates
private final boolean trustedMatch;
// PKIXParameter date
private final Date pkixDate;
// Timestamp of the signed JAR file
private final Timestamp jarTimestamp;
public CertConstraintParameters(X509Certificate c, boolean match,
Date pkixdate, Timestamp jarTime) {
cert = c;
trustedMatch = match;
pkixDate = pkixdate;
jarTimestamp = jarTime;
}
public CertConstraintParameters(X509Certificate c) {
this(c, false, null, null);
}
// Returns if the trust anchor has a match if anchor checking is enabled.
public boolean isTrustedMatch() {
return trustedMatch;
}
public X509Certificate getCertificate() {
return cert;
}
public Date getPKIXParamDate() {
return pkixDate;
}
public Timestamp getJARTimestamp() {
return jarTimestamp;
}
}

View File

@ -0,0 +1,135 @@
/*
* Copyright (c) 2016, 2017 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. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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.
*/
package sun.security.util;
import sun.security.validator.Validator;
import java.security.AlgorithmParameters;
import java.security.Key;
import java.security.Timestamp;
import java.security.cert.X509Certificate;
import java.util.Date;
/**
* This class contains parameters for checking against constraints that extend
* past the publicly available parameters in java.security.AlgorithmConstraints.
* This is currently on passed between between PKIX, AlgorithmChecker,
* and DisabledAlgorithmConstraints.
*/
public class ConstraintsParameters {
/*
* The below 3 values are used the same as the permit() methods
* published in java.security.AlgorithmConstraints.
*/
// Algorithm string to be checked against constraints
private final String algorithm;
// AlgorithmParameters to the algorithm being checked
private final AlgorithmParameters algParams;
// Public Key being checked against constraints
private final Key publicKey;
/*
* New values that are checked against constraints that the current public
* API does not support.
*/
// A certificate being passed to check against constraints.
private final X509Certificate cert;
// This is true if the trust anchor in the certificate chain matches a cert
// in AnchorCertificates
private final boolean trustedMatch;
// PKIXParameter date
private final Date pkixDate;
// Timestamp of the signed JAR file
private final Timestamp jarTimestamp;
private final String variant;
public ConstraintsParameters(X509Certificate c, boolean match,
Date pkixdate, Timestamp jarTime, String variant) {
cert = c;
trustedMatch = match;
pkixDate = pkixdate;
jarTimestamp = jarTime;
this.variant = (variant == null ? Validator.VAR_GENERIC : variant);
algorithm = null;
algParams = null;
publicKey = null;
}
public ConstraintsParameters(String algorithm, AlgorithmParameters params,
Key key, String variant) {
this.algorithm = algorithm;
algParams = params;
this.publicKey = key;
cert = null;
trustedMatch = false;
pkixDate = null;
jarTimestamp = null;
this.variant = (variant == null ? Validator.VAR_GENERIC : variant);
}
public ConstraintsParameters(X509Certificate c) {
this(c, false, null, null,
Validator.VAR_GENERIC);
}
public ConstraintsParameters(Timestamp jarTime) {
this(null, false, null, jarTime, Validator.VAR_GENERIC);
}
public String getAlgorithm() {
return algorithm;
}
public AlgorithmParameters getAlgParams() {
return algParams;
}
public Key getPublicKey() {
return publicKey;
}
// Returns if the trust anchor has a match if anchor checking is enabled.
public boolean isTrustedMatch() {
return trustedMatch;
}
public X509Certificate getCertificate() {
return cert;
}
public Date getPKIXParamDate() {
return pkixDate;
}
public Timestamp getJARTimestamp() {
return jarTimestamp;
}
public String getVariant() {
return variant;
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2010, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2010, 2017, 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
@ -25,6 +25,8 @@
package sun.security.util;
import sun.security.validator.Validator;
import java.security.CryptoPrimitive;
import java.security.AlgorithmParameters;
import java.security.Key;
@ -32,10 +34,12 @@ import java.security.cert.CertPathValidatorException;
import java.security.cert.CertPathValidatorException.BasicReason;
import java.security.cert.X509Certificate;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
@ -100,12 +104,6 @@ public class DisabledAlgorithmConstraints extends AbstractAlgorithmConstraints {
@Override
public final boolean permits(Set<CryptoPrimitive> primitives,
String algorithm, AlgorithmParameters parameters) {
if (primitives == null || primitives.isEmpty()) {
throw new IllegalArgumentException(
"No cryptographic primitive specified");
}
return checkAlgorithm(disabledAlgorithms, algorithm, decomposer);
}
@ -133,6 +131,18 @@ public class DisabledAlgorithmConstraints extends AbstractAlgorithmConstraints {
return checkConstraints(primitives, algorithm, key, parameters);
}
public final void permits(ConstraintsParameters cp)
throws CertPathValidatorException {
permits(cp.getAlgorithm(), cp);
}
public final void permits(String algorithm, Key key,
AlgorithmParameters params, String variant)
throws CertPathValidatorException {
permits(algorithm, new ConstraintsParameters(algorithm, params, key,
(variant == null) ? Validator.VAR_GENERIC : variant));
}
/*
* Check if a x509Certificate object is permitted. Check if all
* algorithms are allowed, certificate constraints, and the
@ -140,18 +150,10 @@ public class DisabledAlgorithmConstraints extends AbstractAlgorithmConstraints {
*
* Uses new style permit() which throws exceptions.
*/
public final void permits(Set<CryptoPrimitive> primitives,
CertConstraintParameters cp) throws CertPathValidatorException {
checkConstraints(primitives, cp);
}
/*
* Check if Certificate object is within the constraints.
* Uses new style permit() which throws exceptions.
*/
public final void permits(Set<CryptoPrimitive> primitives,
X509Certificate cert) throws CertPathValidatorException {
checkConstraints(primitives, new CertConstraintParameters(cert));
public final void permits(String algorithm, ConstraintsParameters cp)
throws CertPathValidatorException {
algorithmConstraints.permits(algorithm, cp);
}
// Check if a string is contained inside the property
@ -174,7 +176,7 @@ public class DisabledAlgorithmConstraints extends AbstractAlgorithmConstraints {
throw new IllegalArgumentException("The key cannot be null");
}
// check the signature algorithm
// check the signature algorithm with parameters
if (algorithm != null && algorithm.length() != 0) {
if (!permits(primitives, algorithm, parameters)) {
return false;
@ -190,36 +192,6 @@ public class DisabledAlgorithmConstraints extends AbstractAlgorithmConstraints {
return algorithmConstraints.permits(key);
}
/*
* Check algorithm constraints with Certificate
* Uses new style permit() which throws exceptions.
*/
private void checkConstraints(Set<CryptoPrimitive> primitives,
CertConstraintParameters cp) throws CertPathValidatorException {
X509Certificate cert = cp.getCertificate();
String algorithm = cert.getSigAlgName();
// Check signature algorithm is not disabled
if (!permits(primitives, algorithm, null)) {
throw new CertPathValidatorException(
"Algorithm constraints check failed on disabled "+
"signature algorithm: " + algorithm,
null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
}
// Check key algorithm is not disabled
if (!permits(primitives, cert.getPublicKey().getAlgorithm(), null)) {
throw new CertPathValidatorException(
"Algorithm constraints check failed on disabled "+
"public key algorithm: " + algorithm,
null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
}
// Check the certificate and key constraints
algorithmConstraints.permits(cp);
}
/**
* Key and Certificate Constraints
@ -234,13 +206,13 @@ public class DisabledAlgorithmConstraints extends AbstractAlgorithmConstraints {
* 'true' means the operation is allowed.
* 'false' means it failed the constraints and is disallowed.
*
* When passing CertConstraintParameters through permit(), an exception
* When passing ConstraintsParameters through permit(), an exception
* will be thrown on a failure to better identify why the operation was
* disallowed.
*/
private static class Constraints {
private Map<String, Set<Constraint>> constraintsMap = new HashMap<>();
private Map<String, List<Constraint>> constraintsMap = new HashMap<>();
private static class Holder {
private static final Pattern DENY_AFTER_PATTERN = Pattern.compile(
@ -260,23 +232,22 @@ public class DisabledAlgorithmConstraints extends AbstractAlgorithmConstraints {
// Check if constraint is a complete disabling of an
// algorithm or has conditions.
String algorithm;
String policy;
int space = constraintEntry.indexOf(' ');
if (space > 0) {
algorithm = AlgorithmDecomposer.hashName(
constraintEntry.substring(0, space).
toUpperCase(Locale.ENGLISH));
policy = constraintEntry.substring(space + 1);
} else {
algorithm = constraintEntry.toUpperCase(Locale.ENGLISH);
if (!constraintsMap.containsKey(algorithm)) {
constraintsMap.putIfAbsent(algorithm,
new HashSet<>());
}
String algorithm = AlgorithmDecomposer.hashName(
((space > 0 ? constraintEntry.substring(0, space) :
constraintEntry).
toUpperCase(Locale.ENGLISH)));
List<Constraint> constraintList =
constraintsMap.getOrDefault(algorithm,
new ArrayList<>(1));
constraintsMap.putIfAbsent(algorithm, constraintList);
if (space <= 0) {
constraintList.add(new DisabledConstraint(algorithm));
continue;
}
String policy = constraintEntry.substring(space + 1);
// Convert constraint conditions into Constraint classes
Constraint c, lastConstraint = null;
// Allow only one jdkCA entry per constraint entry
@ -315,7 +286,7 @@ public class DisabledAlgorithmConstraints extends AbstractAlgorithmConstraints {
c = new jdkCAConstraint(algorithm);
jdkCALimit = true;
} else if(entry.startsWith("denyAfter") &&
} else if (entry.startsWith("denyAfter") &&
(matcher = Holder.DENY_AFTER_PATTERN.matcher(entry))
.matches()) {
if (debug != null) {
@ -332,6 +303,12 @@ public class DisabledAlgorithmConstraints extends AbstractAlgorithmConstraints {
c = new DenyAfterConstraint(algorithm, year, month,
day);
denyAfterLimit = true;
} else if (entry.startsWith("usage")) {
String s[] = (entry.substring(5)).trim().split(" ");
c = new UsageConstraint(algorithm, s);
if (debug != null) {
debug.println("Constraints usage length is " + s.length);
}
} else {
throw new IllegalArgumentException("Error in security" +
" property. Constraint unknown: " + entry);
@ -340,11 +317,7 @@ public class DisabledAlgorithmConstraints extends AbstractAlgorithmConstraints {
// Link multiple conditions for a single constraint
// into a linked list.
if (lastConstraint == null) {
if (!constraintsMap.containsKey(algorithm)) {
constraintsMap.putIfAbsent(algorithm,
new HashSet<>());
}
constraintsMap.get(algorithm).add(c);
constraintList.add(c);
} else {
lastConstraint.nextConstraint = c;
}
@ -354,17 +327,17 @@ public class DisabledAlgorithmConstraints extends AbstractAlgorithmConstraints {
}
// Get applicable constraints based off the signature algorithm
private Set<Constraint> getConstraints(String algorithm) {
private List<Constraint> getConstraints(String algorithm) {
return constraintsMap.get(algorithm);
}
// Check if KeySizeConstraints permit the specified key
public boolean permits(Key key) {
Set<Constraint> set = getConstraints(key.getAlgorithm());
if (set == null) {
List<Constraint> list = getConstraints(key.getAlgorithm());
if (list == null) {
return true;
}
for (Constraint constraint : set) {
for (Constraint constraint : list) {
if (!constraint.permits(key)) {
if (debug != null) {
debug.println("keySizeConstraint: failed key " +
@ -377,31 +350,35 @@ public class DisabledAlgorithmConstraints extends AbstractAlgorithmConstraints {
}
// Check if constraints permit this cert.
public void permits(CertConstraintParameters cp)
public void permits(String algorithm, ConstraintsParameters cp)
throws CertPathValidatorException {
X509Certificate cert = cp.getCertificate();
if (debug != null) {
debug.println("Constraints.permits(): " + cert.getSigAlgName());
debug.println("Constraints.permits(): " + algorithm +
" Variant: " + cp.getVariant());
}
// Get all signature algorithms to check for constraints
Set<String> algorithms =
AlgorithmDecomposer.decomposeOneHash(cert.getSigAlgName());
if (algorithms == null || algorithms.isEmpty()) {
return;
Set<String> algorithms = new HashSet<>();
if (algorithm != null) {
algorithms.addAll(AlgorithmDecomposer.decomposeOneHash(algorithm));
}
// Attempt to add the public key algorithm to the set
algorithms.add(cert.getPublicKey().getAlgorithm());
// Attempt to add the public key algorithm if cert provided
if (cert != null) {
algorithms.add(cert.getPublicKey().getAlgorithm());
}
if (cp.getPublicKey() != null) {
algorithms.add(cp.getPublicKey().getAlgorithm());
}
// Check all applicable constraints
for (String algorithm : algorithms) {
Set<Constraint> set = getConstraints(algorithm);
if (set == null) {
for (String alg : algorithms) {
List<Constraint> list = getConstraints(alg);
if (list == null) {
continue;
}
for (Constraint constraint : set) {
for (Constraint constraint : list) {
constraint.permits(cp);
}
}
@ -467,17 +444,17 @@ public class DisabledAlgorithmConstraints extends AbstractAlgorithmConstraints {
/**
* Check if an algorithm constraint is permitted with a given
* CertConstraintParameters.
* ConstraintsParameters.
*
* If the check inside of {@code permits()} fails, it must call
* {@code next()} with the same {@code CertConstraintParameters}
* {@code next()} with the same {@code ConstraintsParameters}
* parameter passed if multiple constraints need to be checked.
*
* @param cp CertConstraintParameter containing certificate info
* @throws CertPathValidatorException if constraint disallows.
*
*/
public abstract void permits(CertConstraintParameters cp)
public abstract void permits(ConstraintsParameters cp)
throws CertPathValidatorException;
/**
@ -491,12 +468,12 @@ public class DisabledAlgorithmConstraints extends AbstractAlgorithmConstraints {
* were disallowed, the last constraint will throw
* {@code CertPathValidatorException}.
*
* @param cp CertConstraintParameters
* @param cp ConstraintsParameters
* @return 'true' if constraint allows the operation, 'false' if
* we are at the end of the constraint list or,
* {@code nextConstraint} is null.
*/
boolean next(CertConstraintParameters cp)
boolean next(ConstraintsParameters cp)
throws CertPathValidatorException {
if (nextConstraint != null) {
nextConstraint.permits(cp);
@ -525,6 +502,14 @@ public class DisabledAlgorithmConstraints extends AbstractAlgorithmConstraints {
}
return false;
}
String extendedMsg(ConstraintsParameters cp) {
return (cp.getCertificate() == null ? "." :
" used with certificate: " +
cp.getCertificate().getSubjectX500Principal() +
(cp.getVariant() != Validator.VAR_GENERIC ?
". Usage was " + cp.getVariant() : "."));
}
}
/*
@ -537,11 +522,11 @@ public class DisabledAlgorithmConstraints extends AbstractAlgorithmConstraints {
}
/*
* Check if CertConstraintParameters has a trusted match, if it does
* Check if ConstraintsParameters has a trusted match, if it does
* call next() for any following constraints. If it does not, exit
* as this constraint(s) does not restrict the operation.
*/
public void permits(CertConstraintParameters cp)
public void permits(ConstraintsParameters cp)
throws CertPathValidatorException {
if (debug != null) {
debug.println("jdkCAConstraints.permits(): " + algorithm);
@ -554,8 +539,7 @@ public class DisabledAlgorithmConstraints extends AbstractAlgorithmConstraints {
}
throw new CertPathValidatorException(
"Algorithm constraints check failed on certificate " +
"anchor limits. " + algorithm + " used with " +
cp.getCertificate().getSubjectX500Principal(),
"anchor limits. " + algorithm + extendedMsg(cp),
null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
}
}
@ -615,7 +599,7 @@ public class DisabledAlgorithmConstraints extends AbstractAlgorithmConstraints {
* constraints. Throw an exception if this is the last constraint.
*/
@Override
public void permits(CertConstraintParameters cp)
public void permits(ConstraintsParameters cp)
throws CertPathValidatorException {
Date currentDate;
String errmsg;
@ -628,7 +612,7 @@ public class DisabledAlgorithmConstraints extends AbstractAlgorithmConstraints {
errmsg = "PKIXParameter date: ";
} else {
currentDate = new Date();
errmsg = "Certificate date: ";
errmsg = "Current date: ";
}
if (!denyAfterDate.after(currentDate)) {
@ -637,9 +621,9 @@ public class DisabledAlgorithmConstraints extends AbstractAlgorithmConstraints {
}
throw new CertPathValidatorException(
"denyAfter constraint check failed: " + algorithm +
" used with Constraint date: " +
dateFormat.format(denyAfterDate) + "; "
+ errmsg + dateFormat.format(currentDate),
" used with Constraint date: " +
dateFormat.format(denyAfterDate) + "; " + errmsg +
dateFormat.format(currentDate) + extendedMsg(cp),
null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
}
}
@ -660,6 +644,48 @@ public class DisabledAlgorithmConstraints extends AbstractAlgorithmConstraints {
}
}
/*
* The usage constraint is for the "usage" keyword. It checks against the
* variant value in ConstraintsParameters.
*/
private static class UsageConstraint extends Constraint {
String[] usages;
UsageConstraint(String algorithm, String[] usages) {
this.algorithm = algorithm;
this.usages = usages;
}
public void permits(ConstraintsParameters cp)
throws CertPathValidatorException {
for (String usage : usages) {
String v = null;
if (usage.compareToIgnoreCase("TLSServer") == 0) {
v = Validator.VAR_TLS_SERVER;
} else if (usage.compareToIgnoreCase("TLSClient") == 0) {
v = Validator.VAR_TLS_CLIENT;
} else if (usage.compareToIgnoreCase("SignedJAR") == 0) {
v = Validator.VAR_PLUGIN_CODE_SIGNING;
}
if (debug != null) {
debug.println("Checking if usage constraint " + v +
" matches " + cp.getVariant());
}
if (cp.getVariant().compareTo(v) == 0) {
if (next(cp)) {
return;
}
throw new CertPathValidatorException("Usage constraint " +
usage + " check failed: " + algorithm +
extendedMsg(cp),
null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
}
}
}
}
/*
* This class contains constraints dealing with the key size
* support limits per algorithm. e.g. "keySize <= 1024"
@ -713,17 +739,22 @@ public class DisabledAlgorithmConstraints extends AbstractAlgorithmConstraints {
* constraint Any permitted constraint will exit the linked list
* to allow the operation.
*/
public void permits(CertConstraintParameters cp)
public void permits(ConstraintsParameters cp)
throws CertPathValidatorException {
if (!permitsImpl(cp.getCertificate().getPublicKey())) {
Key key = null;
if (cp.getPublicKey() != null) {
key = cp.getPublicKey();
} else if (cp.getCertificate() != null) {
key = cp.getCertificate().getPublicKey();
}
if (key != null && !permitsImpl(key)) {
if (nextConstraint != null) {
nextConstraint.permits(cp);
return;
}
throw new CertPathValidatorException(
"Algorithm constraints check failed on keysize limits. "
+ algorithm + " " + size + "bit key used with "
+ cp.getCertificate().getSubjectX500Principal(),
+ algorithm + " " + size + "bit key" + extendedMsg(cp),
null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
}
}
@ -762,5 +793,26 @@ public class DisabledAlgorithmConstraints extends AbstractAlgorithmConstraints {
return true;
}
}
/*
* This constraint is used for the complete disabling of the algorithm.
*/
private static class DisabledConstraint extends Constraint {
DisabledConstraint(String algo) {
algorithm = algo;
}
public void permits(ConstraintsParameters cp)
throws CertPathValidatorException {
throw new CertPathValidatorException(
"Algorithm constraints check failed on disabled " +
"algorithm: " + algorithm + extendedMsg(cp),
null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
}
public boolean permits(Key key) {
return false;
}
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2017, 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
@ -28,25 +28,23 @@ package sun.security.util;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.security.CodeSigner;
import java.security.CryptoPrimitive;
import java.security.GeneralSecurityException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SignatureException;
import java.security.Timestamp;
import java.security.cert.CertPath;
import java.security.cert.X509Certificate;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.util.ArrayList;
import java.util.Base64;
import java.util.Collections;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.jar.Attributes;
import java.util.jar.JarException;
import java.util.jar.JarFile;
@ -61,9 +59,6 @@ public class SignatureFileVerifier {
/* Are we debugging ? */
private static final Debug debug = Debug.getInstance("jar");
private static final Set<CryptoPrimitive> DIGEST_PRIMITIVE_SET =
Collections.unmodifiableSet(EnumSet.of(CryptoPrimitive.MESSAGE_DIGEST));
private static final DisabledAlgorithmConstraints JAR_DISABLED_CHECK =
new DisabledAlgorithmConstraints(
DisabledAlgorithmConstraints.PROPERTY_JAR_DISABLED_ALGS);
@ -97,6 +92,14 @@ public class SignatureFileVerifier {
/* for generating certpath objects */
private CertificateFactory certificateFactory = null;
/** Algorithms that have been checked if they are weak. */
private Map<String, Boolean> permittedAlgs= new HashMap<>();
/** TSA timestamp of signed jar. The newest timestamp is used. If there
* was no TSA timestamp used when signed, current time is used ("null").
*/
private Timestamp timestamp = null;
/**
* Create the named SignatureFileVerifier.
*
@ -222,15 +225,8 @@ public class SignatureFileVerifier {
/** get digest from cache */
private MessageDigest getDigest(String algorithm) throws SignatureException {
// check that algorithm is not restricted
if (!JAR_DISABLED_CHECK.permits(DIGEST_PRIMITIVE_SET, algorithm, null)) {
SignatureException e =
new SignatureException("SignatureFile check failed. " +
"Disabled algorithm used: " + algorithm);
throw e;
}
private MessageDigest getDigest(String algorithm)
throws SignatureException {
if (createdDigests == null)
createdDigests = new HashMap<>();
@ -302,6 +298,27 @@ public class SignatureFileVerifier {
if (newSigners == null)
return;
/*
* Look for the latest timestamp in the signature block. If an entry
* has no timestamp, use current time (aka null).
*/
for (CodeSigner s: newSigners) {
if (debug != null) {
debug.println("Gathering timestamp for: " + s.toString());
}
if (s.getTimestamp() == null) {
timestamp = null;
break;
} else if (timestamp == null) {
timestamp = s.getTimestamp();
} else {
if (timestamp.getTimestamp().before(
s.getTimestamp().getTimestamp())) {
timestamp = s.getTimestamp();
}
}
}
Iterator<Map.Entry<String,Attributes>> entries =
sf.getEntries().entrySet().iterator();
@ -344,6 +361,68 @@ public class SignatureFileVerifier {
updateSigners(newSigners, signers, JarFile.MANIFEST_NAME);
}
/**
* Check if algorithm is permitted using the permittedAlgs Map.
* If the algorithm is not in the map, check against disabled algorithms and
* store the result. If the algorithm is in the map use that result.
* False is returned for weak algorithm, true for good algorithms.
*/
boolean permittedCheck(String key, String algorithm) {
Boolean permitted = permittedAlgs.get(algorithm);
if (permitted == null) {
try {
JAR_DISABLED_CHECK.permits(algorithm,
new ConstraintsParameters(timestamp));
} catch(GeneralSecurityException e) {
permittedAlgs.put(algorithm, Boolean.FALSE);
permittedAlgs.put(key.toUpperCase(), Boolean.FALSE);
if (debug != null) {
if (e.getMessage() != null) {
debug.println(key + ": " + e.getMessage());
} else {
debug.println(key + ": " + algorithm +
" was disabled, no exception msg given.");
e.printStackTrace();
}
}
return false;
}
permittedAlgs.put(algorithm, Boolean.TRUE);
return true;
}
// Algorithm has already been checked, return the value from map.
return permitted.booleanValue();
}
/**
* With a given header (*-DIGEST*), return a string that lists all the
* algorithms associated with the header.
* If there are none, return "Unknown Algorithm".
*/
String getWeakAlgorithms(String header) {
String w = "";
try {
for (String key : permittedAlgs.keySet()) {
if (key.endsWith(header)) {
w += key.substring(0, key.length() - header.length()) + " ";
}
}
} catch (RuntimeException e) {
w = "Unknown Algorithm(s). Error processing " + header + ". " +
e.getMessage();
}
// This means we have an error in finding weak algorithms, run in
// debug mode to see permittedAlgs map's values.
if (w.length() == 0) {
return "Unknown Algorithm(s)";
}
return w;
}
/**
* See if the whole manifest was signed.
*/
@ -354,6 +433,7 @@ public class SignatureFileVerifier {
{
Attributes mattr = sf.getMainAttributes();
boolean manifestSigned = false;
boolean weakAlgs = true;
// go through all the attributes and process *-Digest-Manifest entries
for (Map.Entry<Object,Object> se : mattr.entrySet()) {
@ -364,6 +444,15 @@ public class SignatureFileVerifier {
// 16 is length of "-Digest-Manifest"
String algorithm = key.substring(0, key.length()-16);
// Check if this algorithm is permitted, skip if false.
if (!permittedCheck(key, algorithm)) {
continue;
}
// A non-weak algorithm was used, any weak algorithms found do
// not need to be reported.
weakAlgs = false;
manifestDigests.add(key);
manifestDigests.add(se.getValue());
MessageDigest digest = getDigest(algorithm);
@ -373,15 +462,14 @@ public class SignatureFileVerifier {
Base64.getMimeDecoder().decode((String)se.getValue());
if (debug != null) {
debug.println("Signature File: Manifest digest " +
digest.getAlgorithm());
debug.println( " sigfile " + toHex(expectedHash));
debug.println( " computed " + toHex(computedHash));
debug.println();
debug.println("Signature File: Manifest digest " +
algorithm);
debug.println( " sigfile " + toHex(expectedHash));
debug.println( " computed " + toHex(computedHash));
debug.println();
}
if (MessageDigest.isEqual(computedHash,
expectedHash)) {
if (MessageDigest.isEqual(computedHash, expectedHash)) {
manifestSigned = true;
} else {
//XXX: we will continue and verify each section
@ -389,15 +477,31 @@ public class SignatureFileVerifier {
}
}
}
if (debug != null) {
debug.println("PermittedAlgs mapping: ");
for (String key : permittedAlgs.keySet()) {
debug.println(key + " : " +
permittedAlgs.get(key).toString());
}
}
// If there were only weak algorithms used, throw an exception.
if (weakAlgs) {
String weakAlgorithms = getWeakAlgorithms("-DIGEST-MANIFEST");
throw new SignatureException("Manifest hash check failed " +
"(DIGEST-MANIFEST). Disabled algorithm(s) used: " +
weakAlgorithms);
}
return manifestSigned;
}
private boolean verifyManifestMainAttrs(Manifest sf,
ManifestDigester md)
private boolean verifyManifestMainAttrs(Manifest sf, ManifestDigester md)
throws IOException, SignatureException
{
Attributes mattr = sf.getMainAttributes();
boolean attrsVerified = true;
boolean weakAlgs = true;
// go through all the attributes and process
// digest entries for the manifest main attributes
@ -408,6 +512,15 @@ public class SignatureFileVerifier {
String algorithm =
key.substring(0, key.length() - ATTR_DIGEST.length());
// Check if this algorithm is permitted, skip if false.
if (!permittedCheck(key, algorithm)) {
continue;
}
// A non-weak algorithm was used, any weak algorithms found do
// not need to be reported.
weakAlgs = false;
MessageDigest digest = getDigest(algorithm);
if (digest != null) {
ManifestDigester.Entry mde =
@ -425,8 +538,7 @@ public class SignatureFileVerifier {
debug.println();
}
if (MessageDigest.isEqual(computedHash,
expectedHash)) {
if (MessageDigest.isEqual(computedHash, expectedHash)) {
// good
} else {
// we will *not* continue and verify each section
@ -442,6 +554,23 @@ public class SignatureFileVerifier {
}
}
if (debug != null) {
debug.println("PermittedAlgs mapping: ");
for (String key : permittedAlgs.keySet()) {
debug.println(key + " : " +
permittedAlgs.get(key).toString());
}
}
// If there were only weak algorithms used, throw an exception.
if (weakAlgs) {
String weakAlgorithms = getWeakAlgorithms("-DIGEST-" +
ManifestDigester.MF_MAIN_ATTRS);
throw new SignatureException("Manifest Main Attribute check " +
"failed (DIGEST-" + ManifestDigester.MF_MAIN_ATTRS +
"). " + "Disabled algorithm(s) used: " + weakAlgorithms);
}
// this method returns 'true' if either:
// . manifest main attributes were not signed, or
// . manifest main attributes were signed and verified
@ -464,6 +593,7 @@ public class SignatureFileVerifier {
{
boolean oneDigestVerified = false;
ManifestDigester.Entry mde = md.get(name,block.isOldStyle());
boolean weakAlgs = true;
if (mde == null) {
throw new SecurityException(
@ -471,7 +601,6 @@ public class SignatureFileVerifier {
}
if (sfAttr != null) {
//sun.security.util.HexDumpEncoder hex = new sun.security.util.HexDumpEncoder();
//hex.encodeBuffer(data, System.out);
@ -483,6 +612,15 @@ public class SignatureFileVerifier {
// 7 is length of "-Digest"
String algorithm = key.substring(0, key.length()-7);
// Check if this algorithm is permitted, skip if false.
if (!permittedCheck(key, algorithm)) {
continue;
}
// A non-weak algorithm was used, any weak algorithms found do
// not need to be reported.
weakAlgs = false;
MessageDigest digest = getDigest(algorithm);
if (digest != null) {
@ -532,6 +670,23 @@ public class SignatureFileVerifier {
}
}
}
if (debug != null) {
debug.println("PermittedAlgs mapping: ");
for (String key : permittedAlgs.keySet()) {
debug.println(key + " : " +
permittedAlgs.get(key).toString());
}
}
// If there were only weak algorithms used, throw an exception.
if (weakAlgs) {
String weakAlgorithms = getWeakAlgorithms("DIGEST");
throw new SignatureException("Manifest Main Attribute check " +
"failed (DIGEST). " + "Disabled algorithm(s) used: " +
weakAlgorithms);
}
return oneDigestVerified;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2002, 2017, 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
@ -33,7 +33,7 @@ import java.security.cert.*;
import javax.security.auth.x500.X500Principal;
import sun.security.action.GetBooleanAction;
import sun.security.provider.certpath.AlgorithmChecker;
import sun.security.provider.certpath.PKIXTimestampParameters;
import sun.security.provider.certpath.PKIXExtendedParameters;
/**
* Validator implementation built on the PKIX CertPath API. This
@ -199,9 +199,9 @@ public final class PKIXValidator extends Validator {
PKIXBuilderParameters pkixParameters = null;
if (parameter instanceof Timestamp && plugin) {
try {
pkixParameters = new PKIXTimestampParameters(
pkixParameters = new PKIXExtendedParameters(
(PKIXBuilderParameters) parameterTemplate.clone(),
(Timestamp) parameter);
(Timestamp) parameter, variant);
} catch (InvalidAlgorithmParameterException e) {
// ignore exception
}
@ -211,7 +211,8 @@ public final class PKIXValidator extends Validator {
// add new algorithm constraints checker
if (constraints != null) {
pkixParameters.addCertPathChecker(new AlgorithmChecker(constraints));
pkixParameters.addCertPathChecker(
new AlgorithmChecker(constraints, null, variant));
}
// attach it to the PKIXBuilderParameters.

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2002, 2017, 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
@ -155,12 +155,14 @@ public final class SimpleValidator extends Validator {
// create default algorithm constraints checker
TrustAnchor anchor = new TrustAnchor(anchorCert, null);
AlgorithmChecker defaultAlgChecker = new AlgorithmChecker(anchor);
AlgorithmChecker defaultAlgChecker =
new AlgorithmChecker(anchor, variant);
// create application level algorithm constraints checker
AlgorithmChecker appAlgChecker = null;
if (constraints != null) {
appAlgChecker = new AlgorithmChecker(anchor, constraints);
appAlgChecker = new AlgorithmChecker(anchor, constraints, null,
variant);
}
// verify top down, starting at the certificate issued by

View File

@ -494,7 +494,8 @@ krb5.kdc.bad.policy = tryLast
# (see below)
#
# Constraint:
# KeySizeConstraint | CAConstraint | DenyAfterConstraint
# KeySizeConstraint | CAConstraint | DenyAfterConstraint |
# UsageConstraint
#
# KeySizeConstraint:
# keySize Operator KeyLength
@ -511,6 +512,9 @@ krb5.kdc.bad.policy = tryLast
# DenyAfterConstraint:
# denyAfter YYYY-MM-DD
#
# UsageConstraint:
# usage [TLSServer] [TLSClient] [SignedJAR]
#
# The "AlgorithmName" is the standard algorithm name of the disabled
# algorithm. See "Java Cryptography Architecture Standard Algorithm Name
# Documentation" for information about Standard Algorithm Names. Matching
@ -560,6 +564,19 @@ krb5.kdc.bad.policy = tryLast
# Example: To deny usage of RSA 2048 bit certificates after Feb 3 2020,
# use the following: "RSA keySize == 2048 & denyAfter 2020-02-03"
#
# UsageConstraint:
# usage [TLSServer] [TLSClient] [SignedJAR]
# This constraint prohibits the specified algorithm for
# a specified usage. This should be used when disabling an algorithm
# for all usages is not practical. 'TLSServer' restricts the algorithm
# in TLS server certificate chains when server authentication is
# performed. 'TLSClient' restricts the algorithm in TLS client
# certificate chains when client authentication is performed.
# 'SignedJAR' constrains use of certificates in signed jar files.
# The usage type follows the keyword and more than one usage type can
# be specified with a whitespace delimiter.
# Example: "SHA1 usage TLSServer TLSClient"
#
# When an algorithm must satisfy more than one constraint, it must be
# delimited by an ampersand '&'. For example, to restrict certificates in a
# chain that terminate at a distribution provided trust anchor and contain
@ -599,17 +616,20 @@ jdk.certpath.disabledAlgorithms=MD2, MD5, SHA1 jdkCA & denyAfter 2017-01-01, \
# " DisabledAlgorithm { , DisabledAlgorithm } "
#
# DisabledAlgorithm:
# AlgorithmName [Constraint]
# AlgorithmName [Constraint] { '&' Constraint }
#
# AlgorithmName:
# (see below)
#
# Constraint:
# KeySizeConstraint
# KeySizeConstraint | DenyAfterConstraint
#
# KeySizeConstraint:
# keySize Operator KeyLength
#
# DenyAfterConstraint:
# denyAfter YYYY-MM-DD
#
# Operator:
# <= | < | == | != | >= | >
#
@ -620,6 +640,8 @@ jdk.certpath.disabledAlgorithms=MD2, MD5, SHA1 jdkCA & denyAfter 2017-01-01, \
# implementation. It is not guaranteed to be examined and used by other
# implementations.
#
# See "jdk.certpath.disabledAlgorithms" for syntax descriptions.
#
jdk.jar.disabledAlgorithms=MD2, MD5, RSA keySize < 1024, \
DSA keySize < 1024

View File

@ -456,7 +456,7 @@ public class TimestampCheck {
.shouldMatch("Timestamp signature algorithm: .*key.*weak");
verify(file, "-J-Djava.security.debug=jar")
.shouldHaveExitValue(0)
.shouldMatch("SignatureException:.*Disabled");
.shouldMatch("SignatureException:.*disabled");
}
static void checkHalfWeak(String file) throws Throwable {