< prev index next >

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

Print this page


   1 /*
   2  * Copyright (c) 2009, 2015, 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.util.HashSet;
  35 import java.math.BigInteger;
  36 import java.security.PublicKey;
  37 import java.security.KeyFactory;
  38 import java.security.AlgorithmParameters;
  39 import java.security.NoSuchAlgorithmException;
  40 import java.security.GeneralSecurityException;
  41 import java.security.cert.Certificate;
  42 import java.security.cert.X509CRL;
  43 import java.security.cert.X509Certificate;
  44 import java.security.cert.PKIXCertPathChecker;
  45 import java.security.cert.TrustAnchor;
  46 import java.security.cert.CRLException;
  47 import java.security.cert.CertificateException;
  48 import java.security.cert.CertPathValidatorException;
  49 import java.security.cert.CertPathValidatorException.BasicReason;
  50 import java.security.cert.PKIXReason;
  51 import java.io.IOException;
  52 import java.security.interfaces.*;
  53 import java.security.spec.*;
  54 



  55 import sun.security.util.DisabledAlgorithmConstraints;
  56 import sun.security.x509.X509CertImpl;
  57 import sun.security.x509.X509CRLImpl;
  58 import sun.security.x509.AlgorithmId;
  59 
  60 /**
  61  * A <code>PKIXCertPathChecker</code> implementation to check whether a
  62  * specified certificate contains the required algorithm constraints.
  63  * <p>
  64  * Certificate fields such as the subject public key, the signature
  65  * algorithm, key usage, extended key usage, etc. need to conform to
  66  * the specified algorithm constraints.
  67  *
  68  * @see PKIXCertPathChecker
  69  * @see PKIXParameters
  70  */
  71 public final class AlgorithmChecker extends PKIXCertPathChecker {

  72 
  73     private final AlgorithmConstraints constraints;
  74     private final PublicKey trustedPubKey;
  75     private PublicKey prevPubKey;
  76 
  77     private static final Set<CryptoPrimitive> SIGNATURE_PRIMITIVE_SET =
  78         Collections.unmodifiableSet(EnumSet.of(CryptoPrimitive.SIGNATURE));
  79 
  80     private static final Set<CryptoPrimitive> KU_PRIMITIVE_SET =
  81         Collections.unmodifiableSet(EnumSet.of(
  82             CryptoPrimitive.SIGNATURE,
  83             CryptoPrimitive.KEY_ENCAPSULATION,
  84             CryptoPrimitive.PUBLIC_KEY_ENCRYPTION,
  85             CryptoPrimitive.KEY_AGREEMENT));
  86 
  87     private static final DisabledAlgorithmConstraints
  88         certPathDefaultConstraints = new DisabledAlgorithmConstraints(
  89             DisabledAlgorithmConstraints.PROPERTY_CERTPATH_DISABLED_ALGS);
  90 








  91     /**
  92      * Create a new <code>AlgorithmChecker</code> with the algorithm
  93      * constraints specified in security property
  94      * "jdk.certpath.disabledAlgorithms".
  95      *
  96      * @param anchor the trust anchor selected to validate the target
  97      *     certificate
  98      */
  99     public AlgorithmChecker(TrustAnchor anchor) {
 100         this(anchor, certPathDefaultConstraints);
 101     }
 102 
 103     /**
 104      * Create a new <code>AlgorithmChecker</code> with the
 105      * given {@code AlgorithmConstraints}.
 106      * <p>
 107      * Note that this constructor will be used to check a certification
 108      * path where the trust anchor is unknown, or a certificate list which may
 109      * contain the trust anchor. This constructor is used by SunJSSE.
 110      *


 119     /**
 120      * Create a new <code>AlgorithmChecker</code> with the
 121      * given <code>TrustAnchor</code> and <code>AlgorithmConstraints</code>.
 122      *
 123      * @param anchor the trust anchor selected to validate the target
 124      *     certificate
 125      * @param constraints the algorithm constraints (or null)
 126      *
 127      * @throws IllegalArgumentException if the <code>anchor</code> is null
 128      */
 129     public AlgorithmChecker(TrustAnchor anchor,
 130             AlgorithmConstraints constraints) {
 131 
 132         if (anchor == null) {
 133             throw new IllegalArgumentException(
 134                         "The trust anchor cannot be null");
 135         }
 136 
 137         if (anchor.getTrustedCert() != null) {
 138             this.trustedPubKey = anchor.getTrustedCert().getPublicKey();





 139         } else {
 140             this.trustedPubKey = anchor.getCAPublicKey();
 141         }
 142 
 143         this.prevPubKey = trustedPubKey;
 144         this.constraints = constraints;
 145     }
 146 













 147     @Override
 148     public void init(boolean forward) throws CertPathValidatorException {
 149         //  Note that this class does not support forward mode.
 150         if (!forward) {
 151             if (trustedPubKey != null) {
 152                 prevPubKey = trustedPubKey;
 153             } else {
 154                 prevPubKey = null;
 155             }
 156         } else {
 157             throw new
 158                 CertPathValidatorException("forward checking not supported");
 159         }
 160     }
 161 
 162     @Override
 163     public boolean isForwardCheckingSupported() {
 164         //  Note that as this class does not support forward mode, the method
 165         //  will always returns false.
 166         return false;
 167     }
 168 
 169     @Override
 170     public Set<String> getSupportedExtensions() {
 171         return null;
 172     }
 173 
 174     @Override
 175     public void check(Certificate cert,
 176             Collection<String> unresolvedCritExts)
 177             throws CertPathValidatorException {
 178 
 179         if (!(cert instanceof X509Certificate) || constraints == null) {
 180             // ignore the check for non-x.509 certificate or null constraints
 181             return;
 182         }
 183 
 184         X509CertImpl x509Cert = null;
 185         try {
 186             x509Cert = X509CertImpl.toImpl((X509Certificate)cert);
 187         } catch (CertificateException ce) {
 188             throw new CertPathValidatorException(ce);
 189         }
 190 
 191         PublicKey currPubKey = x509Cert.getPublicKey();
 192         String currSigAlg = x509Cert.getSigAlgName();
 193 
 194         AlgorithmId algorithmId = null;
 195         try {
 196             algorithmId = (AlgorithmId)x509Cert.get(X509CertImpl.SIG_ALG);
 197         } catch (CertificateException ce) {
 198             throw new CertPathValidatorException(ce);
 199         }
 200 
 201         AlgorithmParameters currSigAlgParams = algorithmId.getParameters();
 202 
 203         // Check the current signature algorithm
 204         if (!constraints.permits(
 205                 SIGNATURE_PRIMITIVE_SET,
 206                 currSigAlg, currSigAlgParams)) {
 207             throw new CertPathValidatorException(
 208                 "Algorithm constraints check failed: " + currSigAlg,
 209                 null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
 210         }
 211 
 212         // check the key usage and key size
 213         boolean[] keyUsage = x509Cert.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",
 252                     null, null, -1, PKIXReason.INVALID_KEY_USAGE);
 253             }
 254         }
 255 







































 256         if (!constraints.permits(primitives, currPubKey)) {
 257             throw new CertPathValidatorException(
 258                 "algorithm constraints check failed",

 259                 null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
 260         }

 261 
 262         // Check with previous cert for signature algorithm and public key
 263         if (prevPubKey != null) {
 264             if (currSigAlg != null) {
 265                 if (!constraints.permits(
 266                         SIGNATURE_PRIMITIVE_SET,
 267                         currSigAlg, prevPubKey, currSigAlgParams)) {
 268                     throw new CertPathValidatorException(
 269                         "Algorithm constraints check failed: " + currSigAlg,

 270                         null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
 271                 }
 272             }
 273 
 274             // Inherit key parameters from previous key
 275             if (PKIX.isDSAPublicKeyWithoutParams(currPubKey)) {
 276                 // Inherit DSA parameters from previous key
 277                 if (!(prevPubKey instanceof DSAPublicKey)) {
 278                     throw new CertPathValidatorException("Input key is not " +
 279                         "of a appropriate type for inheriting parameters");
 280                 }
 281 
 282                 DSAParams params = ((DSAPublicKey)prevPubKey).getParams();
 283                 if (params == null) {
 284                     throw new CertPathValidatorException(
 285                                     "Key parameters missing");
 286                 }
 287 
 288                 try {
 289                     BigInteger y = ((DSAPublicKey)currPubKey).getY();
 290                     KeyFactory kf = KeyFactory.getInstance("DSA");
 291                     DSAPublicKeySpec ks = new DSAPublicKeySpec(y,
 292                                                        params.getP(),
 293                                                        params.getQ(),
 294                                                        params.getG());
 295                     currPubKey = kf.generatePublic(ks);
 296                 } catch (GeneralSecurityException e) {
 297                     throw new CertPathValidatorException("Unable to generate " +
 298                         "key with inherited parameters: " + e.getMessage(), e);
 299                 }
 300             }
 301         }
 302 
 303         // reset the previous public key
 304         prevPubKey = currPubKey;
 305 


 313      * Try to set the trust anchor of the checker.
 314      * <p>
 315      * If there is no trust anchor specified and the checker has not started,
 316      * set the trust anchor.
 317      *
 318      * @param anchor the trust anchor selected to validate the target
 319      *     certificate
 320      */
 321     void trySetTrustAnchor(TrustAnchor anchor) {
 322         // Don't bother if the check has started or trust anchor has already
 323         // specified.
 324         if (prevPubKey == null) {
 325             if (anchor == null) {
 326                 throw new IllegalArgumentException(
 327                         "The trust anchor cannot be null");
 328             }
 329 
 330             // Don't bother to change the trustedPubKey.
 331             if (anchor.getTrustedCert() != null) {
 332                 prevPubKey = anchor.getTrustedCert().getPublicKey();





 333             } else {
 334                 prevPubKey = anchor.getCAPublicKey();
 335             }
 336         }
 337     }
 338 
 339     /**
 340      * Check the signature algorithm with the specified public key.
 341      *
 342      * @param key the public key to verify the CRL signature
 343      * @param crl the target CRL
 344      */
 345     static void check(PublicKey key, X509CRL crl)
 346                         throws CertPathValidatorException {
 347 
 348         X509CRLImpl x509CRLImpl = null;
 349         try {
 350             x509CRLImpl = X509CRLImpl.toImpl(crl);
 351         } catch (CRLException ce) {
 352             throw new CertPathValidatorException(ce);
 353         }
 354 
 355         AlgorithmId algorithmId = x509CRLImpl.getSigAlgId();
 356         check(key, algorithmId);
 357     }
 358 
 359     /**
 360      * Check the signature algorithm with the specified public key.
 361      *
 362      * @param key the public key to verify the CRL signature
 363      * @param crl the target CRL
 364      */
 365     static void check(PublicKey key, AlgorithmId algorithmId)
 366                         throws CertPathValidatorException {
 367         String sigAlgName = algorithmId.getName();
 368         AlgorithmParameters sigAlgParams = algorithmId.getParameters();
 369 
 370         if (!certPathDefaultConstraints.permits(
 371                 SIGNATURE_PRIMITIVE_SET, sigAlgName, key, sigAlgParams)) {
 372             throw new CertPathValidatorException(
 373                 "algorithm check failed: " + sigAlgName + " is disabled",

 374                 null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
 375         }
 376     }
 377 
 378 }
 379 
   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 public final 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 static final Set<CryptoPrimitive> SIGNATURE_PRIMITIVE_SET =
  80         Collections.unmodifiableSet(EnumSet.of(CryptoPrimitive.SIGNATURE));
  81 
  82     private static final 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 static final 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      *


 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) {
 180                 prevPubKey = trustedPubKey;
 181             } else {
 182                 prevPubKey = null;
 183             }
 184         } else {
 185             throw new
 186                 CertPathValidatorException("forward checking not supported");
 187         }
 188     }
 189 
 190     @Override
 191     public boolean isForwardCheckingSupported() {
 192         //  Note that as this class does not support forward mode, the method
 193         //  will always returns false.
 194         return false;
 195     }
 196 
 197     @Override
 198     public Set<String> getSupportedExtensions() {
 199         return 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         // Check against DisabledAlgorithmConstraints certpath constraints.
 259         // permits() will throw exception on failure.
 260         certPathDefaultConstraints.permits(primitives,
 261                 new CertConstraintParameters((X509Certificate)cert,
 262                         trustedMatch));
 263                 // new CertConstraintParameters(x509Cert, trustedMatch));
 264         // If there is no previous key, set one and exit
 265         if (prevPubKey == null) {
 266             prevPubKey = currPubKey;
 267             return;
 268         }
 269 
 270         X509CertImpl x509Cert;
 271         AlgorithmId algorithmId;
 272         try {
 273             x509Cert = X509CertImpl.toImpl((X509Certificate)cert);
 274             algorithmId = (AlgorithmId)x509Cert.get(X509CertImpl.SIG_ALG);
 275         } catch (CertificateException ce) {
 276             throw new CertPathValidatorException(ce);
 277         }
 278 
 279         AlgorithmParameters currSigAlgParams = algorithmId.getParameters();
 280         String currSigAlg = x509Cert.getSigAlgName();
 281 
 282         // If 'constraints' is not of DisabledAlgorithmConstraints, check all
 283         // everything individually
 284         if (!(constraints instanceof DisabledAlgorithmConstraints)) {
 285             // Check the current signature algorithm
 286             if (!constraints.permits(
 287                     SIGNATURE_PRIMITIVE_SET,
 288                     currSigAlg, currSigAlgParams)) {
 289                 throw new CertPathValidatorException(
 290                         "Algorithm constraints check failed on signature " +
 291                                 "algorithm: " + currSigAlg, null, null, -1,
 292                         BasicReason.ALGORITHM_CONSTRAINED);
 293             }
 294 
 295             if (!constraints.permits(primitives, currPubKey)) {
 296                 throw new CertPathValidatorException(
 297                         "Algorithm constraints check failed on keysize: " +
 298                                 sun.security.util.KeyUtil.getKeySize(currPubKey),
 299                         null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
 300             }
 301         }
 302 
 303         // Check with previous cert for signature algorithm and public key
 304         if (prevPubKey != null) {

 305             if (!constraints.permits(
 306                     SIGNATURE_PRIMITIVE_SET,
 307                     currSigAlg, prevPubKey, currSigAlgParams)) {
 308                 throw new CertPathValidatorException(
 309                     "Algorithm constraints check failed on " +
 310                             "signature algorithm: " + currSigAlg,
 311                     null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
 312             }

 313 
 314             // Inherit key parameters from previous key
 315             if (PKIX.isDSAPublicKeyWithoutParams(currPubKey)) {
 316                 // Inherit DSA parameters from previous key
 317                 if (!(prevPubKey instanceof DSAPublicKey)) {
 318                     throw new CertPathValidatorException("Input key is not " +
 319                         "of a appropriate type for inheriting parameters");
 320                 }
 321 
 322                 DSAParams params = ((DSAPublicKey)prevPubKey).getParams();
 323                 if (params == null) {
 324                     throw new CertPathValidatorException(
 325                         "Key parameters missing from public key.");
 326                 }
 327 
 328                 try {
 329                     BigInteger y = ((DSAPublicKey)currPubKey).getY();
 330                     KeyFactory kf = KeyFactory.getInstance("DSA");
 331                     DSAPublicKeySpec ks = new DSAPublicKeySpec(y,
 332                                                        params.getP(),
 333                                                        params.getQ(),
 334                                                        params.getG());
 335                     currPubKey = kf.generatePublic(ks);
 336                 } catch (GeneralSecurityException e) {
 337                     throw new CertPathValidatorException("Unable to generate " +
 338                         "key with inherited parameters: " + e.getMessage(), e);
 339                 }
 340             }
 341         }
 342 
 343         // reset the previous public key
 344         prevPubKey = currPubKey;
 345 


 353      * Try to set the trust anchor of the checker.
 354      * <p>
 355      * If there is no trust anchor specified and the checker has not started,
 356      * set the trust anchor.
 357      *
 358      * @param anchor the trust anchor selected to validate the target
 359      *     certificate
 360      */
 361     void trySetTrustAnchor(TrustAnchor anchor) {
 362         // Don't bother if the check has started or trust anchor has already
 363         // specified.
 364         if (prevPubKey == null) {
 365             if (anchor == null) {
 366                 throw new IllegalArgumentException(
 367                         "The trust anchor cannot be null");
 368             }
 369 
 370             // Don't bother to change the trustedPubKey.
 371             if (anchor.getTrustedCert() != null) {
 372                 prevPubKey = anchor.getTrustedCert().getPublicKey();
 373                 // Check for anchor certificate restrictions
 374                 trustedMatch = checkFingerprint(anchor.getTrustedCert());
 375                 if (trustedMatch && debug != null) {
 376                     debug.println("trustedMatch = true");
 377                 }
 378             } else {
 379                 prevPubKey = anchor.getCAPublicKey();
 380             }
 381         }
 382     }
 383 
 384     /**
 385      * Check the signature algorithm with the specified public key.
 386      *
 387      * @param key the public key to verify the CRL signature
 388      * @param crl the target CRL
 389      */
 390     static void check(PublicKey key, X509CRL crl)
 391                         throws CertPathValidatorException {
 392 
 393         X509CRLImpl x509CRLImpl = null;
 394         try {
 395             x509CRLImpl = X509CRLImpl.toImpl(crl);
 396         } catch (CRLException ce) {
 397             throw new CertPathValidatorException(ce);
 398         }
 399 
 400         AlgorithmId algorithmId = x509CRLImpl.getSigAlgId();
 401         check(key, algorithmId);
 402     }
 403 
 404     /**
 405      * Check the signature algorithm with the specified public key.
 406      *
 407      * @param key the public key to verify the CRL signature
 408      * @param crl the target CRL
 409      */
 410     static void check(PublicKey key, AlgorithmId algorithmId)
 411                         throws CertPathValidatorException {
 412         String sigAlgName = algorithmId.getName();
 413         AlgorithmParameters sigAlgParams = algorithmId.getParameters();
 414 
 415         if (!certPathDefaultConstraints.permits(
 416                 SIGNATURE_PRIMITIVE_SET, sigAlgName, key, sigAlgParams)) {
 417             throw new CertPathValidatorException(
 418                 "Algorithm constraints check failed on signature algorithm: " +
 419                 sigAlgName + " is disabled",
 420                 null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
 421         }
 422     }
 423 
 424 }
 425 
< prev index next >