8176350: Usage constraints don't take effect when using PKIX
authorascarpino
Fri, 10 Mar 2017 21:04:15 -0800
changeset 44158 49deb8a1ed3f
parent 44157 8296ab3368eb
child 44159 c30e64a9859b
child 44338 92f2d268e81b
8176350: Usage constraints don't take effect when using PKIX Reviewed-by: xuelei, mullan
jdk/src/java.base/share/classes/sun/security/provider/certpath/AlgorithmChecker.java
jdk/src/java.base/share/classes/sun/security/provider/certpath/PKIXCertPathValidator.java
jdk/src/java.base/share/classes/sun/security/util/DisabledAlgorithmConstraints.java
jdk/src/java.base/share/classes/sun/security/validator/PKIXValidator.java
jdk/src/java.base/share/classes/sun/security/validator/SimpleValidator.java
--- 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