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