Home | History | Annotate | Download | only in provider
      1 package org.bouncycastle.jce.provider;
      2 
      3 import java.io.ByteArrayOutputStream;
      4 import java.io.IOException;
      5 import java.math.BigInteger;
      6 import java.security.GeneralSecurityException;
      7 import java.security.KeyFactory;
      8 import java.security.PublicKey;
      9 import java.security.cert.CRLException;
     10 import java.security.cert.CertPath;
     11 import java.security.cert.CertPathValidatorException;
     12 import java.security.cert.CertStore;
     13 import java.security.cert.CertStoreException;
     14 import java.security.cert.Certificate;
     15 import java.security.cert.CertificateParsingException;
     16 import java.security.cert.PolicyQualifierInfo;
     17 import java.security.cert.TrustAnchor;
     18 import java.security.cert.X509CRL;
     19 import java.security.cert.X509CRLEntry;
     20 import java.security.cert.X509CRLSelector;
     21 import java.security.cert.X509CertSelector;
     22 import java.security.cert.X509Certificate;
     23 import java.security.interfaces.DSAParams;
     24 import java.security.interfaces.DSAPublicKey;
     25 import java.security.spec.DSAPublicKeySpec;
     26 import java.text.ParseException;
     27 import java.util.ArrayList;
     28 import java.util.Collection;
     29 import java.util.Collections;
     30 import java.util.Date;
     31 import java.util.Enumeration;
     32 import java.util.HashSet;
     33 import java.util.Iterator;
     34 import java.util.LinkedHashSet;
     35 import java.util.List;
     36 import java.util.Map;
     37 import java.util.Set;
     38 
     39 import javax.security.auth.x500.X500Principal;
     40 
     41 import org.bouncycastle.asn1.ASN1Encodable;
     42 import org.bouncycastle.asn1.ASN1Enumerated;
     43 import org.bouncycastle.asn1.ASN1GeneralizedTime;
     44 import org.bouncycastle.asn1.ASN1InputStream;
     45 import org.bouncycastle.asn1.ASN1Integer;
     46 import org.bouncycastle.asn1.ASN1ObjectIdentifier;
     47 import org.bouncycastle.asn1.ASN1OctetString;
     48 import org.bouncycastle.asn1.ASN1OutputStream;
     49 import org.bouncycastle.asn1.ASN1Primitive;
     50 import org.bouncycastle.asn1.ASN1Sequence;
     51 import org.bouncycastle.asn1.DEROctetString;
     52 import org.bouncycastle.asn1.DERSequence;
     53 import org.bouncycastle.asn1.isismtt.ISISMTTObjectIdentifiers;
     54 import org.bouncycastle.asn1.x500.X500Name;
     55 import org.bouncycastle.asn1.x500.style.RFC4519Style;
     56 import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
     57 import org.bouncycastle.asn1.x509.AuthorityKeyIdentifier;
     58 import org.bouncycastle.asn1.x509.CRLDistPoint;
     59 import org.bouncycastle.asn1.x509.CRLReason;
     60 import org.bouncycastle.asn1.x509.DistributionPoint;
     61 import org.bouncycastle.asn1.x509.DistributionPointName;
     62 import org.bouncycastle.asn1.x509.Extension;
     63 import org.bouncycastle.asn1.x509.GeneralName;
     64 import org.bouncycastle.asn1.x509.GeneralNames;
     65 import org.bouncycastle.asn1.x509.PolicyInformation;
     66 import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
     67 import org.bouncycastle.jcajce.PKIXCRLStore;
     68 import org.bouncycastle.jcajce.PKIXCRLStoreSelector;
     69 import org.bouncycastle.jcajce.PKIXCertStore;
     70 import org.bouncycastle.jcajce.PKIXCertStoreSelector;
     71 import org.bouncycastle.jcajce.PKIXExtendedParameters;
     72 import org.bouncycastle.jcajce.util.JcaJceHelper;
     73 import org.bouncycastle.jce.exception.ExtCertPathValidatorException;
     74 import org.bouncycastle.util.Selector;
     75 import org.bouncycastle.util.Store;
     76 import org.bouncycastle.util.StoreException;
     77 import org.bouncycastle.x509.X509AttributeCertificate;
     78 // BEGIN android-removed
     79 // import org.bouncycastle.x509.extension.X509ExtensionUtil;
     80 // END android-removed
     81 
     82 class CertPathValidatorUtilities
     83 {
     84     protected static final PKIXCRLUtil CRL_UTIL = new PKIXCRLUtil();
     85 
     86     protected static final String CERTIFICATE_POLICIES = Extension.certificatePolicies.getId();
     87     protected static final String BASIC_CONSTRAINTS = Extension.basicConstraints.getId();
     88     protected static final String POLICY_MAPPINGS = Extension.policyMappings.getId();
     89     protected static final String SUBJECT_ALTERNATIVE_NAME = Extension.subjectAlternativeName.getId();
     90     protected static final String NAME_CONSTRAINTS = Extension.nameConstraints.getId();
     91     protected static final String KEY_USAGE = Extension.keyUsage.getId();
     92     protected static final String INHIBIT_ANY_POLICY = Extension.inhibitAnyPolicy.getId();
     93     protected static final String ISSUING_DISTRIBUTION_POINT = Extension.issuingDistributionPoint.getId();
     94     protected static final String DELTA_CRL_INDICATOR = Extension.deltaCRLIndicator.getId();
     95     protected static final String POLICY_CONSTRAINTS = Extension.policyConstraints.getId();
     96     protected static final String FRESHEST_CRL = Extension.freshestCRL.getId();
     97     protected static final String CRL_DISTRIBUTION_POINTS = Extension.cRLDistributionPoints.getId();
     98     protected static final String AUTHORITY_KEY_IDENTIFIER = Extension.authorityKeyIdentifier.getId();
     99 
    100     protected static final String ANY_POLICY = "2.5.29.32.0";
    101 
    102     protected static final String CRL_NUMBER = Extension.cRLNumber.getId();
    103 
    104     /*
    105     * key usage bits
    106     */
    107     protected static final int KEY_CERT_SIGN = 5;
    108     protected static final int CRL_SIGN = 6;
    109 
    110     protected static final String[] crlReasons = new String[]{
    111         "unspecified",
    112         "keyCompromise",
    113         "cACompromise",
    114         "affiliationChanged",
    115         "superseded",
    116         "cessationOfOperation",
    117         "certificateHold",
    118         "unknown",
    119         "removeFromCRL",
    120         "privilegeWithdrawn",
    121         "aACompromise"};
    122 
    123     /**
    124      * Search the given Set of TrustAnchor's for one that is the
    125      * issuer of the given X509 certificate. Uses the default provider
    126      * for signature verification.
    127      *
    128      * @param cert         the X509 certificate
    129      * @param trustAnchors a Set of TrustAnchor's
    130      * @return the <code>TrustAnchor</code> object if found or
    131      *         <code>null</code> if not.
    132      * @throws AnnotatedException if a TrustAnchor was found but the signature verification
    133      * on the given certificate has thrown an exception.
    134      */
    135     protected static TrustAnchor findTrustAnchor(
    136         X509Certificate cert,
    137         Set trustAnchors)
    138         throws AnnotatedException
    139     {
    140         return findTrustAnchor(cert, trustAnchors, null);
    141     }
    142 
    143     /**
    144      * Search the given Set of TrustAnchor's for one that is the
    145      * issuer of the given X509 certificate. Uses the specified
    146      * provider for signature verification, or the default provider
    147      * if null.
    148      *
    149      * @param cert         the X509 certificate
    150      * @param trustAnchors a Set of TrustAnchor's
    151      * @param sigProvider  the provider to use for signature verification
    152      * @return the <code>TrustAnchor</code> object if found or
    153      *         <code>null</code> if not.
    154      * @throws AnnotatedException if a TrustAnchor was found but the signature verification
    155      * on the given certificate has thrown an exception.
    156      */
    157     protected static TrustAnchor findTrustAnchor(
    158         X509Certificate cert,
    159         Set trustAnchors,
    160         String sigProvider)
    161         throws AnnotatedException
    162     {
    163         TrustAnchor trust = null;
    164         PublicKey trustPublicKey = null;
    165         Exception invalidKeyEx = null;
    166 
    167         X509CertSelector certSelectX509 = new X509CertSelector();
    168         X500Name certIssuer = PrincipalUtils.getEncodedIssuerPrincipal(cert);
    169 
    170         try
    171         {
    172             certSelectX509.setSubject(certIssuer.getEncoded());
    173         }
    174         catch (IOException ex)
    175         {
    176             throw new AnnotatedException("Cannot set subject search criteria for trust anchor.", ex);
    177         }
    178 
    179         Iterator iter = trustAnchors.iterator();
    180         while (iter.hasNext() && trust == null)
    181         {
    182             trust = (TrustAnchor)iter.next();
    183             if (trust.getTrustedCert() != null)
    184             {
    185                 if (certSelectX509.match(trust.getTrustedCert()))
    186                 {
    187                     trustPublicKey = trust.getTrustedCert().getPublicKey();
    188                 }
    189                 else
    190                 {
    191                     trust = null;
    192                 }
    193             }
    194             else if (trust.getCAName() != null
    195                 && trust.getCAPublicKey() != null)
    196             {
    197                 try
    198                 {
    199                     X500Name caName = PrincipalUtils.getCA(trust);
    200                     if (certIssuer.equals(caName))
    201                     {
    202                         trustPublicKey = trust.getCAPublicKey();
    203                     }
    204                     else
    205                     {
    206                         trust = null;
    207                     }
    208                 }
    209                 catch (IllegalArgumentException ex)
    210                 {
    211                     trust = null;
    212                 }
    213             }
    214             else
    215             {
    216                 trust = null;
    217             }
    218 
    219             if (trustPublicKey != null)
    220             {
    221                 try
    222                 {
    223                     verifyX509Certificate(cert, trustPublicKey, sigProvider);
    224                 }
    225                 catch (Exception ex)
    226                 {
    227                     invalidKeyEx = ex;
    228                     trust = null;
    229                     trustPublicKey = null;
    230                 }
    231             }
    232         }
    233 
    234         if (trust == null && invalidKeyEx != null)
    235         {
    236             throw new AnnotatedException("TrustAnchor found but certificate validation failed.", invalidKeyEx);
    237         }
    238 
    239         return trust;
    240     }
    241 
    242     static List<PKIXCertStore> getAdditionalStoresFromAltNames(
    243         byte[] issuerAlternativeName,
    244         Map<GeneralName, PKIXCertStore> altNameCertStoreMap)
    245         throws CertificateParsingException
    246     {
    247         // if in the IssuerAltName extension an URI
    248         // is given, add an additional X.509 store
    249         if (issuerAlternativeName != null)
    250         {
    251             GeneralNames issuerAltName = GeneralNames.getInstance(ASN1OctetString.getInstance(issuerAlternativeName).getOctets());
    252 
    253             GeneralName[] names = issuerAltName.getNames();
    254             List<PKIXCertStore>  stores = new ArrayList<PKIXCertStore>();
    255 
    256             for (int i = 0; i != names.length; i++)
    257             {
    258                 GeneralName altName = names[i];
    259 
    260                 PKIXCertStore altStore = altNameCertStoreMap.get(altName);
    261 
    262                 if (altStore != null)
    263                 {
    264                     stores.add(altStore);
    265                 }
    266             }
    267 
    268             return stores;
    269         }
    270         else
    271         {
    272             return Collections.EMPTY_LIST;
    273         }
    274     }
    275 
    276     protected static Date getValidDate(PKIXExtendedParameters paramsPKIX)
    277     {
    278         Date validDate = paramsPKIX.getDate();
    279 
    280         if (validDate == null)
    281         {
    282             validDate = new Date();
    283         }
    284 
    285         return validDate;
    286     }
    287 
    288     protected static boolean isSelfIssued(X509Certificate cert)
    289     {
    290         return cert.getSubjectDN().equals(cert.getIssuerDN());
    291     }
    292 
    293 
    294     /**
    295      * Extract the value of the given extension, if it exists.
    296      *
    297      * @param ext The extension object.
    298      * @param oid The object identifier to obtain.
    299      * @throws AnnotatedException if the extension cannot be read.
    300      */
    301     protected static ASN1Primitive getExtensionValue(
    302         java.security.cert.X509Extension ext,
    303         String oid)
    304         throws AnnotatedException
    305     {
    306         byte[] bytes = ext.getExtensionValue(oid);
    307         if (bytes == null)
    308         {
    309             return null;
    310         }
    311 
    312         return getObject(oid, bytes);
    313     }
    314 
    315     private static ASN1Primitive getObject(
    316         String oid,
    317         byte[] ext)
    318         throws AnnotatedException
    319     {
    320         try
    321         {
    322             ASN1InputStream aIn = new ASN1InputStream(ext);
    323             ASN1OctetString octs = (ASN1OctetString)aIn.readObject();
    324 
    325             aIn = new ASN1InputStream(octs.getOctets());
    326             return aIn.readObject();
    327         }
    328         catch (Exception e)
    329         {
    330             throw new AnnotatedException("exception processing extension " + oid, e);
    331         }
    332     }
    333 
    334     protected static AlgorithmIdentifier getAlgorithmIdentifier(
    335         PublicKey key)
    336         throws CertPathValidatorException
    337     {
    338         try
    339         {
    340             ASN1InputStream aIn = new ASN1InputStream(key.getEncoded());
    341 
    342             SubjectPublicKeyInfo info = SubjectPublicKeyInfo.getInstance(aIn.readObject());
    343 
    344             return info.getAlgorithm();
    345         }
    346         catch (Exception e)
    347         {
    348             throw new ExtCertPathValidatorException("Subject public key cannot be decoded.", e);
    349         }
    350     }
    351 
    352     // crl checking
    353 
    354 
    355     //
    356     // policy checking
    357     //
    358 
    359     protected static final Set getQualifierSet(ASN1Sequence qualifiers)
    360         throws CertPathValidatorException
    361     {
    362         Set pq = new HashSet();
    363 
    364         if (qualifiers == null)
    365         {
    366             return pq;
    367         }
    368 
    369         ByteArrayOutputStream bOut = new ByteArrayOutputStream();
    370         ASN1OutputStream aOut = new ASN1OutputStream(bOut);
    371 
    372         Enumeration e = qualifiers.getObjects();
    373 
    374         while (e.hasMoreElements())
    375         {
    376             try
    377             {
    378                 aOut.writeObject((ASN1Encodable)e.nextElement());
    379 
    380                 pq.add(new PolicyQualifierInfo(bOut.toByteArray()));
    381             }
    382             catch (IOException ex)
    383             {
    384                 throw new ExtCertPathValidatorException("Policy qualifier info cannot be decoded.", ex);
    385             }
    386 
    387             bOut.reset();
    388         }
    389 
    390         return pq;
    391     }
    392 
    393     protected static PKIXPolicyNode removePolicyNode(
    394         PKIXPolicyNode validPolicyTree,
    395         List[] policyNodes,
    396         PKIXPolicyNode _node)
    397     {
    398         PKIXPolicyNode _parent = (PKIXPolicyNode)_node.getParent();
    399 
    400         if (validPolicyTree == null)
    401         {
    402             return null;
    403         }
    404 
    405         if (_parent == null)
    406         {
    407             for (int j = 0; j < policyNodes.length; j++)
    408             {
    409                 policyNodes[j] = new ArrayList();
    410             }
    411 
    412             return null;
    413         }
    414         else
    415         {
    416             _parent.removeChild(_node);
    417             removePolicyNodeRecurse(policyNodes, _node);
    418 
    419             return validPolicyTree;
    420         }
    421     }
    422 
    423     private static void removePolicyNodeRecurse(
    424         List[] policyNodes,
    425         PKIXPolicyNode _node)
    426     {
    427         policyNodes[_node.getDepth()].remove(_node);
    428 
    429         if (_node.hasChildren())
    430         {
    431             Iterator _iter = _node.getChildren();
    432             while (_iter.hasNext())
    433             {
    434                 PKIXPolicyNode _child = (PKIXPolicyNode)_iter.next();
    435                 removePolicyNodeRecurse(policyNodes, _child);
    436             }
    437         }
    438     }
    439 
    440 
    441     protected static boolean processCertD1i(
    442         int index,
    443         List[] policyNodes,
    444         ASN1ObjectIdentifier pOid,
    445         Set pq)
    446     {
    447         List policyNodeVec = policyNodes[index - 1];
    448 
    449         for (int j = 0; j < policyNodeVec.size(); j++)
    450         {
    451             PKIXPolicyNode node = (PKIXPolicyNode)policyNodeVec.get(j);
    452             Set expectedPolicies = node.getExpectedPolicies();
    453 
    454             if (expectedPolicies.contains(pOid.getId()))
    455             {
    456                 Set childExpectedPolicies = new HashSet();
    457                 childExpectedPolicies.add(pOid.getId());
    458 
    459                 PKIXPolicyNode child = new PKIXPolicyNode(new ArrayList(),
    460                     index,
    461                     childExpectedPolicies,
    462                     node,
    463                     pq,
    464                     pOid.getId(),
    465                     false);
    466                 node.addChild(child);
    467                 policyNodes[index].add(child);
    468 
    469                 return true;
    470             }
    471         }
    472 
    473         return false;
    474     }
    475 
    476     protected static void processCertD1ii(
    477         int index,
    478         List[] policyNodes,
    479         ASN1ObjectIdentifier _poid,
    480         Set _pq)
    481     {
    482         List policyNodeVec = policyNodes[index - 1];
    483 
    484         for (int j = 0; j < policyNodeVec.size(); j++)
    485         {
    486             PKIXPolicyNode _node = (PKIXPolicyNode)policyNodeVec.get(j);
    487 
    488             if (ANY_POLICY.equals(_node.getValidPolicy()))
    489             {
    490                 Set _childExpectedPolicies = new HashSet();
    491                 _childExpectedPolicies.add(_poid.getId());
    492 
    493                 PKIXPolicyNode _child = new PKIXPolicyNode(new ArrayList(),
    494                     index,
    495                     _childExpectedPolicies,
    496                     _node,
    497                     _pq,
    498                     _poid.getId(),
    499                     false);
    500                 _node.addChild(_child);
    501                 policyNodes[index].add(_child);
    502                 return;
    503             }
    504         }
    505     }
    506 
    507     protected static void prepareNextCertB1(
    508         int i,
    509         List[] policyNodes,
    510         String id_p,
    511         Map m_idp,
    512         X509Certificate cert
    513     )
    514         throws AnnotatedException, CertPathValidatorException
    515     {
    516         boolean idp_found = false;
    517         Iterator nodes_i = policyNodes[i].iterator();
    518         while (nodes_i.hasNext())
    519         {
    520             PKIXPolicyNode node = (PKIXPolicyNode)nodes_i.next();
    521             if (node.getValidPolicy().equals(id_p))
    522             {
    523                 idp_found = true;
    524                 node.expectedPolicies = (Set)m_idp.get(id_p);
    525                 break;
    526             }
    527         }
    528 
    529         if (!idp_found)
    530         {
    531             nodes_i = policyNodes[i].iterator();
    532             while (nodes_i.hasNext())
    533             {
    534                 PKIXPolicyNode node = (PKIXPolicyNode)nodes_i.next();
    535                 if (ANY_POLICY.equals(node.getValidPolicy()))
    536                 {
    537                     Set pq = null;
    538                     ASN1Sequence policies = null;
    539                     try
    540                     {
    541                         policies = DERSequence.getInstance(getExtensionValue(cert, CERTIFICATE_POLICIES));
    542                     }
    543                     catch (Exception e)
    544                     {
    545                         throw new AnnotatedException("Certificate policies cannot be decoded.", e);
    546                     }
    547                     Enumeration e = policies.getObjects();
    548                     while (e.hasMoreElements())
    549                     {
    550                         PolicyInformation pinfo = null;
    551 
    552                         try
    553                         {
    554                             pinfo = PolicyInformation.getInstance(e.nextElement());
    555                         }
    556                         catch (Exception ex)
    557                         {
    558                             throw new AnnotatedException("Policy information cannot be decoded.", ex);
    559                         }
    560                         if (ANY_POLICY.equals(pinfo.getPolicyIdentifier().getId()))
    561                         {
    562                             try
    563                             {
    564                                 pq = getQualifierSet(pinfo.getPolicyQualifiers());
    565                             }
    566                             catch (CertPathValidatorException ex)
    567                             {
    568                                 throw new ExtCertPathValidatorException(
    569                                     "Policy qualifier info set could not be built.", ex);
    570                             }
    571                             break;
    572                         }
    573                     }
    574                     boolean ci = false;
    575                     if (cert.getCriticalExtensionOIDs() != null)
    576                     {
    577                         ci = cert.getCriticalExtensionOIDs().contains(CERTIFICATE_POLICIES);
    578                     }
    579 
    580                     PKIXPolicyNode p_node = (PKIXPolicyNode)node.getParent();
    581                     if (ANY_POLICY.equals(p_node.getValidPolicy()))
    582                     {
    583                         PKIXPolicyNode c_node = new PKIXPolicyNode(
    584                             new ArrayList(), i,
    585                             (Set)m_idp.get(id_p),
    586                             p_node, pq, id_p, ci);
    587                         p_node.addChild(c_node);
    588                         policyNodes[i].add(c_node);
    589                     }
    590                     break;
    591                 }
    592             }
    593         }
    594     }
    595 
    596     protected static PKIXPolicyNode prepareNextCertB2(
    597         int i,
    598         List[] policyNodes,
    599         String id_p,
    600         PKIXPolicyNode validPolicyTree)
    601     {
    602         Iterator nodes_i = policyNodes[i].iterator();
    603         while (nodes_i.hasNext())
    604         {
    605             PKIXPolicyNode node = (PKIXPolicyNode)nodes_i.next();
    606             if (node.getValidPolicy().equals(id_p))
    607             {
    608                 PKIXPolicyNode p_node = (PKIXPolicyNode)node.getParent();
    609                 p_node.removeChild(node);
    610                 nodes_i.remove();
    611                 for (int k = (i - 1); k >= 0; k--)
    612                 {
    613                     List nodes = policyNodes[k];
    614                     for (int l = 0; l < nodes.size(); l++)
    615                     {
    616                         PKIXPolicyNode node2 = (PKIXPolicyNode)nodes.get(l);
    617                         if (!node2.hasChildren())
    618                         {
    619                             validPolicyTree = removePolicyNode(validPolicyTree, policyNodes, node2);
    620                             if (validPolicyTree == null)
    621                             {
    622                                 break;
    623                             }
    624                         }
    625                     }
    626                 }
    627             }
    628         }
    629         return validPolicyTree;
    630     }
    631 
    632     protected static boolean isAnyPolicy(
    633         Set policySet)
    634     {
    635         return policySet == null || policySet.contains(ANY_POLICY) || policySet.isEmpty();
    636     }
    637 
    638     /**
    639      * Return a Collection of all certificates or attribute certificates found
    640      * in the X509Store's that are matching the certSelect criteriums.
    641      *
    642      * @param certSelect a {@link Selector} object that will be used to select
    643      *                   the certificates
    644      * @param certStores a List containing only {@link Store} objects. These
    645      *                   are used to search for certificates.
    646      * @return a Collection of all found {@link X509Certificate}
    647      *         May be empty but never <code>null</code>.
    648      */
    649     protected static Collection findCertificates(PKIXCertStoreSelector certSelect,
    650                                                  List certStores)
    651         throws AnnotatedException
    652     {
    653         Set certs = new LinkedHashSet();
    654         Iterator iter = certStores.iterator();
    655 
    656         while (iter.hasNext())
    657         {
    658             Object obj = iter.next();
    659 
    660             // BEGIN android-removed
    661             // if (obj instanceof X509Store)
    662             // {
    663             //     X509Store certStore = (X509Store)obj;
    664             //     try
    665             //     {
    666             //         certs.addAll(certStore.getMatches(certSelect));
    667             //     }
    668             //     catch (StoreException e)
    669             //     {
    670             //         throw new AnnotatedException(
    671             //                 "Problem while picking certificates from X.509 store.", e);
    672             //     }
    673             // }
    674             // else
    675             // END android-removed
    676             {
    677                 CertStore certStore = (CertStore)obj;
    678 
    679                 try
    680                 {
    681                     certs.addAll(PKIXCertStoreSelector.getCertificates(certSelect, certStore));
    682                 }
    683                 catch (CertStoreException e)
    684                 {
    685                     throw new AnnotatedException(
    686                         "Problem while picking certificates from certificate store.",
    687                         e);
    688                 }
    689             }
    690         }
    691         return certs;
    692     }
    693 
    694     static List<PKIXCRLStore> getAdditionalStoresFromCRLDistributionPoint(CRLDistPoint crldp, Map<GeneralName, PKIXCRLStore> namedCRLStoreMap)
    695         throws AnnotatedException
    696     {
    697         if (crldp != null)
    698         {
    699             DistributionPoint dps[] = null;
    700             try
    701             {
    702                 dps = crldp.getDistributionPoints();
    703             }
    704             catch (Exception e)
    705             {
    706                 throw new AnnotatedException(
    707                     "Distribution points could not be read.", e);
    708             }
    709             List<PKIXCRLStore> stores = new ArrayList<PKIXCRLStore>();
    710 
    711             for (int i = 0; i < dps.length; i++)
    712             {
    713                 DistributionPointName dpn = dps[i].getDistributionPoint();
    714                 // look for URIs in fullName
    715                 if (dpn != null)
    716                 {
    717                     if (dpn.getType() == DistributionPointName.FULL_NAME)
    718                     {
    719                         GeneralName[] genNames = GeneralNames.getInstance(
    720                             dpn.getName()).getNames();
    721 
    722                         for (int j = 0; j < genNames.length; j++)
    723                         {
    724                             PKIXCRLStore store = namedCRLStoreMap.get(genNames[j]);
    725                             if (store != null)
    726                             {
    727                                 stores.add(store);
    728                             }
    729                         }
    730                     }
    731                 }
    732             }
    733 
    734             return stores;
    735         }
    736         else
    737         {
    738             return Collections.EMPTY_LIST;
    739         }
    740     }
    741 
    742     /**
    743      * Add the CRL issuers from the cRLIssuer field of the distribution point or
    744      * from the certificate if not given to the issuer criterion of the
    745      * <code>selector</code>.
    746      * <p>
    747      * The <code>issuerPrincipals</code> are a collection with a single
    748      * <code>X500Name</code> for <code>X509Certificate</code>s.
    749      * </p>
    750      * @param dp               The distribution point.
    751      * @param issuerPrincipals The issuers of the certificate or attribute
    752      *                         certificate which contains the distribution point.
    753      * @param selector         The CRL selector.
    754      * @throws AnnotatedException if an exception occurs while processing.
    755      * @throws ClassCastException if <code>issuerPrincipals</code> does not
    756      * contain only <code>X500Name</code>s.
    757      */
    758     protected static void getCRLIssuersFromDistributionPoint(
    759         DistributionPoint dp,
    760         Collection issuerPrincipals,
    761         X509CRLSelector selector)
    762         throws AnnotatedException
    763     {
    764         List issuers = new ArrayList();
    765         // indirect CRL
    766         if (dp.getCRLIssuer() != null)
    767         {
    768             GeneralName genNames[] = dp.getCRLIssuer().getNames();
    769             // look for a DN
    770             for (int j = 0; j < genNames.length; j++)
    771             {
    772                 if (genNames[j].getTagNo() == GeneralName.directoryName)
    773                 {
    774                     try
    775                     {
    776                         issuers.add(X500Name.getInstance(genNames[j].getName()
    777                             .toASN1Primitive().getEncoded()));
    778                     }
    779                     catch (IOException e)
    780                     {
    781                         throw new AnnotatedException(
    782                             "CRL issuer information from distribution point cannot be decoded.",
    783                             e);
    784                     }
    785                 }
    786             }
    787         }
    788         else
    789         {
    790             /*
    791              * certificate issuer is CRL issuer, distributionPoint field MUST be
    792              * present.
    793              */
    794             if (dp.getDistributionPoint() == null)
    795             {
    796                 throw new AnnotatedException(
    797                     "CRL issuer is omitted from distribution point but no distributionPoint field present.");
    798             }
    799             // add and check issuer principals
    800             for (Iterator it = issuerPrincipals.iterator(); it.hasNext(); )
    801             {
    802                 issuers.add(it.next());
    803             }
    804         }
    805         // TODO: is not found although this should correctly add the rel name. selector of Sun is buggy here or PKI test case is invalid
    806         // distributionPoint
    807 //        if (dp.getDistributionPoint() != null)
    808 //        {
    809 //            // look for nameRelativeToCRLIssuer
    810 //            if (dp.getDistributionPoint().getType() == DistributionPointName.NAME_RELATIVE_TO_CRL_ISSUER)
    811 //            {
    812 //                // append fragment to issuer, only one
    813 //                // issuer can be there, if this is given
    814 //                if (issuers.size() != 1)
    815 //                {
    816 //                    throw new AnnotatedException(
    817 //                        "nameRelativeToCRLIssuer field is given but more than one CRL issuer is given.");
    818 //                }
    819 //                ASN1Encodable relName = dp.getDistributionPoint().getName();
    820 //                Iterator it = issuers.iterator();
    821 //                List issuersTemp = new ArrayList(issuers.size());
    822 //                while (it.hasNext())
    823 //                {
    824 //                    Enumeration e = null;
    825 //                    try
    826 //                    {
    827 //                        e = ASN1Sequence.getInstance(
    828 //                            new ASN1InputStream(((X500Principal) it.next())
    829 //                                .getEncoded()).readObject()).getObjects();
    830 //                    }
    831 //                    catch (IOException ex)
    832 //                    {
    833 //                        throw new AnnotatedException(
    834 //                            "Cannot decode CRL issuer information.", ex);
    835 //                    }
    836 //                    ASN1EncodableVector v = new ASN1EncodableVector();
    837 //                    while (e.hasMoreElements())
    838 //                    {
    839 //                        v.add((ASN1Encodable) e.nextElement());
    840 //                    }
    841 //                    v.add(relName);
    842 //                    issuersTemp.add(new X500Principal(new DERSequence(v)
    843 //                        .getDEREncoded()));
    844 //                }
    845 //                issuers.clear();
    846 //                issuers.addAll(issuersTemp);
    847 //            }
    848 //        }
    849         Iterator it = issuers.iterator();
    850         while (it.hasNext())
    851         {
    852             try
    853             {
    854                 selector.addIssuerName(((X500Name)it.next()).getEncoded());
    855             }
    856             catch (IOException ex)
    857             {
    858                 throw new AnnotatedException(
    859                     "Cannot decode CRL issuer information.", ex);
    860             }
    861         }
    862     }
    863 
    864     private static BigInteger getSerialNumber(
    865         Object cert)
    866     {
    867         return ((X509Certificate)cert).getSerialNumber();
    868     }
    869 
    870     protected static void getCertStatus(
    871         Date validDate,
    872         X509CRL crl,
    873         Object cert,
    874         CertStatus certStatus)
    875         throws AnnotatedException
    876     {
    877         X509CRLEntry crl_entry = null;
    878 
    879         boolean isIndirect;
    880         try
    881         {
    882             isIndirect = X509CRLObject.isIndirectCRL(crl);
    883         }
    884         catch (CRLException exception)
    885         {
    886             throw new AnnotatedException("Failed check for indirect CRL.", exception);
    887         }
    888 
    889         if (isIndirect)
    890         {
    891             crl_entry = crl.getRevokedCertificate(getSerialNumber(cert));
    892 
    893             if (crl_entry == null)
    894             {
    895                 return;
    896             }
    897             X500Principal certificateIssuer = crl_entry.getCertificateIssuer();
    898             X500Name certIssuer;
    899             if (certificateIssuer == null)
    900             {
    901                 certIssuer = PrincipalUtils.getIssuerPrincipal(crl);
    902             }
    903             else
    904             {
    905                 certIssuer = X500Name.getInstance(certificateIssuer.getEncoded());
    906             }
    907 
    908             if (! PrincipalUtils.getEncodedIssuerPrincipal(cert).equals(certIssuer))
    909             {
    910                 return;
    911             }
    912         }
    913         else if (! PrincipalUtils.getEncodedIssuerPrincipal(cert).equals(PrincipalUtils.getIssuerPrincipal(crl)))
    914         {
    915             return;  // not for our issuer, ignore
    916         }
    917         else
    918         {
    919             crl_entry = crl.getRevokedCertificate(getSerialNumber(cert));
    920 
    921             if (crl_entry == null)
    922             {
    923                 return;
    924             }
    925         }
    926 
    927         ASN1Enumerated reasonCode = null;
    928         if (crl_entry.hasExtensions())
    929         {
    930             try
    931             {
    932                 reasonCode = ASN1Enumerated
    933                     .getInstance(CertPathValidatorUtilities
    934                         .getExtensionValue(crl_entry,
    935                             Extension.reasonCode.getId()));
    936             }
    937             catch (Exception e)
    938             {
    939                 throw new AnnotatedException(
    940                     "Reason code CRL entry extension could not be decoded.",
    941                     e);
    942             }
    943         }
    944 
    945         // for reason keyCompromise, caCompromise, aACompromise or
    946         // unspecified
    947         if (!(validDate.getTime() < crl_entry.getRevocationDate().getTime())
    948             || reasonCode == null
    949             || reasonCode.getValue().intValue() == 0
    950             || reasonCode.getValue().intValue() == 1
    951             || reasonCode.getValue().intValue() == 2
    952             || reasonCode.getValue().intValue() == 8)
    953         {
    954 
    955             // (i) or (j) (1)
    956             if (reasonCode != null)
    957             {
    958                 certStatus.setCertStatus(reasonCode.getValue().intValue());
    959             }
    960             // (i) or (j) (2)
    961             else
    962             {
    963                 certStatus.setCertStatus(CRLReason.unspecified);
    964             }
    965             certStatus.setRevocationDate(crl_entry.getRevocationDate());
    966         }
    967     }
    968 
    969     /**
    970      * Fetches delta CRLs according to RFC 3280 section 5.2.4.
    971      *
    972      * @param validityDate The date for which the delta CRLs must be valid.
    973      * @param completeCRL The complete CRL the delta CRL is for.
    974      * @return A <code>Set</code> of <code>X509CRL</code>s with delta CRLs.
    975      * @throws AnnotatedException if an exception occurs while picking the delta
    976      * CRLs.
    977      */
    978     protected static Set getDeltaCRLs(Date validityDate,
    979                                       X509CRL completeCRL, List<CertStore> certStores, List<PKIXCRLStore> pkixCrlStores)
    980         throws AnnotatedException
    981     {
    982         X509CRLSelector baseDeltaSelect = new X509CRLSelector();
    983         // 5.2.4 (a)
    984         try
    985         {
    986             baseDeltaSelect.addIssuerName(PrincipalUtils.getIssuerPrincipal(completeCRL).getEncoded());
    987         }
    988         catch (IOException e)
    989         {
    990             throw new AnnotatedException("Cannot extract issuer from CRL.", e);
    991         }
    992 
    993 
    994 
    995         BigInteger completeCRLNumber = null;
    996         try
    997         {
    998             ASN1Primitive derObject = CertPathValidatorUtilities.getExtensionValue(completeCRL,
    999                 CRL_NUMBER);
   1000             if (derObject != null)
   1001             {
   1002                 completeCRLNumber = ASN1Integer.getInstance(derObject).getPositiveValue();
   1003             }
   1004         }
   1005         catch (Exception e)
   1006         {
   1007             throw new AnnotatedException(
   1008                 "CRL number extension could not be extracted from CRL.", e);
   1009         }
   1010 
   1011         // 5.2.4 (b)
   1012         byte[] idp = null;
   1013         try
   1014         {
   1015             idp = completeCRL.getExtensionValue(ISSUING_DISTRIBUTION_POINT);
   1016         }
   1017         catch (Exception e)
   1018         {
   1019             throw new AnnotatedException(
   1020                 "Issuing distribution point extension value could not be read.",
   1021                 e);
   1022         }
   1023 
   1024         // 5.2.4 (d)
   1025 
   1026         baseDeltaSelect.setMinCRLNumber(completeCRLNumber == null ? null : completeCRLNumber
   1027             .add(BigInteger.valueOf(1)));
   1028 
   1029         PKIXCRLStoreSelector.Builder selBuilder = new PKIXCRLStoreSelector.Builder(baseDeltaSelect);
   1030 
   1031         selBuilder.setIssuingDistributionPoint(idp);
   1032         selBuilder.setIssuingDistributionPointEnabled(true);
   1033 
   1034         // 5.2.4 (c)
   1035         selBuilder.setMaxBaseCRLNumber(completeCRLNumber);
   1036 
   1037         PKIXCRLStoreSelector deltaSelect = selBuilder.build();
   1038 
   1039         // find delta CRLs
   1040         Set temp = CRL_UTIL.findCRLs(deltaSelect, validityDate, certStores, pkixCrlStores);
   1041 
   1042         Set result = new HashSet();
   1043 
   1044         for (Iterator it = temp.iterator(); it.hasNext(); )
   1045         {
   1046             X509CRL crl = (X509CRL)it.next();
   1047 
   1048             if (isDeltaCRL(crl))
   1049             {
   1050                 result.add(crl);
   1051             }
   1052         }
   1053 
   1054         return result;
   1055     }
   1056 
   1057     private static boolean isDeltaCRL(X509CRL crl)
   1058     {
   1059         Set critical = crl.getCriticalExtensionOIDs();
   1060 
   1061         if (critical == null)
   1062         {
   1063             return false;
   1064         }
   1065 
   1066         return critical.contains(RFC3280CertPathUtilities.DELTA_CRL_INDICATOR);
   1067     }
   1068 
   1069     /**
   1070      * Fetches complete CRLs according to RFC 3280.
   1071      *
   1072      * @param dp          The distribution point for which the complete CRL
   1073      * @param cert        The <code>X509Certificate</code> for
   1074      *                    which the CRL should be searched.
   1075      * @param currentDate The date for which the delta CRLs must be valid.
   1076      * @param paramsPKIX  The extended PKIX parameters.
   1077      * @return A <code>Set</code> of <code>X509CRL</code>s with complete
   1078      *         CRLs.
   1079      * @throws AnnotatedException if an exception occurs while picking the CRLs
   1080      * or no CRLs are found.
   1081      */
   1082     protected static Set getCompleteCRLs(DistributionPoint dp, Object cert,
   1083                                          Date currentDate, PKIXExtendedParameters paramsPKIX)
   1084         throws AnnotatedException
   1085     {
   1086         X509CRLSelector baseCrlSelect = new X509CRLSelector();
   1087 
   1088         try
   1089         {
   1090             Set issuers = new HashSet();
   1091 
   1092             issuers.add(PrincipalUtils.getEncodedIssuerPrincipal(cert));
   1093 
   1094             CertPathValidatorUtilities.getCRLIssuersFromDistributionPoint(dp, issuers, baseCrlSelect);
   1095         }
   1096         catch (AnnotatedException e)
   1097         {
   1098             throw new AnnotatedException(
   1099                 "Could not get issuer information from distribution point.", e);
   1100         }
   1101 
   1102         if (cert instanceof X509Certificate)
   1103         {
   1104             baseCrlSelect.setCertificateChecking((X509Certificate)cert);
   1105         }
   1106 
   1107         PKIXCRLStoreSelector crlSelect = new PKIXCRLStoreSelector.Builder(baseCrlSelect).setCompleteCRLEnabled(true).build();
   1108 
   1109         Date validityDate = currentDate;
   1110 
   1111         if (paramsPKIX.getDate() != null)
   1112         {
   1113             validityDate = paramsPKIX.getDate();
   1114         }
   1115 
   1116         Set crls = CRL_UTIL.findCRLs(crlSelect, validityDate, paramsPKIX.getCertStores(), paramsPKIX.getCRLStores());
   1117 
   1118         checkCRLsNotEmpty(crls, cert);
   1119 
   1120         return crls;
   1121     }
   1122 
   1123     protected static Date getValidCertDateFromValidityModel(
   1124         PKIXExtendedParameters paramsPKIX, CertPath certPath, int index)
   1125         throws AnnotatedException
   1126     {
   1127         if (paramsPKIX.getValidityModel() == PKIXExtendedParameters.CHAIN_VALIDITY_MODEL)
   1128         {
   1129             // if end cert use given signing/encryption/... time
   1130             if (index <= 0)
   1131             {
   1132                 return CertPathValidatorUtilities.getValidDate(paramsPKIX);
   1133                 // else use time when previous cert was created
   1134             }
   1135             else
   1136             {
   1137                 if (index - 1 == 0)
   1138                 {
   1139                     ASN1GeneralizedTime dateOfCertgen = null;
   1140                     try
   1141                     {
   1142                         byte[] extBytes = ((X509Certificate)certPath.getCertificates().get(index - 1)).getExtensionValue(ISISMTTObjectIdentifiers.id_isismtt_at_dateOfCertGen.getId());
   1143                         if (extBytes != null)
   1144                         {
   1145                             dateOfCertgen = ASN1GeneralizedTime.getInstance(ASN1Primitive.fromByteArray(extBytes));
   1146                         }
   1147                     }
   1148                     catch (IOException e)
   1149                     {
   1150                         throw new AnnotatedException(
   1151                             "Date of cert gen extension could not be read.");
   1152                     }
   1153                     catch (IllegalArgumentException e)
   1154                     {
   1155                         throw new AnnotatedException(
   1156                             "Date of cert gen extension could not be read.");
   1157                     }
   1158                     if (dateOfCertgen != null)
   1159                     {
   1160                         try
   1161                         {
   1162                             return dateOfCertgen.getDate();
   1163                         }
   1164                         catch (ParseException e)
   1165                         {
   1166                             throw new AnnotatedException(
   1167                                 "Date from date of cert gen extension could not be parsed.",
   1168                                 e);
   1169                         }
   1170                     }
   1171                     return ((X509Certificate)certPath.getCertificates().get(
   1172                         index - 1)).getNotBefore();
   1173                 }
   1174                 else
   1175                 {
   1176                     return ((X509Certificate)certPath.getCertificates().get(
   1177                         index - 1)).getNotBefore();
   1178                 }
   1179             }
   1180         }
   1181         else
   1182         {
   1183             return getValidDate(paramsPKIX);
   1184         }
   1185     }
   1186 
   1187     /**
   1188      * Return the next working key inheriting DSA parameters if necessary.
   1189      * <p>
   1190      * This methods inherits DSA parameters from the indexed certificate or
   1191      * previous certificates in the certificate chain to the returned
   1192      * <code>PublicKey</code>. The list is searched upwards, meaning the end
   1193      * certificate is at position 0 and previous certificates are following.
   1194      * </p>
   1195      * <p>
   1196      * If the indexed certificate does not contain a DSA key this method simply
   1197      * returns the public key. If the DSA key already contains DSA parameters
   1198      * the key is also only returned.
   1199      * </p>
   1200      *
   1201      * @param certs The certification path.
   1202      * @param index The index of the certificate which contains the public key
   1203      *              which should be extended with DSA parameters.
   1204      * @return The public key of the certificate in list position
   1205      *         <code>index</code> extended with DSA parameters if applicable.
   1206      * @throws AnnotatedException if DSA parameters cannot be inherited.
   1207      */
   1208     protected static PublicKey getNextWorkingKey(List certs, int index, JcaJceHelper helper)
   1209         throws CertPathValidatorException
   1210     {
   1211         Certificate cert = (Certificate)certs.get(index);
   1212         PublicKey pubKey = cert.getPublicKey();
   1213         if (!(pubKey instanceof DSAPublicKey))
   1214         {
   1215             return pubKey;
   1216         }
   1217         DSAPublicKey dsaPubKey = (DSAPublicKey)pubKey;
   1218         if (dsaPubKey.getParams() != null)
   1219         {
   1220             return dsaPubKey;
   1221         }
   1222         for (int i = index + 1; i < certs.size(); i++)
   1223         {
   1224             X509Certificate parentCert = (X509Certificate)certs.get(i);
   1225             pubKey = parentCert.getPublicKey();
   1226             if (!(pubKey instanceof DSAPublicKey))
   1227             {
   1228                 throw new CertPathValidatorException(
   1229                     "DSA parameters cannot be inherited from previous certificate.");
   1230             }
   1231             DSAPublicKey prevDSAPubKey = (DSAPublicKey)pubKey;
   1232             if (prevDSAPubKey.getParams() == null)
   1233             {
   1234                 continue;
   1235             }
   1236             DSAParams dsaParams = prevDSAPubKey.getParams();
   1237             DSAPublicKeySpec dsaPubKeySpec = new DSAPublicKeySpec(
   1238                 dsaPubKey.getY(), dsaParams.getP(), dsaParams.getQ(), dsaParams.getG());
   1239             try
   1240             {
   1241                 KeyFactory keyFactory = helper.createKeyFactory("DSA");
   1242                 return keyFactory.generatePublic(dsaPubKeySpec);
   1243             }
   1244             catch (Exception exception)
   1245             {
   1246                 throw new RuntimeException(exception.getMessage());
   1247             }
   1248         }
   1249         throw new CertPathValidatorException("DSA parameters cannot be inherited from previous certificate.");
   1250     }
   1251 
   1252     /**
   1253      * Find the issuer certificates of a given certificate.
   1254      *
   1255      * @param cert       The certificate for which an issuer should be found.
   1256      * @return A <code>Collection</code> object containing the issuer
   1257      *         <code>X509Certificate</code>s. Never <code>null</code>.
   1258      * @throws AnnotatedException if an error occurs.
   1259      */
   1260     static Collection findIssuerCerts(
   1261         X509Certificate cert,
   1262         List<CertStore> certStores,
   1263         List<PKIXCertStore> pkixCertStores)
   1264         throws AnnotatedException
   1265     {
   1266         X509CertSelector selector = new X509CertSelector();
   1267 
   1268         try
   1269         {
   1270             selector.setSubject(PrincipalUtils.getIssuerPrincipal(cert).getEncoded());
   1271         }
   1272         catch (IOException e)
   1273         {
   1274             throw new AnnotatedException(
   1275                            "Subject criteria for certificate selector to find issuer certificate could not be set.", e);
   1276         }
   1277 
   1278         try
   1279         {
   1280             byte[] akiExtensionValue = cert.getExtensionValue(AUTHORITY_KEY_IDENTIFIER);
   1281             if (akiExtensionValue != null)
   1282             {
   1283                 ASN1OctetString aki = ASN1OctetString.getInstance(akiExtensionValue);
   1284                 byte[] authorityKeyIdentifier = AuthorityKeyIdentifier.getInstance(aki.getOctets()).getKeyIdentifier();
   1285                 if (authorityKeyIdentifier != null)
   1286                 {
   1287                     selector.setSubjectKeyIdentifier(new DEROctetString(authorityKeyIdentifier).getEncoded());
   1288                 }
   1289             }
   1290         }
   1291         catch (Exception e)
   1292         {
   1293             // authority key identifier could not be retrieved from target cert, just search without it
   1294         }
   1295 
   1296         PKIXCertStoreSelector certSelect = new PKIXCertStoreSelector.Builder(selector).build();
   1297         Set certs = new LinkedHashSet();
   1298 
   1299         Iterator iter;
   1300 
   1301         try
   1302         {
   1303             List matches = new ArrayList();
   1304 
   1305             matches.addAll(CertPathValidatorUtilities.findCertificates(certSelect, certStores));
   1306             matches.addAll(CertPathValidatorUtilities.findCertificates(certSelect, pkixCertStores));
   1307 
   1308             iter = matches.iterator();
   1309         }
   1310         catch (AnnotatedException e)
   1311         {
   1312             throw new AnnotatedException("Issuer certificate cannot be searched.", e);
   1313         }
   1314 
   1315         X509Certificate issuer = null;
   1316         while (iter.hasNext())
   1317         {
   1318             issuer = (X509Certificate)iter.next();
   1319             // issuer cannot be verified because possible DSA inheritance
   1320             // parameters are missing
   1321             certs.add(issuer);
   1322         }
   1323         return certs;
   1324     }
   1325 
   1326     protected static void verifyX509Certificate(X509Certificate cert, PublicKey publicKey,
   1327                                                 String sigProvider)
   1328         throws GeneralSecurityException
   1329     {
   1330         if (sigProvider == null)
   1331         {
   1332             cert.verify(publicKey);
   1333         }
   1334         else
   1335         {
   1336             cert.verify(publicKey, sigProvider);
   1337         }
   1338     }
   1339 
   1340     static void checkCRLsNotEmpty(Set crls, Object cert)
   1341         throws AnnotatedException
   1342     {
   1343         if (crls.isEmpty())
   1344         {
   1345             if (cert instanceof X509AttributeCertificate)
   1346             {
   1347                 X509AttributeCertificate aCert = (X509AttributeCertificate)cert;
   1348 
   1349                 throw new AnnotatedException("No CRLs found for issuer \"" + aCert.getIssuer().getPrincipals()[0] + "\"");
   1350             }
   1351             else
   1352             {
   1353                 X509Certificate xCert = (X509Certificate)cert;
   1354 
   1355                 throw new AnnotatedException("No CRLs found for issuer \"" + RFC4519Style.INSTANCE.toString(PrincipalUtils.getIssuerPrincipal(xCert)) + "\"");
   1356             }
   1357         }
   1358     }
   1359 }
   1360