if (p.onlyContainsUserCerts() && (bc == null || bc.isCA()))
if (p.onlyContainsUserCerts() && (bc != null && bc.isCA()))
    public CertPathValidatorResult engineValidate(        CertPath certPath,        CertPathParameters params)        throws CertPathValidatorException, InvalidAlgorithmParameterException    {        if (!(params instanceof PKIXParameters))        {            throw new InvalidAlgorithmParameterException("params must be a PKIXParameters instance");        }        PKIXParameters paramsPKIX = (PKIXParameters)params;        if (paramsPKIX.getTrustAnchors() == null)        {            throw new InvalidAlgorithmParameterException("trustAnchors is null, this is not allowed for path validation");        }        //        // 6.1.1 - inputs        //        //        // (a)        //        List    certs = certPath.getCertificates();        int     n = certs.size();                if (certs.isEmpty())        {            throw new CertPathValidatorException("CertPath is empty", null, certPath, 0);        }        //        // (b)        //        Date validDate = paramsPKIX.getDate();        if (validDate == null)        {            validDate = new Date();        }        //        // (c)        //        Set userInitialPolicySet = paramsPKIX.getInitialPolicies();        //        // (d)        //         TrustAnchor trust = findTrustAnchor((X509Certificate)certs.get(certs.size() - 1), certPath, certs.size() - 1, paramsPKIX.getTrustAnchors());        if (trust == null)        {            throw new CertPathValidatorException("TrustAnchor for CertPath not found.", null, certPath, -1);        }                //        // (e), (f), (g) are part of the paramsPKIX object.        //        Iterator certIter;        int index = 0;        int i;        //Certificate for each interation of the validation loop        //Signature information for each iteration of the validation loop        Set subTreeContraints = new HashSet();        Set subTreeExcludes = new HashSet();        //        // 6.1.2 - setup        //        //        // (a)        //        List     []  policyNodes = new ArrayList[n + 1];        for (int j = 0; j < policyNodes.length; j++)        {            policyNodes[j] = new ArrayList();        }        Set policySet = new HashSet();        policySet.add(ANY_POLICY);        PKIXPolicyNode  validPolicyTree = new PKIXPolicyNode(new ArrayList(), 0, policySet, null, new HashSet(), ANY_POLICY, false);        policyNodes[0].add(validPolicyTree);        //        // (b)        //        Set     permittedSubtreesDN = new HashSet();        Set     permittedSubtreesEmail = new HashSet();        Set     permittedSubtreesIP = new HashSet();            //        // (c)        //        Set     excludedSubtreesDN = new HashSet();        Set     excludedSubtreesEmail = new HashSet();        Set     excludedSubtreesIP = new HashSet();            //        // (d)        //        int explicitPolicy;        Set acceptablePolicies = null;        if (paramsPKIX.isExplicitPolicyRequired())        {            explicitPolicy = 0;        }        else        {            explicitPolicy = n + 1;        }        //        // (e)        //        int inhibitAnyPolicy;        if (paramsPKIX.isAnyPolicyInhibited())        {            inhibitAnyPolicy = 0;        }        else        {            inhibitAnyPolicy = n + 1;        }            //        // (f)        //        int policyMapping;        if (paramsPKIX.isPolicyMappingInhibited())        {            policyMapping = 0;        }        else        {            policyMapping = n + 1;        }            //        // (g), (h), (i), (j)        //        PublicKey workingPublicKey;        X509Principal workingIssuerName;        X509Certificate sign = trust.getTrustedCert();        try        {            if (sign != null)            {                workingIssuerName = getSubjectPrincipal(sign);                workingPublicKey = sign.getPublicKey();            }            else            {                workingIssuerName = new X509Principal(trust.getCAName());                workingPublicKey = trust.getCAPublicKey();            }        }        catch (IllegalArgumentException ex)        {            throw new CertPathValidatorException("TrustAnchor subjectDN: " + ex.toString());        }        AlgorithmIdentifier workingAlgId = getAlgorithmIdentifier(workingPublicKey);        DERObjectIdentifier workingPublicKeyAlgorithm = workingAlgId.getObjectId();        DEREncodable        workingPublicKeyParameters = workingAlgId.getParameters();            //        // (k)        //        int maxPathLength = n;        //        // 6.1.3        //        Iterator tmpIter;        byte[] tmpData;        int tmpInt;        boolean tmpTest;        X509CRLSelector crlselect;        X509CertSelector certselect;        CertStore certstore;        if (paramsPKIX.getTargetCertConstraints() != null            && !paramsPKIX.getTargetCertConstraints().match((X509Certificate)certs.get(0)))        {            throw new CertPathValidatorException("target certificate in certpath does not match targetcertconstraints", null, certPath, 0);        }        //         // initialise CertPathChecker's        //        List  pathCheckers = paramsPKIX.getCertPathCheckers();        certIter = pathCheckers.iterator();        while (certIter.hasNext())        {            ((PKIXCertPathChecker)certIter.next()).init(false);        }        X509Certificate cert = null;        for (index = certs.size() - 1; index >= 0 ; index--)        {            //            // i as defined in the algorithm description            //            i = n - index;            //            // set certificate to be checked in this round            // sign and workingPublicKey and workingIssuerName are set            // at the end of the for loop and initialied the            // first time from the TrustAnchor            //            cert = (X509Certificate)certs.get(index);            //            // 6.1.3            //            //            // (a) verify            //            try            {                // (a) (1)                //                cert.verify(workingPublicKey, "BC");            }            catch (GeneralSecurityException e)            {                throw new CertPathValidatorException("Could not validate certificate signature.", e, certPath, index);            }            try            {                // (a) (2)                //                cert.checkValidity(validDate);            }            catch (CertificateExpiredException e)            {                throw new CertPathValidatorException("Could not validate certificate: " + e.getMessage(), e, certPath, index);            }            catch (CertificateNotYetValidException e)            {                throw new CertPathValidatorException("Could not validate certificate: " + e.getMessage(), e, certPath, index);            }            //            // (a) (3)            //            if (paramsPKIX.isRevocationEnabled())            {                tmpTest = false;                crlselect = new X509CRLSelector();                try                {                    crlselect.addIssuerName(getEncodedIssuerPrincipal(cert).getEncoded());                }                catch (IOException e)                {                    throw new CertPathValidatorException("Cannot extract issuer from certificate: " + e);                }                crlselect.setCertificateChecking(cert);                Iterator crl_iter = findCRLs(crlselect, paramsPKIX.getCertStores()).iterator();                X509CRLEntry crl_entry;                while (crl_iter.hasNext())                {                    X509CRL crl = (X509CRL)crl_iter.next();                    if (cert.getNotAfter().after(crl.getThisUpdate()))                    {                        if (crl.getNextUpdate() == null                            || validDate.before(crl.getNextUpdate()))                         {                            tmpTest = true;                        }                        if (sign != null)                        {                            boolean[] keyusage = sign.getKeyUsage();                            if (keyusage != null                                && (keyusage.length < 7 || !keyusage[CRL_SIGN]))                            {                                throw new CertPathValidatorException(                                    "Issuer certificate keyusage extension does not permit crl signing.\n" + sign,                                    null, certPath, index);                            }                        }                        try                        {                            crl.verify(workingPublicKey, "BC");                        }                        catch (Exception e)                        {                            throw new CertPathValidatorException("can't verify CRL: " + e);                        }                        crl_entry = crl.getRevokedCertificate(cert.getSerialNumber());                        if (crl_entry != null                            && !validDate.before(crl_entry.getRevocationDate()))                        {                            String reason = null;                                                        if (crl_entry.hasExtensions())                            {                                DEREnumerated reasonCode = DEREnumerated.getInstance(getExtensionValue(crl_entry, X509Extensions.ReasonCode.getId()));                                if (reasonCode != null)                                {                                    reason = crlReasons[reasonCode.getValue().intValue()];                                }                            }                                                        String message = "Certificate revocation after " + crl_entry.getRevocationDate();                                                        if (reason != null)                            {                                message += ", reason: " + reason;                            }                                                        throw new CertPathValidatorException(message, null, certPath, index);                        }                        //                        // check the DeltaCRL indicator, base point and the issuing distribution point                        //                        DERObject idp = getExtensionValue(crl, ISSUING_DISTRIBUTION_POINT);                        DERObject dci = getExtensionValue(crl, DELTA_CRL_INDICATOR);                        if (dci != null)                        {                            X509CRLSelector baseSelect = new X509CRLSelector();                            try                            {                                baseSelect.addIssuerName(getIssuerPrincipal(crl).getEncoded());                            }                            catch (IOException e)                            {                                throw new CertPathValidatorException("can't extract issuer from certificate: " + e);                            }                            baseSelect.setMinCRLNumber(((DERInteger)dci).getPositiveValue());                            baseSelect.setMaxCRLNumber(((DERInteger)getExtensionValue(crl, CRL_NUMBER)).getPositiveValue().subtract(BigInteger.valueOf(1)));                                                        boolean  foundBase = false;                            Iterator it  = findCRLs(baseSelect, paramsPKIX.getCertStores()).iterator();                            while (it.hasNext())                            {                                X509CRL base = (X509CRL)it.next();                                DERObject baseIdp = getExtensionValue(base, ISSUING_DISTRIBUTION_POINT);                                                                if (idp == null)                                {                                    if (baseIdp == null)                                    {                                        foundBase = true;                                        break;                                    }                                }                                else                                {                                    if (idp.equals(baseIdp))                                    {                                        foundBase = true;                                        break;                                    }                                }                            }                                                        if (!foundBase)                            {                                throw new CertPathValidatorException("No base CRL for delta CRL");                            }                        }                        if (idp != null)                        {                            IssuingDistributionPoint    p = IssuingDistributionPoint.getInstance(idp);                            BasicConstraints    bc = BasicConstraints.getInstance(getExtensionValue(cert, BASIC_CONSTRAINTS));                                                        if (p.onlyContainsUserCerts() && (bc == null || bc.isCA()))                            {                                throw new CertPathValidatorException("CA Cert CRL only contains user certificates");                            }                                                        if (p.onlyContainsCACerts() && (bc == null || !bc.isCA()))                            {                                throw new CertPathValidatorException("End CRL only contains CA certificates");                            }                                                        if (p.onlyContainsAttributeCerts())                            {                                throw new CertPathValidatorException("onlyContainsAttributeCerts boolean is asserted");                            }                        }                    }                }                if (!tmpTest)                {                    throw new CertPathValidatorException("no valid CRL found", null, certPath, index);                }            }            //            // (a) (4) name chaining            //            if (!getEncodedIssuerPrincipal(cert).equals(workingIssuerName))            {                throw new CertPathValidatorException(                            "IssuerName(" + getEncodedIssuerPrincipal(cert) +                            ") does not match SubjectName(" + workingIssuerName +                            ") of signing certificate", null, certPath, index);            }            //            // (b), (c) permitted and excluded subtree checking.            //            if (!(isSelfIssued(cert) && (i < n)))            {                X509Principal principal = getSubjectPrincipal(cert);                ASN1InputStream aIn = new ASN1InputStream(new ByteArrayInputStream(principal.getEncoded()));                ASN1Sequence    dns;                try                {                    dns = (ASN1Sequence)aIn.readObject();                }                catch (IOException e)                {                    throw new CertPathValidatorException("exception extracting subject name when checking subtrees");                }                checkPermittedDN(permittedSubtreesDN, dns);                checkExcludedDN(excludedSubtreesDN, dns);                        ASN1Sequence   altName = (ASN1Sequence)getExtensionValue(cert, SUBJECT_ALTERNATIVE_NAME);                if (altName != null)                {                    for (int j = 0; j < altName.size(); j++)                    {                        ASN1TaggedObject o = (ASN1TaggedObject)altName.getObjectAt(j);                        switch(o.getTagNo())                        {                        case 1:                            String email = DERIA5String.getInstance(o, true).getString();                            checkPermittedEmail(permittedSubtreesEmail, email);                            checkExcludedEmail(excludedSubtreesEmail, email);                            break;                        case 4:                            ASN1Sequence altDN = ASN1Sequence.getInstance(o, true);                            checkPermittedDN(permittedSubtreesDN, altDN);                            checkExcludedDN(excludedSubtreesDN, altDN);                            break;                        case 7:                            byte[] ip = ASN1OctetString.getInstance(o, true).getOctets();                            checkPermittedIP(permittedSubtreesIP, ip);                            checkExcludedIP(excludedSubtreesIP, ip);                        }                    }                }            }            //            // (d) policy Information checking against initial policy and            // policy mapping            //            ASN1Sequence   certPolicies = (ASN1Sequence)getExtensionValue(cert, CERTIFICATE_POLICIES);            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 (!ANY_POLICY.equals(pOid.getId()))                    {                        Set pq = getQualifierSet(pInfo.getPolicyQualifiers());                                                boolean match = processCertD1i(i, policyNodes, pOid, pq);                                                if (!match)                        {                            processCertD1ii(i, policyNodes, pOid, pq);                        }                    }                }                if (acceptablePolicies == null || acceptablePolicies.contains(ANY_POLICY))                {                    acceptablePolicies = 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 = t1;                }                //                // (d) (2)                //                if ((inhibitAnyPolicy > 0) || ((i < n) && isSelfIssued(cert)))                {                    e = certPolicies.getObjects();                    while (e.hasMoreElements())                    {                        PolicyInformation   pInfo = PolicyInformation.getInstance(e.nextElement());                        if (ANY_POLICY.equals(pInfo.getPolicyIdentifier().getId()))                        {                            Set    _apq   = 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;                        }                    }                }                            //                // (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 = removePolicyNode(validPolicyTree, policyNodes, node);                            if (validPolicyTree == null)                            {                                break;                            }                        }                    }                }                            //                // d (4)                //                Set criticalExtensionOids = cert.getCriticalExtensionOIDs();                                if (criticalExtensionOids != null)                {                    boolean critical = criticalExtensionOids.contains(CERTIFICATE_POLICIES);                                    List      nodes = policyNodes[i];                    for (int j = 0; j < nodes.size(); j++)                    {                        PKIXPolicyNode node = (PKIXPolicyNode)nodes.get(j);                        node.setCritical(critical);                    }                }            }            //             // (e)            //            if (certPolicies == null)            {                validPolicyTree = null;            }            //            // (f)            //            if (explicitPolicy <= 0 && validPolicyTree == null)            {                throw new CertPathValidatorException("No valid policy tree found when one expected.");            }            //            // 6.1.4            //            if (i != n)            {                if (cert != null && cert.getVersion() == 1)                {                    throw new CertPathValidatorException(                            "Version 1 certs can't be used as CA ones");                }                //                // (a) check the policy mappings                //                DERObject   pm = getExtensionValue(cert, POLICY_MAPPINGS);                if (pm != null)                {                    ASN1Sequence mappings = (ASN1Sequence)pm;                                    for (int j = 0; j < mappings.size(); j++)                    {                        ASN1Sequence    mapping = (ASN1Sequence)mappings.getObjectAt(j);                        DERObjectIdentifier issuerDomainPolicy = (DERObjectIdentifier)mapping.getObjectAt(0);                        DERObjectIdentifier subjectDomainPolicy = (DERObjectIdentifier)mapping.getObjectAt(1);                        if (ANY_POLICY.equals(issuerDomainPolicy.getId()))                        {                                                    throw new CertPathValidatorException("IssuerDomainPolicy is anyPolicy");                        }                                            if (ANY_POLICY.equals(subjectDomainPolicy.getId()))                        {                                                    throw new CertPathValidatorException("SubjectDomainPolicy is anyPolicy");                        }                    }                }                                //                // (b)                //                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 (ANY_POLICY.equals(node.getValidPolicy()))                                    {                                        Set pq = null;                                        ASN1Sequence policies = (ASN1Sequence)getExtensionValue(                                                cert, CERTIFICATE_POLICIES);                                        Enumeration e = policies.getObjects();                                        while (e.hasMoreElements())                                        {                                            PolicyInformation pinfo = PolicyInformation.getInstance(e.nextElement());                                            if (ANY_POLICY.equals(pinfo.getPolicyIdentifier().getId()))                                            {                                                pq = getQualifierSet(pinfo.getPolicyQualifiers());                                                break;                                            }                                        }                                        boolean ci = false;                                        if (cert.getCriticalExtensionOIDs() != null)                                        {                                            ci = cert.getCriticalExtensionOIDs().contains(CERTIFICATE_POLICIES);                                        }                                        PKIXPolicyNode p_node = (PKIXPolicyNode)node.getParent();                                        if (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 = removePolicyNode(                                                        validPolicyTree,                                                        policyNodes, node2);                                                if (validPolicyTree == null)                                                    break;                                            }                                        }                                    }                                }                            }                        }                    }                }                                //                // (g) handle the name constraints extension                //                ASN1Sequence ncSeq = (ASN1Sequence)getExtensionValue(cert, NAME_CONSTRAINTS);                if (ncSeq != null)                {                    NameConstraints nc = new NameConstraints(ncSeq);                    //                    // (g) (1) permitted subtrees                    //                    ASN1Sequence permitted = nc.getPermittedSubtrees();                    if (permitted != null)                    {                        Enumeration e = permitted.getObjects();                        while (e.hasMoreElements())                        {                            GeneralSubtree  subtree = GeneralSubtree.getInstance(e.nextElement());                            GeneralName     base = subtree.getBase();                            switch(base.getTagNo())                            {                                case 1:                                    permittedSubtreesEmail = intersectEmail(permittedSubtreesEmail, DERIA5String.getInstance(base.getName()).getString());                                    break;                                case 4:                                    permittedSubtreesDN = intersectDN(permittedSubtreesDN, (ASN1Sequence)base.getName());                                    break;                                case 7:                                    permittedSubtreesIP = intersectIP(permittedSubtreesIP, ASN1OctetString.getInstance(base.getName()).getOctets());                                    break;                            }                        }                    }                                    //                    // (g) (2) excluded subtrees                    //                    ASN1Sequence excluded = nc.getExcludedSubtrees();                    if (excluded != null)                    {                        Enumeration e = excluded.getObjects();                        while (e.hasMoreElements())                        {                            GeneralSubtree  subtree = GeneralSubtree.getInstance(e.nextElement());                            GeneralName     base = subtree.getBase();                            switch(base.getTagNo())                            {                            case 1:                                excludedSubtreesEmail = unionEmail(excludedSubtreesEmail, DERIA5String.getInstance(base.getName()).getString());                                break;                            case 4:                                excludedSubtreesDN = unionDN(excludedSubtreesDN, (ASN1Sequence)base.getName());                                break;                            case 7:                                excludedSubtreesIP = unionIP(excludedSubtreesIP, ASN1OctetString.getInstance(base.getName()).getOctets());                                break;                            }                        }                    }                }                //                // (h)                //                if (!isSelfIssued(cert))                {                    //                    // (1)                    //                    if (explicitPolicy != 0)                    {                        explicitPolicy--;                    }                                    //                    // (2)                    //                    if (policyMapping != 0)                    {                        policyMapping--;                    }                                    //                    // (3)                    //                    if (inhibitAnyPolicy != 0)                    {                        inhibitAnyPolicy--;                    }                }                        //                // (i)                //                ASN1Sequence pc = (ASN1Sequence)getExtensionValue(cert, POLICY_CONSTRAINTS);                            if (pc != null)                {                    Enumeration policyConstraints = pc.getObjects();                    while (policyConstraints.hasMoreElements())                    {                        ASN1TaggedObject    constraint = (ASN1TaggedObject)policyConstraints.nextElement();                        switch (constraint.getTagNo())                        {                        case 0:                            tmpInt = DERInteger.getInstance(constraint).getValue().intValue();                            if (tmpInt < explicitPolicy)                            {                                explicitPolicy = tmpInt;                            }                            break;                        case 1:                            tmpInt = DERInteger.getInstance(constraint).getValue().intValue();                            if (tmpInt < policyMapping)                            {                                policyMapping = tmpInt;                            }                        break;                        }                    }                }                        //                // (j)                //                DERInteger iap = (DERInteger)getExtensionValue(cert, INHIBIT_ANY_POLICY);                            if (iap != null)                {                    int _inhibitAnyPolicy = iap.getValue().intValue();                                    if (_inhibitAnyPolicy < inhibitAnyPolicy)                    {                        inhibitAnyPolicy = _inhibitAnyPolicy;                    }                }                        //                // (k)                //                BasicConstraints    bc = BasicConstraints.getInstance(                                            getExtensionValue(cert, BASIC_CONSTRAINTS));                if (bc != null)                {                    if (!(bc.isCA()))                    {                        throw new CertPathValidatorException("Not a CA certificate");                    }                }                else                {                    throw new CertPathValidatorException("Intermediate certificate lacks BasicConstraints");                }                            //                // (l)                //                if (!isSelfIssued(cert))                {                    if (maxPathLength <= 0)                    {                        throw new CertPathValidatorException("Max path length not greater than zero");                    }                                    maxPathLength--;                }                        //                // (m)                //                if (bc != null)                {                    BigInteger          _pathLengthConstraint = bc.getPathLenConstraint();                                if (_pathLengthConstraint != null)                    {                        int _plc = _pathLengthConstraint.intValue();                        if (_plc < maxPathLength)                        {                            maxPathLength = _plc;                        }                    }                }                        //                // (n)                //                boolean[] _usage = cert.getKeyUsage();                            if ((_usage != null) && !_usage[5])                {                    throw new CertPathValidatorException(                                "Issuer certificate keyusage extension is critical an does not permit key signing.\n",                                null, certPath, index);                }                //                // (o)                //                Set criticalExtensions = new HashSet(cert.getCriticalExtensionOIDs());                // these extensions are handle by the algorithem                criticalExtensions.remove(KEY_USAGE);                criticalExtensions.remove(CERTIFICATE_POLICIES);                criticalExtensions.remove(POLICY_MAPPINGS);                criticalExtensions.remove(INHIBIT_ANY_POLICY);                criticalExtensions.remove(ISSUING_DISTRIBUTION_POINT);                criticalExtensions.remove(DELTA_CRL_INDICATOR);                criticalExtensions.remove(POLICY_CONSTRAINTS);                criticalExtensions.remove(BASIC_CONSTRAINTS);                criticalExtensions.remove(SUBJECT_ALTERNATIVE_NAME);                criticalExtensions.remove(NAME_CONSTRAINTS);                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 CertPathValidatorException(                        "Certificate has unsupported critical extension", null, certPath, index);                }            }                // set signing certificate for next round            sign = cert;            workingPublicKey = sign.getPublicKey();            try            {                workingIssuerName = getSubjectPrincipal(sign);            }            catch (IllegalArgumentException ex)            {                throw new CertPathValidatorException(sign.getSubjectDN().getName() + " :" + ex.toString());            }            workingAlgId = getAlgorithmIdentifier(workingPublicKey);            workingPublicKeyAlgorithm = workingAlgId.getObjectId();            workingPublicKeyParameters = workingAlgId.getParameters();        }        //        // 6.1.5 Wrap-up procedure        //        //        // (a)        //        if (!isSelfIssued(cert) && (explicitPolicy != 0))        {            explicitPolicy--;        }            //        // (b)        //        ASN1Sequence pc = (ASN1Sequence)getExtensionValue(cert, POLICY_CONSTRAINTS);        if (pc != null)        {            Enumeration policyConstraints = pc.getObjects();            while (policyConstraints.hasMoreElements())            {                ASN1TaggedObject    constraint = (ASN1TaggedObject)policyConstraints.nextElement();                switch (constraint.getTagNo())                {                case 0:                    tmpInt = DERInteger.getInstance(constraint).getValue().intValue();                    if (tmpInt == 0)                    {                        explicitPolicy = 0;                    }                    break;                }            }        }            //        // (c) (d) and (e) are already done        //            //        // (f)         //        Set criticalExtensions = cert.getCriticalExtensionOIDs();                if (criticalExtensions != null)        {            criticalExtensions = new HashSet(criticalExtensions);            // these extensions are handle by the algorithm            criticalExtensions.remove(KEY_USAGE);            criticalExtensions.remove(CERTIFICATE_POLICIES);            criticalExtensions.remove(POLICY_MAPPINGS);            criticalExtensions.remove(INHIBIT_ANY_POLICY);            criticalExtensions.remove(ISSUING_DISTRIBUTION_POINT);            criticalExtensions.remove(DELTA_CRL_INDICATOR);            criticalExtensions.remove(POLICY_CONSTRAINTS);            criticalExtensions.remove(BASIC_CONSTRAINTS);            criticalExtensions.remove(SUBJECT_ALTERNATIVE_NAME);            criticalExtensions.remove(NAME_CONSTRAINTS);        }        else        {            criticalExtensions = new HashSet();        }                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 CertPathValidatorException(                "Certificate has unsupported critical extension", null, certPath, index);        }        //        // (g)        //        PKIXPolicyNode intersection;                //        // (g) (i)        //        if (validPolicyTree == null)        {             if (paramsPKIX.isExplicitPolicyRequired())            {                throw new CertPathValidatorException("Explicit policy requested but none available.");            }            intersection = null;        }        else if (isAnyPolicy(userInitialPolicySet)) // (g) (ii)        {            if (paramsPKIX.isExplicitPolicyRequired())            {                if (acceptablePolicies.isEmpty())                {                    throw new CertPathValidatorException("Explicit policy requested but none available.");                }                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 (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 = removePolicyNode(validPolicyTree, policyNodes, node);                                }                            }                        }                    }                }            }            intersection = validPolicyTree;        }        else        {            //            // (g) (iii)            //            //            // (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 (ANY_POLICY.equals(_node.getValidPolicy()))                    {                        Iterator _iter = _node.getChildren();                        while (_iter.hasNext())                        {                            PKIXPolicyNode _c_node = (PKIXPolicyNode)_iter.next();                            if (!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 = 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 = removePolicyNode(validPolicyTree, policyNodes, node);                        }                    }                }            }                        intersection = validPolicyTree;        }         if ((explicitPolicy > 0) || (intersection != null))        {            return new PKIXCertPathValidatorResult(trust, intersection, workingPublicKey);        }        throw new CertPathValidatorException("Path processing failed on policy.", null, certPath, index);    }