• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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      */
findTrustAnchor( X509Certificate cert, Set trustAnchors)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      */
findTrustAnchor( X509Certificate cert, Set trustAnchors, String sigProvider)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 
getAdditionalStoresFromAltNames( byte[] issuerAlternativeName, Map<GeneralName, PKIXCertStore> altNameCertStoreMap)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 
getValidDate(PKIXExtendedParameters paramsPKIX)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 
isSelfIssued(X509Certificate cert)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      */
getExtensionValue( java.security.cert.X509Extension ext, String oid)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 
getObject( String oid, byte[] ext)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 
getAlgorithmIdentifier( PublicKey key)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 
getQualifierSet(ASN1Sequence qualifiers)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 
removePolicyNode( PKIXPolicyNode validPolicyTree, List[] policyNodes, PKIXPolicyNode _node)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 
removePolicyNodeRecurse( List[] policyNodes, PKIXPolicyNode _node)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 
processCertD1i( int index, List[] policyNodes, ASN1ObjectIdentifier pOid, Set pq)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 
processCertD1ii( int index, List[] policyNodes, ASN1ObjectIdentifier _poid, Set _pq)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 
prepareNextCertB1( int i, List[] policyNodes, String id_p, Map m_idp, X509Certificate cert )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 
prepareNextCertB2( int i, List[] policyNodes, String id_p, PKIXPolicyNode validPolicyTree)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 
isAnyPolicy( Set policySet)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      */
findCertificates(PKIXCertStoreSelector certSelect, List certStores)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 
getAdditionalStoresFromCRLDistributionPoint(CRLDistPoint crldp, Map<GeneralName, PKIXCRLStore> namedCRLStoreMap)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      */
getCRLIssuersFromDistributionPoint( DistributionPoint dp, Collection issuerPrincipals, X509CRLSelector selector)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 
getSerialNumber( Object cert)864     private static BigInteger getSerialNumber(
865         Object cert)
866     {
867         return ((X509Certificate)cert).getSerialNumber();
868     }
869 
getCertStatus( Date validDate, X509CRL crl, Object cert, CertStatus certStatus)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      */
getDeltaCRLs(Date validityDate, X509CRL completeCRL, List<CertStore> certStores, List<PKIXCRLStore> pkixCrlStores)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 
isDeltaCRL(X509CRL crl)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      */
getCompleteCRLs(DistributionPoint dp, Object cert, Date currentDate, PKIXExtendedParameters paramsPKIX)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 
getValidCertDateFromValidityModel( PKIXExtendedParameters paramsPKIX, CertPath certPath, int index)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      */
getNextWorkingKey(List certs, int index, JcaJceHelper helper)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      */
findIssuerCerts( X509Certificate cert, List<CertStore> certStores, List<PKIXCertStore> pkixCertStores)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 
verifyX509Certificate(X509Certificate cert, PublicKey publicKey, String sigProvider)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 
checkCRLsNotEmpty(Set crls, Object cert)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