package org.bouncycastle.jce.provider;

import java.io.IOException;
import java.math.BigInteger;
import java.security.GeneralSecurityException;
import java.security.PublicKey;
import java.security.cert.CertPath;
import java.security.cert.CertPathBuilder;
import java.security.cert.CertPathBuilderException;
import java.security.cert.CertPathValidatorException;
import java.security.cert.CertificateExpiredException;
import java.security.cert.CertificateNotYetValidException;
import java.security.cert.PKIXCertPathChecker;
import java.security.cert.X509CRL;
import java.security.cert.X509Certificate;
import java.security.cert.X509Extension;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Vector;

import javax.security.auth.x500.X500Principal;

import org.bouncycastle.asn1.ASN1Encodable;
import org.bouncycastle.asn1.ASN1EncodableVector;
import org.bouncycastle.asn1.ASN1InputStream;
import org.bouncycastle.asn1.ASN1Primitive;
import org.bouncycastle.asn1.ASN1Sequence;
import org.bouncycastle.asn1.ASN1TaggedObject;
import org.bouncycastle.asn1.DERInteger;
import org.bouncycastle.asn1.DERObjectIdentifier;
import org.bouncycastle.asn1.DERSequence;
import org.bouncycastle.asn1.x509.BasicConstraints;
import org.bouncycastle.asn1.x509.CRLDistPoint;
import org.bouncycastle.asn1.x509.CRLReason;
import org.bouncycastle.asn1.x509.DistributionPoint;
import org.bouncycastle.asn1.x509.DistributionPointName;
import org.bouncycastle.asn1.x509.GeneralName;
import org.bouncycastle.asn1.x509.GeneralNames;
import org.bouncycastle.asn1.x509.GeneralSubtree;
import org.bouncycastle.asn1.x509.IssuingDistributionPoint;
import org.bouncycastle.asn1.x509.NameConstraints;
import org.bouncycastle.asn1.x509.PolicyInformation;
import org.bouncycastle.asn1.x509.X509Extensions;
import org.bouncycastle.asn1.x509.X509Name;
import org.bouncycastle.jce.exception.ExtCertPathValidatorException;
import org.bouncycastle.util.Arrays;
import org.bouncycastle.x509.ExtendedPKIXBuilderParameters;
import org.bouncycastle.x509.ExtendedPKIXParameters;
import org.bouncycastle.x509.X509CRLStoreSelector;
import org.bouncycastle.x509.X509CertStoreSelector;

public class RFC3280CertPathUtilities
{
    private static final PKIXCRLUtil CRL_UTIL = new PKIXCRLUtil();

    /**
     * If the complete CRL includes an issuing distribution point (IDP) CRL
     * extension check the following:
     * <p/>
     * (i) If the distribution point name is present in the IDP CRL extension
     * and the distribution field is present in the DP, then verify that one of
     * the names in the IDP matches one of the names in the DP. If the
     * distribution point name is present in the IDP CRL extension and the
     * distribution field is omitted from the DP, then verify that one of the
     * names in the IDP matches one of the names in the cRLIssuer field of the
     * DP.
     * </p>
     * <p/>
     * (ii) If the onlyContainsUserCerts boolean is asserted in the IDP CRL
     * extension, verify that the certificate does not include the basic
     * constraints extension with the cA boolean asserted.
     * </p>
     * <p/>
     * (iii) If the onlyContainsCACerts boolean is asserted in the IDP CRL
     * extension, verify that the certificate includes the basic constraints
     * extension with the cA boolean asserted.
     * </p>
     * <p/>
     * (iv) Verify that the onlyContainsAttributeCerts boolean is not asserted.
     * </p>
     *
     * @param dp   The distribution point.
     * @param cert The certificate.
     * @param crl  The CRL.
     * @throws AnnotatedException if one of the conditions is not met or an error occurs.
     */
    protected static void processCRLB2(
        DistributionPoint dp,
        Object cert,
        X509CRL crl)
        throws AnnotatedException
    {
        IssuingDistributionPoint idp = null;
        try
        {
            idp = IssuingDistributionPoint.getInstance(CertPathValidatorUtilities.getExtensionValue(crl,
                RFC3280CertPathUtilities.ISSUING_DISTRIBUTION_POINT));
        }
        catch (Exception e)
        {
            throw new AnnotatedException("Issuing distribution point extension could not be decoded.", e);
        }
        // (b) (2) (i)
        // distribution point name is present
        if (idp != null)
        {
            if (idp.getDistributionPoint() != null)
            {
                // make list of names
                DistributionPointName dpName = IssuingDistributionPoint.getInstance(idp).getDistributionPoint();
                List names = new ArrayList();

                if (dpName.getType() == DistributionPointName.FULL_NAME)
                {
                    GeneralName[] genNames = GeneralNames.getInstance(dpName.getName()).getNames();
                    for (int j = 0; j < genNames.length; j++)
                    {
                        names.add(genNames[j]);
                    }
                }
                if (dpName.getType() == DistributionPointName.NAME_RELATIVE_TO_CRL_ISSUER)
                {
                    ASN1EncodableVector vec = new ASN1EncodableVector();
                    try
                    {
                        Enumeration e = ASN1Sequence.getInstance(
                            ASN1Sequence.fromByteArray(CertPathValidatorUtilities.getIssuerPrincipal(crl)
                                .getEncoded())).getObjects();
                        while (e.hasMoreElements())
                        {
                            vec.add((ASN1Encodable)e.nextElement());
                        }
                    }
                    catch (IOException e)
                    {
                        throw new AnnotatedException("Could not read CRL issuer.", e);
                    }
                    vec.add(dpName.getName());
                    names.add(new GeneralName(X509Name.getInstance(new DERSequence(vec))));
                }
                boolean matches = false;
                // verify that one of the names in the IDP matches one
                // of the names in the DP.
                if (dp.getDistributionPoint() != null)
                {
                    dpName = dp.getDistributionPoint();
                    GeneralName[] genNames = null;
                    if (dpName.getType() == DistributionPointName.FULL_NAME)
                    {
                        genNames = GeneralNames.getInstance(dpName.getName()).getNames();
                    }
                    if (dpName.getType() == DistributionPointName.NAME_RELATIVE_TO_CRL_ISSUER)
                    {
                        if (dp.getCRLIssuer() != null)
                        {
                            genNames = dp.getCRLIssuer().getNames();
                        }
                        else
                        {
                            genNames = new GeneralName[1];
                            try
                            {
                                genNames[0] = new GeneralName(new X509Name(
                                    (ASN1Sequence)ASN1Sequence.fromByteArray(CertPathValidatorUtilities
                                        .getEncodedIssuerPrincipal(cert).getEncoded())));
                            }
                            catch (IOException e)
                            {
                                throw new AnnotatedException("Could not read certificate issuer.", e);
                            }
                        }
                        for (int j = 0; j < genNames.length; j++)
                        {
                            Enumeration e = ASN1Sequence.getInstance(genNames[j].getName().toASN1Primitive()).getObjects();
                            ASN1EncodableVector vec = new ASN1EncodableVector();
                            while (e.hasMoreElements())
                            {
                                vec.add((ASN1Encodable)e.nextElement());
                            }
                            vec.add(dpName.getName());
                            genNames[j] = new GeneralName(new X509Name(new DERSequence(vec)));
                        }
                    }
                    if (genNames != null)
                    {
                        for (int j = 0; j < genNames.length; j++)
                        {
                            if (names.contains(genNames[j]))
                            {
                                matches = true;
                                break;
                            }
                        }
                    }
                    if (!matches)
                    {
                        throw new AnnotatedException(
                            "No match for certificate CRL issuing distribution point name to cRLIssuer CRL distribution point.");
                    }
                }
                // verify that one of the names in
                // the IDP matches one of the names in the cRLIssuer field of
                // the DP
                else
                {
                    if (dp.getCRLIssuer() == null)
                    {
                        throw new AnnotatedException("Either the cRLIssuer or the distributionPoint field must "
                            + "be contained in DistributionPoint.");
                    }
                    GeneralName[] genNames = dp.getCRLIssuer().getNames();
                    for (int j = 0; j < genNames.length; j++)
                    {
                        if (names.contains(genNames[j]))
                        {
                            matches = true;
                            break;
                        }
                    }
                    if (!matches)
                    {
                        throw new AnnotatedException(
                            "No match for certificate CRL issuing distribution point name to cRLIssuer CRL distribution point.");
                    }
                }
            }
            BasicConstraints bc = null;
            try
            {
                bc = BasicConstraints.getInstance(CertPathValidatorUtilities.getExtensionValue((X509Extension)cert,
                    BASIC_CONSTRAINTS));
            }
            catch (Exception e)
            {
                throw new AnnotatedException("Basic constraints extension could not be decoded.", e);
            }

            if (cert instanceof X509Certificate)
            {
                // (b) (2) (ii)
                if (idp.onlyContainsUserCerts() && (bc != null && bc.isCA()))
                {
                    throw new AnnotatedException("CA Cert CRL only contains user certificates.");
                }

                // (b) (2) (iii)
                if (idp.onlyContainsCACerts() && (bc == null || !bc.isCA()))
                {
                    throw new AnnotatedException("End CRL only contains CA certificates.");
                }
            }

            // (b) (2) (iv)
            if (idp.onlyContainsAttributeCerts())
            {
                throw new AnnotatedException("onlyContainsAttributeCerts boolean is asserted.");
            }
        }
    }

