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