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