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