< prev index next >

src/share/classes/sun/security/provider/certpath/AlgorithmChecker.java

Print this page


   1 /*
   2  * Copyright (c) 2009, 2016, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package sun.security.provider.certpath;
  27 
  28 import java.security.AlgorithmConstraints;
  29 import java.security.CryptoPrimitive;


  30 import java.util.Collection;
  31 import java.util.Collections;

  32 import java.util.Set;
  33 import java.util.EnumSet;
  34 import java.math.BigInteger;
  35 import java.security.PublicKey;
  36 import java.security.KeyFactory;
  37 import java.security.AlgorithmParameters;
  38 import java.security.GeneralSecurityException;
  39 import java.security.cert.Certificate;
  40 import java.security.cert.X509CRL;
  41 import java.security.cert.X509Certificate;
  42 import java.security.cert.PKIXCertPathChecker;
  43 import java.security.cert.TrustAnchor;
  44 import java.security.cert.CRLException;
  45 import java.security.cert.CertificateException;
  46 import java.security.cert.CertPathValidatorException;
  47 import java.security.cert.CertPathValidatorException.BasicReason;
  48 import java.security.cert.PKIXReason;
  49 import java.security.interfaces.DSAParams;
  50 import java.security.interfaces.DSAPublicKey;
  51 import java.security.spec.DSAPublicKeySpec;
  52 
  53 import sun.security.util.AnchorCertificates;
  54 import sun.security.util.CertConstraintParameters;
  55 import sun.security.util.Debug;
  56 import sun.security.util.DisabledAlgorithmConstraints;

  57 import sun.security.x509.X509CertImpl;
  58 import sun.security.x509.X509CRLImpl;
  59 import sun.security.x509.AlgorithmId;
  60 
  61 /**
  62  * A <code>PKIXCertPathChecker</code> implementation to check whether a
  63  * specified certificate contains the required algorithm constraints.
  64  * <p>
  65  * Certificate fields such as the subject public key, the signature
  66  * algorithm, key usage, extended key usage, etc. need to conform to
  67  * the specified algorithm constraints.
  68  *
  69  * @see PKIXCertPathChecker
  70  * @see PKIXParameters
  71  */
  72 final public class AlgorithmChecker extends PKIXCertPathChecker {
  73     private static final Debug debug = Debug.getInstance("certpath");
  74 
  75     private final AlgorithmConstraints constraints;
  76     private final PublicKey trustedPubKey;

  77     private PublicKey prevPubKey;


  78 
  79     private final static Set<CryptoPrimitive> SIGNATURE_PRIMITIVE_SET =
  80         Collections.unmodifiableSet(EnumSet.of(CryptoPrimitive.SIGNATURE));
  81 
  82     private final static Set<CryptoPrimitive> KU_PRIMITIVE_SET =
  83         Collections.unmodifiableSet(EnumSet.of(
  84             CryptoPrimitive.SIGNATURE,
  85             CryptoPrimitive.KEY_ENCAPSULATION,
  86             CryptoPrimitive.PUBLIC_KEY_ENCRYPTION,
  87             CryptoPrimitive.KEY_AGREEMENT));
  88 
  89     private final static DisabledAlgorithmConstraints
  90         certPathDefaultConstraints = new DisabledAlgorithmConstraints(
  91             DisabledAlgorithmConstraints.PROPERTY_CERTPATH_DISABLED_ALGS);
  92 
  93     // If there is no "cacerts" keyword, then disable anchor checking
  94     private static final boolean publicCALimits =
  95             certPathDefaultConstraints.checkProperty("jdkCA");
  96 
  97     // If anchor checking enabled, this will be true if the trust anchor
  98     // has a match in the cacerts file
  99     private boolean trustedMatch = false;
 100 
 101     /**
 102      * Create a new <code>AlgorithmChecker</code> with the algorithm
 103      * constraints specified in security property
 104      * "jdk.certpath.disabledAlgorithms".
 105      *
 106      * @param anchor the trust anchor selected to validate the target
 107      *     certificate


 108      */
 109     public AlgorithmChecker(TrustAnchor anchor) {
 110         this(anchor, certPathDefaultConstraints);
 111     }
 112 
 113     /**
 114      * Create a new <code>AlgorithmChecker</code> with the
 115      * given {@code AlgorithmConstraints}.
 116      * <p>
 117      * Note that this constructor will be used to check a certification
 118      * path where the trust anchor is unknown, or a certificate list which may
 119      * contain the trust anchor. This constructor is used by SunJSSE.
 120      *
 121      * @param constraints the algorithm constraints (or null)




 122      */
 123     public AlgorithmChecker(AlgorithmConstraints constraints) {
 124         this.prevPubKey = null;
 125         this.trustedPubKey = null;
 126         this.constraints = constraints;
 127     }
 128 
 129     /**
 130      * Create a new <code>AlgorithmChecker</code> with the
 131      * given <code>TrustAnchor</code> and <code>AlgorithmConstraints</code>.

 132      *
 133      * @param anchor the trust anchor selected to validate the target
 134      *     certificate
 135      * @param constraints the algorithm constraints (or null)
 136      *
 137      * @throws IllegalArgumentException if the <code>anchor</code> is null





 138      */
 139     public AlgorithmChecker(TrustAnchor anchor,
 140             AlgorithmConstraints constraints) {
 141 
 142         if (anchor == null) {
 143             throw new IllegalArgumentException(
 144                         "The trust anchor cannot be null");
 145         }
 146 

 147         if (anchor.getTrustedCert() != null) {
 148             this.trustedPubKey = anchor.getTrustedCert().getPublicKey();
 149             // Check for anchor certificate restrictions
 150             trustedMatch = checkFingerprint(anchor.getTrustedCert());
 151             if (trustedMatch && debug != null) {
 152                 debug.println("trustedMatch = true");
 153             }
 154         } else {
 155             this.trustedPubKey = anchor.getCAPublicKey();
 156         }

















 157 
 158         this.prevPubKey = trustedPubKey;
 159         this.constraints = constraints;











 160     }
 161 
 162     // Check this 'cert' for restrictions in the AnchorCertificates
 163     // trusted certificates list
 164     private static boolean checkFingerprint(X509Certificate cert) {
 165         if (!publicCALimits) {
 166             return false;
 167         }
 168 
 169         if (debug != null) {
 170             debug.println("AlgorithmChecker.contains: " + cert.getSigAlgName());
 171         }
 172         return AnchorCertificates.contains(cert);
 173     }
 174 
 175     @Override
 176     public void init(boolean forward) throws CertPathValidatorException {
 177         //  Note that this class does not support forward mode.
 178         if (!forward) {
 179             if (trustedPubKey != null) {


 200     }
 201 
 202     @Override
 203     public void check(Certificate cert,
 204             Collection<String> unresolvedCritExts)
 205             throws CertPathValidatorException {
 206 
 207         if (!(cert instanceof X509Certificate) || constraints == null) {
 208             // ignore the check for non-x.509 certificate or null constraints
 209             return;
 210         }
 211 
 212         // check the key usage and key size
 213         boolean[] keyUsage = ((X509Certificate) cert).getKeyUsage();
 214         if (keyUsage != null && keyUsage.length < 9) {
 215             throw new CertPathValidatorException(
 216                 "incorrect KeyUsage extension",
 217                 null, null, -1, PKIXReason.INVALID_KEY_USAGE);
 218         }
 219 






















 220         // Assume all key usage bits are set if key usage is not present
 221         Set<CryptoPrimitive> primitives = KU_PRIMITIVE_SET;
 222 
 223         if (keyUsage != null) {
 224                 primitives = EnumSet.noneOf(CryptoPrimitive.class);
 225 
 226             if (keyUsage[0] || keyUsage[1] || keyUsage[5] || keyUsage[6]) {
 227                 // keyUsage[0]: KeyUsage.digitalSignature
 228                 // keyUsage[1]: KeyUsage.nonRepudiation
 229                 // keyUsage[5]: KeyUsage.keyCertSign
 230                 // keyUsage[6]: KeyUsage.cRLSign
 231                 primitives.add(CryptoPrimitive.SIGNATURE);
 232             }
 233 
 234             if (keyUsage[2]) {      // KeyUsage.keyEncipherment
 235                 primitives.add(CryptoPrimitive.KEY_ENCAPSULATION);
 236             }
 237 
 238             if (keyUsage[3]) {      // KeyUsage.dataEncipherment
 239                 primitives.add(CryptoPrimitive.PUBLIC_KEY_ENCRYPTION);
 240             }
 241 
 242             if (keyUsage[4]) {      // KeyUsage.keyAgreement
 243                 primitives.add(CryptoPrimitive.KEY_AGREEMENT);
 244             }
 245 
 246             // KeyUsage.encipherOnly and KeyUsage.decipherOnly are
 247             // undefined in the absence of the keyAgreement bit.
 248 
 249             if (primitives.isEmpty()) {
 250                 throw new CertPathValidatorException(
 251                     "incorrect KeyUsage extension bits",
 252                     null, null, -1, PKIXReason.INVALID_KEY_USAGE);
 253             }
 254         }
 255 
 256         PublicKey currPubKey = cert.getPublicKey();


 257 

 258         if (constraints instanceof DisabledAlgorithmConstraints) {
 259             // Check against DisabledAlgorithmConstraints certpath constraints.
 260             // permits() will throw exception on failure.
 261             ((DisabledAlgorithmConstraints)constraints).permits(primitives,
 262                 new CertConstraintParameters((X509Certificate)cert,
 263                         trustedMatch));
 264             // If there is no previous key, set one and exit
 265             if (prevPubKey == null) {
 266                 prevPubKey = currPubKey;
 267                 return;
 268             }
 269         }
 270 
 271         X509CertImpl x509Cert;
 272         AlgorithmId algorithmId;
 273         try {
 274             x509Cert = X509CertImpl.toImpl((X509Certificate)cert);
 275             algorithmId = (AlgorithmId)x509Cert.get(X509CertImpl.SIG_ALG);
 276         } catch (CertificateException ce) {
 277             throw new CertPathValidatorException(ce);
 278         }
 279 
 280         AlgorithmParameters currSigAlgParams = algorithmId.getParameters();
 281         String currSigAlg = x509Cert.getSigAlgName();
 282 
 283         // If 'constraints' is not of DisabledAlgorithmConstraints, check all
 284         // everything individually
 285         if (!(constraints instanceof DisabledAlgorithmConstraints)) {
 286             // Check the current signature algorithm
 287             if (!constraints.permits(
 288                     SIGNATURE_PRIMITIVE_SET,
 289                     currSigAlg, currSigAlgParams)) {
 290                 throw new CertPathValidatorException(
 291                         "Algorithm constraints check failed on signature " +
 292                                 "algorithm: " + currSigAlg, null, null, -1,
 293                         BasicReason.ALGORITHM_CONSTRAINED);
 294             }
 295 




 296         if (!constraints.permits(primitives, currPubKey)) {
 297             throw new CertPathValidatorException(
 298                         "Algorithm constraints check failed on keysize: " +
 299                                 sun.security.util.KeyUtil.getKeySize(currPubKey),


 300                 null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
 301         }
 302         }
 303 






 304         // Check with previous cert for signature algorithm and public key
 305         if (prevPubKey != null) {
 306                 if (!constraints.permits(
 307                         SIGNATURE_PRIMITIVE_SET,
 308                         currSigAlg, prevPubKey, currSigAlgParams)) {
 309                     throw new CertPathValidatorException(
 310                     "Algorithm constraints check failed on " +
 311                             "signature algorithm: " + currSigAlg,
 312                         null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
 313                 }
 314 
 315             // Inherit key parameters from previous key
 316             if (PKIX.isDSAPublicKeyWithoutParams(currPubKey)) {
 317                 // Inherit DSA parameters from previous key
 318                 if (!(prevPubKey instanceof DSAPublicKey)) {
 319                     throw new CertPathValidatorException("Input key is not " +
 320                         "of a appropriate type for inheriting parameters");
 321                 }
 322 
 323                 DSAParams params = ((DSAPublicKey)prevPubKey).getParams();
 324                 if (params == null) {
 325                     throw new CertPathValidatorException(
 326                         "Key parameters missing from public key.");
 327                 }
 328 
 329                 try {
 330                     BigInteger y = ((DSAPublicKey)currPubKey).getY();
 331                     KeyFactory kf = KeyFactory.getInstance("DSA");
 332                     DSAPublicKeySpec ks = new DSAPublicKeySpec(y,
 333                                                        params.getP(),
 334                                                        params.getQ(),
 335                                                        params.getG());
 336                     currPubKey = kf.generatePublic(ks);
 337                 } catch (GeneralSecurityException e) {
 338                     throw new CertPathValidatorException("Unable to generate " +
 339                         "key with inherited parameters: " + e.getMessage(), e);
 340                 }
 341             }
 342         }
 343 
 344         // reset the previous public key
 345         prevPubKey = currPubKey;
 346 
 347         // check the extended key usage, ignore the check now
 348         // List<String> extendedKeyUsages = x509Cert.getExtendedKeyUsage();
 349 
 350         // DO NOT remove any unresolved critical extensions
 351     }
 352 
 353     /**
 354      * Try to set the trust anchor of the checker.
 355      * <p>
 356      * If there is no trust anchor specified and the checker has not started,
 357      * set the trust anchor.
 358      *
 359      * @param anchor the trust anchor selected to validate the target
 360      *     certificate
 361      */
 362     void trySetTrustAnchor(TrustAnchor anchor) {
 363         // Don't bother if the check has started or trust anchor has already
 364         // specified.
 365         if (prevPubKey == null) {
 366             if (anchor == null) {
 367                 throw new IllegalArgumentException(
 368                         "The trust anchor cannot be null");
 369             }
 370 
 371             // Don't bother to change the trustedPubKey.
 372             if (anchor.getTrustedCert() != null) {
 373                 prevPubKey = anchor.getTrustedCert().getPublicKey();
 374                 // Check for anchor certificate restrictions
 375                 trustedMatch = checkFingerprint(anchor.getTrustedCert());
 376                 if (trustedMatch && debug != null) {
 377                     debug.println("trustedMatch = true");
 378                 }
 379             } else {
 380                 prevPubKey = anchor.getCAPublicKey();
 381             }
 382         }
 383     }
 384 
 385     /**
 386      * Check the signature algorithm with the specified public key.
 387      *
 388      * @param key the public key to verify the CRL signature
 389      * @param crl the target CRL


 390      */
 391     static void check(PublicKey key, X509CRL crl)
 392                         throws CertPathValidatorException {
 393 
 394         X509CRLImpl x509CRLImpl = null;
 395         try {
 396             x509CRLImpl = X509CRLImpl.toImpl(crl);
 397         } catch (CRLException ce) {
 398             throw new CertPathValidatorException(ce);
 399         }
 400 
 401         AlgorithmId algorithmId = x509CRLImpl.getSigAlgId();
 402         check(key, algorithmId);
 403     }
 404 
 405     /**
 406      * Check the signature algorithm with the specified public key.
 407      *
 408      * @param key the public key to verify the CRL signature
 409      * @param crl the target CRL


 410      */
 411     static void check(PublicKey key, AlgorithmId algorithmId)
 412                         throws CertPathValidatorException {
 413         String sigAlgName = algorithmId.getName();
 414         AlgorithmParameters sigAlgParams = algorithmId.getParameters();
 415 
 416         if (!certPathDefaultConstraints.permits(
 417                 SIGNATURE_PRIMITIVE_SET, sigAlgName, key, sigAlgParams)) {
 418             throw new CertPathValidatorException(
 419                 "Algorithm constraints check failed on signature algorithm: " +
 420                 sigAlgName + " is disabled",
 421                 null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
 422         }
 423     }
 424 
 425 }
 426 
   1 /*
   2  * Copyright (c) 2009, 2017, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package sun.security.provider.certpath;
  27 
  28 import java.security.AlgorithmConstraints;
  29 import java.security.CryptoPrimitive;
  30 import java.security.Timestamp;
  31 import java.security.cert.CertPathValidator;
  32 import java.util.Collection;
  33 import java.util.Collections;
  34 import java.util.Date;
  35 import java.util.Set;
  36 import java.util.EnumSet;
  37 import java.math.BigInteger;
  38 import java.security.PublicKey;
  39 import java.security.KeyFactory;
  40 import java.security.AlgorithmParameters;
  41 import java.security.GeneralSecurityException;
  42 import java.security.cert.Certificate;
  43 import java.security.cert.X509CRL;
  44 import java.security.cert.X509Certificate;
  45 import java.security.cert.PKIXCertPathChecker;
  46 import java.security.cert.TrustAnchor;
  47 import java.security.cert.CRLException;
  48 import java.security.cert.CertificateException;
  49 import java.security.cert.CertPathValidatorException;
  50 import java.security.cert.CertPathValidatorException.BasicReason;
  51 import java.security.cert.PKIXReason;
  52 import java.security.interfaces.DSAParams;
  53 import java.security.interfaces.DSAPublicKey;
  54 import java.security.spec.DSAPublicKeySpec;
  55 
  56 import sun.security.util.AnchorCertificates;
  57 import sun.security.util.ConstraintsParameters;
  58 import sun.security.util.Debug;
  59 import sun.security.util.DisabledAlgorithmConstraints;
  60 import sun.security.validator.Validator;
  61 import sun.security.x509.X509CertImpl;
  62 import sun.security.x509.X509CRLImpl;
  63 import sun.security.x509.AlgorithmId;
  64 
  65 /**
  66  * A {@code PKIXCertPathChecker} implementation to check whether a
  67  * specified certificate contains the required algorithm constraints.
  68  * <p>
  69  * Certificate fields such as the subject public key, the signature
  70  * algorithm, key usage, extended key usage, etc. need to conform to
  71  * the specified algorithm constraints.
  72  *
  73  * @see PKIXCertPathChecker
  74  * @see PKIXParameters
  75  */
  76 public final class AlgorithmChecker extends PKIXCertPathChecker {
  77     private static final Debug debug = Debug.getInstance("certpath");
  78 
  79     private final AlgorithmConstraints constraints;
  80     private final PublicKey trustedPubKey;
  81     private final Date pkixdate;
  82     private PublicKey prevPubKey;
  83     private final Timestamp jarTimestamp;
  84     private final String variant;
  85 
  86     private static final Set<CryptoPrimitive> SIGNATURE_PRIMITIVE_SET =
  87         Collections.unmodifiableSet(EnumSet.of(CryptoPrimitive.SIGNATURE));
  88 
  89     private static final Set<CryptoPrimitive> KU_PRIMITIVE_SET =
  90         Collections.unmodifiableSet(EnumSet.of(
  91             CryptoPrimitive.SIGNATURE,
  92             CryptoPrimitive.KEY_ENCAPSULATION,
  93             CryptoPrimitive.PUBLIC_KEY_ENCRYPTION,
  94             CryptoPrimitive.KEY_AGREEMENT));
  95 
  96     private static final DisabledAlgorithmConstraints
  97         certPathDefaultConstraints = new DisabledAlgorithmConstraints(
  98             DisabledAlgorithmConstraints.PROPERTY_CERTPATH_DISABLED_ALGS);
  99 
 100     // If there is no "cacerts" keyword, then disable anchor checking
 101     private static final boolean publicCALimits =
 102             certPathDefaultConstraints.checkProperty("jdkCA");
 103 
 104     // If anchor checking enabled, this will be true if the trust anchor
 105     // has a match in the cacerts file
 106     private boolean trustedMatch = false;
 107 
 108     /**
 109      * Create a new {@code AlgorithmChecker} with the given algorithm
 110      * given {@code TrustAnchor} and {@code String} variant.

 111      *
 112      * @param anchor the trust anchor selected to validate the target
 113      *     certificate
 114      * @param variant is the Validator variants of the operation. A null value
 115      *                passed will set it to Validator.GENERIC.
 116      */
 117     public AlgorithmChecker(TrustAnchor anchor, String variant) {
 118         this(anchor, certPathDefaultConstraints, null, null, variant);
 119     }
 120 
 121     /**
 122      * Create a new {@code AlgorithmChecker} with the given
 123      * {@code AlgorithmConstraints}, {@code Timestamp}, and {@code String}
 124      * variant.
 125      *
 126      * Note that this constructor can initialize a variation of situations where
 127      * the AlgorithmConstraints, Timestamp, or Variant maybe known.
 128      *
 129      * @param constraints the algorithm constraints (or null)
 130      * @param jarTimestamp Timestamp passed for JAR timestamp constraint
 131      *                     checking. Set to null if not applicable.
 132      * @param variant is the Validator variants of the operation. A null value
 133      *                passed will set it to Validator.GENERIC.
 134      */
 135     public AlgorithmChecker(AlgorithmConstraints constraints,
 136             Timestamp jarTimestamp, String variant) {
 137         this(null, constraints, null, jarTimestamp, variant);

 138     }
 139 
 140     /**
 141      * Create a new {@code AlgorithmChecker} with the
 142      * given {@code TrustAnchor}, {@code AlgorithmConstraints},
 143      * {@code Timestamp}, and {@code String} variant.
 144      *
 145      * @param anchor the trust anchor selected to validate the target
 146      *     certificate
 147      * @param constraints the algorithm constraints (or null)
 148      * @param pkixdate The date specified by the PKIXParameters date.  If the
 149      *                 PKIXParameters is null, the current date is used.  This
 150      *                 should be null when jar files are being checked.
 151      * @param jarTimestamp Timestamp passed for JAR timestamp constraint
 152      *                     checking. Set to null if not applicable.
 153      * @param variant is the Validator variants of the operation. A null value
 154      *                passed will set it to Validator.GENERIC.
 155      */
 156     public AlgorithmChecker(TrustAnchor anchor,
 157             AlgorithmConstraints constraints, Date pkixdate,
 158             Timestamp jarTimestamp, String variant) {




 159 
 160         if (anchor != null) {
 161             if (anchor.getTrustedCert() != null) {
 162                 this.trustedPubKey = anchor.getTrustedCert().getPublicKey();
 163                 // Check for anchor certificate restrictions
 164                 trustedMatch = checkFingerprint(anchor.getTrustedCert());
 165                 if (trustedMatch && debug != null) {
 166                     debug.println("trustedMatch = true");
 167                 }
 168             } else {
 169                 this.trustedPubKey = anchor.getCAPublicKey();
 170             }
 171         } else {
 172             this.trustedPubKey = null;
 173             if (debug != null) {
 174                 debug.println("TrustAnchor is null, trustedMatch is false.");
 175             }
 176         }
 177 
 178         this.prevPubKey = this.trustedPubKey;
 179         this.constraints = (constraints == null ? certPathDefaultConstraints :
 180                 constraints);
 181         // If we are checking jar files, set pkixdate the same as the timestamp
 182         // for certificate checking
 183         this.pkixdate = (jarTimestamp != null ? jarTimestamp.getTimestamp() :
 184                 pkixdate);
 185         this.jarTimestamp = jarTimestamp;
 186         this.variant = (variant == null ? Validator.VAR_GENERIC : variant);
 187     }
 188 
 189     /**
 190      * Create a new {@code AlgorithmChecker} with the given {@code TrustAnchor},
 191      * {@code PKIXParameter} date, and {@code varient}
 192      *
 193      * @param anchor the trust anchor selected to validate the target
 194      *     certificate
 195      * @param pkixdate Date the constraints are checked against. The value is
 196      *             either the PKIXParameters date or null for the current date.
 197      * @param variant is the Validator variants of the operation. A null value
 198      *                passed will set it to Validator.GENERIC.
 199      */
 200     public AlgorithmChecker(TrustAnchor anchor, Date pkixdate, String variant) {
 201         this(anchor, certPathDefaultConstraints, pkixdate, null, variant);
 202     }
 203 
 204     // Check this 'cert' for restrictions in the AnchorCertificates
 205     // trusted certificates list
 206     private static boolean checkFingerprint(X509Certificate cert) {
 207         if (!publicCALimits) {
 208             return false;
 209         }
 210 
 211         if (debug != null) {
 212             debug.println("AlgorithmChecker.contains: " + cert.getSigAlgName());
 213         }
 214         return AnchorCertificates.contains(cert);
 215     }
 216 
 217     @Override
 218     public void init(boolean forward) throws CertPathValidatorException {
 219         //  Note that this class does not support forward mode.
 220         if (!forward) {
 221             if (trustedPubKey != null) {


 242     }
 243 
 244     @Override
 245     public void check(Certificate cert,
 246             Collection<String> unresolvedCritExts)
 247             throws CertPathValidatorException {
 248 
 249         if (!(cert instanceof X509Certificate) || constraints == null) {
 250             // ignore the check for non-x.509 certificate or null constraints
 251             return;
 252         }
 253 
 254         // check the key usage and key size
 255         boolean[] keyUsage = ((X509Certificate) cert).getKeyUsage();
 256         if (keyUsage != null && keyUsage.length < 9) {
 257             throw new CertPathValidatorException(
 258                 "incorrect KeyUsage extension",
 259                 null, null, -1, PKIXReason.INVALID_KEY_USAGE);
 260         }
 261 
 262         X509CertImpl x509Cert;
 263         AlgorithmId algorithmId;
 264         try {
 265             x509Cert = X509CertImpl.toImpl((X509Certificate)cert);
 266             algorithmId = (AlgorithmId)x509Cert.get(X509CertImpl.SIG_ALG);
 267         } catch (CertificateException ce) {
 268             throw new CertPathValidatorException(ce);
 269         }
 270 
 271         AlgorithmParameters currSigAlgParams = algorithmId.getParameters();
 272         PublicKey currPubKey = cert.getPublicKey();
 273         String currSigAlg = ((X509Certificate)cert).getSigAlgName();
 274 
 275         // Check the signature algorithm and parameters against constraints.
 276         if (!constraints.permits(SIGNATURE_PRIMITIVE_SET, currSigAlg,
 277                 currSigAlgParams)) {
 278             throw new CertPathValidatorException(
 279                     "Algorithm constraints check failed on signature " +
 280                             "algorithm: " + currSigAlg, null, null, -1,
 281                     BasicReason.ALGORITHM_CONSTRAINED);
 282         }
 283 
 284         // Assume all key usage bits are set if key usage is not present
 285         Set<CryptoPrimitive> primitives = KU_PRIMITIVE_SET;
 286 
 287         if (keyUsage != null) {
 288                 primitives = EnumSet.noneOf(CryptoPrimitive.class);
 289 
 290             if (keyUsage[0] || keyUsage[1] || keyUsage[5] || keyUsage[6]) {
 291                 // keyUsage[0]: KeyUsage.digitalSignature
 292                 // keyUsage[1]: KeyUsage.nonRepudiation
 293                 // keyUsage[5]: KeyUsage.keyCertSign
 294                 // keyUsage[6]: KeyUsage.cRLSign
 295                 primitives.add(CryptoPrimitive.SIGNATURE);
 296             }
 297 
 298             if (keyUsage[2]) {      // KeyUsage.keyEncipherment
 299                 primitives.add(CryptoPrimitive.KEY_ENCAPSULATION);
 300             }
 301 
 302             if (keyUsage[3]) {      // KeyUsage.dataEncipherment
 303                 primitives.add(CryptoPrimitive.PUBLIC_KEY_ENCRYPTION);
 304             }
 305 
 306             if (keyUsage[4]) {      // KeyUsage.keyAgreement
 307                 primitives.add(CryptoPrimitive.KEY_AGREEMENT);
 308             }
 309 
 310             // KeyUsage.encipherOnly and KeyUsage.decipherOnly are
 311             // undefined in the absence of the keyAgreement bit.
 312 
 313             if (primitives.isEmpty()) {
 314                 throw new CertPathValidatorException(
 315                     "incorrect KeyUsage extension bits",
 316                     null, null, -1, PKIXReason.INVALID_KEY_USAGE);
 317             }
 318         }
 319 
 320         ConstraintsParameters cp =
 321                 new ConstraintsParameters((X509Certificate)cert,
 322                         trustedMatch, pkixdate, jarTimestamp, variant);
 323 
 324         // Check against local constraints if it is DisabledAlgorithmConstraints
 325         if (constraints instanceof DisabledAlgorithmConstraints) {
 326             ((DisabledAlgorithmConstraints)constraints).permits(currSigAlg, cp);
 327             // DisabledAlgorithmsConstraints does not check primitives, so key
 328             // additional key check.

































 329 
 330         } else {
 331             // Perform the default constraints checking anyway.
 332             certPathDefaultConstraints.permits(currSigAlg, cp);
 333             // Call locally set constraints to check key with primitives.
 334             if (!constraints.permits(primitives, currPubKey)) {
 335                 throw new CertPathValidatorException(
 336                         "Algorithm constraints check failed on key " +
 337                                 currPubKey.getAlgorithm() + " with size of " +
 338                                 sun.security.util.KeyUtil.getKeySize(currPubKey) +
 339                                 "bits",
 340                         null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
 341             }
 342         }
 343 
 344         // If there is no previous key, set one and exit
 345         if (prevPubKey == null) {
 346             prevPubKey = currPubKey;
 347             return;
 348         }
 349 
 350         // Check with previous cert for signature algorithm and public key

 351         if (!constraints.permits(
 352                 SIGNATURE_PRIMITIVE_SET,
 353                 currSigAlg, prevPubKey, currSigAlgParams)) {
 354             throw new CertPathValidatorException(
 355                     "Algorithm constraints check failed on " +
 356                             "signature algorithm: " + currSigAlg,
 357                     null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
 358         }
 359 
 360         // Inherit key parameters from previous key
 361         if (PKIX.isDSAPublicKeyWithoutParams(currPubKey)) {
 362             // Inherit DSA parameters from previous key
 363             if (!(prevPubKey instanceof DSAPublicKey)) {
 364                 throw new CertPathValidatorException("Input key is not " +
 365                         "of a appropriate type for inheriting parameters");
 366             }
 367 
 368             DSAParams params = ((DSAPublicKey)prevPubKey).getParams();
 369             if (params == null) {
 370                 throw new CertPathValidatorException(
 371                         "Key parameters missing from public key.");
 372             }
 373 
 374             try {
 375                 BigInteger y = ((DSAPublicKey)currPubKey).getY();
 376                 KeyFactory kf = KeyFactory.getInstance("DSA");
 377                 DSAPublicKeySpec ks = new DSAPublicKeySpec(y, params.getP(),
 378                         params.getQ(), params.getG());


 379                 currPubKey = kf.generatePublic(ks);
 380             } catch (GeneralSecurityException e) {
 381                 throw new CertPathValidatorException("Unable to generate " +
 382                         "key with inherited parameters: " + e.getMessage(), e);
 383             }
 384         }

 385 
 386         // reset the previous public key
 387         prevPubKey = currPubKey;





 388     }
 389 
 390     /**
 391      * Try to set the trust anchor of the checker.
 392      * <p>
 393      * If there is no trust anchor specified and the checker has not started,
 394      * set the trust anchor.
 395      *
 396      * @param anchor the trust anchor selected to validate the target
 397      *     certificate
 398      */
 399     void trySetTrustAnchor(TrustAnchor anchor) {
 400         // Don't bother if the check has started or trust anchor has already
 401         // specified.
 402         if (prevPubKey == null) {
 403             if (anchor == null) {
 404                 throw new IllegalArgumentException(
 405                         "The trust anchor cannot be null");
 406             }
 407 
 408             // Don't bother to change the trustedPubKey.
 409             if (anchor.getTrustedCert() != null) {
 410                 prevPubKey = anchor.getTrustedCert().getPublicKey();
 411                 // Check for anchor certificate restrictions
 412                 trustedMatch = checkFingerprint(anchor.getTrustedCert());
 413                 if (trustedMatch && debug != null) {
 414                     debug.println("trustedMatch = true");
 415                 }
 416             } else {
 417                 prevPubKey = anchor.getCAPublicKey();
 418             }
 419         }
 420     }
 421 
 422     /**
 423      * Check the signature algorithm with the specified public key.
 424      *
 425      * @param key the public key to verify the CRL signature
 426      * @param crl the target CRL
 427      * @param variant is the Validator variants of the operation. A null value
 428      *                passed will set it to Validator.GENERIC.
 429      */
 430     static void check(PublicKey key, X509CRL crl, String variant)
 431                         throws CertPathValidatorException {
 432 
 433         X509CRLImpl x509CRLImpl = null;
 434         try {
 435             x509CRLImpl = X509CRLImpl.toImpl(crl);
 436         } catch (CRLException ce) {
 437             throw new CertPathValidatorException(ce);
 438         }
 439 
 440         AlgorithmId algorithmId = x509CRLImpl.getSigAlgId();
 441         check(key, algorithmId, variant);
 442     }
 443 
 444     /**
 445      * Check the signature algorithm with the specified public key.
 446      *
 447      * @param key the public key to verify the CRL signature
 448      * @param algorithmId signature algorithm Algorithm ID
 449      * @param variant is the Validator variants of the operation. A null value
 450      *                passed will set it to Validator.GENERIC.
 451      */
 452     static void check(PublicKey key, AlgorithmId algorithmId, String variant)
 453                         throws CertPathValidatorException {
 454         String sigAlgName = algorithmId.getName();
 455         AlgorithmParameters sigAlgParams = algorithmId.getParameters();
 456 
 457         certPathDefaultConstraints.permits(new ConstraintsParameters(
 458                 sigAlgName, sigAlgParams, key, variant));




 459     }


 460 }
 461 
< prev index next >