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