    /**
     * If the DP includes cRLIssuer, then verify that the issuer field in the
     * complete CRL matches cRLIssuer in the DP and that the complete CRL
     * contains an issuing distribution point extension with the indirectCRL
     * boolean asserted. Otherwise, verify that the CRL issuer matches the
     * certificate issuer.
     *
     * @param dp   The distribution point.
     * @param cert The certificate ot attribute certificate.
     * @param crl  The CRL for <code>cert</code>.
     * @throws AnnotatedException if one of the above conditions does not apply or an error
     *                            occurs.
     */
    protected static void processCRLB1(
        DistributionPoint dp,
        Object cert,
        X509CRL crl)
        throws AnnotatedException
    {
        ASN1Primitive idp = CertPathValidatorUtilities.getExtensionValue(crl, ISSUING_DISTRIBUTION_POINT);
        boolean isIndirect = false;
        if (idp != null)
        {
            if (IssuingDistributionPoint.getInstance(idp).isIndirectCRL())
            {
                isIndirect = true;
            }
        }
        byte[] issuerBytes = CertPathValidatorUtilities.getIssuerPrincipal(crl).getEncoded();

        boolean matchIssuer = false;
        if (dp.getCRLIssuer() != null)
        {
            GeneralName genNames[] = dp.getCRLIssuer().getNames();
            for (int j = 0; j < genNames.length; j++)
            {
                if (genNames[j].getTagNo() == GeneralName.directoryName)
                {
                    try
                    {
                        if (Arrays.areEqual(genNames[j].getName().toASN1Primitive().getEncoded(), issuerBytes))
                        {
                            matchIssuer = true;
                        }
                    }
                    catch (IOException e)
                    {
                        throw new AnnotatedException(
                            "CRL issuer information from distribution point cannot be decoded.", e);
                    }
                }
            }
            if (matchIssuer && !isIndirect)
            {
                throw new AnnotatedException("Distribution point contains cRLIssuer field but CRL is not indirect.");
            }
            if (!matchIssuer)
            {
                throw new AnnotatedException("CRL issuer of CRL does not match CRL issuer of distribution point.");
            }
        }
        else
        {
            if (CertPathValidatorUtilities.getIssuerPrincipal(crl).equals(
                CertPathValidatorUtilities.getEncodedIssuerPrincipal(cert)))
            {
                matchIssuer = true;
            }
        }
        if (!matchIssuer)
        {
            throw new AnnotatedException("Cannot find matching CRL issuer for certificate.");
        }
    }

    protected static ReasonsMask processCRLD(
        X509CRL crl,
        DistributionPoint dp)
        throws AnnotatedException
    {
        IssuingDistributionPoint idp = null;
        try
        {
            idp = IssuingDistributionPoint.getInstance(CertPathValidatorUtilities.getExtensionValue(crl,
                RFC3280CertPathUtilities.ISSUING_DISTRIBUTION_POINT));
        }
        catch (Exception e)
        {
            throw new AnnotatedException("Issuing distribution point extension could not be decoded.", e);
        }
        // (d) (1)
        if (idp != null && idp.getOnlySomeReasons() != null && dp.getReasons() != null)
        {
            return new ReasonsMask(dp.getReasons()).intersect(new ReasonsMask(idp.getOnlySomeReasons()));
        }
        // (d) (4)
        if ((idp == null || idp.getOnlySomeReasons() == null) && dp.getReasons() == null)
        {
            return ReasonsMask.allReasons;
        }
        // (d) (2) and (d)(3)
        return (dp.getReasons() == null
            ? ReasonsMask.allReasons
            : new ReasonsMask(dp.getReasons())).intersect(idp == null
            ? ReasonsMask.allReasons
            : new ReasonsMask(idp.getOnlySomeReasons()));

    }

    protected static final String CERTIFICATE_POLICIES = X509Extensions.CertificatePolicies.getId();

    protected static final String POLICY_MAPPINGS = X509Extensions.PolicyMappings.getId();

    protected static final String INHIBIT_ANY_POLICY = X509Extensions.InhibitAnyPolicy.getId();

    protected static final String ISSUING_DISTRIBUTION_POINT = X509Extensions.IssuingDistributionPoint.getId();

    protected static final String FRESHEST_CRL = X509Extensions.FreshestCRL.getId();

    protected static final String DELTA_CRL_INDICATOR = X509Extensions.DeltaCRLIndicator.getId();

    protected static final String POLICY_CONSTRAINTS = X509Extensions.PolicyConstraints.getId();

    protected static final String BASIC_CONSTRAINTS = X509Extensions.BasicConstraints.getId();

    protected static final String CRL_DISTRIBUTION_POINTS = X509Extensions.CRLDistributionPoints.getId();

    protected static final String SUBJECT_ALTERNATIVE_NAME = X509Extensions.SubjectAlternativeName.getId();

    protected static final String NAME_CONSTRAINTS = X509Extensions.NameConstraints.getId();

    protected static final String AUTHORITY_KEY_IDENTIFIER = X509Extensions.AuthorityKeyIdentifier.getId();

    protected static final String KEY_USAGE = X509Extensions.KeyUsage.getId();

    protected static final String CRL_NUMBER = X509Extensions.CRLNumber.getId();

    protected static final String ANY_POLICY = "2.5.29.32.0";

    /*
     * key usage bits
     */
    protected static final int KEY_CERT_SIGN = 5;

    protected static final int CRL_SIGN = 6;

    /**
     * Obtain and validate the certification path for the complete CRL issuer.
     * If a key usage extension is present in the CRL issuer's certificate,
     * verify that the cRLSign bit is set.
     *
     * @param crl                CRL which contains revocation information for the certificate
     *                           <code>cert</code>.
     * @param cert               The attribute certificate or certificate to check if it is
     *                           revoked.
     * @param defaultCRLSignCert The issuer certificate of the certificate <code>cert</code>.
     * @param defaultCRLSignKey  The public key of the issuer certificate
     *                           <code>defaultCRLSignCert</code>.
     * @param paramsPKIX         paramsPKIX PKIX parameters.
     * @param certPathCerts      The certificates on the certification path.
     * @return A <code>Set</code> with all keys of possible CRL issuer
     *         certificates.
     * @throws AnnotatedException if the CRL is not valid or the status cannot be checked or
     *                            some error occurs.
     */
    protected static Set processCRLF(
        X509CRL crl,
        Object cert,
        X509Certificate defaultCRLSignCert,
        PublicKey defaultCRLSignKey,
        ExtendedPKIXParameters paramsPKIX,
        List certPathCerts)
        throws AnnotatedException
    {
        // (f)

        // get issuer from CRL
        X509CertStoreSelector selector = new X509CertStoreSelector();
        try
        {
            byte[] issuerPrincipal = CertPathValidatorUtilities.getIssuerPrincipal(crl).getEncoded();
            selector.setSubject(issuerPrincipal);
        }
        catch (IOException e)
        {
            throw new AnnotatedException(
                "Subject criteria for certificate selector to find issuer certificate for CRL could not be set.", e);
        }

        // get CRL signing certs
        Collection coll;
        try
        {
            coll = CertPathValidatorUtilities.findCertificates(selector, paramsPKIX.getStores());
            coll.addAll(CertPathValidatorUtilities.findCertificates(selector, paramsPKIX.getAdditionalStores()));
            coll.addAll(CertPathValidatorUtilities.findCertificates(selector, paramsPKIX.getCertStores()));
        }
        catch (AnnotatedException e)
        {
            throw new AnnotatedException("Issuer certificate for CRL cannot be searched.", e);
        }

        coll.add(defaultCRLSignCert);

        Iterator cert_it = coll.iterator();

        List validCerts = new ArrayList();
        List validKeys = new ArrayList();

        while (cert_it.hasNext())
        {
            X509Certificate signingCert = (X509Certificate)cert_it.next();

            /*
             * CA of the certificate, for which this CRL is checked, has also
             * signed CRL, so skip the path validation, because is already done
             */
            if (signingCert.equals(defaultCRLSignCert))
            {
                validCerts.add(signingCert);
                validKeys.add(defaultCRLSignKey);
                continue;
            }
            try
            {
                CertPathBuilder builder = CertPathBuilder.getInstance("PKIX", BouncyCastleProvider.PROVIDER_NAME);
                selector = new X509CertStoreSelector();
                selector.setCertificate(signingCert);
                ExtendedPKIXParameters temp = (ExtendedPKIXParameters)paramsPKIX.clone();
                temp.setTargetCertConstraints(selector);
                ExtendedPKIXBuilderParameters params = (ExtendedPKIXBuilderParameters)ExtendedPKIXBuilderParameters
                    .getInstance(temp);
                /*
                 * if signingCert is placed not higher on the cert path a
                 * dependency loop results. CRL for cert is checked, but
                 * signingCert is needed for checking the CRL which is dependent
                 * on checking cert because it is higher in the cert path and so
                 * signing signingCert transitively. so, revocation is disabled,
                 * forgery attacks of the CRL are detected in this outer loop
                 * for all other it must be enabled to prevent forgery attacks
                 */
                if (certPathCerts.contains(signingCert))
                {
                    params.setRevocationEnabled(false);
                }
                else
                {
                    params.setRevocationEnabled(true);
                }
                List certs = builder.build(params).getCertPath().getCertificates();
                validCerts.add(signingCert);
                validKeys.add(CertPathValidatorUtilities.getNextWorkingKey(certs, 0));
            }
            catch (CertPathBuilderException e)
            {
                throw new AnnotatedException("Internal error.", e);
            }
            catch (CertPathValidatorException e)
            {
                throw new AnnotatedException("Public key of issuer certificate of CRL could not be retrieved.", e);
            }
            catch (Exception e)
            {
                throw new RuntimeException(e.getMessage());
            }
        }

        Set checkKeys = new HashSet();

        AnnotatedException lastException = null;
        for (int i = 0; i < validCerts.size(); i++)
        {
            X509Certificate signCert = (X509Certificate)validCerts.get(i);
            boolean[] keyusage = signCert.getKeyUsage();

            if (keyusage != null && (keyusage.length < 7 || !keyusage[CRL_SIGN]))
            {
                lastException = new AnnotatedException(
                    "Issuer certificate key usage extension does not permit CRL signing.");
            }
            else
            {
                checkKeys.add(validKeys.get(i));
            }
        }

        if (checkKeys.isEmpty() && lastException == null)
        {
            throw new AnnotatedException("Cannot find a valid issuer certificate.");
        }
        if (checkKeys.isEmpty() && lastException != null)
        {
            throw lastException;
        }

        return checkKeys;
    }

