8176350: Usage constraints don't take effect when using PKIX
Reviewed-by: xuelei, mullan
--- a/jdk/src/java.base/share/classes/sun/security/provider/certpath/AlgorithmChecker.java Fri Mar 10 09:20:55 2017 -0800
+++ b/jdk/src/java.base/share/classes/sun/security/provider/certpath/AlgorithmChecker.java Fri Mar 10 21:04:15 2017 -0800
@@ -106,9 +106,8 @@
private boolean trustedMatch = false;
/**
- * Create a new {@code AlgorithmChecker} with the algorithm
- * constraints specified in security property
- * "jdk.certpath.disabledAlgorithms".
+ * Create a new {@code AlgorithmChecker} with the given algorithm
+ * given {@code TrustAnchor} and {@code String} variant.
*
* @param anchor the trust anchor selected to validate the target
* certificate
@@ -116,13 +115,14 @@
* passed will set it to Validator.GENERIC.
*/
public AlgorithmChecker(TrustAnchor anchor, String variant) {
- this(anchor, certPathDefaultConstraints, null, variant);
+ this(anchor, certPathDefaultConstraints, null, null, variant);
}
/**
* Create a new {@code AlgorithmChecker} with the given
- * {@code AlgorithmConstraints}, {@code Timestamp}, and/or {@code Variant}.
- * <p>
+ * {@code AlgorithmConstraints}, {@code Timestamp}, and {@code String}
+ * variant.
+ *
* Note that this constructor can initialize a variation of situations where
* the AlgorithmConstraints, Timestamp, or Variant maybe known.
*
@@ -134,32 +134,28 @@
*/
public AlgorithmChecker(AlgorithmConstraints constraints,
Timestamp jarTimestamp, String variant) {
- this.prevPubKey = null;
- this.trustedPubKey = null;
- this.constraints = (constraints == null ? certPathDefaultConstraints :
- constraints);
- this.pkixdate = (jarTimestamp != null ? jarTimestamp.getTimestamp() :
- null);
- this.jarTimestamp = jarTimestamp;
- this.variant = (variant == null ? Validator.VAR_GENERIC : variant);
+ this(null, constraints, null, jarTimestamp, variant);
}
/**
* Create a new {@code AlgorithmChecker} with the
- * given {@code TrustAnchor} and {@code AlgorithmConstraints}.
+ * given {@code TrustAnchor}, {@code AlgorithmConstraints},
+ * {@code Timestamp}, and {@code String} variant.
*
* @param anchor the trust anchor selected to validate the target
* certificate
* @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 pkixdate The date specified by the PKIXParameters date. If the
+ * PKIXParameters is null, the current date is used. This
+ * should be null when jar files are being checked.
+ * @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.
- *
- * @throws IllegalArgumentException if the {@code anchor} is null
*/
public AlgorithmChecker(TrustAnchor anchor,
- AlgorithmConstraints constraints, Date pkixdate, String variant) {
+ AlgorithmConstraints constraints, Date pkixdate,
+ Timestamp jarTimestamp, String variant) {
if (anchor != null) {
if (anchor.getTrustedCert() != null) {
@@ -179,28 +175,30 @@
}
}
- this.prevPubKey = trustedPubKey;
- this.constraints = constraints;
- this.pkixdate = pkixdate;
- this.jarTimestamp = null;
+ this.prevPubKey = this.trustedPubKey;
+ this.constraints = (constraints == null ? certPathDefaultConstraints :
+ constraints);
+ // If we are checking jar files, set pkixdate the same as the timestamp
+ // for certificate checking
+ this.pkixdate = (jarTimestamp != null ? jarTimestamp.getTimestamp() :
+ pkixdate);
+ this.jarTimestamp = jarTimestamp;
this.variant = (variant == null ? Validator.VAR_GENERIC : variant);
}
/**
- * Create a new {@code AlgorithmChecker} with the
- * given {@code TrustAnchor} and {@code PKIXParameter} date.
+ * Create a new {@code AlgorithmChecker} with the given {@code TrustAnchor},
+ * {@code PKIXParameter} date, and {@code varient}
*
* @param anchor the trust anchor selected to validate the target
* certificate
* @param pkixdate Date the constraints are checked against. The value is
- * either the PKIXParameter date or null for the current date.
+ * either the PKIXParameters 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, String variant) {
- this(anchor, certPathDefaultConstraints, pkixdate, variant);
+ this(anchor, certPathDefaultConstraints, pkixdate, null, variant);
}
// Check this 'cert' for restrictions in the AnchorCertificates
@@ -216,10 +214,6 @@
return AnchorCertificates.contains(cert);
}
- Timestamp getJarTimestamp() {
- return jarTimestamp;
- }
-
@Override
public void init(boolean forward) throws CertPathValidatorException {
// Note that this class does not support forward mode.
--- a/jdk/src/java.base/share/classes/sun/security/provider/certpath/PKIXCertPathValidator.java Fri Mar 10 09:20:55 2017 -0800
+++ b/jdk/src/java.base/share/classes/sun/security/provider/certpath/PKIXCertPathValidator.java Fri Mar 10 21:04:15 2017 -0800
@@ -172,12 +172,8 @@
List<PKIXCertPathChecker> certPathCheckers = new ArrayList<>();
// add standard checkers that we will be using
certPathCheckers.add(untrustedChecker);
- if (params.timestamp() == null) {
- certPathCheckers.add(new AlgorithmChecker(anchor, params.date(), null));
- } else {
- certPathCheckers.add(new AlgorithmChecker(null,
- params.timestamp(), params.variant()));
- }
+ certPathCheckers.add(new AlgorithmChecker(anchor, null, params.date(),
+ params.timestamp(), params.variant()));
certPathCheckers.add(new KeyChecker(certPathLen,
params.targetCertConstraints()));
certPathCheckers.add(new ConstraintsChecker(certPathLen));
@@ -195,13 +191,10 @@
certPathCheckers.add(pc);
// default value for date is current time
BasicChecker bc;
- if (params.timestamp() == null) {
- bc = new BasicChecker(anchor, params.date(), params.sigProvider(),
- false);
- } else {
- bc = new BasicChecker(anchor, params.timestamp().getTimestamp(),
- params.sigProvider(), false);
- }
+ bc = new BasicChecker(anchor,
+ (params.timestamp() == null ? params.date() :
+ params.timestamp().getTimestamp()),
+ params.sigProvider(), false);
certPathCheckers.add(bc);
boolean revCheckerAdded = false;
--- a/jdk/src/java.base/share/classes/sun/security/util/DisabledAlgorithmConstraints.java Fri Mar 10 09:20:55 2017 -0800
+++ b/jdk/src/java.base/share/classes/sun/security/util/DisabledAlgorithmConstraints.java Fri Mar 10 21:04:15 2017 -0800
@@ -27,6 +27,8 @@
import sun.security.validator.Validator;
+import java.io.ByteArrayOutputStream;
+import java.io.PrintStream;
import java.security.CryptoPrimitive;
import java.security.AlgorithmParameters;
import java.security.Key;
@@ -670,8 +672,14 @@
}
if (debug != null) {
- debug.println("Checking if usage constraint " + v +
- " matches " + cp.getVariant());
+ debug.println("Checking if usage constraint \"" + v +
+ "\" matches \"" + cp.getVariant() + "\"");
+ // Because usage checking can come from many places
+ // a stack trace is very helpful.
+ ByteArrayOutputStream ba = new ByteArrayOutputStream();
+ PrintStream ps = new PrintStream(ba);
+ (new Exception()).printStackTrace(ps);
+ debug.println(ba.toString());
}
if (cp.getVariant().compareTo(v) == 0) {
if (next(cp)) {
--- a/jdk/src/java.base/share/classes/sun/security/validator/PKIXValidator.java Fri Mar 10 09:20:55 2017 -0800
+++ b/jdk/src/java.base/share/classes/sun/security/validator/PKIXValidator.java Fri Mar 10 21:04:15 2017 -0800
@@ -195,18 +195,16 @@
("null or zero-length certificate chain");
}
- // Check if 'parameter' affects 'pkixParameters'
+ // Use PKIXExtendedParameters for timestamp and variant additions
PKIXBuilderParameters pkixParameters = null;
- if (parameter instanceof Timestamp && plugin) {
- try {
- pkixParameters = new PKIXExtendedParameters(
- (PKIXBuilderParameters) parameterTemplate.clone(),
- (Timestamp) parameter, variant);
- } catch (InvalidAlgorithmParameterException e) {
- // ignore exception
- }
- } else {
- pkixParameters = (PKIXBuilderParameters) parameterTemplate.clone();
+ try {
+ pkixParameters = new PKIXExtendedParameters(
+ (PKIXBuilderParameters) parameterTemplate.clone(),
+ (parameter instanceof Timestamp) ?
+ (Timestamp) parameter : null,
+ variant);
+ } catch (InvalidAlgorithmParameterException e) {
+ // ignore exception
}
// add new algorithm constraints checker
--- a/jdk/src/java.base/share/classes/sun/security/validator/SimpleValidator.java Fri Mar 10 09:20:55 2017 -0800
+++ b/jdk/src/java.base/share/classes/sun/security/validator/SimpleValidator.java Fri Mar 10 21:04:15 2017 -0800
@@ -162,7 +162,7 @@
AlgorithmChecker appAlgChecker = null;
if (constraints != null) {
appAlgChecker = new AlgorithmChecker(anchor, constraints, null,
- variant);
+ null, variant);
}
// verify top down, starting at the certificate issued by