173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root/*
273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root *
573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * This code is free software; you can redistribute it and/or modify it
673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * under the terms of the GNU General Public License version 2 only, as
773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * published by the Free Software Foundation.  Oracle designates this
873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * particular file as subject to the "Classpath" exception as provided
973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * by Oracle in the LICENSE file that accompanied this code.
1073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root *
1173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * This code is distributed in the hope that it will be useful, but WITHOUT
1273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
1373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
1473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * version 2 for more details (a copy is included in the LICENSE file that
1573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * accompanied this code).
1673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root *
1773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * You should have received a copy of the GNU General Public License version
1873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * 2 along with this work; if not, write to the Free Software Foundation,
1973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
2073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root *
2173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * or visit www.oracle.com if you need additional information or have any
2373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * questions.
2473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root */
2573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root
2673405ff8729cca39da90b2e2f604062e323f6f7aKenny Rootpackage sun.security.provider.certpath;
2773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root
2873405ff8729cca39da90b2e2f604062e323f6f7aKenny Rootimport java.io.IOException;
2973405ff8729cca39da90b2e2f604062e323f6f7aKenny Rootimport java.security.GeneralSecurityException;
3073405ff8729cca39da90b2e2f604062e323f6f7aKenny Rootimport java.security.cert.Certificate;
3173405ff8729cca39da90b2e2f604062e323f6f7aKenny Rootimport java.security.cert.CertificateException;
3273405ff8729cca39da90b2e2f604062e323f6f7aKenny Rootimport java.security.cert.CertPathValidatorException;
3373405ff8729cca39da90b2e2f604062e323f6f7aKenny Rootimport java.security.cert.PKIXCertPathChecker;
3473405ff8729cca39da90b2e2f604062e323f6f7aKenny Rootimport java.security.cert.PKIXReason;
3573405ff8729cca39da90b2e2f604062e323f6f7aKenny Rootimport java.security.cert.PolicyNode;
3673405ff8729cca39da90b2e2f604062e323f6f7aKenny Rootimport java.security.cert.PolicyQualifierInfo;
3773405ff8729cca39da90b2e2f604062e323f6f7aKenny Rootimport java.security.cert.X509Certificate;
3873405ff8729cca39da90b2e2f604062e323f6f7aKenny Rootimport java.util.*;
3973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root
4073405ff8729cca39da90b2e2f604062e323f6f7aKenny Rootimport sun.security.util.Debug;
4173405ff8729cca39da90b2e2f604062e323f6f7aKenny Rootimport sun.security.x509.CertificatePoliciesExtension;
4273405ff8729cca39da90b2e2f604062e323f6f7aKenny Rootimport sun.security.x509.PolicyConstraintsExtension;
4373405ff8729cca39da90b2e2f604062e323f6f7aKenny Rootimport sun.security.x509.PolicyMappingsExtension;
4473405ff8729cca39da90b2e2f604062e323f6f7aKenny Rootimport sun.security.x509.CertificatePolicyMap;
4573405ff8729cca39da90b2e2f604062e323f6f7aKenny Rootimport static sun.security.x509.PKIXExtensions.*;
4673405ff8729cca39da90b2e2f604062e323f6f7aKenny Rootimport sun.security.x509.PolicyInformation;
4773405ff8729cca39da90b2e2f604062e323f6f7aKenny Rootimport sun.security.x509.X509CertImpl;
4873405ff8729cca39da90b2e2f604062e323f6f7aKenny Rootimport sun.security.x509.InhibitAnyPolicyExtension;
4973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root
5073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root/**
5173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * PolicyChecker is a <code>PKIXCertPathChecker</code> that checks policy
5273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * information on a PKIX certificate, namely certificate policies, policy
5373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * mappings, policy constraints and policy qualifiers.
5473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root *
5573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * @since       1.4
5673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root * @author      Yassir Elley
5773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root */
5873405ff8729cca39da90b2e2f604062e323f6f7aKenny Rootclass PolicyChecker extends PKIXCertPathChecker {
5973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root
6073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root    private final Set<String> initPolicies;
6173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root    private final int certPathLen;
6273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root    private final boolean expPolicyRequired;
6373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root    private final boolean polMappingInhibited;
6473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root    private final boolean anyPolicyInhibited;
6573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root    private final boolean rejectPolicyQualifiers;
6673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root    private PolicyNodeImpl rootNode;
6773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root    private int explicitPolicy;
6873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root    private int policyMapping;
6973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root    private int inhibitAnyPolicy;
7073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root    private int certIndex;
7173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root
7273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root    private Set<String> supportedExts;
7373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root
7473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root    private static final Debug debug = Debug.getInstance("certpath");
7573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root    static final String ANY_POLICY = "2.5.29.32.0";
7673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root
7773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root    /**
7873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     * Constructs a Policy Checker.
7973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     *
8073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     * @param initialPolicies Set of initial policies
8173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     * @param certPathLen length of the certification path to be checked
8273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     * @param expPolicyRequired true if explicit policy is required
8373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     * @param polMappingInhibited true if policy mapping is inhibited
8473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     * @param anyPolicyInhibited true if the ANY_POLICY OID should be inhibited
8573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     * @param rejectPolicyQualifiers true if pol qualifiers are to be rejected
8673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     * @param rootNode the initial root node of the valid policy tree
8773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     */
8873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root    PolicyChecker(Set<String> initialPolicies, int certPathLen,
8973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        boolean expPolicyRequired, boolean polMappingInhibited,
9073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        boolean anyPolicyInhibited, boolean rejectPolicyQualifiers,
9173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        PolicyNodeImpl rootNode)
9273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root    {
9373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        if (initialPolicies.isEmpty()) {
9473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            // if no initialPolicies are specified by user, set
9573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            // initPolicies to be anyPolicy by default
9673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            this.initPolicies = new HashSet<String>(1);
9773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            this.initPolicies.add(ANY_POLICY);
9873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        } else {
9973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            this.initPolicies = new HashSet<String>(initialPolicies);
10073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        }
10173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        this.certPathLen = certPathLen;
10273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        this.expPolicyRequired = expPolicyRequired;
10373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        this.polMappingInhibited = polMappingInhibited;
10473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        this.anyPolicyInhibited = anyPolicyInhibited;
10573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        this.rejectPolicyQualifiers = rejectPolicyQualifiers;
10673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        this.rootNode = rootNode;
10773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root    }
10873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root
10973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root    /**
11073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     * Initializes the internal state of the checker from parameters
11173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     * specified in the constructor
11273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     *
11373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     * @param forward a boolean indicating whether this checker should be
11473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     *        initialized capable of building in the forward direction
11573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     * @throws CertPathValidatorException if user wants to enable forward
11673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     *         checking and forward checking is not supported.
11773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     */
11873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root    @Override
11973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root    public void init(boolean forward) throws CertPathValidatorException {
12073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        if (forward) {
12173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            throw new CertPathValidatorException
12273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                                        ("forward checking not supported");
12373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        }
12473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root
12573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        certIndex = 1;
12673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        explicitPolicy = (expPolicyRequired ? 0 : certPathLen + 1);
12773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        policyMapping = (polMappingInhibited ? 0 : certPathLen + 1);
12873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        inhibitAnyPolicy = (anyPolicyInhibited ? 0 : certPathLen + 1);
12973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root    }
13073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root
13173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root    /**
13273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     * Checks if forward checking is supported. Forward checking refers
13373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     * to the ability of the PKIXCertPathChecker to perform its checks
13473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     * when presented with certificates in the forward direction (from
13573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     * target to anchor).
13673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     *
13773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     * @return true if forward checking is supported, false otherwise
13873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     */
13973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root    @Override
14073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root    public boolean isForwardCheckingSupported() {
14173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        return false;
14273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root    }
14373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root
14473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root    /**
14573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     * Gets an immutable Set of the OID strings for the extensions that
14673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     * the PKIXCertPathChecker supports (i.e. recognizes, is able to
14773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     * process), or null if no extensions are
14873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     * supported. All OID strings that a PKIXCertPathChecker might
14973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     * possibly be able to process should be included.
15073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     *
15173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     * @return the Set of extensions supported by this PKIXCertPathChecker,
15273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     * or null if no extensions are supported
15373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     */
15473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root    @Override
15573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root    public Set<String> getSupportedExtensions() {
15673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        if (supportedExts == null) {
15773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            supportedExts = new HashSet<String>(4);
15873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            supportedExts.add(CertificatePolicies_Id.toString());
15973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            supportedExts.add(PolicyMappings_Id.toString());
16073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            supportedExts.add(PolicyConstraints_Id.toString());
16173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            supportedExts.add(InhibitAnyPolicy_Id.toString());
16273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            supportedExts = Collections.unmodifiableSet(supportedExts);
16373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        }
16473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        return supportedExts;
16573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root    }
16673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root
16773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root    /**
16873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     * Performs the policy processing checks on the certificate using its
16973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     * internal state.
17073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     *
17173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     * @param cert the Certificate to be processed
17273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     * @param unresCritExts the unresolved critical extensions
17373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     * @throws CertPathValidatorException if the certificate does not verify
17473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     */
17573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root    @Override
17673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root    public void check(Certificate cert, Collection<String> unresCritExts)
17773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        throws CertPathValidatorException
17873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root    {
17973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        // now do the policy checks
18073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        checkPolicy((X509Certificate) cert);
18173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root
18273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        if (unresCritExts != null && !unresCritExts.isEmpty()) {
18373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            unresCritExts.remove(CertificatePolicies_Id.toString());
18473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            unresCritExts.remove(PolicyMappings_Id.toString());
18573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            unresCritExts.remove(PolicyConstraints_Id.toString());
18673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            unresCritExts.remove(InhibitAnyPolicy_Id.toString());
18773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        }
18873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root    }
18973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root
19073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root    /**
19173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     * Internal method to run through all the checks.
19273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     *
19373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     * @param currCert the certificate to be processed
19473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     * @exception CertPathValidatorException Exception thrown if
19573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     * the certificate does not verify
19673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     */
19773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root    private void checkPolicy(X509Certificate currCert)
19873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        throws CertPathValidatorException
19973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root    {
20073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        String msg = "certificate policies";
20173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        if (debug != null) {
20273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            debug.println("PolicyChecker.checkPolicy() ---checking " + msg
20373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                + "...");
20473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            debug.println("PolicyChecker.checkPolicy() certIndex = "
20573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                + certIndex);
20673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            debug.println("PolicyChecker.checkPolicy() BEFORE PROCESSING: "
20773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                + "explicitPolicy = " + explicitPolicy);
20873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            debug.println("PolicyChecker.checkPolicy() BEFORE PROCESSING: "
20973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                + "policyMapping = " + policyMapping);
21073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            debug.println("PolicyChecker.checkPolicy() BEFORE PROCESSING: "
21173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                + "inhibitAnyPolicy = " + inhibitAnyPolicy);
21273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            debug.println("PolicyChecker.checkPolicy() BEFORE PROCESSING: "
21373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                + "policyTree = " + rootNode);
21473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        }
21573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root
21673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        X509CertImpl currCertImpl = null;
21773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        try {
21873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            currCertImpl = X509CertImpl.toImpl(currCert);
21973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        } catch (CertificateException ce) {
22073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            throw new CertPathValidatorException(ce);
22173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        }
22273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root
22373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        boolean finalCert = (certIndex == certPathLen);
22473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root
22573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        rootNode = processPolicies(certIndex, initPolicies, explicitPolicy,
22673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            policyMapping, inhibitAnyPolicy, rejectPolicyQualifiers, rootNode,
22773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            currCertImpl, finalCert);
22873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root
22973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        if (!finalCert) {
23073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            explicitPolicy = mergeExplicitPolicy(explicitPolicy, currCertImpl,
23173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                                                 finalCert);
23273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            policyMapping = mergePolicyMapping(policyMapping, currCertImpl);
23373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            inhibitAnyPolicy = mergeInhibitAnyPolicy(inhibitAnyPolicy,
23473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                                                     currCertImpl);
23573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        }
23673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root
23773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        certIndex++;
23873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root
23973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        if (debug != null) {
24073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            debug.println("PolicyChecker.checkPolicy() AFTER PROCESSING: "
24173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                + "explicitPolicy = " + explicitPolicy);
24273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            debug.println("PolicyChecker.checkPolicy() AFTER PROCESSING: "
24373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                + "policyMapping = " + policyMapping);
24473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            debug.println("PolicyChecker.checkPolicy() AFTER PROCESSING: "
24573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                + "inhibitAnyPolicy = " + inhibitAnyPolicy);
24673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            debug.println("PolicyChecker.checkPolicy() AFTER PROCESSING: "
24773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                + "policyTree = " + rootNode);
24873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            debug.println("PolicyChecker.checkPolicy() " + msg + " verified");
24973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        }
25073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root    }
25173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root
25273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root    /**
25373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     * Merges the specified explicitPolicy value with the
25473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     * requireExplicitPolicy field of the <code>PolicyConstraints</code>
25573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     * extension obtained from the certificate. An explicitPolicy
25673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     * value of -1 implies no constraint.
25773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     *
25873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     * @param explicitPolicy an integer which indicates if a non-null
25973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     * valid policy tree is required
26073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     * @param currCert the Certificate to be processed
26173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     * @param finalCert a boolean indicating whether currCert is
26273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     * the final cert in the cert path
26373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     * @return returns the new explicitPolicy value
26473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     * @exception CertPathValidatorException Exception thrown if an error
26573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     * occurs
26673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     */
26773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root    static int mergeExplicitPolicy(int explicitPolicy, X509CertImpl currCert,
26873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        boolean finalCert) throws CertPathValidatorException
26973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root    {
27073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        if ((explicitPolicy > 0) && !X509CertImpl.isSelfIssued(currCert)) {
27173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            explicitPolicy--;
27273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        }
27373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root
27473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        try {
27573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            PolicyConstraintsExtension polConstExt
27673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                = currCert.getPolicyConstraintsExtension();
27773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            if (polConstExt == null)
27873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                return explicitPolicy;
27973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            int require =
28073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                polConstExt.get(PolicyConstraintsExtension.REQUIRE).intValue();
28173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            if (debug != null) {
28273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                debug.println("PolicyChecker.mergeExplicitPolicy() "
28373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                   + "require Index from cert = " + require);
28473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            }
28573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            if (!finalCert) {
28673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                if (require != -1) {
28773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                    if ((explicitPolicy == -1) || (require < explicitPolicy)) {
28873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                        explicitPolicy = require;
28973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                    }
29073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                }
29173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            } else {
29273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                if (require == 0)
29373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                    explicitPolicy = require;
29473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            }
29573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        } catch (IOException e) {
29673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            if (debug != null) {
29773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                debug.println("PolicyChecker.mergeExplicitPolicy "
29873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                              + "unexpected exception");
29973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                e.printStackTrace();
30073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            }
30173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            throw new CertPathValidatorException(e);
30273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        }
30373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root
30473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        return explicitPolicy;
30573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root    }
30673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root
30773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root    /**
30873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     * Merges the specified policyMapping value with the
30973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     * inhibitPolicyMapping field of the <code>PolicyConstraints</code>
31073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     * extension obtained from the certificate. A policyMapping
31173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     * value of -1 implies no constraint.
31273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     *
31373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     * @param policyMapping an integer which indicates if policy mapping
31473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     * is inhibited
31573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     * @param currCert the Certificate to be processed
31673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     * @return returns the new policyMapping value
31773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     * @exception CertPathValidatorException Exception thrown if an error
31873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     * occurs
31973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     */
32073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root    static int mergePolicyMapping(int policyMapping, X509CertImpl currCert)
32173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        throws CertPathValidatorException
32273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root    {
32373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        if ((policyMapping > 0) && !X509CertImpl.isSelfIssued(currCert)) {
32473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            policyMapping--;
32573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        }
32673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root
32773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        try {
32873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            PolicyConstraintsExtension polConstExt
32973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                = currCert.getPolicyConstraintsExtension();
33073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            if (polConstExt == null)
33173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                return policyMapping;
33273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root
33373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            int inhibit =
33473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                polConstExt.get(PolicyConstraintsExtension.INHIBIT).intValue();
33573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            if (debug != null)
33673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                debug.println("PolicyChecker.mergePolicyMapping() "
33773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                    + "inhibit Index from cert = " + inhibit);
33873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root
33973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            if (inhibit != -1) {
34073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                if ((policyMapping == -1) || (inhibit < policyMapping)) {
34173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                    policyMapping = inhibit;
34273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                }
34373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            }
34473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        } catch (IOException e) {
34573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            if (debug != null) {
34673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                debug.println("PolicyChecker.mergePolicyMapping "
34773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                              + "unexpected exception");
34873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                e.printStackTrace();
34973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            }
35073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            throw new CertPathValidatorException(e);
35173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        }
35273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root
35373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        return policyMapping;
35473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root    }
35573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root
35673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root    /**
35773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     * Merges the specified inhibitAnyPolicy value with the
35873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     * SkipCerts value of the InhibitAnyPolicy
35973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     * extension obtained from the certificate.
36073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     *
36173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     * @param inhibitAnyPolicy an integer which indicates whether
36273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     * "any-policy" is considered a match
36373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     * @param currCert the Certificate to be processed
36473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     * @return returns the new inhibitAnyPolicy value
36573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     * @exception CertPathValidatorException Exception thrown if an error
36673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     * occurs
36773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     */
36873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root    static int mergeInhibitAnyPolicy(int inhibitAnyPolicy,
36973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        X509CertImpl currCert) throws CertPathValidatorException
37073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root    {
37173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        if ((inhibitAnyPolicy > 0) && !X509CertImpl.isSelfIssued(currCert)) {
37273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            inhibitAnyPolicy--;
37373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        }
37473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root
37573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        try {
37673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            InhibitAnyPolicyExtension inhAnyPolExt = (InhibitAnyPolicyExtension)
37773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                currCert.getExtension(InhibitAnyPolicy_Id);
37873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            if (inhAnyPolExt == null)
37973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                return inhibitAnyPolicy;
38073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root
38173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            int skipCerts =
38273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                inhAnyPolExt.get(InhibitAnyPolicyExtension.SKIP_CERTS).intValue();
38373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            if (debug != null)
38473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                debug.println("PolicyChecker.mergeInhibitAnyPolicy() "
38573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                    + "skipCerts Index from cert = " + skipCerts);
38673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root
38773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            if (skipCerts != -1) {
38873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                if (skipCerts < inhibitAnyPolicy) {
38973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                    inhibitAnyPolicy = skipCerts;
39073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                }
39173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            }
39273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        } catch (IOException e) {
39373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            if (debug != null) {
39473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                debug.println("PolicyChecker.mergeInhibitAnyPolicy "
39573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                              + "unexpected exception");
39673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                e.printStackTrace();
39773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            }
39873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            throw new CertPathValidatorException(e);
39973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        }
40073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root
40173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        return inhibitAnyPolicy;
40273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root    }
40373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root
40473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root    /**
40573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     * Processes certificate policies in the certificate.
40673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     *
40773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     * @param certIndex the index of the certificate
40873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     * @param initPolicies the initial policies required by the user
40973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     * @param explicitPolicy an integer which indicates if a non-null
41073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     * valid policy tree is required
41173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     * @param policyMapping an integer which indicates if policy
41273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     * mapping is inhibited
41373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     * @param inhibitAnyPolicy an integer which indicates whether
41473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     * "any-policy" is considered a match
41573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     * @param rejectPolicyQualifiers a boolean indicating whether the
41673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     * user wants to reject policies that have qualifiers
41773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     * @param origRootNode the root node of the valid policy tree
41873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     * @param currCert the Certificate to be processed
41973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     * @param finalCert a boolean indicating whether currCert is the final
42073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     * cert in the cert path
42173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     * @return the root node of the valid policy tree after modification
42273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     * @exception CertPathValidatorException Exception thrown if an
42373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     * error occurs while processing policies.
42473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     */
42573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root    static PolicyNodeImpl processPolicies(int certIndex, Set<String> initPolicies,
42673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        int explicitPolicy, int policyMapping, int inhibitAnyPolicy,
42773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        boolean rejectPolicyQualifiers, PolicyNodeImpl origRootNode,
42873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        X509CertImpl currCert, boolean finalCert)
42973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        throws CertPathValidatorException
43073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root    {
43173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        boolean policiesCritical = false;
43273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        List<PolicyInformation> policyInfo;
43373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        PolicyNodeImpl rootNode = null;
43473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        Set<PolicyQualifierInfo> anyQuals = new HashSet<>();
43573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root
43673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        if (origRootNode == null)
43773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            rootNode = null;
43873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        else
43973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            rootNode = origRootNode.copyTree();
44073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root
44173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        // retrieve policyOIDs from currCert
44273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        CertificatePoliciesExtension currCertPolicies
44373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            = currCert.getCertificatePoliciesExtension();
44473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root
44573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        // PKIX: Section 6.1.3: Step (d)
44673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        if ((currCertPolicies != null) && (rootNode != null)) {
44773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            policiesCritical = currCertPolicies.isCritical();
44873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            if (debug != null)
44973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                debug.println("PolicyChecker.processPolicies() "
45073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                    + "policiesCritical = " + policiesCritical);
45173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root
45273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            try {
45373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                policyInfo = currCertPolicies.get(CertificatePoliciesExtension.POLICIES);
45473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            } catch (IOException ioe) {
45573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                throw new CertPathValidatorException("Exception while "
45673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                    + "retrieving policyOIDs", ioe);
45773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            }
45873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root
45973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            if (debug != null)
46073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                debug.println("PolicyChecker.processPolicies() "
46173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                    + "rejectPolicyQualifiers = " + rejectPolicyQualifiers);
46273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root
46373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            boolean foundAnyPolicy = false;
46473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root
46573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            // process each policy in cert
46673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            for (PolicyInformation curPolInfo : policyInfo) {
46773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                String curPolicy =
46873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                    curPolInfo.getPolicyIdentifier().getIdentifier().toString();
46973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root
47073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                if (curPolicy.equals(ANY_POLICY)) {
47173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                    foundAnyPolicy = true;
47273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                    anyQuals = curPolInfo.getPolicyQualifiers();
47373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                } else {
47473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                    // PKIX: Section 6.1.3: Step (d)(1)
47573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                    if (debug != null)
47673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                        debug.println("PolicyChecker.processPolicies() "
47773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                                      + "processing policy: " + curPolicy);
47873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root
47973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                    // retrieve policy qualifiers from cert
48073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                    Set<PolicyQualifierInfo> pQuals =
48173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                                        curPolInfo.getPolicyQualifiers();
48273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root
48373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                    // reject cert if we find critical policy qualifiers and
48473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                    // the policyQualifiersRejected flag is set in the params
48573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                    if (!pQuals.isEmpty() && rejectPolicyQualifiers &&
48673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                        policiesCritical) {
48773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                        throw new CertPathValidatorException(
48873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                            "critical policy qualifiers present in certificate",
48973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                            null, null, -1, PKIXReason.INVALID_POLICY);
49073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                    }
49173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root
49273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                    // PKIX: Section 6.1.3: Step (d)(1)(i)
49373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                    boolean foundMatch = processParents(certIndex,
49473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                        policiesCritical, rejectPolicyQualifiers, rootNode,
49573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                        curPolicy, pQuals, false);
49673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root
49773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                    if (!foundMatch) {
49873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                        // PKIX: Section 6.1.3: Step (d)(1)(ii)
49973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                        processParents(certIndex, policiesCritical,
50073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                            rejectPolicyQualifiers, rootNode, curPolicy,
50173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                            pQuals, true);
50273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                    }
50373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                }
50473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            }
50573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root
50673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            // PKIX: Section 6.1.3: Step (d)(2)
50773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            if (foundAnyPolicy) {
50873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                if ((inhibitAnyPolicy > 0) ||
50973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                        (!finalCert && X509CertImpl.isSelfIssued(currCert))) {
51073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                    if (debug != null) {
51173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                        debug.println("PolicyChecker.processPolicies() "
51273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                            + "processing policy: " + ANY_POLICY);
51373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                    }
51473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                    processParents(certIndex, policiesCritical,
51573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                        rejectPolicyQualifiers, rootNode, ANY_POLICY, anyQuals,
51673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                        true);
51773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                }
51873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            }
51973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root
52073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            // PKIX: Section 6.1.3: Step (d)(3)
52173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            rootNode.prune(certIndex);
52273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            if (!rootNode.getChildren().hasNext()) {
52373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                rootNode = null;
52473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            }
52573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        } else if (currCertPolicies == null) {
52673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            if (debug != null)
52773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                debug.println("PolicyChecker.processPolicies() "
52873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                              + "no policies present in cert");
52973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            // PKIX: Section 6.1.3: Step (e)
53073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            rootNode = null;
53173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        }
53273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root
53373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        // We delay PKIX: Section 6.1.3: Step (f) to the end
53473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        // because the code that follows may delete some nodes
53573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        // resulting in a null tree
53673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        if (rootNode != null) {
53773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            if (!finalCert) {
53873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                // PKIX: Section 6.1.4: Steps (a)-(b)
53973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                rootNode = processPolicyMappings(currCert, certIndex,
54073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                    policyMapping, rootNode, policiesCritical, anyQuals);
54173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            }
54273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        }
54373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root
54473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        // At this point, we optimize the PKIX algorithm by
54573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        // removing those nodes which would later have
54673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        // been removed by PKIX: Section 6.1.5: Step (g)(iii)
54773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root
54873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        if ((rootNode != null) && (!initPolicies.contains(ANY_POLICY))
54973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            && (currCertPolicies != null)) {
55073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            rootNode = removeInvalidNodes(rootNode, certIndex,
55173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                                          initPolicies, currCertPolicies);
55273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root
55373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            // PKIX: Section 6.1.5: Step (g)(iii)
55473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            if ((rootNode != null) && finalCert) {
55573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                // rewrite anyPolicy leaf nodes (see method comments)
55673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                rootNode = rewriteLeafNodes(certIndex, initPolicies, rootNode);
55773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            }
55873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        }
55973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root
56073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root
56173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        if (finalCert) {
56273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            // PKIX: Section 6.1.5: Steps (a) and (b)
56373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            explicitPolicy = mergeExplicitPolicy(explicitPolicy, currCert,
56473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                                             finalCert);
56573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        }
56673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root
56773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        // PKIX: Section 6.1.3: Step (f)
56873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        // verify that either explicit policy is greater than 0 or
56973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        // the valid_policy_tree is not equal to NULL
57073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root
57173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        if ((explicitPolicy == 0) && (rootNode == null)) {
57273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            throw new CertPathValidatorException
57373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                ("non-null policy tree required and policy tree is null",
57473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                 null, null, -1, PKIXReason.INVALID_POLICY);
57573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        }
57673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root
57773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        return rootNode;
57873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root    }
57973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root
58073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root    /**
58173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     * Rewrite leaf nodes at the end of validation as described in RFC 3280
58273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     * section 6.1.5: Step (g)(iii). Leaf nodes with anyPolicy are replaced
58373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     * by nodes explicitly representing initial policies not already
58473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     * represented by leaf nodes.
58573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     *
58673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     * This method should only be called when processing the final cert
58773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     * and if the policy tree is not null and initial policies is not
58873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     * anyPolicy.
58973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     *
59073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     * @param certIndex the depth of the tree
59173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     * @param initPolicies Set of user specified initial policies
59273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     * @param rootNode the root of the policy tree
59373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     */
59473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root    private static PolicyNodeImpl rewriteLeafNodes(int certIndex,
59573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            Set<String> initPolicies, PolicyNodeImpl rootNode) {
59673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        Set<PolicyNodeImpl> anyNodes =
59773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                        rootNode.getPolicyNodesValid(certIndex, ANY_POLICY);
59873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        if (anyNodes.isEmpty()) {
59973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            return rootNode;
60073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        }
60173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        PolicyNodeImpl anyNode = anyNodes.iterator().next();
60273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        PolicyNodeImpl parentNode = (PolicyNodeImpl)anyNode.getParent();
60373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        parentNode.deleteChild(anyNode);
60473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        // see if there are any initialPolicies not represented by leaf nodes
60573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        Set<String> initial = new HashSet<>(initPolicies);
60673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        for (PolicyNodeImpl node : rootNode.getPolicyNodes(certIndex)) {
60773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            initial.remove(node.getValidPolicy());
60873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        }
60973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        if (initial.isEmpty()) {
61073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            // we deleted the anyPolicy node and have nothing to re-add,
61173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            // so we need to prune the tree
61273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            rootNode.prune(certIndex);
61373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            if (rootNode.getChildren().hasNext() == false) {
61473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                rootNode = null;
61573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            }
61673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        } else {
61773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            boolean anyCritical = anyNode.isCritical();
61873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            Set<PolicyQualifierInfo> anyQualifiers =
61973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                                                anyNode.getPolicyQualifiers();
62073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            for (String policy : initial) {
62173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                Set<String> expectedPolicies = Collections.singleton(policy);
62273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                PolicyNodeImpl node = new PolicyNodeImpl(parentNode, policy,
62373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                    anyQualifiers, anyCritical, expectedPolicies, false);
62473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            }
62573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        }
62673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        return rootNode;
62773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root    }
62873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root
62973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root    /**
63073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     * Finds the policy nodes of depth (certIndex-1) where curPolicy
63173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     * is in the expected policy set and creates a new child node
63273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     * appropriately. If matchAny is true, then a value of ANY_POLICY
63373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     * in the expected policy set will match any curPolicy. If matchAny
63473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     * is false, then the expected policy set must exactly contain the
63573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     * curPolicy to be considered a match. This method returns a boolean
63673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     * value indicating whether a match was found.
63773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     *
63873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     * @param certIndex the index of the certificate whose policy is
63973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     * being processed
64073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     * @param policiesCritical a boolean indicating whether the certificate
64173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     * policies extension is critical
64273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     * @param rejectPolicyQualifiers a boolean indicating whether the
64373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     * user wants to reject policies that have qualifiers
64473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     * @param rootNode the root node of the valid policy tree
64573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     * @param curPolicy a String representing the policy being processed
64673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     * @param pQuals the policy qualifiers of the policy being processed or an
64773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     * empty Set if there are no qualifiers
64873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     * @param matchAny a boolean indicating whether a value of ANY_POLICY
64973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     * in the expected policy set will be considered a match
65073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     * @return a boolean indicating whether a match was found
65173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     * @exception CertPathValidatorException Exception thrown if error occurs.
65273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     */
65373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root    private static boolean processParents(int certIndex,
65473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        boolean policiesCritical, boolean rejectPolicyQualifiers,
65573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        PolicyNodeImpl rootNode, String curPolicy,
65673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        Set<PolicyQualifierInfo> pQuals,
65773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        boolean matchAny) throws CertPathValidatorException
65873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root    {
65973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        boolean foundMatch = false;
66073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root
66173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        if (debug != null)
66273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            debug.println("PolicyChecker.processParents(): matchAny = "
66373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                + matchAny);
66473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root
66573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        // find matching parents
66673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        Set<PolicyNodeImpl> parentNodes =
66773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                rootNode.getPolicyNodesExpected(certIndex - 1,
66873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                                                curPolicy, matchAny);
66973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root
67073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        // for each matching parent, extend policy tree
67173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        for (PolicyNodeImpl curParent : parentNodes) {
67273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            if (debug != null)
67373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                debug.println("PolicyChecker.processParents() "
67473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                              + "found parent:\n" + curParent.asString());
67573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root
67673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            foundMatch = true;
67773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            String curParPolicy = curParent.getValidPolicy();
67873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root
67973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            PolicyNodeImpl curNode = null;
68073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            Set<String> curExpPols = null;
68173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root
68273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            if (curPolicy.equals(ANY_POLICY)) {
68373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                // do step 2
68473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                Set<String> parExpPols = curParent.getExpectedPolicies();
68573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            parentExplicitPolicies:
68673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                for (String curParExpPol : parExpPols) {
68773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root
68873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                    Iterator<PolicyNodeImpl> childIter =
68973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                                        curParent.getChildren();
69073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                    while (childIter.hasNext()) {
69173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                        PolicyNodeImpl childNode = childIter.next();
69273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                        String childPolicy = childNode.getValidPolicy();
69373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                        if (curParExpPol.equals(childPolicy)) {
69473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                            if (debug != null)
69573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                                debug.println(childPolicy + " in parent's "
69673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                                    + "expected policy set already appears in "
69773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                                    + "child node");
69873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                            continue parentExplicitPolicies;
69973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                        }
70073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                    }
70173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root
70273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                    Set<String> expPols = new HashSet<>();
70373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                    expPols.add(curParExpPol);
70473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root
70573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                    curNode = new PolicyNodeImpl
70673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                        (curParent, curParExpPol, pQuals,
70773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                         policiesCritical, expPols, false);
70873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                }
70973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            } else {
71073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                curExpPols = new HashSet<String>();
71173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                curExpPols.add(curPolicy);
71273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root
71373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                curNode = new PolicyNodeImpl
71473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                    (curParent, curPolicy, pQuals,
71573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                     policiesCritical, curExpPols, false);
71673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            }
71773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        }
71873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root
71973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        return foundMatch;
72073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root    }
72173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root
72273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root    /**
72373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     * Processes policy mappings in the certificate.
72473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     *
72573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     * @param currCert the Certificate to be processed
72673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     * @param certIndex the index of the current certificate
72773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     * @param policyMapping an integer which indicates if policy
72873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     * mapping is inhibited
72973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     * @param rootNode the root node of the valid policy tree
73073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     * @param policiesCritical a boolean indicating if the certificate policies
73173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     * extension is critical
73273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     * @param anyQuals the qualifiers associated with ANY-POLICY, or an empty
73373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     * Set if there are no qualifiers associated with ANY-POLICY
73473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     * @return the root node of the valid policy tree after modification
73573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     * @exception CertPathValidatorException exception thrown if an error
73673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     * occurs while processing policy mappings
73773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     */
73873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root    private static PolicyNodeImpl processPolicyMappings(X509CertImpl currCert,
73973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        int certIndex, int policyMapping, PolicyNodeImpl rootNode,
74073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        boolean policiesCritical, Set<PolicyQualifierInfo> anyQuals)
74173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        throws CertPathValidatorException
74273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root    {
74373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        PolicyMappingsExtension polMappingsExt
74473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            = currCert.getPolicyMappingsExtension();
74573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root
74673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        if (polMappingsExt == null)
74773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            return rootNode;
74873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root
74973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        if (debug != null)
75073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            debug.println("PolicyChecker.processPolicyMappings() "
75173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                + "inside policyMapping check");
75273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root
75373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        List<CertificatePolicyMap> maps = null;
75473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        try {
75573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            maps = polMappingsExt.get(PolicyMappingsExtension.MAP);
75673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        } catch (IOException e) {
75773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            if (debug != null) {
75873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                debug.println("PolicyChecker.processPolicyMappings() "
75973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                    + "mapping exception");
76073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                e.printStackTrace();
76173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            }
76273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            throw new CertPathValidatorException("Exception while checking "
76373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                                                 + "mapping", e);
76473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        }
76573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root
76673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        boolean childDeleted = false;
76773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        for (CertificatePolicyMap polMap : maps) {
76873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            String issuerDomain
76973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                = polMap.getIssuerIdentifier().getIdentifier().toString();
77073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            String subjectDomain
77173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                = polMap.getSubjectIdentifier().getIdentifier().toString();
77273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            if (debug != null) {
77373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                debug.println("PolicyChecker.processPolicyMappings() "
77473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                              + "issuerDomain = " + issuerDomain);
77573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                debug.println("PolicyChecker.processPolicyMappings() "
77673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                              + "subjectDomain = " + subjectDomain);
77773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            }
77873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root
77973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            if (issuerDomain.equals(ANY_POLICY)) {
78073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                throw new CertPathValidatorException
78173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                    ("encountered an issuerDomainPolicy of ANY_POLICY",
78273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                     null, null, -1, PKIXReason.INVALID_POLICY);
78373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            }
78473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root
78573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            if (subjectDomain.equals(ANY_POLICY)) {
78673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                throw new CertPathValidatorException
78773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                    ("encountered a subjectDomainPolicy of ANY_POLICY",
78873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                     null, null, -1, PKIXReason.INVALID_POLICY);
78973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            }
79073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root
79173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            Set<PolicyNodeImpl> validNodes =
79273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                rootNode.getPolicyNodesValid(certIndex, issuerDomain);
79373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            if (!validNodes.isEmpty()) {
79473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                for (PolicyNodeImpl curNode : validNodes) {
79573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                    if ((policyMapping > 0) || (policyMapping == -1)) {
79673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                        curNode.addExpectedPolicy(subjectDomain);
79773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                    } else if (policyMapping == 0) {
79873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                        PolicyNodeImpl parentNode =
79973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                            (PolicyNodeImpl) curNode.getParent();
80073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                        if (debug != null)
80173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                            debug.println("PolicyChecker.processPolicyMappings"
80273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                                + "() before deleting: policy tree = "
80373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                                + rootNode);
80473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                        parentNode.deleteChild(curNode);
80573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                        childDeleted = true;
80673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                        if (debug != null)
80773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                            debug.println("PolicyChecker.processPolicyMappings"
80873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                                + "() after deleting: policy tree = "
80973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                                + rootNode);
81073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                    }
81173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                }
81273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            } else { // no node of depth i has a valid policy
81373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                if ((policyMapping > 0) || (policyMapping == -1)) {
81473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                    Set<PolicyNodeImpl> validAnyNodes =
81573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                        rootNode.getPolicyNodesValid(certIndex, ANY_POLICY);
81673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                    for (PolicyNodeImpl curAnyNode : validAnyNodes) {
81773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                        PolicyNodeImpl curAnyNodeParent =
81873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                            (PolicyNodeImpl) curAnyNode.getParent();
81973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root
82073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                        Set<String> expPols = new HashSet<>();
82173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                        expPols.add(subjectDomain);
82273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root
82373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                        PolicyNodeImpl curNode = new PolicyNodeImpl
82473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                            (curAnyNodeParent, issuerDomain, anyQuals,
82573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                             policiesCritical, expPols, true);
82673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                    }
82773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                }
82873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            }
82973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        }
83073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root
83173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        if (childDeleted) {
83273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            rootNode.prune(certIndex);
83373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            if (!rootNode.getChildren().hasNext()) {
83473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                if (debug != null)
83573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                    debug.println("setting rootNode to null");
83673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                rootNode = null;
83773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            }
83873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        }
83973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root
84073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        return rootNode;
84173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root    }
84273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root
84373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root    /**
84473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     * Removes those nodes which do not intersect with the initial policies
84573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     * specified by the user.
84673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     *
84773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     * @param rootNode the root node of the valid policy tree
84873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     * @param certIndex the index of the certificate being processed
84973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     * @param initPolicies the Set of policies required by the user
85073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     * @param currCertPolicies the CertificatePoliciesExtension of the
85173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     * certificate being processed
85273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     * @returns the root node of the valid policy tree after modification
85373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     * @exception CertPathValidatorException Exception thrown if error occurs.
85473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     */
85573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root    private static PolicyNodeImpl removeInvalidNodes(PolicyNodeImpl rootNode,
85673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        int certIndex, Set<String> initPolicies,
85773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        CertificatePoliciesExtension currCertPolicies)
85873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        throws CertPathValidatorException
85973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root    {
86073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        List<PolicyInformation> policyInfo = null;
86173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        try {
86273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            policyInfo = currCertPolicies.get(CertificatePoliciesExtension.POLICIES);
86373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        } catch (IOException ioe) {
86473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            throw new CertPathValidatorException("Exception while "
86573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                + "retrieving policyOIDs", ioe);
86673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        }
86773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root
86873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        boolean childDeleted = false;
86973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        for (PolicyInformation curPolInfo : policyInfo) {
87073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            String curPolicy =
87173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                curPolInfo.getPolicyIdentifier().getIdentifier().toString();
87273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root
87373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            if (debug != null)
87473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                debug.println("PolicyChecker.processPolicies() "
87573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                              + "processing policy second time: " + curPolicy);
87673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root
87773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            Set<PolicyNodeImpl> validNodes =
87873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                        rootNode.getPolicyNodesValid(certIndex, curPolicy);
87973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            for (PolicyNodeImpl curNode : validNodes) {
88073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                PolicyNodeImpl parentNode = (PolicyNodeImpl)curNode.getParent();
88173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                if (parentNode.getValidPolicy().equals(ANY_POLICY)) {
88273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                    if ((!initPolicies.contains(curPolicy)) &&
88373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                        (!curPolicy.equals(ANY_POLICY))) {
88473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                        if (debug != null)
88573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                            debug.println("PolicyChecker.processPolicies() "
88673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                                + "before deleting: policy tree = " + rootNode);
88773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                        parentNode.deleteChild(curNode);
88873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                        childDeleted = true;
88973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                        if (debug != null)
89073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                            debug.println("PolicyChecker.processPolicies() "
89173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                                + "after deleting: policy tree = " + rootNode);
89273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                    }
89373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                }
89473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            }
89573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        }
89673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root
89773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        if (childDeleted) {
89873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            rootNode.prune(certIndex);
89973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            if (!rootNode.getChildren().hasNext()) {
90073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root                rootNode = null;
90173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            }
90273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        }
90373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root
90473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        return rootNode;
90573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root    }
90673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root
90773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root    /**
90873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     * Gets the root node of the valid policy tree, or null if the
90973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     * valid policy tree is null. Marks each node of the returned tree
91073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     * immutable and thread-safe.
91173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     *
91273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     * @returns the root node of the valid policy tree, or null if
91373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     * the valid policy tree is null
91473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root     */
91573405ff8729cca39da90b2e2f604062e323f6f7aKenny Root    PolicyNode getPolicyTree() {
91673405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        if (rootNode == null)
91773405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            return null;
91873405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        else {
91973405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            PolicyNodeImpl policyTree = rootNode.copyTree();
92073405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            policyTree.setImmutable();
92173405ff8729cca39da90b2e2f604062e323f6f7aKenny Root            return policyTree;
92273405ff8729cca39da90b2e2f604062e323f6f7aKenny Root        }
92373405ff8729cca39da90b2e2f604062e323f6f7aKenny Root    }
92473405ff8729cca39da90b2e2f604062e323f6f7aKenny Root}
925