    protected static PublicKey processCRLG(
        X509CRL crl,
        Set keys)
        throws AnnotatedException
    {
        Exception lastException = null;
        for (Iterator it = keys.iterator(); it.hasNext();)
        {
            PublicKey key = (PublicKey)it.next();
            try
            {
                crl.verify(key);
                return key;
            }
            catch (Exception e)
            {
                lastException = e;
            }
        }
        throw new AnnotatedException("Cannot verify CRL.", lastException);
    }

    protected static X509CRL processCRLH(
        Set deltacrls,
        PublicKey key)
        throws AnnotatedException
    {
        Exception lastException = null;

        for (Iterator it = deltacrls.iterator(); it.hasNext();)
        {
            X509CRL crl = (X509CRL)it.next();
            try
            {
                crl.verify(key);
                return crl;
            }
            catch (Exception e)
            {
                lastException = e;
            }
        }

        if (lastException != null)
        {
            throw new AnnotatedException("Cannot verify delta CRL.", lastException);
        }
        return null;
    }

    protected static Set processCRLA1i(
        Date currentDate,
        ExtendedPKIXParameters paramsPKIX,
        X509Certificate cert,
        X509CRL crl)
        throws AnnotatedException
    {
        Set set = new HashSet();
        if (paramsPKIX.isUseDeltasEnabled())
        {
            CRLDistPoint freshestCRL = null;
            try
            {
                freshestCRL = CRLDistPoint
                    .getInstance(CertPathValidatorUtilities.getExtensionValue(cert, FRESHEST_CRL));
            }
            catch (AnnotatedException e)
            {
                throw new AnnotatedException("Freshest CRL extension could not be decoded from certificate.", e);
            }
            if (freshestCRL == null)
            {
                try
                {
                    freshestCRL = CRLDistPoint.getInstance(CertPathValidatorUtilities.getExtensionValue(crl,
                        FRESHEST_CRL));
                }
                catch (AnnotatedException e)
                {
                    throw new AnnotatedException("Freshest CRL extension could not be decoded from CRL.", e);
                }
            }
            if (freshestCRL != null)
            {
                try
                {
                    CertPathValidatorUtilities.addAdditionalStoresFromCRLDistributionPoint(freshestCRL, paramsPKIX);
                }
                catch (AnnotatedException e)
                {
                    throw new AnnotatedException(
                        "No new delta CRL locations could be added from Freshest CRL extension.", e);
                }
                // get delta CRL(s)
                try
                {
                    set.addAll(CertPathValidatorUtilities.getDeltaCRLs(currentDate, paramsPKIX, crl));
                }
                catch (AnnotatedException e)
                {
                    throw new AnnotatedException("Exception obtaining delta CRLs.", e);
                }
            }
        }
        return set;
    }

    protected static Set[] processCRLA1ii(
        Date currentDate,
        ExtendedPKIXParameters paramsPKIX,
        X509Certificate cert,
        X509CRL crl)
        throws AnnotatedException
    {
        Set deltaSet = new HashSet();
        X509CRLStoreSelector crlselect = new X509CRLStoreSelector();
        crlselect.setCertificateChecking(cert);

        try
        {
            crlselect.addIssuerName(crl.getIssuerX500Principal().getEncoded());
        }
        catch (IOException e)
        {
            throw new AnnotatedException("Cannot extract issuer from CRL." + e, e);
        }

        crlselect.setCompleteCRLEnabled(true);
        Set completeSet = CRL_UTIL.findCRLs(crlselect, paramsPKIX, currentDate);

        if (paramsPKIX.isUseDeltasEnabled())
        {
            // get delta CRL(s)
            try
            {
                deltaSet.addAll(CertPathValidatorUtilities.getDeltaCRLs(currentDate, paramsPKIX, crl));
            }
            catch (AnnotatedException e)
            {
                throw new AnnotatedException("Exception obtaining delta CRLs.", e);
            }
        }
        return new Set[]
            {
                completeSet,
                deltaSet};
    }



    /**
     * If use-deltas is set, verify the issuer and scope of the delta CRL.
     *
     * @param deltaCRL    The delta CRL.
     * @param completeCRL The complete CRL.
     * @param pkixParams  The PKIX paramaters.
     * @throws AnnotatedException if an exception occurs.
     */
    protected static void processCRLC(
        X509CRL deltaCRL,
        X509CRL completeCRL,
        ExtendedPKIXParameters pkixParams)
        throws AnnotatedException
    {
        if (deltaCRL == null)
        {
            return;
        }
        IssuingDistributionPoint completeidp = null;
        try
        {
            completeidp = IssuingDistributionPoint.getInstance(CertPathValidatorUtilities.getExtensionValue(
                completeCRL, RFC3280CertPathUtilities.ISSUING_DISTRIBUTION_POINT));
        }
        catch (Exception e)
        {
            throw new AnnotatedException("Issuing distribution point extension could not be decoded.", e);
        }

        if (pkixParams.isUseDeltasEnabled())
        {
            // (c) (1)
            if (!deltaCRL.getIssuerX500Principal().equals(completeCRL.getIssuerX500Principal()))
            {
                throw new AnnotatedException("Complete CRL issuer does not match delta CRL issuer.");
            }

            // (c) (2)
            IssuingDistributionPoint deltaidp = null;
            try
            {
                deltaidp = IssuingDistributionPoint.getInstance(CertPathValidatorUtilities.getExtensionValue(
                    deltaCRL, ISSUING_DISTRIBUTION_POINT));
            }
            catch (Exception e)
            {
                throw new AnnotatedException(
                    "Issuing distribution point extension from delta CRL could not be decoded.", e);
            }

            boolean match = false;
            if (completeidp == null)
            {
                if (deltaidp == null)
                {
                    match = true;
                }
            }
            else
            {
                if (completeidp.equals(deltaidp))
                {
                    match = true;
                }
            }
            if (!match)
            {
                throw new AnnotatedException(
                    "Issuing distribution point extension from delta CRL and complete CRL does not match.");
            }

            // (c) (3)
            ASN1Primitive completeKeyIdentifier = null;
            try
            {
                completeKeyIdentifier = CertPathValidatorUtilities.getExtensionValue(
                    completeCRL, AUTHORITY_KEY_IDENTIFIER);
            }
            catch (AnnotatedException e)
            {
                throw new AnnotatedException(
                    "Authority key identifier extension could not be extracted from complete CRL.", e);
            }

            ASN1Primitive deltaKeyIdentifier = null;
            try
            {
                deltaKeyIdentifier = CertPathValidatorUtilities.getExtensionValue(
                    deltaCRL, AUTHORITY_KEY_IDENTIFIER);
            }
            catch (AnnotatedException e)
            {
                throw new AnnotatedException(
                    "Authority key identifier extension could not be extracted from delta CRL.", e);
            }

            if (completeKeyIdentifier == null)
            {
                throw new AnnotatedException("CRL authority key identifier is null.");
            }

            if (deltaKeyIdentifier == null)
            {
                throw new AnnotatedException("Delta CRL authority key identifier is null.");
            }

            if (!completeKeyIdentifier.equals(deltaKeyIdentifier))
            {
                throw new AnnotatedException(
                    "Delta CRL authority key identifier does not match complete CRL authority key identifier.");
            }
        }
    }

    protected static void processCRLI(
        Date validDate,
        X509CRL deltacrl,
        Object cert,
        CertStatus certStatus,
        ExtendedPKIXParameters pkixParams)
        throws AnnotatedException
    {
        if (pkixParams.isUseDeltasEnabled() && deltacrl != null)
        {
            CertPathValidatorUtilities.getCertStatus(validDate, deltacrl, cert, certStatus);
        }
    }

    protected static void processCRLJ(
        Date validDate,
        X509CRL completecrl,
        Object cert,
        CertStatus certStatus)
        throws AnnotatedException
    {
        if (certStatus.getCertStatus() == CertStatus.UNREVOKED)
        {
            CertPathValidatorUtilities.getCertStatus(validDate, completecrl, cert, certStatus);
        }
    }

