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