Home | History | Annotate | Download | only in provider
      1 package org.bouncycastle.jce.provider;
      2 
      3 import java.io.IOException;
      4 import java.math.BigInteger;
      5 import java.security.GeneralSecurityException;
      6 import java.security.PublicKey;
      7 import java.security.cert.CertPath;
      8 import java.security.cert.CertPathBuilder;
      9 import java.security.cert.CertPathBuilderException;
     10 import java.security.cert.CertPathValidatorException;
     11 import java.security.cert.CertificateExpiredException;
     12 import java.security.cert.CertificateNotYetValidException;
     13 import java.security.cert.PKIXCertPathChecker;
     14 import java.security.cert.X509CRL;
     15 import java.security.cert.X509Certificate;
     16 import java.security.cert.X509Extension;
     17 import java.util.ArrayList;
     18 import java.util.Collection;
     19 import java.util.Date;
     20 import java.util.Enumeration;
     21 import java.util.HashMap;
     22 import java.util.HashSet;
     23 import java.util.Iterator;
     24 import java.util.List;
     25 import java.util.Map;
     26 import java.util.Set;
     27 import java.util.Vector;
     28 
     29 import javax.security.auth.x500.X500Principal;
     30 
     31 import org.bouncycastle.asn1.ASN1EncodableVector;
     32 import org.bouncycastle.asn1.ASN1InputStream;
     33 import org.bouncycastle.asn1.ASN1Sequence;
     34 import org.bouncycastle.asn1.ASN1TaggedObject;
     35 import org.bouncycastle.asn1.DEREncodable;
     36 import org.bouncycastle.asn1.DERInteger;
     37 import org.bouncycastle.asn1.DERObject;
     38 import org.bouncycastle.asn1.DERObjectIdentifier;
     39 import org.bouncycastle.asn1.DERSequence;
     40 import org.bouncycastle.asn1.x509.BasicConstraints;
     41 import org.bouncycastle.asn1.x509.CRLDistPoint;
     42 import org.bouncycastle.asn1.x509.CRLReason;
     43 import org.bouncycastle.asn1.x509.DistributionPoint;
     44 import org.bouncycastle.asn1.x509.DistributionPointName;
     45 import org.bouncycastle.asn1.x509.GeneralName;
     46 import org.bouncycastle.asn1.x509.GeneralNames;
     47 import org.bouncycastle.asn1.x509.GeneralSubtree;
     48 import org.bouncycastle.asn1.x509.IssuingDistributionPoint;
     49 import org.bouncycastle.asn1.x509.NameConstraints;
     50 import org.bouncycastle.asn1.x509.PolicyInformation;
     51 import org.bouncycastle.asn1.x509.X509Extensions;
     52 import org.bouncycastle.asn1.x509.X509Name;
     53 import org.bouncycastle.jce.exception.ExtCertPathValidatorException;
     54 import org.bouncycastle.util.Arrays;
     55 import org.bouncycastle.x509.ExtendedPKIXBuilderParameters;
     56 import org.bouncycastle.x509.ExtendedPKIXParameters;
     57 import org.bouncycastle.x509.X509CRLStoreSelector;
     58 import org.bouncycastle.x509.X509CertStoreSelector;
     59 
     60 public class RFC3280CertPathUtilities
     61 {
     62     private static final PKIXCRLUtil CRL_UTIL = new PKIXCRLUtil();
     63 
     64     /**
     65      * If the complete CRL includes an issuing distribution point (IDP) CRL
     66      * extension check the following:
     67      * <p/>
     68      * (i) If the distribution point name is present in the IDP CRL extension
     69      * and the distribution field is present in the DP, then verify that one of
     70      * the names in the IDP matches one of the names in the DP. If the
     71      * distribution point name is present in the IDP CRL extension and the
     72      * distribution field is omitted from the DP, then verify that one of the
     73      * names in the IDP matches one of the names in the cRLIssuer field of the
     74      * DP.
     75      * </p>
     76      * <p/>
     77      * (ii) If the onlyContainsUserCerts boolean is asserted in the IDP CRL
     78      * extension, verify that the certificate does not include the basic
     79      * constraints extension with the cA boolean asserted.
     80      * </p>
     81      * <p/>
     82      * (iii) If the onlyContainsCACerts boolean is asserted in the IDP CRL
     83      * extension, verify that the certificate includes the basic constraints
     84      * extension with the cA boolean asserted.
     85      * </p>
     86      * <p/>
     87      * (iv) Verify that the onlyContainsAttributeCerts boolean is not asserted.
     88      * </p>
     89      *
     90      * @param dp   The distribution point.
     91      * @param cert The certificate.
     92      * @param crl  The CRL.
     93      * @throws AnnotatedException if one of the conditions is not met or an error occurs.
     94      */
     95     protected static void processCRLB2(
     96         DistributionPoint dp,
     97         Object cert,
     98         X509CRL crl)
     99         throws AnnotatedException
    100     {
    101         IssuingDistributionPoint idp = null;
    102         try
    103         {
    104             idp = IssuingDistributionPoint.getInstance(CertPathValidatorUtilities.getExtensionValue(crl,
    105                 RFC3280CertPathUtilities.ISSUING_DISTRIBUTION_POINT));
    106         }
    107         catch (Exception e)
    108         {
    109             throw new AnnotatedException("Issuing distribution point extension could not be decoded.", e);
    110         }
    111         // (b) (2) (i)
    112         // distribution point name is present
    113         if (idp != null)
    114         {
    115             if (idp.getDistributionPoint() != null)
    116             {
    117                 // make list of names
    118                 DistributionPointName dpName = IssuingDistributionPoint.getInstance(idp).getDistributionPoint();
    119                 List names = new ArrayList();
    120 
    121                 if (dpName.getType() == DistributionPointName.FULL_NAME)
    122                 {
    123                     GeneralName[] genNames = GeneralNames.getInstance(dpName.getName()).getNames();
    124                     for (int j = 0; j < genNames.length; j++)
    125                     {
    126                         names.add(genNames[j]);
    127                     }
    128                 }
    129                 if (dpName.getType() == DistributionPointName.NAME_RELATIVE_TO_CRL_ISSUER)
    130                 {
    131                     ASN1EncodableVector vec = new ASN1EncodableVector();
    132                     try
    133                     {
    134                         Enumeration e = ASN1Sequence.getInstance(
    135                             ASN1Sequence.fromByteArray(CertPathValidatorUtilities.getIssuerPrincipal(crl)
    136                                 .getEncoded())).getObjects();
    137                         while (e.hasMoreElements())
    138                         {
    139                             vec.add((DEREncodable)e.nextElement());
    140                         }
    141                     }
    142                     catch (IOException e)
    143                     {
    144                         throw new AnnotatedException("Could not read CRL issuer.", e);
    145                     }
    146                     vec.add(dpName.getName());
    147                     names.add(new GeneralName(X509Name.getInstance(new DERSequence(vec))));
    148                 }
    149                 boolean matches = false;
    150                 // verify that one of the names in the IDP matches one
    151                 // of the names in the DP.
    152                 if (dp.getDistributionPoint() != null)
    153                 {
    154                     dpName = dp.getDistributionPoint();
    155                     GeneralName[] genNames = null;
    156                     if (dpName.getType() == DistributionPointName.FULL_NAME)
    157                     {
    158                         genNames = GeneralNames.getInstance(dpName.getName()).getNames();
    159                     }
    160                     if (dpName.getType() == DistributionPointName.NAME_RELATIVE_TO_CRL_ISSUER)
    161                     {
    162                         if (dp.getCRLIssuer() != null)
    163                         {
    164                             genNames = dp.getCRLIssuer().getNames();
    165                         }
    166                         else
    167                         {
    168                             genNames = new GeneralName[1];
    169                             try
    170                             {
    171                                 genNames[0] = new GeneralName(new X509Name(
    172                                     (ASN1Sequence)ASN1Sequence.fromByteArray(CertPathValidatorUtilities
    173                                         .getEncodedIssuerPrincipal(cert).getEncoded())));
    174                             }
    175                             catch (IOException e)
    176                             {
    177                                 throw new AnnotatedException("Could not read certificate issuer.", e);
    178                             }
    179                         }
    180                         for (int j = 0; j < genNames.length; j++)
    181                         {
    182                             Enumeration e = ASN1Sequence.getInstance(genNames[j].getName().getDERObject()).getObjects();
    183                             ASN1EncodableVector vec = new ASN1EncodableVector();
    184                             while (e.hasMoreElements())
    185                             {
    186                                 vec.add((DEREncodable)e.nextElement());
    187                             }
    188                             vec.add(dpName.getName());
    189                             genNames[j] = new GeneralName(new X509Name(new DERSequence(vec)));
    190                         }
    191                     }
    192                     if (genNames != null)
    193                     {
    194                         for (int j = 0; j < genNames.length; j++)
    195                         {
    196                             if (names.contains(genNames[j]))
    197                             {
    198                                 matches = true;
    199                                 break;
    200                             }
    201                         }
    202                     }
    203                     if (!matches)
    204                     {
    205                         throw new AnnotatedException(
    206                             "No match for certificate CRL issuing distribution point name to cRLIssuer CRL distribution point.");
    207                     }
    208                 }
    209                 // verify that one of the names in
    210                 // the IDP matches one of the names in the cRLIssuer field of
    211                 // the DP
    212                 else
    213                 {
    214                     if (dp.getCRLIssuer() == null)
    215                     {
    216                         throw new AnnotatedException("Either the cRLIssuer or the distributionPoint field must "
    217                             + "be contained in DistributionPoint.");
    218                     }
    219                     GeneralName[] genNames = dp.getCRLIssuer().getNames();
    220                     for (int j = 0; j < genNames.length; j++)
    221                     {
    222                         if (names.contains(genNames[j]))
    223                         {
    224                             matches = true;
    225                             break;
    226                         }
    227                     }
    228                     if (!matches)
    229                     {
    230                         throw new AnnotatedException(
    231                             "No match for certificate CRL issuing distribution point name to cRLIssuer CRL distribution point.");
    232                     }
    233                 }
    234             }
    235             BasicConstraints bc = null;
    236             try
    237             {
    238                 bc = BasicConstraints.getInstance(CertPathValidatorUtilities.getExtensionValue((X509Extension)cert,
    239                     BASIC_CONSTRAINTS));
    240             }
    241             catch (Exception e)
    242             {
    243                 throw new AnnotatedException("Basic constraints extension could not be decoded.", e);
    244             }
    245 
    246             if (cert instanceof X509Certificate)
    247             {
    248                 // (b) (2) (ii)
    249                 if (idp.onlyContainsUserCerts() && (bc != null && bc.isCA()))
    250                 {
    251                     throw new AnnotatedException("CA Cert CRL only contains user certificates.");
    252                 }
    253 
    254                 // (b) (2) (iii)
    255                 if (idp.onlyContainsCACerts() && (bc == null || !bc.isCA()))
    256                 {
    257                     throw new AnnotatedException("End CRL only contains CA certificates.");
    258                 }
    259             }
    260 
    261             // (b) (2) (iv)
    262             if (idp.onlyContainsAttributeCerts())
    263             {
    264                 throw new AnnotatedException("onlyContainsAttributeCerts boolean is asserted.");
    265             }
    266         }
    267     }
    268 
    269     /**
    270      * If the DP includes cRLIssuer, then verify that the issuer field in the
    271      * complete CRL matches cRLIssuer in the DP and that the complete CRL
    272      * contains an issuing distribution point extension with the indirectCRL
    273      * boolean asserted. Otherwise, verify that the CRL issuer matches the
    274      * certificate issuer.
    275      *
    276      * @param dp   The distribution point.
    277      * @param cert The certificate ot attribute certificate.
    278      * @param crl  The CRL for <code>cert</code>.
    279      * @throws AnnotatedException if one of the above conditions does not apply or an error
    280      *                            occurs.
    281      */
    282     protected static void processCRLB1(
    283         DistributionPoint dp,
    284         Object cert,
    285         X509CRL crl)
    286         throws AnnotatedException
    287     {
    288         DERObject idp = CertPathValidatorUtilities.getExtensionValue(crl, ISSUING_DISTRIBUTION_POINT);
    289         boolean isIndirect = false;
    290         if (idp != null)
    291         {
    292             if (IssuingDistributionPoint.getInstance(idp).isIndirectCRL())
    293             {
    294                 isIndirect = true;
    295             }
    296         }
    297         byte[] issuerBytes = CertPathValidatorUtilities.getIssuerPrincipal(crl).getEncoded();
    298 
    299         boolean matchIssuer = false;
    300         if (dp.getCRLIssuer() != null)
    301         {
    302             GeneralName genNames[] = dp.getCRLIssuer().getNames();
    303             for (int j = 0; j < genNames.length; j++)
    304             {
    305                 if (genNames[j].getTagNo() == GeneralName.directoryName)
    306                 {
    307                     try
    308                     {
    309                         if (Arrays.areEqual(genNames[j].getName().getDERObject().getEncoded(), issuerBytes))
    310                         {
    311                             matchIssuer = true;
    312                         }
    313                     }
    314                     catch (IOException e)
    315                     {
    316                         throw new AnnotatedException(
    317                             "CRL issuer information from distribution point cannot be decoded.", e);
    318                     }
    319                 }
    320             }
    321             if (matchIssuer && !isIndirect)
    322             {
    323                 throw new AnnotatedException("Distribution point contains cRLIssuer field but CRL is not indirect.");
    324             }
    325             if (!matchIssuer)
    326             {
    327                 throw new AnnotatedException("CRL issuer of CRL does not match CRL issuer of distribution point.");
    328             }
    329         }
    330         else
    331         {
    332             if (CertPathValidatorUtilities.getIssuerPrincipal(crl).equals(
    333                 CertPathValidatorUtilities.getEncodedIssuerPrincipal(cert)))
    334             {
    335                 matchIssuer = true;
    336             }
    337         }
    338         if (!matchIssuer)
    339         {
    340             throw new AnnotatedException("Cannot find matching CRL issuer for certificate.");
    341         }
    342     }
    343 
    344     protected static ReasonsMask processCRLD(
    345         X509CRL crl,
    346         DistributionPoint dp)
    347         throws AnnotatedException
    348     {
    349         IssuingDistributionPoint idp = null;
    350         try
    351         {
    352             idp = IssuingDistributionPoint.getInstance(CertPathValidatorUtilities.getExtensionValue(crl,
    353                 RFC3280CertPathUtilities.ISSUING_DISTRIBUTION_POINT));
    354         }
    355         catch (Exception e)
    356         {
    357             throw new AnnotatedException("Issuing distribution point extension could not be decoded.", e);
    358         }
    359         // (d) (1)
    360         if (idp != null && idp.getOnlySomeReasons() != null && dp.getReasons() != null)
    361         {
    362             return new ReasonsMask(dp.getReasons().intValue()).intersect(new ReasonsMask(idp.getOnlySomeReasons()
    363                 .intValue()));
    364         }
    365         // (d) (4)
    366         if ((idp == null || idp.getOnlySomeReasons() == null) && dp.getReasons() == null)
    367         {
    368             return ReasonsMask.allReasons;
    369         }
    370         // (d) (2) and (d)(3)
    371         return (dp.getReasons() == null
    372             ? ReasonsMask.allReasons
    373             : new ReasonsMask(dp.getReasons().intValue())).intersect(idp == null
    374             ? ReasonsMask.allReasons
    375             : new ReasonsMask(idp.getOnlySomeReasons().intValue()));
    376 
    377     }
    378 
    379     protected static final String CERTIFICATE_POLICIES = X509Extensions.CertificatePolicies.getId();
    380 
    381     protected static final String POLICY_MAPPINGS = X509Extensions.PolicyMappings.getId();
    382 
    383     protected static final String INHIBIT_ANY_POLICY = X509Extensions.InhibitAnyPolicy.getId();
    384 
    385     protected static final String ISSUING_DISTRIBUTION_POINT = X509Extensions.IssuingDistributionPoint.getId();
    386 
    387     protected static final String FRESHEST_CRL = X509Extensions.FreshestCRL.getId();
    388 
    389     protected static final String DELTA_CRL_INDICATOR = X509Extensions.DeltaCRLIndicator.getId();
    390 
    391     protected static final String POLICY_CONSTRAINTS = X509Extensions.PolicyConstraints.getId();
    392 
    393     protected static final String BASIC_CONSTRAINTS = X509Extensions.BasicConstraints.getId();
    394 
    395     protected static final String CRL_DISTRIBUTION_POINTS = X509Extensions.CRLDistributionPoints.getId();
    396 
    397     protected static final String SUBJECT_ALTERNATIVE_NAME = X509Extensions.SubjectAlternativeName.getId();
    398 
    399     protected static final String NAME_CONSTRAINTS = X509Extensions.NameConstraints.getId();
    400 
    401     protected static final String AUTHORITY_KEY_IDENTIFIER = X509Extensions.AuthorityKeyIdentifier.getId();
    402 
    403     protected static final String KEY_USAGE = X509Extensions.KeyUsage.getId();
    404 
    405     protected static final String CRL_NUMBER = X509Extensions.CRLNumber.getId();
    406 
    407     protected static final String ANY_POLICY = "2.5.29.32.0";
    408 
    409     /*
    410      * key usage bits
    411      */
    412     protected static final int KEY_CERT_SIGN = 5;
    413 
    414     protected static final int CRL_SIGN = 6;
    415 
    416     /**
    417      * Obtain and validate the certification path for the complete CRL issuer.
    418      * If a key usage extension is present in the CRL issuer's certificate,
    419      * verify that the cRLSign bit is set.
    420      *
    421      * @param crl                CRL which contains revocation information for the certificate
    422      *                           <code>cert</code>.
    423      * @param cert               The attribute certificate or certificate to check if it is
    424      *                           revoked.
    425      * @param defaultCRLSignCert The issuer certificate of the certificate <code>cert</code>.
    426      * @param defaultCRLSignKey  The public key of the issuer certificate
    427      *                           <code>defaultCRLSignCert</code>.
    428      * @param paramsPKIX         paramsPKIX PKIX parameters.
    429      * @param certPathCerts      The certificates on the certification path.
    430      * @return A <code>Set</code> with all keys of possible CRL issuer
    431      *         certificates.
    432      * @throws AnnotatedException if the CRL is not valid or the status cannot be checked or
    433      *                            some error occurs.
    434      */
    435     protected static Set processCRLF(
    436         X509CRL crl,
    437         Object cert,
    438         X509Certificate defaultCRLSignCert,
    439         PublicKey defaultCRLSignKey,
    440         ExtendedPKIXParameters paramsPKIX,
    441         List certPathCerts)
    442         throws AnnotatedException
    443     {
    444         // (f)
    445 
    446         // get issuer from CRL
    447         X509CertStoreSelector selector = new X509CertStoreSelector();
    448         try
    449         {
    450             byte[] issuerPrincipal = CertPathValidatorUtilities.getIssuerPrincipal(crl).getEncoded();
    451             selector.setSubject(issuerPrincipal);
    452         }
    453         catch (IOException e)
    454         {
    455             throw new AnnotatedException(
    456                 "Subject criteria for certificate selector to find issuer certificate for CRL could not be set.", e);
    457         }
    458 
    459         // get CRL signing certs
    460         Collection coll;
    461         try
    462         {
    463             coll = CertPathValidatorUtilities.findCertificates(selector, paramsPKIX.getStores());
    464             coll.addAll(CertPathValidatorUtilities.findCertificates(selector, paramsPKIX.getAdditionalStores()));
    465             coll.addAll(CertPathValidatorUtilities.findCertificates(selector, paramsPKIX.getCertStores()));
    466         }
    467         catch (AnnotatedException e)
    468         {
    469             throw new AnnotatedException("Issuer certificate for CRL cannot be searched.", e);
    470         }
    471 
    472         coll.add(defaultCRLSignCert);
    473 
    474         Iterator cert_it = coll.iterator();
    475 
    476         List validCerts = new ArrayList();
    477         List validKeys = new ArrayList();
    478 
    479         while (cert_it.hasNext())
    480         {
    481             X509Certificate signingCert = (X509Certificate)cert_it.next();
    482 
    483             /*
    484              * CA of the certificate, for which this CRL is checked, has also
    485              * signed CRL, so skip the path validation, because is already done
    486              */
    487             if (signingCert.equals(defaultCRLSignCert))
    488             {
    489                 validCerts.add(signingCert);
    490                 validKeys.add(defaultCRLSignKey);
    491                 continue;
    492             }
    493             try
    494             {
    495                 CertPathBuilder builder = CertPathBuilder.getInstance("PKIX", BouncyCastleProvider.PROVIDER_NAME);
    496                 selector = new X509CertStoreSelector();
    497                 selector.setCertificate(signingCert);
    498                 ExtendedPKIXParameters temp = (ExtendedPKIXParameters)paramsPKIX.clone();
    499                 temp.setTargetCertConstraints(selector);
    500                 ExtendedPKIXBuilderParameters params = (ExtendedPKIXBuilderParameters)ExtendedPKIXBuilderParameters
    501                     .getInstance(temp);
    502                 /*
    503                  * if signingCert is placed not higher on the cert path a
    504                  * dependency loop results. CRL for cert is checked, but
    505                  * signingCert is needed for checking the CRL which is dependent
    506                  * on checking cert because it is higher in the cert path and so
    507                  * signing signingCert transitively. so, revocation is disabled,
    508                  * forgery attacks of the CRL are detected in this outer loop
    509                  * for all other it must be enabled to prevent forgery attacks
    510                  */
    511                 if (certPathCerts.contains(signingCert))
    512                 {
    513                     params.setRevocationEnabled(false);
    514                 }
    515                 else
    516                 {
    517                     params.setRevocationEnabled(true);
    518                 }
    519                 List certs = builder.build(params).getCertPath().getCertificates();
    520                 validCerts.add(signingCert);
    521                 validKeys.add(CertPathValidatorUtilities.getNextWorkingKey(certs, 0));
    522             }
    523             catch (CertPathBuilderException e)
    524             {
    525                 throw new AnnotatedException("Internal error.", e);
    526             }
    527             catch (CertPathValidatorException e)
    528             {
    529                 throw new AnnotatedException("Public key of issuer certificate of CRL could not be retrieved.", e);
    530             }
    531             catch (Exception e)
    532             {
    533                 throw new RuntimeException(e.getMessage());
    534             }
    535         }
    536 
    537         Set checkKeys = new HashSet();
    538 
    539         AnnotatedException lastException = null;
    540         for (int i = 0; i < validCerts.size(); i++)
    541         {
    542             X509Certificate signCert = (X509Certificate)validCerts.get(i);
    543             boolean[] keyusage = signCert.getKeyUsage();
    544 
    545             if (keyusage != null && (keyusage.length < 7 || !keyusage[CRL_SIGN]))
    546             {
    547                 lastException = new AnnotatedException(
    548                     "Issuer certificate key usage extension does not permit CRL signing.");
    549             }
    550             else
    551             {
    552                 checkKeys.add(validKeys.get(i));
    553             }
    554         }
    555 
    556         if (checkKeys.isEmpty() && lastException == null)
    557         {
    558             throw new AnnotatedException("Cannot find a valid issuer certificate.");
    559         }
    560         if (checkKeys.isEmpty() && lastException != null)
    561         {
    562             throw lastException;
    563         }
    564 
    565         return checkKeys;
    566     }
    567 
    568     protected static PublicKey processCRLG(
    569         X509CRL crl,
    570         Set keys)
    571         throws AnnotatedException
    572     {
    573         Exception lastException = null;
    574         for (Iterator it = keys.iterator(); it.hasNext();)
    575         {
    576             PublicKey key = (PublicKey)it.next();
    577             try
    578             {
    579                 crl.verify(key);
    580                 return key;
    581             }
    582             catch (Exception e)
    583             {
    584                 lastException = e;
    585             }
    586         }
    587         throw new AnnotatedException("Cannot verify CRL.", lastException);
    588     }
    589 
    590     protected static X509CRL processCRLH(
    591         Set deltacrls,
    592         PublicKey key)
    593         throws AnnotatedException
    594     {
    595         Exception lastException = null;
    596 
    597         for (Iterator it = deltacrls.iterator(); it.hasNext();)
    598         {
    599             X509CRL crl = (X509CRL)it.next();
    600             try
    601             {
    602                 crl.verify(key);
    603                 return crl;
    604             }
    605             catch (Exception e)
    606             {
    607                 lastException = e;
    608             }
    609         }
    610 
    611         if (lastException != null)
    612         {
    613             throw new AnnotatedException("Cannot verify delta CRL.", lastException);
    614         }
    615         return null;
    616     }
    617 
    618     protected static Set processCRLA1i(
    619         Date currentDate,
    620         ExtendedPKIXParameters paramsPKIX,
    621         X509Certificate cert,
    622         X509CRL crl)
    623         throws AnnotatedException
    624     {
    625         Set set = new HashSet();
    626         if (paramsPKIX.isUseDeltasEnabled())
    627         {
    628             CRLDistPoint freshestCRL = null;
    629             try
    630             {
    631                 freshestCRL = CRLDistPoint
    632                     .getInstance(CertPathValidatorUtilities.getExtensionValue(cert, FRESHEST_CRL));
    633             }
    634             catch (AnnotatedException e)
    635             {
    636                 throw new AnnotatedException("Freshest CRL extension could not be decoded from certificate.", e);
    637             }
    638             if (freshestCRL == null)
    639             {
    640                 try
    641                 {
    642                     freshestCRL = CRLDistPoint.getInstance(CertPathValidatorUtilities.getExtensionValue(crl,
    643                         FRESHEST_CRL));
    644                 }
    645                 catch (AnnotatedException e)
    646                 {
    647                     throw new AnnotatedException("Freshest CRL extension could not be decoded from CRL.", e);
    648                 }
    649             }
    650             if (freshestCRL != null)
    651             {
    652                 try
    653                 {
    654                     CertPathValidatorUtilities.addAdditionalStoresFromCRLDistributionPoint(freshestCRL, paramsPKIX);
    655                 }
    656                 catch (AnnotatedException e)
    657                 {
    658                     throw new AnnotatedException(
    659                         "No new delta CRL locations could be added from Freshest CRL extension.", e);
    660                 }
    661                 // get delta CRL(s)
    662                 try
    663                 {
    664                     set.addAll(CertPathValidatorUtilities.getDeltaCRLs(currentDate, paramsPKIX, crl));
    665                 }
    666                 catch (AnnotatedException e)
    667                 {
    668                     throw new AnnotatedException("Exception obtaining delta CRLs.", e);
    669                 }
    670             }
    671         }
    672         return set;
    673     }
    674 
    675     protected static Set[] processCRLA1ii(
    676         Date currentDate,
    677         ExtendedPKIXParameters paramsPKIX,
    678         X509Certificate cert,
    679         X509CRL crl)
    680         throws AnnotatedException
    681     {
    682         Set deltaSet = new HashSet();
    683         X509CRLStoreSelector crlselect = new X509CRLStoreSelector();
    684         crlselect.setCertificateChecking(cert);
    685 
    686         try
    687         {
    688             crlselect.addIssuerName(crl.getIssuerX500Principal().getEncoded());
    689         }
    690         catch (IOException e)
    691         {
    692             throw new AnnotatedException("Cannot extract issuer from CRL." + e, e);
    693         }
    694 
    695         crlselect.setCompleteCRLEnabled(true);
    696         Set completeSet = CRL_UTIL.findCRLs(crlselect, paramsPKIX, currentDate);
    697 
    698         if (paramsPKIX.isUseDeltasEnabled())
    699         {
    700             // get delta CRL(s)
    701             try
    702             {
    703                 deltaSet.addAll(CertPathValidatorUtilities.getDeltaCRLs(currentDate, paramsPKIX, crl));
    704             }
    705             catch (AnnotatedException e)
    706             {
    707                 throw new AnnotatedException("Exception obtaining delta CRLs.", e);
    708             }
    709         }
    710         return new Set[]
    711             {
    712                 completeSet,
    713                 deltaSet};
    714     }
    715 
    716 
    717 
    718     /**
    719      * If use-deltas is set, verify the issuer and scope of the delta CRL.
    720      *
    721      * @param deltaCRL    The delta CRL.
    722      * @param completeCRL The complete CRL.
    723      * @param pkixParams  The PKIX paramaters.
    724      * @throws AnnotatedException if an exception occurs.
    725      */
    726     protected static void processCRLC(
    727         X509CRL deltaCRL,
    728         X509CRL completeCRL,
    729         ExtendedPKIXParameters pkixParams)
    730         throws AnnotatedException
    731     {
    732         if (deltaCRL == null)
    733         {
    734             return;
    735         }
    736         IssuingDistributionPoint completeidp = null;
    737         try
    738         {
    739             completeidp = IssuingDistributionPoint.getInstance(CertPathValidatorUtilities.getExtensionValue(
    740                 completeCRL, RFC3280CertPathUtilities.ISSUING_DISTRIBUTION_POINT));
    741         }
    742         catch (Exception e)
    743         {
    744             throw new AnnotatedException("Issuing distribution point extension could not be decoded.", e);
    745         }
    746 
    747         if (pkixParams.isUseDeltasEnabled())
    748         {
    749             // (c) (1)
    750             if (!deltaCRL.getIssuerX500Principal().equals(completeCRL.getIssuerX500Principal()))
    751             {
    752                 throw new AnnotatedException("Complete CRL issuer does not match delta CRL issuer.");
    753             }
    754 
    755             // (c) (2)
    756             IssuingDistributionPoint deltaidp = null;
    757             try
    758             {
    759                 deltaidp = IssuingDistributionPoint.getInstance(CertPathValidatorUtilities.getExtensionValue(
    760                     deltaCRL, ISSUING_DISTRIBUTION_POINT));
    761             }
    762             catch (Exception e)
    763             {
    764                 throw new AnnotatedException(
    765                     "Issuing distribution point extension from delta CRL could not be decoded.", e);
    766             }
    767 
    768             boolean match = false;
    769             if (completeidp == null)
    770             {
    771                 if (deltaidp == null)
    772                 {
    773                     match = true;
    774                 }
    775             }
    776             else
    777             {
    778                 if (completeidp.equals(deltaidp))
    779                 {
    780                     match = true;
    781                 }
    782             }
    783             if (!match)
    784             {
    785                 throw new AnnotatedException(
    786                     "Issuing distribution point extension from delta CRL and complete CRL does not match.");
    787             }
    788 
    789             // (c) (3)
    790             DERObject completeKeyIdentifier = null;
    791             try
    792             {
    793                 completeKeyIdentifier = CertPathValidatorUtilities.getExtensionValue(
    794                     completeCRL, AUTHORITY_KEY_IDENTIFIER);
    795             }
    796             catch (AnnotatedException e)
    797             {
    798                 throw new AnnotatedException(
    799                     "Authority key identifier extension could not be extracted from complete CRL.", e);
    800             }
    801 
    802             DERObject deltaKeyIdentifier = null;
    803             try
    804             {
    805                 deltaKeyIdentifier = CertPathValidatorUtilities.getExtensionValue(
    806                     deltaCRL, AUTHORITY_KEY_IDENTIFIER);
    807             }
    808             catch (AnnotatedException e)
    809             {
    810                 throw new AnnotatedException(
    811                     "Authority key identifier extension could not be extracted from delta CRL.", e);
    812             }
    813 
    814             if (completeKeyIdentifier == null)
    815             {
    816                 throw new AnnotatedException("CRL authority key identifier is null.");
    817             }
    818 
    819             if (deltaKeyIdentifier == null)
    820             {
    821                 throw new AnnotatedException("Delta CRL authority key identifier is null.");
    822             }
    823 
    824             if (!completeKeyIdentifier.equals(deltaKeyIdentifier))
    825             {
    826                 throw new AnnotatedException(
    827                     "Delta CRL authority key identifier does not match complete CRL authority key identifier.");
    828             }
    829         }
    830     }
    831 
    832     protected static void processCRLI(
    833         Date validDate,
    834         X509CRL deltacrl,
    835         Object cert,
    836         CertStatus certStatus,
    837         ExtendedPKIXParameters pkixParams)
    838         throws AnnotatedException
    839     {
    840         if (pkixParams.isUseDeltasEnabled() && deltacrl != null)
    841         {
    842             CertPathValidatorUtilities.getCertStatus(validDate, deltacrl, cert, certStatus);
    843         }
    844     }
    845 
    846     protected static void processCRLJ(
    847         Date validDate,
    848         X509CRL completecrl,
    849         Object cert,
    850         CertStatus certStatus)
    851         throws AnnotatedException
    852     {
    853         if (certStatus.getCertStatus() == CertStatus.UNREVOKED)
    854         {
    855             CertPathValidatorUtilities.getCertStatus(validDate, completecrl, cert, certStatus);
    856         }
    857     }
    858 
    859     protected static PKIXPolicyNode prepareCertB(
    860         CertPath certPath,
    861         int index,
    862         List[] policyNodes,
    863         PKIXPolicyNode validPolicyTree,
    864         int policyMapping)
    865         throws CertPathValidatorException
    866     {
    867         List certs = certPath.getCertificates();
    868         X509Certificate cert = (X509Certificate)certs.get(index);
    869         int n = certs.size();
    870         // i as defined in the algorithm description
    871         int i = n - index;
    872         // (b)
    873         //
    874         ASN1Sequence pm = null;
    875         try
    876         {
    877             pm = DERSequence.getInstance(CertPathValidatorUtilities.getExtensionValue(cert,
    878                 RFC3280CertPathUtilities.POLICY_MAPPINGS));
    879         }
    880         catch (AnnotatedException ex)
    881         {
    882             throw new ExtCertPathValidatorException("Policy mappings extension could not be decoded.", ex, certPath,
    883                 index);
    884         }
    885         PKIXPolicyNode _validPolicyTree = validPolicyTree;
    886         if (pm != null)
    887         {
    888             ASN1Sequence mappings = (ASN1Sequence)pm;
    889             Map m_idp = new HashMap();
    890             Set s_idp = new HashSet();
    891 
    892             for (int j = 0; j < mappings.size(); j++)
    893             {
    894                 ASN1Sequence mapping = (ASN1Sequence)mappings.getObjectAt(j);
    895                 String id_p = ((DERObjectIdentifier)mapping.getObjectAt(0)).getId();
    896                 String sd_p = ((DERObjectIdentifier)mapping.getObjectAt(1)).getId();
    897                 Set tmp;
    898 
    899                 if (!m_idp.containsKey(id_p))
    900                 {
    901                     tmp = new HashSet();
    902                     tmp.add(sd_p);
    903                     m_idp.put(id_p, tmp);
    904                     s_idp.add(id_p);
    905                 }
    906                 else
    907                 {
    908                     tmp = (Set)m_idp.get(id_p);
    909                     tmp.add(sd_p);
    910                 }
    911             }
    912 
    913             Iterator it_idp = s_idp.iterator();
    914             while (it_idp.hasNext())
    915             {
    916                 String id_p = (String)it_idp.next();
    917 
    918                 //
    919                 // (1)
    920                 //
    921                 if (policyMapping > 0)
    922                 {
    923                     boolean idp_found = false;
    924                     Iterator nodes_i = policyNodes[i].iterator();
    925                     while (nodes_i.hasNext())
    926                     {
    927                         PKIXPolicyNode node = (PKIXPolicyNode)nodes_i.next();
    928                         if (node.getValidPolicy().equals(id_p))
    929                         {
    930                             idp_found = true;
    931                             node.expectedPolicies = (Set)m_idp.get(id_p);
    932                             break;
    933                         }
    934                     }
    935 
    936                     if (!idp_found)
    937                     {
    938                         nodes_i = policyNodes[i].iterator();
    939                         while (nodes_i.hasNext())
    940                         {
    941                             PKIXPolicyNode node = (PKIXPolicyNode)nodes_i.next();
    942                             if (RFC3280CertPathUtilities.ANY_POLICY.equals(node.getValidPolicy()))
    943                             {
    944                                 Set pq = null;
    945                                 ASN1Sequence policies = null;
    946                                 try
    947                                 {
    948                                     policies = (ASN1Sequence)CertPathValidatorUtilities.getExtensionValue(cert,
    949                                         RFC3280CertPathUtilities.CERTIFICATE_POLICIES);
    950                                 }
    951                                 catch (AnnotatedException e)
    952                                 {
    953                                     throw new ExtCertPathValidatorException(
    954                                         "Certificate policies extension could not be decoded.", e, certPath, index);
    955                                 }
    956                                 Enumeration e = policies.getObjects();
    957                                 while (e.hasMoreElements())
    958                                 {
    959                                     PolicyInformation pinfo = null;
    960                                     try
    961                                     {
    962                                         pinfo = PolicyInformation.getInstance(e.nextElement());
    963                                     }
    964                                     catch (Exception ex)
    965                                     {
    966                                         throw new CertPathValidatorException(
    967                                             "Policy information could not be decoded.", ex, certPath, index);
    968                                     }
    969                                     if (RFC3280CertPathUtilities.ANY_POLICY.equals(pinfo.getPolicyIdentifier().getId()))
    970                                     {
    971                                         try
    972                                         {
    973                                             pq = CertPathValidatorUtilities
    974                                                 .getQualifierSet(pinfo.getPolicyQualifiers());
    975                                         }
    976                                         catch (CertPathValidatorException ex)
    977                                         {
    978 
    979                                             throw new ExtCertPathValidatorException(
    980                                                 "Policy qualifier info set could not be decoded.", ex, certPath,
    981                                                 index);
    982                                         }
    983                                         break;
    984                                     }
    985                                 }
    986                                 boolean ci = false;
    987                                 if (cert.getCriticalExtensionOIDs() != null)
    988                                 {
    989                                     ci = cert.getCriticalExtensionOIDs().contains(
    990                                         RFC3280CertPathUtilities.CERTIFICATE_POLICIES);
    991                                 }
    992 
    993                                 PKIXPolicyNode p_node = (PKIXPolicyNode)node.getParent();
    994                                 if (RFC3280CertPathUtilities.ANY_POLICY.equals(p_node.getValidPolicy()))
    995                                 {
    996                                     PKIXPolicyNode c_node = new PKIXPolicyNode(new ArrayList(), i, (Set)m_idp
    997                                         .get(id_p), p_node, pq, id_p, ci);
    998                                     p_node.addChild(c_node);
    999                                     policyNodes[i].add(c_node);
   1000                                 }
   1001                                 break;
   1002                             }
   1003                         }
   1004                     }
   1005 
   1006                     //
   1007                     // (2)
   1008                     //
   1009                 }
   1010                 else if (policyMapping <= 0)
   1011                 {
   1012                     Iterator nodes_i = policyNodes[i].iterator();
   1013                     while (nodes_i.hasNext())
   1014                     {
   1015                         PKIXPolicyNode node = (PKIXPolicyNode)nodes_i.next();
   1016                         if (node.getValidPolicy().equals(id_p))
   1017                         {
   1018                             PKIXPolicyNode p_node = (PKIXPolicyNode)node.getParent();
   1019                             p_node.removeChild(node);
   1020                             nodes_i.remove();
   1021                             for (int k = (i - 1); k >= 0; k--)
   1022                             {
   1023                                 List nodes = policyNodes[k];
   1024                                 for (int l = 0; l < nodes.size(); l++)
   1025                                 {
   1026                                     PKIXPolicyNode node2 = (PKIXPolicyNode)nodes.get(l);
   1027                                     if (!node2.hasChildren())
   1028                                     {
   1029                                         _validPolicyTree = CertPathValidatorUtilities.removePolicyNode(
   1030                                             _validPolicyTree, policyNodes, node2);
   1031                                         if (_validPolicyTree == null)
   1032                                         {
   1033                                             break;
   1034                                         }
   1035                                     }
   1036                                 }
   1037                             }
   1038                         }
   1039                     }
   1040                 }
   1041             }
   1042         }
   1043         return _validPolicyTree;
   1044     }
   1045 
   1046     protected static void prepareNextCertA(
   1047         CertPath certPath,
   1048         int index)
   1049         throws CertPathValidatorException
   1050     {
   1051         List certs = certPath.getCertificates();
   1052         X509Certificate cert = (X509Certificate)certs.get(index);
   1053         //
   1054         //
   1055         // (a) check the policy mappings
   1056         //
   1057         ASN1Sequence pm = null;
   1058         try
   1059         {
   1060             pm = DERSequence.getInstance(CertPathValidatorUtilities.getExtensionValue(cert,
   1061                 RFC3280CertPathUtilities.POLICY_MAPPINGS));
   1062         }
   1063         catch (AnnotatedException ex)
   1064         {
   1065             throw new ExtCertPathValidatorException("Policy mappings extension could not be decoded.", ex, certPath,
   1066                 index);
   1067         }
   1068         if (pm != null)
   1069         {
   1070             ASN1Sequence mappings = pm;
   1071 
   1072             for (int j = 0; j < mappings.size(); j++)
   1073             {
   1074                 DERObjectIdentifier issuerDomainPolicy = null;
   1075                 DERObjectIdentifier subjectDomainPolicy = null;
   1076                 try
   1077                 {
   1078                     ASN1Sequence mapping = DERSequence.getInstance(mappings.getObjectAt(j));
   1079 
   1080                     issuerDomainPolicy = DERObjectIdentifier.getInstance(mapping.getObjectAt(0));
   1081                     subjectDomainPolicy = DERObjectIdentifier.getInstance(mapping.getObjectAt(1));
   1082                 }
   1083                 catch (Exception e)
   1084                 {
   1085                     throw new ExtCertPathValidatorException("Policy mappings extension contents could not be decoded.",
   1086                         e, certPath, index);
   1087                 }
   1088 
   1089                 if (RFC3280CertPathUtilities.ANY_POLICY.equals(issuerDomainPolicy.getId()))
   1090                 {
   1091 
   1092                     throw new CertPathValidatorException("IssuerDomainPolicy is anyPolicy", null, certPath, index);
   1093                 }
   1094 
   1095                 if (RFC3280CertPathUtilities.ANY_POLICY.equals(subjectDomainPolicy.getId()))
   1096                 {
   1097 
   1098                     throw new CertPathValidatorException("SubjectDomainPolicy is anyPolicy,", null, certPath, index);
   1099                 }
   1100             }
   1101         }
   1102     }
   1103 
   1104     protected static void processCertF(
   1105         CertPath certPath,
   1106         int index,
   1107         PKIXPolicyNode validPolicyTree,
   1108         int explicitPolicy)
   1109         throws CertPathValidatorException
   1110     {
   1111         //
   1112         // (f)
   1113         //
   1114         if (explicitPolicy <= 0 && validPolicyTree == null)
   1115         {
   1116             throw new ExtCertPathValidatorException("No valid policy tree found when one expected.", null, certPath,
   1117                 index);
   1118         }
   1119     }
   1120 
   1121     protected static PKIXPolicyNode processCertE(
   1122         CertPath certPath,
   1123         int index,
   1124         PKIXPolicyNode validPolicyTree)
   1125         throws CertPathValidatorException
   1126     {
   1127         List certs = certPath.getCertificates();
   1128         X509Certificate cert = (X509Certificate)certs.get(index);
   1129         //
   1130         // (e)
   1131         //
   1132         ASN1Sequence certPolicies = null;
   1133         try
   1134         {
   1135             certPolicies = DERSequence.getInstance(CertPathValidatorUtilities.getExtensionValue(cert,
   1136                 RFC3280CertPathUtilities.CERTIFICATE_POLICIES));
   1137         }
   1138         catch (AnnotatedException e)
   1139         {
   1140             throw new ExtCertPathValidatorException("Could not read certificate policies extension from certificate.",
   1141                 e, certPath, index);
   1142         }
   1143         if (certPolicies == null)
   1144         {
   1145             validPolicyTree = null;
   1146         }
   1147         return validPolicyTree;
   1148     }
   1149 
   1150     protected static void processCertBC(
   1151         CertPath certPath,
   1152         int index,
   1153         PKIXNameConstraintValidator nameConstraintValidator)
   1154         throws CertPathValidatorException
   1155     {
   1156         List certs = certPath.getCertificates();
   1157         X509Certificate cert = (X509Certificate)certs.get(index);
   1158         int n = certs.size();
   1159         // i as defined in the algorithm description
   1160         int i = n - index;
   1161         //
   1162         // (b), (c) permitted and excluded subtree checking.
   1163         //
   1164         if (!(CertPathValidatorUtilities.isSelfIssued(cert) && (i < n)))
   1165         {
   1166             X500Principal principal = CertPathValidatorUtilities.getSubjectPrincipal(cert);
   1167             ASN1InputStream aIn = new ASN1InputStream(principal.getEncoded());
   1168             ASN1Sequence dns;
   1169 
   1170             try
   1171             {
   1172                 dns = DERSequence.getInstance(aIn.readObject());
   1173             }
   1174             catch (Exception e)
   1175             {
   1176                 throw new CertPathValidatorException("Exception extracting subject name when checking subtrees.", e,
   1177                     certPath, index);
   1178             }
   1179 
   1180             try
   1181             {
   1182                 nameConstraintValidator.checkPermittedDN(dns);
   1183                 nameConstraintValidator.checkExcludedDN(dns);
   1184             }
   1185             catch (PKIXNameConstraintValidatorException e)
   1186             {
   1187                 throw new CertPathValidatorException("Subtree check for certificate subject failed.", e, certPath,
   1188                     index);
   1189             }
   1190 
   1191             GeneralNames altName = null;
   1192             try
   1193             {
   1194                 altName = GeneralNames.getInstance(CertPathValidatorUtilities.getExtensionValue(cert,
   1195                     RFC3280CertPathUtilities.SUBJECT_ALTERNATIVE_NAME));
   1196             }
   1197             catch (Exception e)
   1198             {
   1199                 throw new CertPathValidatorException("Subject alternative name extension could not be decoded.", e,
   1200                     certPath, index);
   1201             }
   1202             Vector emails = new X509Name(dns).getValues(X509Name.EmailAddress);
   1203             for (Enumeration e = emails.elements(); e.hasMoreElements();)
   1204             {
   1205                 String email = (String)e.nextElement();
   1206                 GeneralName emailAsGeneralName = new GeneralName(GeneralName.rfc822Name, email);
   1207                 try
   1208                 {
   1209                     nameConstraintValidator.checkPermitted(emailAsGeneralName);
   1210                     nameConstraintValidator.checkExcluded(emailAsGeneralName);
   1211                 }
   1212                 catch (PKIXNameConstraintValidatorException ex)
   1213                 {
   1214                     throw new CertPathValidatorException(
   1215                         "Subtree check for certificate subject alternative email failed.", ex, certPath, index);
   1216                 }
   1217             }
   1218             if (altName != null)
   1219             {
   1220                 GeneralName[] genNames = null;
   1221                 try
   1222                 {
   1223                     genNames = altName.getNames();
   1224                 }
   1225                 catch (Exception e)
   1226                 {
   1227                     throw new CertPathValidatorException("Subject alternative name contents could not be decoded.", e,
   1228                         certPath, index);
   1229                 }
   1230                 for (int j = 0; j < genNames.length; j++)
   1231                 {
   1232 
   1233                     try
   1234                     {
   1235                         nameConstraintValidator.checkPermitted(genNames[j]);
   1236                         nameConstraintValidator.checkExcluded(genNames[j]);
   1237                     }
   1238                     catch (PKIXNameConstraintValidatorException e)
   1239                     {
   1240                         throw new CertPathValidatorException(
   1241                             "Subtree check for certificate subject alternative name failed.", e, certPath, index);
   1242                     }
   1243                 }
   1244             }
   1245         }
   1246     }
   1247 
   1248     protected static PKIXPolicyNode processCertD(
   1249         CertPath certPath,
   1250         int index,
   1251         Set acceptablePolicies,
   1252         PKIXPolicyNode validPolicyTree,
   1253         List[] policyNodes,
   1254         int inhibitAnyPolicy)
   1255         throws CertPathValidatorException
   1256     {
   1257         List certs = certPath.getCertificates();
   1258         X509Certificate cert = (X509Certificate)certs.get(index);
   1259         int n = certs.size();
   1260         // i as defined in the algorithm description
   1261         int i = n - index;
   1262         //
   1263         // (d) policy Information checking against initial policy and
   1264         // policy mapping
   1265         //
   1266         ASN1Sequence certPolicies = null;
   1267         try
   1268         {
   1269             certPolicies = DERSequence.getInstance(CertPathValidatorUtilities.getExtensionValue(cert,
   1270                 RFC3280CertPathUtilities.CERTIFICATE_POLICIES));
   1271         }
   1272         catch (AnnotatedException e)
   1273         {
   1274             throw new ExtCertPathValidatorException("Could not read certificate policies extension from certificate.",
   1275                 e, certPath, index);
   1276         }
   1277         if (certPolicies != null && validPolicyTree != null)
   1278         {
   1279             //
   1280             // (d) (1)
   1281             //
   1282             Enumeration e = certPolicies.getObjects();
   1283             Set pols = new HashSet();
   1284 
   1285             while (e.hasMoreElements())
   1286             {
   1287                 PolicyInformation pInfo = PolicyInformation.getInstance(e.nextElement());
   1288                 DERObjectIdentifier pOid = pInfo.getPolicyIdentifier();
   1289 
   1290                 pols.add(pOid.getId());
   1291 
   1292                 if (!RFC3280CertPathUtilities.ANY_POLICY.equals(pOid.getId()))
   1293                 {
   1294                     Set pq = null;
   1295                     try
   1296                     {
   1297                         pq = CertPathValidatorUtilities.getQualifierSet(pInfo.getPolicyQualifiers());
   1298                     }
   1299                     catch (CertPathValidatorException ex)
   1300                     {
   1301                         throw new ExtCertPathValidatorException("Policy qualifier info set could not be build.", ex,
   1302                             certPath, index);
   1303                     }
   1304 
   1305                     boolean match = CertPathValidatorUtilities.processCertD1i(i, policyNodes, pOid, pq);
   1306 
   1307                     if (!match)
   1308                     {
   1309                         CertPathValidatorUtilities.processCertD1ii(i, policyNodes, pOid, pq);
   1310                     }
   1311                 }
   1312             }
   1313 
   1314             if (acceptablePolicies.isEmpty() || acceptablePolicies.contains(RFC3280CertPathUtilities.ANY_POLICY))
   1315             {
   1316                 acceptablePolicies.clear();
   1317                 acceptablePolicies.addAll(pols);
   1318             }
   1319             else
   1320             {
   1321                 Iterator it = acceptablePolicies.iterator();
   1322                 Set t1 = new HashSet();
   1323 
   1324                 while (it.hasNext())
   1325                 {
   1326                     Object o = it.next();
   1327 
   1328                     if (pols.contains(o))
   1329                     {
   1330                         t1.add(o);
   1331                     }
   1332                 }
   1333                 acceptablePolicies.clear();
   1334                 acceptablePolicies.addAll(t1);
   1335             }
   1336 
   1337             //
   1338             // (d) (2)
   1339             //
   1340             if ((inhibitAnyPolicy > 0) || ((i < n) && CertPathValidatorUtilities.isSelfIssued(cert)))
   1341             {
   1342                 e = certPolicies.getObjects();
   1343 
   1344                 while (e.hasMoreElements())
   1345                 {
   1346                     PolicyInformation pInfo = PolicyInformation.getInstance(e.nextElement());
   1347 
   1348                     if (RFC3280CertPathUtilities.ANY_POLICY.equals(pInfo.getPolicyIdentifier().getId()))
   1349                     {
   1350                         Set _apq = CertPathValidatorUtilities.getQualifierSet(pInfo.getPolicyQualifiers());
   1351                         List _nodes = policyNodes[i - 1];
   1352 
   1353                         for (int k = 0; k < _nodes.size(); k++)
   1354                         {
   1355                             PKIXPolicyNode _node = (PKIXPolicyNode)_nodes.get(k);
   1356 
   1357                             Iterator _policySetIter = _node.getExpectedPolicies().iterator();
   1358                             while (_policySetIter.hasNext())
   1359                             {
   1360                                 Object _tmp = _policySetIter.next();
   1361 
   1362                                 String _policy;
   1363                                 if (_tmp instanceof String)
   1364                                 {
   1365                                     _policy = (String)_tmp;
   1366                                 }
   1367                                 else if (_tmp instanceof DERObjectIdentifier)
   1368                                 {
   1369                                     _policy = ((DERObjectIdentifier)_tmp).getId();
   1370                                 }
   1371                                 else
   1372                                 {
   1373                                     continue;
   1374                                 }
   1375 
   1376                                 boolean _found = false;
   1377                                 Iterator _childrenIter = _node.getChildren();
   1378 
   1379                                 while (_childrenIter.hasNext())
   1380                                 {
   1381                                     PKIXPolicyNode _child = (PKIXPolicyNode)_childrenIter.next();
   1382 
   1383                                     if (_policy.equals(_child.getValidPolicy()))
   1384                                     {
   1385                                         _found = true;
   1386                                     }
   1387                                 }
   1388 
   1389                                 if (!_found)
   1390                                 {
   1391                                     Set _newChildExpectedPolicies = new HashSet();
   1392                                     _newChildExpectedPolicies.add(_policy);
   1393 
   1394                                     PKIXPolicyNode _newChild = new PKIXPolicyNode(new ArrayList(), i,
   1395                                         _newChildExpectedPolicies, _node, _apq, _policy, false);
   1396                                     _node.addChild(_newChild);
   1397                                     policyNodes[i].add(_newChild);
   1398                                 }
   1399                             }
   1400                         }
   1401                         break;
   1402                     }
   1403                 }
   1404             }
   1405 
   1406             PKIXPolicyNode _validPolicyTree = validPolicyTree;
   1407             //
   1408             // (d) (3)
   1409             //
   1410             for (int j = (i - 1); j >= 0; j--)
   1411             {
   1412                 List nodes = policyNodes[j];
   1413 
   1414                 for (int k = 0; k < nodes.size(); k++)
   1415                 {
   1416                     PKIXPolicyNode node = (PKIXPolicyNode)nodes.get(k);
   1417                     if (!node.hasChildren())
   1418                     {
   1419                         _validPolicyTree = CertPathValidatorUtilities.removePolicyNode(_validPolicyTree, policyNodes,
   1420                             node);
   1421                         if (_validPolicyTree == null)
   1422                         {
   1423                             break;
   1424                         }
   1425                     }
   1426                 }
   1427             }
   1428 
   1429             //
   1430             // d (4)
   1431             //
   1432             Set criticalExtensionOids = cert.getCriticalExtensionOIDs();
   1433 
   1434             if (criticalExtensionOids != null)
   1435             {
   1436                 boolean critical = criticalExtensionOids.contains(RFC3280CertPathUtilities.CERTIFICATE_POLICIES);
   1437 
   1438                 List nodes = policyNodes[i];
   1439                 for (int j = 0; j < nodes.size(); j++)
   1440                 {
   1441                     PKIXPolicyNode node = (PKIXPolicyNode)nodes.get(j);
   1442                     node.setCritical(critical);
   1443                 }
   1444             }
   1445             return _validPolicyTree;
   1446         }
   1447         return null;
   1448     }
   1449 
   1450     protected static void processCertA(
   1451         CertPath certPath,
   1452         ExtendedPKIXParameters paramsPKIX,
   1453         int index,
   1454         PublicKey workingPublicKey,
   1455         boolean verificationAlreadyPerformed,
   1456         X500Principal workingIssuerName,
   1457         X509Certificate sign)
   1458         throws ExtCertPathValidatorException
   1459     {
   1460         List certs = certPath.getCertificates();
   1461         X509Certificate cert = (X509Certificate)certs.get(index);
   1462         //
   1463         // (a) verify
   1464         //
   1465         if (!verificationAlreadyPerformed)
   1466         {
   1467             try
   1468             {
   1469                 // (a) (1)
   1470                 //
   1471                 CertPathValidatorUtilities.verifyX509Certificate(cert, workingPublicKey,
   1472                     paramsPKIX.getSigProvider());
   1473             }
   1474             catch (GeneralSecurityException e)
   1475             {
   1476                 throw new ExtCertPathValidatorException("Could not validate certificate signature.", e, certPath, index);
   1477             }
   1478         }
   1479 
   1480         try
   1481         {
   1482             // (a) (2)
   1483             //
   1484             cert.checkValidity(CertPathValidatorUtilities
   1485                 .getValidCertDateFromValidityModel(paramsPKIX, certPath, index));
   1486         }
   1487         catch (CertificateExpiredException e)
   1488         {
   1489             throw new ExtCertPathValidatorException("Could not validate certificate: " + e.getMessage(), e, certPath, index);
   1490         }
   1491         catch (CertificateNotYetValidException e)
   1492         {
   1493             throw new ExtCertPathValidatorException("Could not validate certificate: " + e.getMessage(), e, certPath, index);
   1494         }
   1495         catch (AnnotatedException e)
   1496         {
   1497             throw new ExtCertPathValidatorException("Could not validate time of certificate.", e, certPath, index);
   1498         }
   1499 
   1500         //
   1501         // (a) (3)
   1502         //
   1503         if (paramsPKIX.isRevocationEnabled())
   1504         {
   1505             try
   1506             {
   1507                 checkCRLs(paramsPKIX, cert, CertPathValidatorUtilities.getValidCertDateFromValidityModel(paramsPKIX,
   1508                     certPath, index), sign, workingPublicKey, certs);
   1509             }
   1510             catch (AnnotatedException e)
   1511             {
   1512                 Throwable cause = e;
   1513                 if (null != e.getCause())
   1514                 {
   1515                     cause = e.getCause();
   1516                 }
   1517                 throw new ExtCertPathValidatorException(e.getMessage(), cause, certPath, index);
   1518             }
   1519         }
   1520 
   1521         //
   1522         // (a) (4) name chaining
   1523         //
   1524         if (!CertPathValidatorUtilities.getEncodedIssuerPrincipal(cert).equals(workingIssuerName))
   1525         {
   1526             throw new ExtCertPathValidatorException("IssuerName(" + CertPathValidatorUtilities.getEncodedIssuerPrincipal(cert)
   1527                 + ") does not match SubjectName(" + workingIssuerName + ") of signing certificate.", null,
   1528                 certPath, index);
   1529         }
   1530     }
   1531 
   1532     protected static int prepareNextCertI1(
   1533         CertPath certPath,
   1534         int index,
   1535         int explicitPolicy)
   1536         throws CertPathValidatorException
   1537     {
   1538         List certs = certPath.getCertificates();
   1539         X509Certificate cert = (X509Certificate)certs.get(index);
   1540         //
   1541         // (i)
   1542         //
   1543         ASN1Sequence pc = null;
   1544         try
   1545         {
   1546             pc = DERSequence.getInstance(CertPathValidatorUtilities.getExtensionValue(cert,
   1547                 RFC3280CertPathUtilities.POLICY_CONSTRAINTS));
   1548         }
   1549         catch (Exception e)
   1550         {
   1551             throw new ExtCertPathValidatorException("Policy constraints extension cannot be decoded.", e, certPath,
   1552                 index);
   1553         }
   1554 
   1555         int tmpInt;
   1556 
   1557         if (pc != null)
   1558         {
   1559             Enumeration policyConstraints = pc.getObjects();
   1560 
   1561             while (policyConstraints.hasMoreElements())
   1562             {
   1563                 try
   1564                 {
   1565 
   1566                     ASN1TaggedObject constraint = ASN1TaggedObject.getInstance(policyConstraints.nextElement());
   1567                     if (constraint.getTagNo() == 0)
   1568                     {
   1569                         tmpInt = DERInteger.getInstance(constraint, false).getValue().intValue();
   1570                         if (tmpInt < explicitPolicy)
   1571                         {
   1572                             return tmpInt;
   1573                         }
   1574                         break;
   1575                     }
   1576                 }
   1577                 catch (IllegalArgumentException e)
   1578                 {
   1579                     throw new ExtCertPathValidatorException("Policy constraints extension contents cannot be decoded.",
   1580                         e, certPath, index);
   1581                 }
   1582             }
   1583         }
   1584         return explicitPolicy;
   1585     }
   1586 
   1587     protected static int prepareNextCertI2(
   1588         CertPath certPath,
   1589         int index,
   1590         int policyMapping)
   1591         throws CertPathValidatorException
   1592     {
   1593         List certs = certPath.getCertificates();
   1594         X509Certificate cert = (X509Certificate)certs.get(index);
   1595         //
   1596         // (i)
   1597         //
   1598         ASN1Sequence pc = null;
   1599         try
   1600         {
   1601             pc = DERSequence.getInstance(CertPathValidatorUtilities.getExtensionValue(cert,
   1602                 RFC3280CertPathUtilities.POLICY_CONSTRAINTS));
   1603         }
   1604         catch (Exception e)
   1605         {
   1606             throw new ExtCertPathValidatorException("Policy constraints extension cannot be decoded.", e, certPath,
   1607                 index);
   1608         }
   1609 
   1610         int tmpInt;
   1611 
   1612         if (pc != null)
   1613         {
   1614             Enumeration policyConstraints = pc.getObjects();
   1615 
   1616             while (policyConstraints.hasMoreElements())
   1617             {
   1618                 try
   1619                 {
   1620                     ASN1TaggedObject constraint = ASN1TaggedObject.getInstance(policyConstraints.nextElement());
   1621                     if (constraint.getTagNo() == 1)
   1622                     {
   1623                         tmpInt = DERInteger.getInstance(constraint, false).getValue().intValue();
   1624                         if (tmpInt < policyMapping)
   1625                         {
   1626                             return tmpInt;
   1627                         }
   1628                         break;
   1629                     }
   1630                 }
   1631                 catch (IllegalArgumentException e)
   1632                 {
   1633                     throw new ExtCertPathValidatorException("Policy constraints extension contents cannot be decoded.",
   1634                         e, certPath, index);
   1635                 }
   1636             }
   1637         }
   1638         return policyMapping;
   1639     }
   1640 
   1641     protected static void prepareNextCertG(
   1642         CertPath certPath,
   1643         int index,
   1644         PKIXNameConstraintValidator nameConstraintValidator)
   1645         throws CertPathValidatorException
   1646     {
   1647         List certs = certPath.getCertificates();
   1648         X509Certificate cert = (X509Certificate)certs.get(index);
   1649         //
   1650         // (g) handle the name constraints extension
   1651         //
   1652         NameConstraints nc = null;
   1653         try
   1654         {
   1655             ASN1Sequence ncSeq = DERSequence.getInstance(CertPathValidatorUtilities.getExtensionValue(cert,
   1656                 RFC3280CertPathUtilities.NAME_CONSTRAINTS));
   1657             if (ncSeq != null)
   1658             {
   1659                 nc = new NameConstraints(ncSeq);
   1660             }
   1661         }
   1662         catch (Exception e)
   1663         {
   1664             throw new ExtCertPathValidatorException("Name constraints extension could not be decoded.", e, certPath,
   1665                 index);
   1666         }
   1667         if (nc != null)
   1668         {
   1669 
   1670             //
   1671             // (g) (1) permitted subtrees
   1672             //
   1673             ASN1Sequence permitted = nc.getPermittedSubtrees();
   1674             if (permitted != null)
   1675             {
   1676                 try
   1677                 {
   1678                     nameConstraintValidator.intersectPermittedSubtree(permitted);
   1679                 }
   1680                 catch (Exception ex)
   1681                 {
   1682                     throw new ExtCertPathValidatorException(
   1683                         "Permitted subtrees cannot be build from name constraints extension.", ex, certPath, index);
   1684                 }
   1685             }
   1686 
   1687             //
   1688             // (g) (2) excluded subtrees
   1689             //
   1690             ASN1Sequence excluded = nc.getExcludedSubtrees();
   1691             if (excluded != null)
   1692             {
   1693                 Enumeration e = excluded.getObjects();
   1694                 try
   1695                 {
   1696                     while (e.hasMoreElements())
   1697                     {
   1698                         GeneralSubtree subtree = GeneralSubtree.getInstance(e.nextElement());
   1699                         nameConstraintValidator.addExcludedSubtree(subtree);
   1700                     }
   1701                 }
   1702                 catch (Exception ex)
   1703                 {
   1704                     throw new ExtCertPathValidatorException(
   1705                         "Excluded subtrees cannot be build from name constraints extension.", ex, certPath, index);
   1706                 }
   1707             }
   1708         }
   1709     }
   1710 
   1711     /**
   1712      * Checks a distribution point for revocation information for the
   1713      * certificate <code>cert</code>.
   1714      *
   1715      * @param dp                 The distribution point to consider.
   1716      * @param paramsPKIX         PKIX parameters.
   1717      * @param cert               Certificate to check if it is revoked.
   1718      * @param validDate          The date when the certificate revocation status should be
   1719      *                           checked.
   1720      * @param defaultCRLSignCert The issuer certificate of the certificate <code>cert</code>.
   1721      * @param defaultCRLSignKey  The public key of the issuer certificate
   1722      *                           <code>defaultCRLSignCert</code>.
   1723      * @param certStatus         The current certificate revocation status.
   1724      * @param reasonMask         The reasons mask which is already checked.
   1725      * @param certPathCerts      The certificates of the certification path.
   1726      * @throws AnnotatedException if the certificate is revoked or the status cannot be checked
   1727      *                            or some error occurs.
   1728      */
   1729     private static void checkCRL(
   1730         DistributionPoint dp,
   1731         ExtendedPKIXParameters paramsPKIX,
   1732         X509Certificate cert,
   1733         Date validDate,
   1734         X509Certificate defaultCRLSignCert,
   1735         PublicKey defaultCRLSignKey,
   1736         CertStatus certStatus,
   1737         ReasonsMask reasonMask,
   1738         List certPathCerts)
   1739         throws AnnotatedException
   1740     {
   1741         Date currentDate = new Date(System.currentTimeMillis());
   1742         if (validDate.getTime() > currentDate.getTime())
   1743         {
   1744             throw new AnnotatedException("Validation time is in future.");
   1745         }
   1746 
   1747         // (a)
   1748         /*
   1749          * We always get timely valid CRLs, so there is no step (a) (1).
   1750          * "locally cached" CRLs are assumed to be in getStore(), additional
   1751          * CRLs must be enabled in the ExtendedPKIXParameters and are in
   1752          * getAdditionalStore()
   1753          */
   1754 
   1755         Set crls = CertPathValidatorUtilities.getCompleteCRLs(dp, cert, currentDate, paramsPKIX);
   1756         boolean validCrlFound = false;
   1757         AnnotatedException lastException = null;
   1758         Iterator crl_iter = crls.iterator();
   1759 
   1760         while (crl_iter.hasNext() && certStatus.getCertStatus() == CertStatus.UNREVOKED && !reasonMask.isAllReasons())
   1761         {
   1762             try
   1763             {
   1764                 X509CRL crl = (X509CRL)crl_iter.next();
   1765 
   1766                 // (d)
   1767                 ReasonsMask interimReasonsMask = RFC3280CertPathUtilities.processCRLD(crl, dp);
   1768 
   1769                 // (e)
   1770                 /*
   1771                  * The reasons mask is updated at the end, so only valid CRLs
   1772                  * can update it. If this CRL does not contain new reasons it
   1773                  * must be ignored.
   1774                  */
   1775                 if (!interimReasonsMask.hasNewReasons(reasonMask))
   1776                 {
   1777                     continue;
   1778                 }
   1779 
   1780                 // (f)
   1781                 Set keys = RFC3280CertPathUtilities.processCRLF(crl, cert, defaultCRLSignCert, defaultCRLSignKey,
   1782                     paramsPKIX, certPathCerts);
   1783                 // (g)
   1784                 PublicKey key = RFC3280CertPathUtilities.processCRLG(crl, keys);
   1785 
   1786                 X509CRL deltaCRL = null;
   1787 
   1788                 if (paramsPKIX.isUseDeltasEnabled())
   1789                 {
   1790                     // get delta CRLs
   1791                     Set deltaCRLs = CertPathValidatorUtilities.getDeltaCRLs(currentDate, paramsPKIX, crl);
   1792                     // we only want one valid delta CRL
   1793                     // (h)
   1794                     deltaCRL = RFC3280CertPathUtilities.processCRLH(deltaCRLs, key);
   1795                 }
   1796 
   1797                 /*
   1798                  * CRL must be be valid at the current time, not the validation
   1799                  * time. If a certificate is revoked with reason keyCompromise,
   1800                  * cACompromise, it can be used for forgery, also for the past.
   1801                  * This reason may not be contained in older CRLs.
   1802                  */
   1803 
   1804                 /*
   1805                  * in the chain model signatures stay valid also after the
   1806                  * certificate has been expired, so they do not have to be in
   1807                  * the CRL validity time
   1808                  */
   1809 
   1810                 if (paramsPKIX.getValidityModel() != ExtendedPKIXParameters.CHAIN_VALIDITY_MODEL)
   1811                 {
   1812                     /*
   1813                      * if a certificate has expired, but was revoked, it is not
   1814                      * more in the CRL, so it would be regarded as valid if the
   1815                      * first check is not done
   1816                      */
   1817                     if (cert.getNotAfter().getTime() < crl.getThisUpdate().getTime())
   1818                     {
   1819                         throw new AnnotatedException("No valid CRL for current time found.");
   1820                     }
   1821                 }
   1822 
   1823                 RFC3280CertPathUtilities.processCRLB1(dp, cert, crl);
   1824 
   1825                 // (b) (2)
   1826                 RFC3280CertPathUtilities.processCRLB2(dp, cert, crl);
   1827 
   1828                 // (c)
   1829                 RFC3280CertPathUtilities.processCRLC(deltaCRL, crl, paramsPKIX);
   1830 
   1831                 // (i)
   1832                 RFC3280CertPathUtilities.processCRLI(validDate, deltaCRL, cert, certStatus, paramsPKIX);
   1833 
   1834                 // (j)
   1835                 RFC3280CertPathUtilities.processCRLJ(validDate, crl, cert, certStatus);
   1836 
   1837                 // (k)
   1838                 if (certStatus.getCertStatus() == CRLReason.removeFromCRL)
   1839                 {
   1840                     certStatus.setCertStatus(CertStatus.UNREVOKED);
   1841                 }
   1842 
   1843                 // update reasons mask
   1844                 reasonMask.addReasons(interimReasonsMask);
   1845 
   1846                 Set criticalExtensions = crl.getCriticalExtensionOIDs();
   1847                 if (criticalExtensions != null)
   1848                 {
   1849                     criticalExtensions = new HashSet(criticalExtensions);
   1850                     criticalExtensions.remove(X509Extensions.IssuingDistributionPoint.getId());
   1851                     criticalExtensions.remove(X509Extensions.DeltaCRLIndicator.getId());
   1852 
   1853                     if (!criticalExtensions.isEmpty())
   1854                     {
   1855                         throw new AnnotatedException("CRL contains unsupported critical extensions.");
   1856                     }
   1857                 }
   1858 
   1859                 if (deltaCRL != null)
   1860                 {
   1861                     criticalExtensions = deltaCRL.getCriticalExtensionOIDs();
   1862                     if (criticalExtensions != null)
   1863                     {
   1864                         criticalExtensions = new HashSet(criticalExtensions);
   1865                         criticalExtensions.remove(X509Extensions.IssuingDistributionPoint.getId());
   1866                         criticalExtensions.remove(X509Extensions.DeltaCRLIndicator.getId());
   1867                         if (!criticalExtensions.isEmpty())
   1868                         {
   1869                             throw new AnnotatedException("Delta CRL contains unsupported critical extension.");
   1870                         }
   1871                     }
   1872                 }
   1873 
   1874                 validCrlFound = true;
   1875             }
   1876             catch (AnnotatedException e)
   1877             {
   1878                 lastException = e;
   1879             }
   1880         }
   1881         if (!validCrlFound)
   1882         {
   1883             throw lastException;
   1884         }
   1885     }
   1886 
   1887     /**
   1888      * Checks a certificate if it is revoked.
   1889      *
   1890      * @param paramsPKIX       PKIX parameters.
   1891      * @param cert             Certificate to check if it is revoked.
   1892      * @param validDate        The date when the certificate revocation status should be
   1893      *                         checked.
   1894      * @param sign             The issuer certificate of the certificate <code>cert</code>.
   1895      * @param workingPublicKey The public key of the issuer certificate <code>sign</code>.
   1896      * @param certPathCerts    The certificates of the certification path.
   1897      * @throws AnnotatedException if the certificate is revoked or the status cannot be checked
   1898      *                            or some error occurs.
   1899      */
   1900     protected static void checkCRLs(
   1901         ExtendedPKIXParameters paramsPKIX,
   1902         X509Certificate cert,
   1903         Date validDate,
   1904         X509Certificate sign,
   1905         PublicKey workingPublicKey,
   1906         List certPathCerts)
   1907         throws AnnotatedException
   1908     {
   1909         AnnotatedException lastException = null;
   1910         CRLDistPoint crldp = null;
   1911         try
   1912         {
   1913             crldp = CRLDistPoint.getInstance(CertPathValidatorUtilities.getExtensionValue(cert,
   1914                 RFC3280CertPathUtilities.CRL_DISTRIBUTION_POINTS));
   1915         }
   1916         catch (Exception e)
   1917         {
   1918             throw new AnnotatedException("CRL distribution point extension could not be read.", e);
   1919         }
   1920         try
   1921         {
   1922             CertPathValidatorUtilities.addAdditionalStoresFromCRLDistributionPoint(crldp, paramsPKIX);
   1923         }
   1924         catch (AnnotatedException e)
   1925         {
   1926             throw new AnnotatedException(
   1927                 "No additional CRL locations could be decoded from CRL distribution point extension.", e);
   1928         }
   1929         CertStatus certStatus = new CertStatus();
   1930         ReasonsMask reasonsMask = new ReasonsMask();
   1931 
   1932         boolean validCrlFound = false;
   1933         // for each distribution point
   1934         if (crldp != null)
   1935         {
   1936             DistributionPoint dps[] = null;
   1937             try
   1938             {
   1939                 dps = crldp.getDistributionPoints();
   1940             }
   1941             catch (Exception e)
   1942             {
   1943                 throw new AnnotatedException("Distribution points could not be read.", e);
   1944             }
   1945             if (dps != null)
   1946             {
   1947                 for (int i = 0; i < dps.length && certStatus.getCertStatus() == CertStatus.UNREVOKED && !reasonsMask.isAllReasons(); i++)
   1948                 {
   1949                     ExtendedPKIXParameters paramsPKIXClone = (ExtendedPKIXParameters)paramsPKIX.clone();
   1950                     try
   1951                     {
   1952                         checkCRL(dps[i], paramsPKIXClone, cert, validDate, sign, workingPublicKey, certStatus, reasonsMask, certPathCerts);
   1953                         validCrlFound = true;
   1954                     }
   1955                     catch (AnnotatedException e)
   1956                     {
   1957                         lastException = e;
   1958                     }
   1959                 }
   1960             }
   1961         }
   1962 
   1963         /*
   1964          * If the revocation status has not been determined, repeat the process
   1965          * above with any available CRLs not specified in a distribution point
   1966          * but issued by the certificate issuer.
   1967          */
   1968 
   1969         if (certStatus.getCertStatus() == CertStatus.UNREVOKED && !reasonsMask.isAllReasons())
   1970         {
   1971             try
   1972             {
   1973                 /*
   1974                  * assume a DP with both the reasons and the cRLIssuer fields
   1975                  * omitted and a distribution point name of the certificate
   1976                  * issuer.
   1977                  */
   1978                 DERObject issuer = null;
   1979                 try
   1980                 {
   1981                     issuer = new ASN1InputStream(CertPathValidatorUtilities.getEncodedIssuerPrincipal(cert).getEncoded())
   1982                         .readObject();
   1983                 }
   1984                 catch (Exception e)
   1985                 {
   1986                     throw new AnnotatedException("Issuer from certificate for CRL could not be reencoded.", e);
   1987                 }
   1988                 DistributionPoint dp = new DistributionPoint(new DistributionPointName(0, new GeneralNames(
   1989                     new GeneralName(GeneralName.directoryName, issuer))), null, null);
   1990                 ExtendedPKIXParameters paramsPKIXClone = (ExtendedPKIXParameters)paramsPKIX.clone();
   1991                 checkCRL(dp, paramsPKIXClone, cert, validDate, sign, workingPublicKey, certStatus, reasonsMask,
   1992                     certPathCerts);
   1993                 validCrlFound = true;
   1994             }
   1995             catch (AnnotatedException e)
   1996             {
   1997                 lastException = e;
   1998             }
   1999         }
   2000 
   2001         if (!validCrlFound)
   2002         {
   2003             if (lastException instanceof AnnotatedException)
   2004             {
   2005                 throw lastException;
   2006             }
   2007 
   2008             throw new AnnotatedException("No valid CRL found.", lastException);
   2009         }
   2010         if (certStatus.getCertStatus() != CertStatus.UNREVOKED)
   2011         {
   2012             String message = "Certificate revocation after " + certStatus.getRevocationDate();
   2013             message += ", reason: " + crlReasons[certStatus.getCertStatus()];
   2014             throw new AnnotatedException(message);
   2015         }
   2016         if (!reasonsMask.isAllReasons() && certStatus.getCertStatus() == CertStatus.UNREVOKED)
   2017         {
   2018             certStatus.setCertStatus(CertStatus.UNDETERMINED);
   2019         }
   2020         if (certStatus.getCertStatus() == CertStatus.UNDETERMINED)
   2021         {
   2022             throw new AnnotatedException("Certificate status could not be determined.");
   2023         }
   2024     }
   2025 
   2026     protected static int prepareNextCertJ(
   2027         CertPath certPath,
   2028         int index,
   2029         int inhibitAnyPolicy)
   2030         throws CertPathValidatorException
   2031     {
   2032         List certs = certPath.getCertificates();
   2033         X509Certificate cert = (X509Certificate)certs.get(index);
   2034         //
   2035         // (j)
   2036         //
   2037         DERInteger iap = null;
   2038         try
   2039         {
   2040             iap = DERInteger.getInstance(CertPathValidatorUtilities.getExtensionValue(cert,
   2041                 RFC3280CertPathUtilities.INHIBIT_ANY_POLICY));
   2042         }
   2043         catch (Exception e)
   2044         {
   2045             throw new ExtCertPathValidatorException("Inhibit any-policy extension cannot be decoded.", e, certPath,
   2046                 index);
   2047         }
   2048 
   2049         if (iap != null)
   2050         {
   2051             int _inhibitAnyPolicy = iap.getValue().intValue();
   2052 
   2053             if (_inhibitAnyPolicy < inhibitAnyPolicy)
   2054             {
   2055                 return _inhibitAnyPolicy;
   2056             }
   2057         }
   2058         return inhibitAnyPolicy;
   2059     }
   2060 
   2061     protected static void prepareNextCertK(
   2062         CertPath certPath,
   2063         int index)
   2064         throws CertPathValidatorException
   2065     {
   2066         List certs = certPath.getCertificates();
   2067         X509Certificate cert = (X509Certificate)certs.get(index);
   2068         //
   2069         // (k)
   2070         //
   2071         BasicConstraints bc = null;
   2072         try
   2073         {
   2074             bc = BasicConstraints.getInstance(CertPathValidatorUtilities.getExtensionValue(cert,
   2075                 RFC3280CertPathUtilities.BASIC_CONSTRAINTS));
   2076         }
   2077         catch (Exception e)
   2078         {
   2079             throw new ExtCertPathValidatorException("Basic constraints extension cannot be decoded.", e, certPath,
   2080                 index);
   2081         }
   2082         if (bc != null)
   2083         {
   2084             if (!(bc.isCA()))
   2085             {
   2086                 throw new CertPathValidatorException("Not a CA certificate");
   2087             }
   2088         }
   2089         else
   2090         {
   2091             throw new CertPathValidatorException("Intermediate certificate lacks BasicConstraints");
   2092         }
   2093     }
   2094 
   2095     protected static int prepareNextCertL(
   2096         CertPath certPath,
   2097         int index,
   2098         int maxPathLength)
   2099         throws CertPathValidatorException
   2100     {
   2101         List certs = certPath.getCertificates();
   2102         X509Certificate cert = (X509Certificate)certs.get(index);
   2103         //
   2104         // (l)
   2105         //
   2106         if (!CertPathValidatorUtilities.isSelfIssued(cert))
   2107         {
   2108             if (maxPathLength <= 0)
   2109             {
   2110                 throw new ExtCertPathValidatorException("Max path length not greater than zero", null, certPath, index);
   2111             }
   2112 
   2113             return maxPathLength - 1;
   2114         }
   2115         return maxPathLength;
   2116     }
   2117 
   2118     protected static int prepareNextCertM(
   2119         CertPath certPath,
   2120         int index,
   2121         int maxPathLength)
   2122         throws CertPathValidatorException
   2123     {
   2124         List certs = certPath.getCertificates();
   2125         X509Certificate cert = (X509Certificate)certs.get(index);
   2126 
   2127         //
   2128         // (m)
   2129         //
   2130         BasicConstraints bc = null;
   2131         try
   2132         {
   2133             bc = BasicConstraints.getInstance(CertPathValidatorUtilities.getExtensionValue(cert,
   2134                 RFC3280CertPathUtilities.BASIC_CONSTRAINTS));
   2135         }
   2136         catch (Exception e)
   2137         {
   2138             throw new ExtCertPathValidatorException("Basic constraints extension cannot be decoded.", e, certPath,
   2139                 index);
   2140         }
   2141         if (bc != null)
   2142         {
   2143             BigInteger _pathLengthConstraint = bc.getPathLenConstraint();
   2144 
   2145             if (_pathLengthConstraint != null)
   2146             {
   2147                 int _plc = _pathLengthConstraint.intValue();
   2148 
   2149                 if (_plc < maxPathLength)
   2150                 {
   2151                     return _plc;
   2152                 }
   2153             }
   2154         }
   2155         return maxPathLength;
   2156     }
   2157 
   2158     protected static void prepareNextCertN(
   2159         CertPath certPath,
   2160         int index)
   2161         throws CertPathValidatorException
   2162     {
   2163         List certs = certPath.getCertificates();
   2164         X509Certificate cert = (X509Certificate)certs.get(index);
   2165 
   2166         //
   2167         // (n)
   2168         //
   2169         boolean[] _usage = cert.getKeyUsage();
   2170 
   2171         if ((_usage != null) && !_usage[RFC3280CertPathUtilities.KEY_CERT_SIGN])
   2172         {
   2173             throw new ExtCertPathValidatorException(
   2174                 "Issuer certificate keyusage extension is critical and does not permit key signing.", null,
   2175                 certPath, index);
   2176         }
   2177     }
   2178 
   2179     protected static void prepareNextCertO(
   2180         CertPath certPath,
   2181         int index,
   2182         Set criticalExtensions,
   2183         List pathCheckers)
   2184         throws CertPathValidatorException
   2185     {
   2186         List certs = certPath.getCertificates();
   2187         X509Certificate cert = (X509Certificate)certs.get(index);
   2188         //
   2189         // (o)
   2190         //
   2191 
   2192         Iterator tmpIter;
   2193         tmpIter = pathCheckers.iterator();
   2194         while (tmpIter.hasNext())
   2195         {
   2196             try
   2197             {
   2198                 ((PKIXCertPathChecker)tmpIter.next()).check(cert, criticalExtensions);
   2199             }
   2200             catch (CertPathValidatorException e)
   2201             {
   2202                 throw new CertPathValidatorException(e.getMessage(), e.getCause(), certPath, index);
   2203             }
   2204         }
   2205         if (!criticalExtensions.isEmpty())
   2206         {
   2207             throw new ExtCertPathValidatorException("Certificate has unsupported critical extension.", null, certPath,
   2208                 index);
   2209         }
   2210     }
   2211 
   2212     protected static int prepareNextCertH1(
   2213         CertPath certPath,
   2214         int index,
   2215         int explicitPolicy)
   2216     {
   2217         List certs = certPath.getCertificates();
   2218         X509Certificate cert = (X509Certificate)certs.get(index);
   2219         //
   2220         // (h)
   2221         //
   2222         if (!CertPathValidatorUtilities.isSelfIssued(cert))
   2223         {
   2224             //
   2225             // (1)
   2226             //
   2227             if (explicitPolicy != 0)
   2228             {
   2229                 return explicitPolicy - 1;
   2230             }
   2231         }
   2232         return explicitPolicy;
   2233     }
   2234 
   2235     protected static int prepareNextCertH2(
   2236         CertPath certPath,
   2237         int index,
   2238         int policyMapping)
   2239     {
   2240         List certs = certPath.getCertificates();
   2241         X509Certificate cert = (X509Certificate)certs.get(index);
   2242         //
   2243         // (h)
   2244         //
   2245         if (!CertPathValidatorUtilities.isSelfIssued(cert))
   2246         {
   2247             //
   2248             // (2)
   2249             //
   2250             if (policyMapping != 0)
   2251             {
   2252                 return policyMapping - 1;
   2253             }
   2254         }
   2255         return policyMapping;
   2256     }
   2257 
   2258     protected static int prepareNextCertH3(
   2259         CertPath certPath,
   2260         int index,
   2261         int inhibitAnyPolicy)
   2262     {
   2263         List certs = certPath.getCertificates();
   2264         X509Certificate cert = (X509Certificate)certs.get(index);
   2265         //
   2266         // (h)
   2267         //
   2268         if (!CertPathValidatorUtilities.isSelfIssued(cert))
   2269         {
   2270             //
   2271             // (3)
   2272             //
   2273             if (inhibitAnyPolicy != 0)
   2274             {
   2275                 return inhibitAnyPolicy - 1;
   2276             }
   2277         }
   2278         return inhibitAnyPolicy;
   2279     }
   2280 
   2281     protected static final String[] crlReasons = new String[]
   2282         {
   2283             "unspecified",
   2284             "keyCompromise",
   2285             "cACompromise",
   2286             "affiliationChanged",
   2287             "superseded",
   2288             "cessationOfOperation",
   2289             "certificateHold",
   2290             "unknown",
   2291             "removeFromCRL",
   2292             "privilegeWithdrawn",
   2293             "aACompromise"};
   2294 
   2295     protected static int wrapupCertA(
   2296         int explicitPolicy,
   2297         X509Certificate cert)
   2298     {
   2299         //
   2300         // (a)
   2301         //
   2302         if (!CertPathValidatorUtilities.isSelfIssued(cert) && (explicitPolicy != 0))
   2303         {
   2304             explicitPolicy--;
   2305         }
   2306         return explicitPolicy;
   2307     }
   2308 
   2309     protected static int wrapupCertB(
   2310         CertPath certPath,
   2311         int index,
   2312         int explicitPolicy)
   2313         throws CertPathValidatorException
   2314     {
   2315         List certs = certPath.getCertificates();
   2316         X509Certificate cert = (X509Certificate)certs.get(index);
   2317         //
   2318         // (b)
   2319         //
   2320         int tmpInt;
   2321         ASN1Sequence pc = null;
   2322         try
   2323         {
   2324             pc = DERSequence.getInstance(CertPathValidatorUtilities.getExtensionValue(cert,
   2325                 RFC3280CertPathUtilities.POLICY_CONSTRAINTS));
   2326         }
   2327         catch (AnnotatedException e)
   2328         {
   2329             throw new ExtCertPathValidatorException("Policy constraints could not be decoded.", e, certPath, index);
   2330         }
   2331         if (pc != null)
   2332         {
   2333             Enumeration policyConstraints = pc.getObjects();
   2334 
   2335             while (policyConstraints.hasMoreElements())
   2336             {
   2337                 ASN1TaggedObject constraint = (ASN1TaggedObject)policyConstraints.nextElement();
   2338                 switch (constraint.getTagNo())
   2339                 {
   2340                     case 0:
   2341                         try
   2342                         {
   2343                             tmpInt = DERInteger.getInstance(constraint, false).getValue().intValue();
   2344                         }
   2345                         catch (Exception e)
   2346                         {
   2347                             throw new ExtCertPathValidatorException(
   2348                                 "Policy constraints requireExplicitPolicy field could not be decoded.", e, certPath,
   2349                                 index);
   2350                         }
   2351                         if (tmpInt == 0)
   2352                         {
   2353                             return 0;
   2354                         }
   2355                         break;
   2356                 }
   2357             }
   2358         }
   2359         return explicitPolicy;
   2360     }
   2361 
   2362     protected static void wrapupCertF(
   2363         CertPath certPath,
   2364         int index,
   2365         List pathCheckers,
   2366         Set criticalExtensions)
   2367         throws CertPathValidatorException
   2368     {
   2369         List certs = certPath.getCertificates();
   2370         X509Certificate cert = (X509Certificate)certs.get(index);
   2371         Iterator tmpIter;
   2372         tmpIter = pathCheckers.iterator();
   2373         while (tmpIter.hasNext())
   2374         {
   2375             try
   2376             {
   2377                 ((PKIXCertPathChecker)tmpIter.next()).check(cert, criticalExtensions);
   2378             }
   2379             catch (CertPathValidatorException e)
   2380             {
   2381                 throw new ExtCertPathValidatorException("Additional certificate path checker failed.", e, certPath,
   2382                     index);
   2383             }
   2384         }
   2385 
   2386         if (!criticalExtensions.isEmpty())
   2387         {
   2388             throw new ExtCertPathValidatorException("Certificate has unsupported critical extension", null, certPath,
   2389                 index);
   2390         }
   2391     }
   2392 
   2393     protected static PKIXPolicyNode wrapupCertG(
   2394         CertPath certPath,
   2395         ExtendedPKIXParameters paramsPKIX,
   2396         Set userInitialPolicySet,
   2397         int index,
   2398         List[] policyNodes,
   2399         PKIXPolicyNode validPolicyTree,
   2400         Set acceptablePolicies)
   2401         throws CertPathValidatorException
   2402     {
   2403         int n = certPath.getCertificates().size();
   2404         //
   2405         // (g)
   2406         //
   2407         PKIXPolicyNode intersection;
   2408 
   2409         //
   2410         // (g) (i)
   2411         //
   2412         if (validPolicyTree == null)
   2413         {
   2414             if (paramsPKIX.isExplicitPolicyRequired())
   2415             {
   2416                 throw new ExtCertPathValidatorException("Explicit policy requested but none available.", null,
   2417                     certPath, index);
   2418             }
   2419             intersection = null;
   2420         }
   2421         else if (CertPathValidatorUtilities.isAnyPolicy(userInitialPolicySet)) // (g)
   2422         // (ii)
   2423         {
   2424             if (paramsPKIX.isExplicitPolicyRequired())
   2425             {
   2426                 if (acceptablePolicies.isEmpty())
   2427                 {
   2428                     throw new ExtCertPathValidatorException("Explicit policy requested but none available.", null,
   2429                         certPath, index);
   2430                 }
   2431                 else
   2432                 {
   2433                     Set _validPolicyNodeSet = new HashSet();
   2434 
   2435                     for (int j = 0; j < policyNodes.length; j++)
   2436                     {
   2437                         List _nodeDepth = policyNodes[j];
   2438 
   2439                         for (int k = 0; k < _nodeDepth.size(); k++)
   2440                         {
   2441                             PKIXPolicyNode _node = (PKIXPolicyNode)_nodeDepth.get(k);
   2442 
   2443                             if (RFC3280CertPathUtilities.ANY_POLICY.equals(_node.getValidPolicy()))
   2444                             {
   2445                                 Iterator _iter = _node.getChildren();
   2446                                 while (_iter.hasNext())
   2447                                 {
   2448                                     _validPolicyNodeSet.add(_iter.next());
   2449                                 }
   2450                             }
   2451                         }
   2452                     }
   2453 
   2454                     Iterator _vpnsIter = _validPolicyNodeSet.iterator();
   2455                     while (_vpnsIter.hasNext())
   2456                     {
   2457                         PKIXPolicyNode _node = (PKIXPolicyNode)_vpnsIter.next();
   2458                         String _validPolicy = _node.getValidPolicy();
   2459 
   2460                         if (!acceptablePolicies.contains(_validPolicy))
   2461                         {
   2462                             // validPolicyTree =
   2463                             // removePolicyNode(validPolicyTree, policyNodes,
   2464                             // _node);
   2465                         }
   2466                     }
   2467                     if (validPolicyTree != null)
   2468                     {
   2469                         for (int j = (n - 1); j >= 0; j--)
   2470                         {
   2471                             List nodes = policyNodes[j];
   2472 
   2473                             for (int k = 0; k < nodes.size(); k++)
   2474                             {
   2475                                 PKIXPolicyNode node = (PKIXPolicyNode)nodes.get(k);
   2476                                 if (!node.hasChildren())
   2477                                 {
   2478                                     validPolicyTree = CertPathValidatorUtilities.removePolicyNode(validPolicyTree,
   2479                                         policyNodes, node);
   2480                                 }
   2481                             }
   2482                         }
   2483                     }
   2484                 }
   2485             }
   2486 
   2487             intersection = validPolicyTree;
   2488         }
   2489         else
   2490         {
   2491             //
   2492             // (g) (iii)
   2493             //
   2494             // This implementation is not exactly same as the one described in
   2495             // RFC3280.
   2496             // However, as far as the validation result is concerned, both
   2497             // produce
   2498             // adequate result. The only difference is whether AnyPolicy is
   2499             // remain
   2500             // in the policy tree or not.
   2501             //
   2502             // (g) (iii) 1
   2503             //
   2504             Set _validPolicyNodeSet = new HashSet();
   2505 
   2506             for (int j = 0; j < policyNodes.length; j++)
   2507             {
   2508                 List _nodeDepth = policyNodes[j];
   2509 
   2510                 for (int k = 0; k < _nodeDepth.size(); k++)
   2511                 {
   2512                     PKIXPolicyNode _node = (PKIXPolicyNode)_nodeDepth.get(k);
   2513 
   2514                     if (RFC3280CertPathUtilities.ANY_POLICY.equals(_node.getValidPolicy()))
   2515                     {
   2516                         Iterator _iter = _node.getChildren();
   2517                         while (_iter.hasNext())
   2518                         {
   2519                             PKIXPolicyNode _c_node = (PKIXPolicyNode)_iter.next();
   2520                             if (!RFC3280CertPathUtilities.ANY_POLICY.equals(_c_node.getValidPolicy()))
   2521                             {
   2522                                 _validPolicyNodeSet.add(_c_node);
   2523                             }
   2524                         }
   2525                     }
   2526                 }
   2527             }
   2528 
   2529             //
   2530             // (g) (iii) 2
   2531             //
   2532             Iterator _vpnsIter = _validPolicyNodeSet.iterator();
   2533             while (_vpnsIter.hasNext())
   2534             {
   2535                 PKIXPolicyNode _node = (PKIXPolicyNode)_vpnsIter.next();
   2536                 String _validPolicy = _node.getValidPolicy();
   2537 
   2538                 if (!userInitialPolicySet.contains(_validPolicy))
   2539                 {
   2540                     validPolicyTree = CertPathValidatorUtilities.removePolicyNode(validPolicyTree, policyNodes, _node);
   2541                 }
   2542             }
   2543 
   2544             //
   2545             // (g) (iii) 4
   2546             //
   2547             if (validPolicyTree != null)
   2548             {
   2549                 for (int j = (n - 1); j >= 0; j--)
   2550                 {
   2551                     List nodes = policyNodes[j];
   2552 
   2553                     for (int k = 0; k < nodes.size(); k++)
   2554                     {
   2555                         PKIXPolicyNode node = (PKIXPolicyNode)nodes.get(k);
   2556                         if (!node.hasChildren())
   2557                         {
   2558                             validPolicyTree = CertPathValidatorUtilities.removePolicyNode(validPolicyTree, policyNodes,
   2559                                 node);
   2560                         }
   2561                     }
   2562                 }
   2563             }
   2564 
   2565             intersection = validPolicyTree;
   2566         }
   2567         return intersection;
   2568     }
   2569 
   2570 }
   2571