    protected static PKIXPolicyNode prepareCertB(
        CertPath certPath,
        int index,
        List[] policyNodes,
        PKIXPolicyNode validPolicyTree,
        int policyMapping)
        throws CertPathValidatorException
    {
        List certs = certPath.getCertificates();
        X509Certificate cert = (X509Certificate)certs.get(index);
        int n = certs.size();
        // i as defined in the algorithm description
        int i = n - index;
        // (b)
        //
        ASN1Sequence pm = null;
        try
        {
            pm = DERSequence.getInstance(CertPathValidatorUtilities.getExtensionValue(cert,
                RFC3280CertPathUtilities.POLICY_MAPPINGS));
        }
        catch (AnnotatedException ex)
        {
            throw new ExtCertPathValidatorException("Policy mappings extension could not be decoded.", ex, certPath,
                index);
        }
        PKIXPolicyNode _validPolicyTree = validPolicyTree;
        if (pm != null)
        {
            ASN1Sequence mappings = (ASN1Sequence)pm;
            Map m_idp = new HashMap();
            Set s_idp = new HashSet();

            for (int j = 0; j < mappings.size(); j++)
            {
                ASN1Sequence mapping = (ASN1Sequence)mappings.getObjectAt(j);
                String id_p = ((DERObjectIdentifier)mapping.getObjectAt(0)).getId();
                String sd_p = ((DERObjectIdentifier)mapping.getObjectAt(1)).getId();
                Set tmp;

                if (!m_idp.containsKey(id_p))
                {
                    tmp = new HashSet();
                    tmp.add(sd_p);
                    m_idp.put(id_p, tmp);
                    s_idp.add(id_p);
                }
                else
                {
                    tmp = (Set)m_idp.get(id_p);
                    tmp.add(sd_p);
                }
            }

            Iterator it_idp = s_idp.iterator();
            while (it_idp.hasNext())
            {
                String id_p = (String)it_idp.next();

                //
                // (1)
                //
                if (policyMapping > 0)
                {
                    boolean idp_found = false;
                    Iterator nodes_i = policyNodes[i].iterator();
                    while (nodes_i.hasNext())
                    {
                        PKIXPolicyNode node = (PKIXPolicyNode)nodes_i.next();
                        if (node.getValidPolicy().equals(id_p))
                        {
                            idp_found = true;
                            node.expectedPolicies = (Set)m_idp.get(id_p);
                            break;
                        }
                    }

                    if (!idp_found)
                    {
                        nodes_i = policyNodes[i].iterator();
                        while (nodes_i.hasNext())
                        {
                            PKIXPolicyNode node = (PKIXPolicyNode)nodes_i.next();
                            if (RFC3280CertPathUtilities.ANY_POLICY.equals(node.getValidPolicy()))
                            {
                                Set pq = null;
                                ASN1Sequence policies = null;
                                try
                                {
                                    policies = (ASN1Sequence)CertPathValidatorUtilities.getExtensionValue(cert,
                                        RFC3280CertPathUtilities.CERTIFICATE_POLICIES);
                                }
                                catch (AnnotatedException e)
                                {
                                    throw new ExtCertPathValidatorException(
                                        "Certificate policies extension could not be decoded.", e, certPath, index);
                                }
                                Enumeration e = policies.getObjects();
                                while (e.hasMoreElements())
                                {
                                    PolicyInformation pinfo = null;
                                    try
                                    {
                                        pinfo = PolicyInformation.getInstance(e.nextElement());
                                    }
                                    catch (Exception ex)
                                    {
                                        throw new CertPathValidatorException(
                                            "Policy information could not be decoded.", ex, certPath, index);
                                    }
                                    if (RFC3280CertPathUtilities.ANY_POLICY.equals(pinfo.getPolicyIdentifier().getId()))
                                    {
                                        try
                                        {
                                            pq = CertPathValidatorUtilities
                                                .getQualifierSet(pinfo.getPolicyQualifiers());
                                        }
                                        catch (CertPathValidatorException ex)
                                        {

                                            throw new ExtCertPathValidatorException(
                                                "Policy qualifier info set could not be decoded.", ex, certPath,
                                                index);
                                        }
                                        break;
                                    }
                                }
                                boolean ci = false;
                                if (cert.getCriticalExtensionOIDs() != null)
                                {
                                    ci = cert.getCriticalExtensionOIDs().contains(
                                        RFC3280CertPathUtilities.CERTIFICATE_POLICIES);
                                }

                                PKIXPolicyNode p_node = (PKIXPolicyNode)node.getParent();
                                if (RFC3280CertPathUtilities.ANY_POLICY.equals(p_node.getValidPolicy()))
                                {
                                    PKIXPolicyNode c_node = new PKIXPolicyNode(new ArrayList(), i, (Set)m_idp
                                        .get(id_p), p_node, pq, id_p, ci);
                                    p_node.addChild(c_node);
                                    policyNodes[i].add(c_node);
                                }
                                break;
                            }
                        }
                    }

                    //
                    // (2)
                    //
                }
                else if (policyMapping <= 0)
                {
                    Iterator nodes_i = policyNodes[i].iterator();
                    while (nodes_i.hasNext())
                    {
                        PKIXPolicyNode node = (PKIXPolicyNode)nodes_i.next();
                        if (node.getValidPolicy().equals(id_p))
                        {
                            PKIXPolicyNode p_node = (PKIXPolicyNode)node.getParent();
                            p_node.removeChild(node);
                            nodes_i.remove();
                            for (int k = (i - 1); k >= 0; k--)
                            {
                                List nodes = policyNodes[k];
                                for (int l = 0; l < nodes.size(); l++)
                                {
                                    PKIXPolicyNode node2 = (PKIXPolicyNode)nodes.get(l);
                                    if (!node2.hasChildren())
                                    {
                                        _validPolicyTree = CertPathValidatorUtilities.removePolicyNode(
                                            _validPolicyTree, policyNodes, node2);
                                        if (_validPolicyTree == null)
                                        {
                                            break;
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
        return _validPolicyTree;
    }

    protected static void prepareNextCertA(
        CertPath certPath,
        int index)
        throws CertPathValidatorException
    {
        List certs = certPath.getCertificates();
        X509Certificate cert = (X509Certificate)certs.get(index);
        //
        //
        // (a) check the policy mappings
        //
        ASN1Sequence pm = null;
        try
        {
            pm = DERSequence.getInstance(CertPathValidatorUtilities.getExtensionValue(cert,
                RFC3280CertPathUtilities.POLICY_MAPPINGS));
        }
        catch (AnnotatedException ex)
        {
            throw new ExtCertPathValidatorException("Policy mappings extension could not be decoded.", ex, certPath,
                index);
        }
        if (pm != null)
        {
            ASN1Sequence mappings = pm;

            for (int j = 0; j < mappings.size(); j++)
            {
                DERObjectIdentifier issuerDomainPolicy = null;
                DERObjectIdentifier subjectDomainPolicy = null;
                try
                {
                    ASN1Sequence mapping = DERSequence.getInstance(mappings.getObjectAt(j));

                    issuerDomainPolicy = DERObjectIdentifier.getInstance(mapping.getObjectAt(0));
                    subjectDomainPolicy = DERObjectIdentifier.getInstance(mapping.getObjectAt(1));
                }
                catch (Exception e)
                {
                    throw new ExtCertPathValidatorException("Policy mappings extension contents could not be decoded.",
                        e, certPath, index);
                }

                if (RFC3280CertPathUtilities.ANY_POLICY.equals(issuerDomainPolicy.getId()))
                {

                    throw new CertPathValidatorException("IssuerDomainPolicy is anyPolicy", null, certPath, index);
                }

                if (RFC3280CertPathUtilities.ANY_POLICY.equals(subjectDomainPolicy.getId()))
                {

                    throw new CertPathValidatorException("SubjectDomainPolicy is anyPolicy,", null, certPath, index);
                }
            }
        }
    }

    protected static void processCertF(
        CertPath certPath,
        int index,
        PKIXPolicyNode validPolicyTree,
        int explicitPolicy)
        throws CertPathValidatorException
    {
        //
        // (f)
        //
        if (explicitPolicy <= 0 && validPolicyTree == null)
        {
            throw new ExtCertPathValidatorException("No valid policy tree found when one expected.", null, certPath,
                index);
        }
    }

    protected static PKIXPolicyNode processCertE(
        CertPath certPath,
        int index,
        PKIXPolicyNode validPolicyTree)
        throws CertPathValidatorException
    {
        List certs = certPath.getCertificates();
        X509Certificate cert = (X509Certificate)certs.get(index);
        // 
        // (e)
        //
        ASN1Sequence certPolicies = null;
        try
        {
            certPolicies = DERSequence.getInstance(CertPathValidatorUtilities.getExtensionValue(cert,
                RFC3280CertPathUtilities.CERTIFICATE_POLICIES));
        }
        catch (AnnotatedException e)
        {
            throw new ExtCertPathValidatorException("Could not read certificate policies extension from certificate.",
                e, certPath, index);
        }
        if (certPolicies == null)
        {
            validPolicyTree = null;
        }
        return validPolicyTree;
    }

    protected static void processCertBC(
        CertPath certPath,
        int index,
        PKIXNameConstraintValidator nameConstraintValidator)
        throws CertPathValidatorException
    {
        List certs = certPath.getCertificates();
        X509Certificate cert = (X509Certificate)certs.get(index);
        int n = certs.size();
        // i as defined in the algorithm description
        int i = n - index;
        //
        // (b), (c) permitted and excluded subtree checking.
        //
        if (!(CertPathValidatorUtilities.isSelfIssued(cert) && (i < n)))
        {
            X500Principal principal = CertPathValidatorUtilities.getSubjectPrincipal(cert);
            ASN1InputStream aIn = new ASN1InputStream(principal.getEncoded());
            ASN1Sequence dns;

            try
            {
                dns = DERSequence.getInstance(aIn.readObject());
            }
            catch (Exception e)
            {
                throw new CertPathValidatorException("Exception extracting subject name when checking subtrees.", e,
                    certPath, index);
            }

            try
            {
                nameConstraintValidator.checkPermittedDN(dns);
                nameConstraintValidator.checkExcludedDN(dns);
            }
            catch (PKIXNameConstraintValidatorException e)
            {
                throw new CertPathValidatorException("Subtree check for certificate subject failed.", e, certPath,
                    index);
            }

            GeneralNames altName = null;
            try
            {
                altName = GeneralNames.getInstance(CertPathValidatorUtilities.getExtensionValue(cert,
                    RFC3280CertPathUtilities.SUBJECT_ALTERNATIVE_NAME));
            }
            catch (Exception e)
            {
                throw new CertPathValidatorException("Subject alternative name extension could not be decoded.", e,
                    certPath, index);
            }
            Vector emails = new X509Name(dns).getValues(X509Name.EmailAddress);
            for (Enumeration e = emails.elements(); e.hasMoreElements();)
            {
                String email = (String)e.nextElement();
                GeneralName emailAsGeneralName = new GeneralName(GeneralName.rfc822Name, email);
                try
                {
                    nameConstraintValidator.checkPermitted(emailAsGeneralName);
                    nameConstraintValidator.checkExcluded(emailAsGeneralName);
                }
                catch (PKIXNameConstraintValidatorException ex)
                {
                    throw new CertPathValidatorException(
                        "Subtree check for certificate subject alternative email failed.", ex, certPath, index);
                }
            }
            if (altName != null)
            {
                GeneralName[] genNames = null;
                try
                {
                    genNames = altName.getNames();
                }
                catch (Exception e)
                {
                    throw new CertPathValidatorException("Subject alternative name contents could not be decoded.", e,
                        certPath, index);
                }
                for (int j = 0; j < genNames.length; j++)
                {

                    try
                    {
                        nameConstraintValidator.checkPermitted(genNames[j]);
                        nameConstraintValidator.checkExcluded(genNames[j]);
                    }
                    catch (PKIXNameConstraintValidatorException e)
                    {
                        throw new CertPathValidatorException(
                            "Subtree check for certificate subject alternative name failed.", e, certPath, index);
                    }
                }
            }
        }
    }

    protected static PKIXPolicyNode processCertD(
        CertPath certPath,
        int index,
        Set acceptablePolicies,
        PKIXPolicyNode validPolicyTree,
        List[] policyNodes,
        int inhibitAnyPolicy)
        throws CertPathValidatorException
    {
        List certs = certPath.getCertificates();
        X509Certificate cert = (X509Certificate)certs.get(index);
        int n = certs.size();
        // i as defined in the algorithm description
        int i = n - index;
        //
        // (d) policy Information checking against initial policy and
        // policy mapping
        //
        ASN1Sequence certPolicies = null;
        try
        {
            certPolicies = DERSequence.getInstance(CertPathValidatorUtilities.getExtensionValue(cert,
                RFC3280CertPathUtilities.CERTIFICATE_POLICIES));
        }
        catch (AnnotatedException e)
        {
            throw new ExtCertPathValidatorException("Could not read certificate policies extension from certificate.",
                e, certPath, index);
        }
        if (certPolicies != null && validPolicyTree != null)
        {
            //
            // (d) (1)
            //
            Enumeration e = certPolicies.getObjects();
            Set pols = new HashSet();

            while (e.hasMoreElements())
            {
                PolicyInformation pInfo = PolicyInformation.getInstance(e.nextElement());
                DERObjectIdentifier pOid = pInfo.getPolicyIdentifier();

                pols.add(pOid.getId());

                if (!RFC3280CertPathUtilities.ANY_POLICY.equals(pOid.getId()))
                {
                    Set pq = null;
                    try
                    {
                        pq = CertPathValidatorUtilities.getQualifierSet(pInfo.getPolicyQualifiers());
                    }
                    catch (CertPathValidatorException ex)
                    {
                        throw new ExtCertPathValidatorException("Policy qualifier info set could not be build.", ex,
                            certPath, index);
                    }

                    boolean match = CertPathValidatorUtilities.processCertD1i(i, policyNodes, pOid, pq);

                    if (!match)
                    {
                        CertPathValidatorUtilities.processCertD1ii(i, policyNodes, pOid, pq);
                    }
                }
            }

            if (acceptablePolicies.isEmpty() || acceptablePolicies.contains(RFC3280CertPathUtilities.ANY_POLICY))
            {
                acceptablePolicies.clear();
                acceptablePolicies.addAll(pols);
            }
            else
            {
                Iterator it = acceptablePolicies.iterator();
                Set t1 = new HashSet();

                while (it.hasNext())
                {
                    Object o = it.next();

                    if (pols.contains(o))
                    {
                        t1.add(o);
                    }
                }
                acceptablePolicies.clear();
                acceptablePolicies.addAll(t1);
            }

            //
            // (d) (2)
            //
            if ((inhibitAnyPolicy > 0) || ((i < n) && CertPathValidatorUtilities.isSelfIssued(cert)))
            {
                e = certPolicies.getObjects();

                while (e.hasMoreElements())
                {
                    PolicyInformation pInfo = PolicyInformation.getInstance(e.nextElement());

                    if (RFC3280CertPathUtilities.ANY_POLICY.equals(pInfo.getPolicyIdentifier().getId()))
                    {
                        Set _apq = CertPathValidatorUtilities.getQualifierSet(pInfo.getPolicyQualifiers());
                        List _nodes = policyNodes[i - 1];

                        for (int k = 0; k < _nodes.size(); k++)
                        {
                            PKIXPolicyNode _node = (PKIXPolicyNode)_nodes.get(k);

                            Iterator _policySetIter = _node.getExpectedPolicies().iterator();
                            while (_policySetIter.hasNext())
                            {
                                Object _tmp = _policySetIter.next();

                                String _policy;
                                if (_tmp instanceof String)
                                {
                                    _policy = (String)_tmp;
                                }
                                else if (_tmp instanceof DERObjectIdentifier)
                                {
                                    _policy = ((DERObjectIdentifier)_tmp).getId();
                                }
                                else
                                {
                                    continue;
                                }

                                boolean _found = false;
                                Iterator _childrenIter = _node.getChildren();

                                while (_childrenIter.hasNext())
                                {
                                    PKIXPolicyNode _child = (PKIXPolicyNode)_childrenIter.next();

                                    if (_policy.equals(_child.getValidPolicy()))
                                    {
                                        _found = true;
                                    }
                                }

                                if (!_found)
                                {
                                    Set _newChildExpectedPolicies = new HashSet();
                                    _newChildExpectedPolicies.add(_policy);

                                    PKIXPolicyNode _newChild = new PKIXPolicyNode(new ArrayList(), i,
                                        _newChildExpectedPolicies, _node, _apq, _policy, false);
                                    _node.addChild(_newChild);
                                    policyNodes[i].add(_newChild);
                                }
                            }
                        }
                        break;
                    }
                }
            }

            PKIXPolicyNode _validPolicyTree = validPolicyTree;
            //
            // (d) (3)
            //
            for (int j = (i - 1); j >= 0; j--)
            {
                List nodes = policyNodes[j];

                for (int k = 0; k < nodes.size(); k++)
                {
                    PKIXPolicyNode node = (PKIXPolicyNode)nodes.get(k);
                    if (!node.hasChildren())
                    {
                        _validPolicyTree = CertPathValidatorUtilities.removePolicyNode(_validPolicyTree, policyNodes,
                            node);
                        if (_validPolicyTree == null)
                        {
                            break;
                        }
                    }
                }
            }

            //
            // d (4)
            //
            Set criticalExtensionOids = cert.getCriticalExtensionOIDs();

            if (criticalExtensionOids != null)
            {
                boolean critical = criticalExtensionOids.contains(RFC3280CertPathUtilities.CERTIFICATE_POLICIES);

                List nodes = policyNodes[i];
                for (int j = 0; j < nodes.size(); j++)
                {
                    PKIXPolicyNode node = (PKIXPolicyNode)nodes.get(j);
                    node.setCritical(critical);
                }
            }
            return _validPolicyTree;
        }
        return null;
    }

    protected static void processCertA(
        CertPath certPath,
        ExtendedPKIXParameters paramsPKIX,
        int index,
        PublicKey workingPublicKey,
        boolean verificationAlreadyPerformed,
        X500Principal workingIssuerName,
        X509Certificate sign)
        throws ExtCertPathValidatorException
    {
        List certs = certPath.getCertificates();
        X509Certificate cert = (X509Certificate)certs.get(index);
        //
        // (a) verify
        //
        if (!verificationAlreadyPerformed)
        {
            try
            {
                // (a) (1)
                //
                CertPathValidatorUtilities.verifyX509Certificate(cert, workingPublicKey,
                    paramsPKIX.getSigProvider());
            }
            catch (GeneralSecurityException e)
            {
                throw new ExtCertPathValidatorException("Could not validate certificate signature.", e, certPath, index);
            }
        }

        try
        {
            // (a) (2)
            //
            cert.checkValidity(CertPathValidatorUtilities
                .getValidCertDateFromValidityModel(paramsPKIX, certPath, index));
        }
        catch (CertificateExpiredException e)
        {
            throw new ExtCertPathValidatorException("Could not validate certificate: " + e.getMessage(), e, certPath, index);
        }
        catch (CertificateNotYetValidException e)
        {
            throw new ExtCertPathValidatorException("Could not validate certificate: " + e.getMessage(), e, certPath, index);
        }
        catch (AnnotatedException e)
        {
            throw new ExtCertPathValidatorException("Could not validate time of certificate.", e, certPath, index);
        }

        //
        // (a) (3)
        //
        if (paramsPKIX.isRevocationEnabled())
        {
            try
            {
                checkCRLs(paramsPKIX, cert, CertPathValidatorUtilities.getValidCertDateFromValidityModel(paramsPKIX,
                    certPath, index), sign, workingPublicKey, certs);
            }
            catch (AnnotatedException e)
            {
                Throwable cause = e;
                if (null != e.getCause())
                {
                    cause = e.getCause();
                }
                throw new ExtCertPathValidatorException(e.getMessage(), cause, certPath, index);
            }
        }

        //
        // (a) (4) name chaining
        //
        if (!CertPathValidatorUtilities.getEncodedIssuerPrincipal(cert).equals(workingIssuerName))
        {
            throw new ExtCertPathValidatorException("IssuerName(" + CertPathValidatorUtilities.getEncodedIssuerPrincipal(cert)
                + ") does not match SubjectName(" + workingIssuerName + ") of signing certificate.", null,
                certPath, index);
        }
    }

    protected static int prepareNextCertI1(
        CertPath certPath,
        int index,
        int explicitPolicy)
        throws CertPathValidatorException
    {
        List certs = certPath.getCertificates();
        X509Certificate cert = (X509Certificate)certs.get(index);
        //
        // (i)
        //
        ASN1Sequence pc = null;
        try
        {
            pc = DERSequence.getInstance(CertPathValidatorUtilities.getExtensionValue(cert,
                RFC3280CertPathUtilities.POLICY_CONSTRAINTS));
        }
        catch (Exception e)
        {
            throw new ExtCertPathValidatorException("Policy constraints extension cannot be decoded.", e, certPath,
                index);
        }

        int tmpInt;

        if (pc != null)
        {
            Enumeration policyConstraints = pc.getObjects();

            while (policyConstraints.hasMoreElements())
            {
                try
                {

                    ASN1TaggedObject constraint = ASN1TaggedObject.getInstance(policyConstraints.nextElement());
                    if (constraint.getTagNo() == 0)
                    {
                        tmpInt = DERInteger.getInstance(constraint, false).getValue().intValue();
                        if (tmpInt < explicitPolicy)
                        {
                            return tmpInt;
                        }
                        break;
                    }
                }
                catch (IllegalArgumentException e)
                {
                    throw new ExtCertPathValidatorException("Policy constraints extension contents cannot be decoded.",
                        e, certPath, index);
                }
            }
        }
        return explicitPolicy;
    }

    protected static int prepareNextCertI2(
        CertPath certPath,
        int index,
        int policyMapping)
        throws CertPathValidatorException
    {
        List certs = certPath.getCertificates();
        X509Certificate cert = (X509Certificate)certs.get(index);
        //
        // (i)
        //
        ASN1Sequence pc = null;
        try
        {
            pc = DERSequence.getInstance(CertPathValidatorUtilities.getExtensionValue(cert,
                RFC3280CertPathUtilities.POLICY_CONSTRAINTS));
        }
        catch (Exception e)
        {
            throw new ExtCertPathValidatorException("Policy constraints extension cannot be decoded.", e, certPath,
                index);
        }

        int tmpInt;

        if (pc != null)
        {
            Enumeration policyConstraints = pc.getObjects();

            while (policyConstraints.hasMoreElements())
            {
                try
                {
                    ASN1TaggedObject constraint = ASN1TaggedObject.getInstance(policyConstraints.nextElement());
                    if (constraint.getTagNo() == 1)
                    {
                        tmpInt = DERInteger.getInstance(constraint, false).getValue().intValue();
                        if (tmpInt < policyMapping)
                        {
                            return tmpInt;
                        }
                        break;
                    }
                }
                catch (IllegalArgumentException e)
                {
                    throw new ExtCertPathValidatorException("Policy constraints extension contents cannot be decoded.",
                        e, certPath, index);
                }
            }
        }
        return policyMapping;
    }

    protected static void prepareNextCertG(
        CertPath certPath,
        int index,
        PKIXNameConstraintValidator nameConstraintValidator)
        throws CertPathValidatorException
    {
        List certs = certPath.getCertificates();
        X509Certificate cert = (X509Certificate)certs.get(index);
        //
        // (g) handle the name constraints extension
        //
        NameConstraints nc = null;
        try
        {
            ASN1Sequence ncSeq = DERSequence.getInstance(CertPathValidatorUtilities.getExtensionValue(cert,
                RFC3280CertPathUtilities.NAME_CONSTRAINTS));
            if (ncSeq != null)
            {
                nc = NameConstraints.getInstance(ncSeq);
            }
        }
        catch (Exception e)
        {
            throw new ExtCertPathValidatorException("Name constraints extension could not be decoded.", e, certPath,
                index);
        }
        if (nc != null)
        {

            //
            // (g) (1) permitted subtrees
            //
            ASN1Sequence permitted = nc.getPermittedSubtrees();
            if (permitted != null)
            {
                try
                {
                    nameConstraintValidator.intersectPermittedSubtree(permitted);
                }
                catch (Exception ex)
                {
                    throw new ExtCertPathValidatorException(
                        "Permitted subtrees cannot be build from name constraints extension.", ex, certPath, index);
                }
            }

            //
            // (g) (2) excluded subtrees
            //
            ASN1Sequence excluded = nc.getExcludedSubtrees();
            if (excluded != null)
            {
                Enumeration e = excluded.getObjects();
                try
                {
                    while (e.hasMoreElements())
                    {
                        GeneralSubtree subtree = GeneralSubtree.getInstance(e.nextElement());
                        nameConstraintValidator.addExcludedSubtree(subtree);
                    }
                }
                catch (Exception ex)
                {
                    throw new ExtCertPathValidatorException(
                        "Excluded subtrees cannot be build from name constraints extension.", ex, certPath, index);
                }
            }
        }
    }

    /**
     * Checks a distribution point for revocation information for the
     * certificate <code>cert</code>.
     *
     * @param dp                 The distribution point to consider.
     * @param paramsPKIX         PKIX parameters.
     * @param cert               Certificate to check if it is revoked.
     * @param validDate          The date when the certificate revocation status should be
     *                           checked.
     * @param defaultCRLSignCert The issuer certificate of the certificate <code>cert</code>.
     * @param defaultCRLSignKey  The public key of the issuer certificate
     *                           <code>defaultCRLSignCert</code>.
     * @param certStatus         The current certificate revocation status.
     * @param reasonMask         The reasons mask which is already checked.
     * @param certPathCerts      The certificates of the certification path.
     * @throws AnnotatedException if the certificate is revoked or the status cannot be checked
     *                            or some error occurs.
     */
    private static void checkCRL(
        DistributionPoint dp,
        ExtendedPKIXParameters paramsPKIX,
        X509Certificate cert,
        Date validDate,
        X509Certificate defaultCRLSignCert,
        PublicKey defaultCRLSignKey,
        CertStatus certStatus,
        ReasonsMask reasonMask,
        List certPathCerts)
        throws AnnotatedException
    {
        Date currentDate = new Date(System.currentTimeMillis());
        if (validDate.getTime() > currentDate.getTime())
        {
            throw new AnnotatedException("Validation time is in future.");
        }

        // (a)
        /*
         * We always get timely valid CRLs, so there is no step (a) (1).
         * "locally cached" CRLs are assumed to be in getStore(), additional
         * CRLs must be enabled in the ExtendedPKIXParameters and are in
         * getAdditionalStore()
         */

        Set crls = CertPathValidatorUtilities.getCompleteCRLs(dp, cert, currentDate, paramsPKIX);
        boolean validCrlFound = false;
        AnnotatedException lastException = null;
        Iterator crl_iter = crls.iterator();

        while (crl_iter.hasNext() && certStatus.getCertStatus() == CertStatus.UNREVOKED && !reasonMask.isAllReasons())
        {
            try
            {
                X509CRL crl = (X509CRL)crl_iter.next();

                // (d)
                ReasonsMask interimReasonsMask = RFC3280CertPathUtilities.processCRLD(crl, dp);

                // (e)
                /*
                 * The reasons mask is updated at the end, so only valid CRLs
                 * can update it. If this CRL does not contain new reasons it
                 * must be ignored.
                 */
                if (!interimReasonsMask.hasNewReasons(reasonMask))
                {
                    continue;
                }

                // (f)
                Set keys = RFC3280CertPathUtilities.processCRLF(crl, cert, defaultCRLSignCert, defaultCRLSignKey,
                    paramsPKIX, certPathCerts);
                // (g)
                PublicKey key = RFC3280CertPathUtilities.processCRLG(crl, keys);

                X509CRL deltaCRL = null;

                if (paramsPKIX.isUseDeltasEnabled())
                {
                    // get delta CRLs
                    Set deltaCRLs = CertPathValidatorUtilities.getDeltaCRLs(currentDate, paramsPKIX, crl);
                    // we only want one valid delta CRL
                    // (h)
                    deltaCRL = RFC3280CertPathUtilities.processCRLH(deltaCRLs, key);
                }

                /*
                 * CRL must be be valid at the current time, not the validation
                 * time. If a certificate is revoked with reason keyCompromise,
                 * cACompromise, it can be used for forgery, also for the past.
                 * This reason may not be contained in older CRLs.
                 */

                /*
                 * in the chain model signatures stay valid also after the
                 * certificate has been expired, so they do not have to be in
                 * the CRL validity time
                 */

                if (paramsPKIX.getValidityModel() != ExtendedPKIXParameters.CHAIN_VALIDITY_MODEL)
                {
                    /*
                     * if a certificate has expired, but was revoked, it is not
                     * more in the CRL, so it would be regarded as valid if the
                     * first check is not done
                     */
                    if (cert.getNotAfter().getTime() < crl.getThisUpdate().getTime())
                    {
                        throw new AnnotatedException("No valid CRL for current time found.");
                    }
                }

                RFC3280CertPathUtilities.processCRLB1(dp, cert, crl);

                // (b) (2)
                RFC3280CertPathUtilities.processCRLB2(dp, cert, crl);

                // (c)
                RFC3280CertPathUtilities.processCRLC(deltaCRL, crl, paramsPKIX);

                // (i)
                RFC3280CertPathUtilities.processCRLI(validDate, deltaCRL, cert, certStatus, paramsPKIX);

                // (j)
                RFC3280CertPathUtilities.processCRLJ(validDate, crl, cert, certStatus);

                // (k)
                if (certStatus.getCertStatus() == CRLReason.removeFromCRL)
                {
                    certStatus.setCertStatus(CertStatus.UNREVOKED);
                }

                // update reasons mask
                reasonMask.addReasons(interimReasonsMask);

                Set criticalExtensions = crl.getCriticalExtensionOIDs();
                if (criticalExtensions != null)
                {
                    criticalExtensions = new HashSet(criticalExtensions);
                    criticalExtensions.remove(X509Extensions.IssuingDistributionPoint.getId());
                    criticalExtensions.remove(X509Extensions.DeltaCRLIndicator.getId());

                    if (!criticalExtensions.isEmpty())
                    {
                        throw new AnnotatedException("CRL contains unsupported critical extensions.");
                    }
                }

                if (deltaCRL != null)
                {
                    criticalExtensions = deltaCRL.getCriticalExtensionOIDs();
                    if (criticalExtensions != null)
                    {
                        criticalExtensions = new HashSet(criticalExtensions);
                        criticalExtensions.remove(X509Extensions.IssuingDistributionPoint.getId());
                        criticalExtensions.remove(X509Extensions.DeltaCRLIndicator.getId());
                        if (!criticalExtensions.isEmpty())
                        {
                            throw new AnnotatedException("Delta CRL contains unsupported critical extension.");
                        }
                    }
                }

                validCrlFound = true;
            }
            catch (AnnotatedException e)
            {
                lastException = e;
            }
        }
        if (!validCrlFound)
        {
            throw lastException;
        }
    }

    /**
     * Checks a certificate if it is revoked.
     *
     * @param paramsPKIX       PKIX parameters.
     * @param cert             Certificate to check if it is revoked.
     * @param validDate        The date when the certificate revocation status should be
     *                         checked.
     * @param sign             The issuer certificate of the certificate <code>cert</code>.
     * @param workingPublicKey The public key of the issuer certificate <code>sign</code>.
     * @param certPathCerts    The certificates of the certification path.
     * @throws AnnotatedException if the certificate is revoked or the status cannot be checked
     *                            or some error occurs.
     */
    protected static void checkCRLs(
        ExtendedPKIXParameters paramsPKIX,
        X509Certificate cert,
        Date validDate,
        X509Certificate sign,
        PublicKey workingPublicKey,
        List certPathCerts)
        throws AnnotatedException
    {
        AnnotatedException lastException = null;
        CRLDistPoint crldp = null;
        try
        {
            crldp = CRLDistPoint.getInstance(CertPathValidatorUtilities.getExtensionValue(cert,
                RFC3280CertPathUtilities.CRL_DISTRIBUTION_POINTS));
        }
        catch (Exception e)
        {
            throw new AnnotatedException("CRL distribution point extension could not be read.", e);
        }
        try
        {
            CertPathValidatorUtilities.addAdditionalStoresFromCRLDistributionPoint(crldp, paramsPKIX);
        }
        catch (AnnotatedException e)
        {
            throw new AnnotatedException(
                "No additional CRL locations could be decoded from CRL distribution point extension.", e);
        }
        CertStatus certStatus = new CertStatus();
        ReasonsMask reasonsMask = new ReasonsMask();

        boolean validCrlFound = false;
        // for each distribution point
        if (crldp != null)
        {
            DistributionPoint dps[] = null;
            try
            {
                dps = crldp.getDistributionPoints();
            }
            catch (Exception e)
            {
                throw new AnnotatedException("Distribution points could not be read.", e);
            }
            if (dps != null)
            {
                for (int i = 0; i < dps.length && certStatus.getCertStatus() == CertStatus.UNREVOKED && !reasonsMask.isAllReasons(); i++)
                {
                    ExtendedPKIXParameters paramsPKIXClone = (ExtendedPKIXParameters)paramsPKIX.clone();
                    try
                    {
                        checkCRL(dps[i], paramsPKIXClone, cert, validDate, sign, workingPublicKey, certStatus, reasonsMask, certPathCerts);
                        validCrlFound = true;
                    }
                    catch (AnnotatedException e)
                    {
                        lastException = e;
                    }
                }
            }
        }

        /*
         * If the revocation status has not been determined, repeat the process
         * above with any available CRLs not specified in a distribution point
         * but issued by the certificate issuer.
         */

        if (certStatus.getCertStatus() == CertStatus.UNREVOKED && !reasonsMask.isAllReasons())
        {
            try
            {
                /*
                 * assume a DP with both the reasons and the cRLIssuer fields
                 * omitted and a distribution point name of the certificate
                 * issuer.
                 */
                ASN1Primitive issuer = null;
                try
                {
                    issuer = new ASN1InputStream(CertPathValidatorUtilities.getEncodedIssuerPrincipal(cert).getEncoded())
                        .readObject();
                }
                catch (Exception e)
                {
                    throw new AnnotatedException("Issuer from certificate for CRL could not be reencoded.", e);
                }
                DistributionPoint dp = new DistributionPoint(new DistributionPointName(0, new GeneralNames(
                    new GeneralName(GeneralName.directoryName, issuer))), null, null);
                ExtendedPKIXParameters paramsPKIXClone = (ExtendedPKIXParameters)paramsPKIX.clone();
                checkCRL(dp, paramsPKIXClone, cert, validDate, sign, workingPublicKey, certStatus, reasonsMask,
                    certPathCerts);
                validCrlFound = true;
            }
            catch (AnnotatedException e)
            {
                lastException = e;
            }
        }

        if (!validCrlFound)
        {
            if (lastException instanceof AnnotatedException)
            {
                throw lastException;
            }

            throw new AnnotatedException("No valid CRL found.", lastException);
        }
        if (certStatus.getCertStatus() != CertStatus.UNREVOKED)
        {
            String message = "Certificate revocation after " + certStatus.getRevocationDate();
            message += ", reason: " + crlReasons[certStatus.getCertStatus()];
            throw new AnnotatedException(message);
        }
        if (!reasonsMask.isAllReasons() && certStatus.getCertStatus() == CertStatus.UNREVOKED)
        {
            certStatus.setCertStatus(CertStatus.UNDETERMINED);
        }
        if (certStatus.getCertStatus() == CertStatus.UNDETERMINED)
        {
            throw new AnnotatedException("Certificate status could not be determined.");
        }
    }

    protected static int prepareNextCertJ(
        CertPath certPath,
        int index,
        int inhibitAnyPolicy)
        throws CertPathValidatorException
    {
        List certs = certPath.getCertificates();
        X509Certificate cert = (X509Certificate)certs.get(index);
        //
        // (j)
        //
        DERInteger iap = null;
        try
        {
            iap = DERInteger.getInstance(CertPathValidatorUtilities.getExtensionValue(cert,
                RFC3280CertPathUtilities.INHIBIT_ANY_POLICY));
        }
        catch (Exception e)
        {
            throw new ExtCertPathValidatorException("Inhibit any-policy extension cannot be decoded.", e, certPath,
                index);
        }

        if (iap != null)
        {
            int _inhibitAnyPolicy = iap.getValue().intValue();

            if (_inhibitAnyPolicy < inhibitAnyPolicy)
            {
                return _inhibitAnyPolicy;
            }
        }
        return inhibitAnyPolicy;
    }

    protected static void prepareNextCertK(
        CertPath certPath,
        int index)
        throws CertPathValidatorException
    {
        List certs = certPath.getCertificates();
        X509Certificate cert = (X509Certificate)certs.get(index);
        //
        // (k)
        //
        BasicConstraints bc = null;
        try
        {
            bc = BasicConstraints.getInstance(CertPathValidatorUtilities.getExtensionValue(cert,
                RFC3280CertPathUtilities.BASIC_CONSTRAINTS));
        }
        catch (Exception e)
        {
            throw new ExtCertPathValidatorException("Basic constraints extension cannot be decoded.", e, certPath,
                index);
        }
        if (bc != null)
        {
            if (!(bc.isCA()))
            {
                throw new CertPathValidatorException("Not a CA certificate");
            }
        }
        else
        {
            throw new CertPathValidatorException("Intermediate certificate lacks BasicConstraints");
        }
    }

    protected static int prepareNextCertL(
        CertPath certPath,
        int index,
        int maxPathLength)
        throws CertPathValidatorException
    {
        List certs = certPath.getCertificates();
        X509Certificate cert = (X509Certificate)certs.get(index);
        //
        // (l)
        //
        if (!CertPathValidatorUtilities.isSelfIssued(cert))
        {
            if (maxPathLength <= 0)
            {
                throw new ExtCertPathValidatorException("Max path length not greater than zero", null, certPath, index);
            }

            return maxPathLength - 1;
        }
        return maxPathLength;
    }

    protected static int prepareNextCertM(
        CertPath certPath,
        int index,
        int maxPathLength)
        throws CertPathValidatorException
    {
        List certs = certPath.getCertificates();
        X509Certificate cert = (X509Certificate)certs.get(index);

        //
        // (m)
        //
        BasicConstraints bc = null;
        try
        {
            bc = BasicConstraints.getInstance(CertPathValidatorUtilities.getExtensionValue(cert,
                RFC3280CertPathUtilities.BASIC_CONSTRAINTS));
        }
        catch (Exception e)
        {
            throw new ExtCertPathValidatorException("Basic constraints extension cannot be decoded.", e, certPath,
                index);
        }
        if (bc != null)
        {
            BigInteger _pathLengthConstraint = bc.getPathLenConstraint();

            if (_pathLengthConstraint != null)
            {
                int _plc = _pathLengthConstraint.intValue();

                if (_plc < maxPathLength)
                {
                    return _plc;
                }
            }
        }
        return maxPathLength;
    }

    protected static void prepareNextCertN(
        CertPath certPath,
        int index)
        throws CertPathValidatorException
    {
        List certs = certPath.getCertificates();
        X509Certificate cert = (X509Certificate)certs.get(index);

        //
        // (n)
        //
        boolean[] _usage = cert.getKeyUsage();

        if ((_usage != null) && !_usage[RFC3280CertPathUtilities.KEY_CERT_SIGN])
        {
            throw new ExtCertPathValidatorException(
                "Issuer certificate keyusage extension is critical and does not permit key signing.", null,
                certPath, index);
        }
    }

    protected static void prepareNextCertO(
        CertPath certPath,
        int index,
        Set criticalExtensions,
        List pathCheckers)
        throws CertPathValidatorException
    {
        List certs = certPath.getCertificates();
        X509Certificate cert = (X509Certificate)certs.get(index);
        //
        // (o)
        //

        Iterator tmpIter;
        tmpIter = pathCheckers.iterator();
        while (tmpIter.hasNext())
        {
            try
            {
                ((PKIXCertPathChecker)tmpIter.next()).check(cert, criticalExtensions);
            }
            catch (CertPathValidatorException e)
            {
                throw new CertPathValidatorException(e.getMessage(), e.getCause(), certPath, index);
            }
        }
        if (!criticalExtensions.isEmpty())
        {
            throw new ExtCertPathValidatorException("Certificate has unsupported critical extension.", null, certPath,
                index);
        }
    }

    protected static int prepareNextCertH1(
        CertPath certPath,
        int index,
        int explicitPolicy)
    {
        List certs = certPath.getCertificates();
        X509Certificate cert = (X509Certificate)certs.get(index);
        //
        // (h)
        //
        if (!CertPathValidatorUtilities.isSelfIssued(cert))
        {
            //
            // (1)
            //
            if (explicitPolicy != 0)
            {
                return explicitPolicy - 1;
            }
        }
        return explicitPolicy;
    }

    protected static int prepareNextCertH2(
        CertPath certPath,
        int index,
        int policyMapping)
    {
        List certs = certPath.getCertificates();
        X509Certificate cert = (X509Certificate)certs.get(index);
        //
        // (h)
        //
        if (!CertPathValidatorUtilities.isSelfIssued(cert))
        {
            //
            // (2)
            //
            if (policyMapping != 0)
            {
                return policyMapping - 1;
            }
        }
        return policyMapping;
    }

    protected static int prepareNextCertH3(
        CertPath certPath,
        int index,
        int inhibitAnyPolicy)
    {
        List certs = certPath.getCertificates();
        X509Certificate cert = (X509Certificate)certs.get(index);
        //
        // (h)
        //
        if (!CertPathValidatorUtilities.isSelfIssued(cert))
        {
            //
            // (3)
            //
            if (inhibitAnyPolicy != 0)
            {
                return inhibitAnyPolicy - 1;
            }
        }
        return inhibitAnyPolicy;
    }

    protected static final String[] crlReasons = new String[]
        {
            "unspecified",
            "keyCompromise",
            "cACompromise",
            "affiliationChanged",
            "superseded",
            "cessationOfOperation",
            "certificateHold",
            "unknown",
            "removeFromCRL",
            "privilegeWithdrawn",
            "aACompromise"};

    protected static int wrapupCertA(
        int explicitPolicy,
        X509Certificate cert)
    {
        //
        // (a)
        //
        if (!CertPathValidatorUtilities.isSelfIssued(cert) && (explicitPolicy != 0))
        {
            explicitPolicy--;
        }
        return explicitPolicy;
    }

    protected static int wrapupCertB(
        CertPath certPath,
        int index,
        int explicitPolicy)
        throws CertPathValidatorException
    {
        List certs = certPath.getCertificates();
        X509Certificate cert = (X509Certificate)certs.get(index);
        //
        // (b)
        //
        int tmpInt;
        ASN1Sequence pc = null;
        try
        {
            pc = DERSequence.getInstance(CertPathValidatorUtilities.getExtensionValue(cert,
                RFC3280CertPathUtilities.POLICY_CONSTRAINTS));
        }
        catch (AnnotatedException e)
        {
            throw new ExtCertPathValidatorException("Policy constraints could not be decoded.", e, certPath, index);
        }
        if (pc != null)
        {
            Enumeration policyConstraints = pc.getObjects();

            while (policyConstraints.hasMoreElements())
            {
                ASN1TaggedObject constraint = (ASN1TaggedObject)policyConstraints.nextElement();
                switch (constraint.getTagNo())
                {
                    case 0:
                        try
                        {
                            tmpInt = DERInteger.getInstance(constraint, false).getValue().intValue();
                        }
                        catch (Exception e)
                        {
                            throw new ExtCertPathValidatorException(
                                "Policy constraints requireExplicitPolicy field could not be decoded.", e, certPath,
                                index);
                        }
                        if (tmpInt == 0)
                        {
                            return 0;
                        }
                        break;
                }
            }
        }
        return explicitPolicy;
    }

    protected static void wrapupCertF(
        CertPath certPath,
        int index,
        List pathCheckers,
        Set criticalExtensions)
        throws CertPathValidatorException
    {
        List certs = certPath.getCertificates();
        X509Certificate cert = (X509Certificate)certs.get(index);
        Iterator tmpIter;
        tmpIter = pathCheckers.iterator();
        while (tmpIter.hasNext())
        {
            try
            {
                ((PKIXCertPathChecker)tmpIter.next()).check(cert, criticalExtensions);
            }
            catch (CertPathValidatorException e)
            {
                throw new ExtCertPathValidatorException("Additional certificate path checker failed.", e, certPath,
                    index);
            }
        }

        if (!criticalExtensions.isEmpty())
        {
            throw new ExtCertPathValidatorException("Certificate has unsupported critical extension", null, certPath,
                index);
        }
    }

    protected static PKIXPolicyNode wrapupCertG(
        CertPath certPath,
        ExtendedPKIXParameters paramsPKIX,
        Set userInitialPolicySet,
        int index,
        List[] policyNodes,
        PKIXPolicyNode validPolicyTree,
        Set acceptablePolicies)
        throws CertPathValidatorException
    {
        int n = certPath.getCertificates().size();
        //
        // (g)
        //
        PKIXPolicyNode intersection;

        //
        // (g) (i)
        //
        if (validPolicyTree == null)
        {
            if (paramsPKIX.isExplicitPolicyRequired())
            {
                throw new ExtCertPathValidatorException("Explicit policy requested but none available.", null,
                    certPath, index);
            }
            intersection = null;
        }
        else if (CertPathValidatorUtilities.isAnyPolicy(userInitialPolicySet)) // (g)
        // (ii)
        {
            if (paramsPKIX.isExplicitPolicyRequired())
            {
                if (acceptablePolicies.isEmpty())
                {
                    throw new ExtCertPathValidatorException("Explicit policy requested but none available.", null,
                        certPath, index);
                }
                else
                {
                    Set _validPolicyNodeSet = new HashSet();

                    for (int j = 0; j < policyNodes.length; j++)
                    {
                        List _nodeDepth = policyNodes[j];

                        for (int k = 0; k < _nodeDepth.size(); k++)
                        {
                            PKIXPolicyNode _node = (PKIXPolicyNode)_nodeDepth.get(k);

                            if (RFC3280CertPathUtilities.ANY_POLICY.equals(_node.getValidPolicy()))
                            {
                                Iterator _iter = _node.getChildren();
                                while (_iter.hasNext())
                                {
                                    _validPolicyNodeSet.add(_iter.next());
                                }
                            }
                        }
                    }

                    Iterator _vpnsIter = _validPolicyNodeSet.iterator();
                    while (_vpnsIter.hasNext())
                    {
                        PKIXPolicyNode _node = (PKIXPolicyNode)_vpnsIter.next();
                        String _validPolicy = _node.getValidPolicy();

                        if (!acceptablePolicies.contains(_validPolicy))
                        {
                            // validPolicyTree =
                            // removePolicyNode(validPolicyTree, policyNodes,
                            // _node);
                        }
                    }
                    if (validPolicyTree != null)
                    {
                        for (int j = (n - 1); j >= 0; j--)
                        {
                            List nodes = policyNodes[j];

                            for (int k = 0; k < nodes.size(); k++)
                            {
                                PKIXPolicyNode node = (PKIXPolicyNode)nodes.get(k);
                                if (!node.hasChildren())
                                {
                                    validPolicyTree = CertPathValidatorUtilities.removePolicyNode(validPolicyTree,
                                        policyNodes, node);
                                }
                            }
                        }
                    }
                }
            }

            intersection = validPolicyTree;
        }
        else
        {
            //
            // (g) (iii)
            //
            // This implementation is not exactly same as the one described in
            // RFC3280.
            // However, as far as the validation result is concerned, both
            // produce
            // adequate result. The only difference is whether AnyPolicy is
            // remain
            // in the policy tree or not.
            //
            // (g) (iii) 1
            //
            Set _validPolicyNodeSet = new HashSet();

            for (int j = 0; j < policyNodes.length; j++)
            {
                List _nodeDepth = policyNodes[j];

                for (int k = 0; k < _nodeDepth.size(); k++)
                {
                    PKIXPolicyNode _node = (PKIXPolicyNode)_nodeDepth.get(k);

                    if (RFC3280CertPathUtilities.ANY_POLICY.equals(_node.getValidPolicy()))
                    {
                        Iterator _iter = _node.getChildren();
                        while (_iter.hasNext())
                        {
                            PKIXPolicyNode _c_node = (PKIXPolicyNode)_iter.next();
                            if (!RFC3280CertPathUtilities.ANY_POLICY.equals(_c_node.getValidPolicy()))
                            {
                                _validPolicyNodeSet.add(_c_node);
                            }
                        }
                    }
                }
            }

            //
            // (g) (iii) 2
            //
            Iterator _vpnsIter = _validPolicyNodeSet.iterator();
            while (_vpnsIter.hasNext())
            {
                PKIXPolicyNode _node = (PKIXPolicyNode)_vpnsIter.next();
                String _validPolicy = _node.getValidPolicy();

                if (!userInitialPolicySet.contains(_validPolicy))
                {
                    validPolicyTree = CertPathValidatorUtilities.removePolicyNode(validPolicyTree, policyNodes, _node);
                }
            }

            //
            // (g) (iii) 4
            //
            if (validPolicyTree != null)
            {
                for (int j = (n - 1); j >= 0; j--)
                {
                    List nodes = policyNodes[j];

                    for (int k = 0; k < nodes.size(); k++)
                    {
                        PKIXPolicyNode node = (PKIXPolicyNode)nodes.get(k);
                        if (!node.hasChildren())
                        {
                            validPolicyTree = CertPathValidatorUtilities.removePolicyNode(validPolicyTree, policyNodes,
                                node);
                        }
                    }
                }
            }

            intersection = validPolicyTree;
        }
        return intersection;
    }

}
