com.tencent.kona.sun.security.provider.certpath.PolicyChecker Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of kona-pkix Show documentation
Show all versions of kona-pkix Show documentation
A Java security provider for supporting ShangMi algorithms in public key infrastructure
/*
* Copyright (c) 2000, 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.tencent.kona.sun.security.provider.certpath;
import java.io.IOException;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.CertPathValidatorException;
import java.security.cert.PKIXCertPathChecker;
import java.security.cert.PKIXReason;
import java.security.cert.PolicyNode;
import java.security.cert.PolicyQualifierInfo;
import java.security.cert.X509Certificate;
import java.util.*;
import com.tencent.kona.sun.security.util.Debug;
import com.tencent.kona.sun.security.util.KnownOIDs;
import com.tencent.kona.sun.security.x509.CertificatePoliciesExtension;
import com.tencent.kona.sun.security.x509.CertificatePolicyMap;
import com.tencent.kona.sun.security.x509.InhibitAnyPolicyExtension;
import static com.tencent.kona.sun.security.x509.PKIXExtensions.*;
import com.tencent.kona.sun.security.x509.PolicyConstraintsExtension;
import com.tencent.kona.sun.security.x509.PolicyInformation;
import com.tencent.kona.sun.security.x509.PolicyMappingsExtension;
import com.tencent.kona.sun.security.x509.X509CertImpl;
/**
* PolicyChecker is a PKIXCertPathChecker
that checks policy
* information on a PKIX certificate, namely certificate policies, policy
* mappings, policy constraints and policy qualifiers.
*
* @since 1.4
* @author Yassir Elley
*/
class PolicyChecker extends PKIXCertPathChecker {
private final Set initPolicies;
private final int certPathLen;
private final boolean expPolicyRequired;
private final boolean polMappingInhibited;
private final boolean anyPolicyInhibited;
private final boolean rejectPolicyQualifiers;
private PolicyNodeImpl rootNode;
private int explicitPolicy;
private int policyMapping;
private int inhibitAnyPolicy;
private int certIndex;
private Set supportedExts;
private static final Debug debug = Debug.getInstance("certpath");
static final String ANY_POLICY = KnownOIDs.CE_CERT_POLICIES_ANY.value();
/**
* Constructs a Policy Checker.
*
* @param initialPolicies Set of initial policies
* @param certPathLen length of the certification path to be checked
* @param expPolicyRequired true if explicit policy is required
* @param polMappingInhibited true if policy mapping is inhibited
* @param anyPolicyInhibited true if the ANY_POLICY OID should be inhibited
* @param rejectPolicyQualifiers true if pol qualifiers are to be rejected
* @param rootNode the initial root node of the valid policy tree
*/
PolicyChecker(Set initialPolicies, int certPathLen,
boolean expPolicyRequired, boolean polMappingInhibited,
boolean anyPolicyInhibited, boolean rejectPolicyQualifiers,
PolicyNodeImpl rootNode)
{
if (initialPolicies.isEmpty()) {
// if no initialPolicies are specified by user, set
// initPolicies to be anyPolicy by default
this.initPolicies = new HashSet<>(1);
this.initPolicies.add(ANY_POLICY);
} else {
this.initPolicies = new HashSet<>(initialPolicies);
}
this.certPathLen = certPathLen;
this.expPolicyRequired = expPolicyRequired;
this.polMappingInhibited = polMappingInhibited;
this.anyPolicyInhibited = anyPolicyInhibited;
this.rejectPolicyQualifiers = rejectPolicyQualifiers;
this.rootNode = rootNode;
}
/**
* Initializes the internal state of the checker from parameters
* specified in the constructor
*
* @param forward a boolean indicating whether this checker should be
* initialized capable of building in the forward direction
* @throws CertPathValidatorException if user wants to enable forward
* checking and forward checking is not supported.
*/
@Override
public void init(boolean forward) throws CertPathValidatorException {
if (forward) {
throw new CertPathValidatorException
("forward checking not supported");
}
certIndex = 1;
explicitPolicy = (expPolicyRequired ? 0 : certPathLen + 1);
policyMapping = (polMappingInhibited ? 0 : certPathLen + 1);
inhibitAnyPolicy = (anyPolicyInhibited ? 0 : certPathLen + 1);
}
/**
* Checks if forward checking is supported. Forward checking refers
* to the ability of the PKIXCertPathChecker to perform its checks
* when presented with certificates in the forward direction (from
* target to anchor).
*
* @return true if forward checking is supported, false otherwise
*/
@Override
public boolean isForwardCheckingSupported() {
return false;
}
/**
* Gets an immutable Set of the OID strings for the extensions that
* the PKIXCertPathChecker supports (i.e. recognizes, is able to
* process), or null if no extensions are
* supported. All OID strings that a PKIXCertPathChecker might
* possibly be able to process should be included.
*
* @return the Set of extensions supported by this PKIXCertPathChecker,
* or null if no extensions are supported
*/
@Override
public Set getSupportedExtensions() {
if (supportedExts == null) {
supportedExts = new HashSet(4);
supportedExts.add(CertificatePolicies_Id.toString());
supportedExts.add(PolicyMappings_Id.toString());
supportedExts.add(PolicyConstraints_Id.toString());
supportedExts.add(InhibitAnyPolicy_Id.toString());
supportedExts = Collections.unmodifiableSet(supportedExts);
}
return supportedExts;
}
/**
* Performs the policy processing checks on the certificate using its
* internal state.
*
* @param cert the Certificate to be processed
* @param unresCritExts the unresolved critical extensions
* @throws CertPathValidatorException if the certificate does not verify
*/
@Override
public void check(Certificate cert, Collection unresCritExts)
throws CertPathValidatorException
{
// now do the policy checks
checkPolicy((X509Certificate) cert);
if (unresCritExts != null && !unresCritExts.isEmpty()) {
unresCritExts.remove(CertificatePolicies_Id.toString());
unresCritExts.remove(PolicyMappings_Id.toString());
unresCritExts.remove(PolicyConstraints_Id.toString());
unresCritExts.remove(InhibitAnyPolicy_Id.toString());
}
}
/**
* Internal method to run through all the checks.
*
* @param currCert the certificate to be processed
* @exception CertPathValidatorException Exception thrown if
* the certificate does not verify
*/
private void checkPolicy(X509Certificate currCert)
throws CertPathValidatorException
{
String msg = "certificate policies";
if (debug != null) {
debug.println("PolicyChecker.checkPolicy() ---checking " + msg
+ "...");
debug.println("PolicyChecker.checkPolicy() certIndex = "
+ certIndex);
debug.println("PolicyChecker.checkPolicy() BEFORE PROCESSING: "
+ "explicitPolicy = " + explicitPolicy);
debug.println("PolicyChecker.checkPolicy() BEFORE PROCESSING: "
+ "policyMapping = " + policyMapping);
debug.println("PolicyChecker.checkPolicy() BEFORE PROCESSING: "
+ "inhibitAnyPolicy = " + inhibitAnyPolicy);
debug.println("PolicyChecker.checkPolicy() BEFORE PROCESSING: "
+ "policyTree = " + rootNode);
}
X509CertImpl currCertImpl;
try {
currCertImpl = X509CertImpl.toImpl(currCert);
} catch (CertificateException ce) {
throw new CertPathValidatorException(ce);
}
boolean finalCert = (certIndex == certPathLen);
rootNode = processPolicies(certIndex, initPolicies, explicitPolicy,
policyMapping, inhibitAnyPolicy, rejectPolicyQualifiers, rootNode,
currCertImpl, finalCert);
if (!finalCert) {
explicitPolicy = mergeExplicitPolicy(explicitPolicy, currCertImpl,
false);
policyMapping = mergePolicyMapping(policyMapping, currCertImpl);
inhibitAnyPolicy = mergeInhibitAnyPolicy(inhibitAnyPolicy,
currCertImpl);
}
certIndex++;
if (debug != null) {
debug.println("PolicyChecker.checkPolicy() AFTER PROCESSING: "
+ "explicitPolicy = " + explicitPolicy);
debug.println("PolicyChecker.checkPolicy() AFTER PROCESSING: "
+ "policyMapping = " + policyMapping);
debug.println("PolicyChecker.checkPolicy() AFTER PROCESSING: "
+ "inhibitAnyPolicy = " + inhibitAnyPolicy);
debug.println("PolicyChecker.checkPolicy() AFTER PROCESSING: "
+ "policyTree = " + rootNode);
debug.println("PolicyChecker.checkPolicy() " + msg + " verified");
}
}
/**
* Merges the specified explicitPolicy value with the
* requireExplicitPolicy field of the PolicyConstraints
* extension obtained from the certificate. An explicitPolicy
* value of -1 implies no constraint.
*
* @param explicitPolicy an integer which indicates if a non-null
* valid policy tree is required
* @param currCert the Certificate to be processed
* @param finalCert a boolean indicating whether currCert is
* the final cert in the cert path
* @return returns the new explicitPolicy value
* @exception CertPathValidatorException Exception thrown if an error
* occurs
*/
static int mergeExplicitPolicy(int explicitPolicy, X509CertImpl currCert,
boolean finalCert) throws CertPathValidatorException {
if ((explicitPolicy > 0) && !X509CertImpl.isSelfIssued(currCert)) {
explicitPolicy--;
}
PolicyConstraintsExtension polConstExt
= currCert.getPolicyConstraintsExtension();
if (polConstExt == null)
return explicitPolicy;
int require = polConstExt.getRequire();
if (debug != null) {
debug.println("PolicyChecker.mergeExplicitPolicy() "
+ "require Index from cert = " + require);
}
if (!finalCert) {
if (require != -1) {
if ((explicitPolicy == -1) || (require < explicitPolicy)) {
explicitPolicy = require;
}
}
} else {
if (require == 0)
explicitPolicy = require;
}
return explicitPolicy;
}
/**
* Merges the specified policyMapping value with the
* inhibitPolicyMapping field of the PolicyConstraints
* extension obtained from the certificate. A policyMapping
* value of -1 implies no constraint.
*
* @param policyMapping an integer which indicates if policy mapping
* is inhibited
* @param currCert the Certificate to be processed
* @return returns the new policyMapping value
* @exception CertPathValidatorException Exception thrown if an error
* occurs
*/
static int mergePolicyMapping(int policyMapping, X509CertImpl currCert)
throws CertPathValidatorException {
if ((policyMapping > 0) && !X509CertImpl.isSelfIssued(currCert)) {
policyMapping--;
}
PolicyConstraintsExtension polConstExt
= currCert.getPolicyConstraintsExtension();
if (polConstExt == null)
return policyMapping;
int inhibit = polConstExt.getInhibit();
if (debug != null)
debug.println("PolicyChecker.mergePolicyMapping() "
+ "inhibit Index from cert = " + inhibit);
if (inhibit != -1) {
if ((policyMapping == -1) || (inhibit < policyMapping)) {
policyMapping = inhibit;
}
}
return policyMapping;
}
/**
* Merges the specified inhibitAnyPolicy value with the
* SkipCerts value of the InhibitAnyPolicy
* extension obtained from the certificate.
*
* @param inhibitAnyPolicy an integer which indicates whether
* "any-policy" is considered a match
* @param currCert the Certificate to be processed
* @return returns the new inhibitAnyPolicy value
* @exception CertPathValidatorException Exception thrown if an error
* occurs
*/
static int mergeInhibitAnyPolicy(int inhibitAnyPolicy,
X509CertImpl currCert) throws CertPathValidatorException {
if ((inhibitAnyPolicy > 0) && !X509CertImpl.isSelfIssued(currCert)) {
inhibitAnyPolicy--;
}
InhibitAnyPolicyExtension inhAnyPolExt = (InhibitAnyPolicyExtension)
currCert.getExtension(InhibitAnyPolicy_Id);
if (inhAnyPolExt == null)
return inhibitAnyPolicy;
int skipCerts = inhAnyPolExt.getSkipCerts();
if (debug != null)
debug.println("PolicyChecker.mergeInhibitAnyPolicy() "
+ "skipCerts Index from cert = " + skipCerts);
if (skipCerts != -1) {
if (skipCerts < inhibitAnyPolicy) {
inhibitAnyPolicy = skipCerts;
}
}
return inhibitAnyPolicy;
}
/**
* Processes certificate policies in the certificate.
*
* @param certIndex the index of the certificate
* @param initPolicies the initial policies required by the user
* @param explicitPolicy an integer which indicates if a non-null
* valid policy tree is required
* @param policyMapping an integer which indicates if policy
* mapping is inhibited
* @param inhibitAnyPolicy an integer which indicates whether
* "any-policy" is considered a match
* @param rejectPolicyQualifiers a boolean indicating whether the
* user wants to reject policies that have qualifiers
* @param origRootNode the root node of the valid policy tree
* @param currCert the Certificate to be processed
* @param finalCert a boolean indicating whether currCert is the final
* cert in the cert path
* @return the root node of the valid policy tree after modification
* @exception CertPathValidatorException Exception thrown if an
* error occurs while processing policies.
*/
static PolicyNodeImpl processPolicies(int certIndex, Set initPolicies,
int explicitPolicy, int policyMapping, int inhibitAnyPolicy,
boolean rejectPolicyQualifiers, PolicyNodeImpl origRootNode,
X509CertImpl currCert, boolean finalCert)
throws CertPathValidatorException
{
boolean policiesCritical = false;
List policyInfo;
PolicyNodeImpl rootNode;
Set anyQuals = new HashSet<>();
if (origRootNode == null)
rootNode = null;
else
rootNode = origRootNode.copyTree();
// retrieve policyOIDs from currCert
CertificatePoliciesExtension currCertPolicies
= currCert.getCertificatePoliciesExtension();
// PKIX: Section 6.1.3: Step (d)
if ((currCertPolicies != null) && (rootNode != null)) {
policiesCritical = currCertPolicies.isCritical();
if (debug != null)
debug.println("PolicyChecker.processPolicies() "
+ "policiesCritical = " + policiesCritical);
policyInfo = currCertPolicies.getCertPolicies();
if (debug != null)
debug.println("PolicyChecker.processPolicies() "
+ "rejectPolicyQualifiers = " + rejectPolicyQualifiers);
boolean foundAnyPolicy = false;
// process each policy in cert
for (PolicyInformation curPolInfo : policyInfo) {
String curPolicy =
curPolInfo.getPolicyIdentifier().getIdentifier().toString();
if (curPolicy.equals(ANY_POLICY)) {
foundAnyPolicy = true;
anyQuals = curPolInfo.getPolicyQualifiers();
} else {
// PKIX: Section 6.1.3: Step (d)(1)
if (debug != null)
debug.println("PolicyChecker.processPolicies() "
+ "processing policy: " + curPolicy);
// retrieve policy qualifiers from cert
Set pQuals =
curPolInfo.getPolicyQualifiers();
// reject cert if we find critical policy qualifiers and
// the policyQualifiersRejected flag is set in the params
if (!pQuals.isEmpty() && rejectPolicyQualifiers &&
policiesCritical) {
throw new CertPathValidatorException(
"critical policy qualifiers present in certificate",
null, null, -1, PKIXReason.INVALID_POLICY);
}
// PKIX: Section 6.1.3: Step (d)(1)(i)
boolean foundMatch = processParents(certIndex,
policiesCritical, rejectPolicyQualifiers, rootNode,
curPolicy, pQuals, false);
if (!foundMatch) {
// PKIX: Section 6.1.3: Step (d)(1)(ii)
processParents(certIndex, policiesCritical,
rejectPolicyQualifiers, rootNode, curPolicy,
pQuals, true);
}
}
}
// PKIX: Section 6.1.3: Step (d)(2)
if (foundAnyPolicy) {
if ((inhibitAnyPolicy > 0) ||
(!finalCert && X509CertImpl.isSelfIssued(currCert))) {
if (debug != null) {
debug.println("PolicyChecker.processPolicies() "
+ "processing policy: " + ANY_POLICY);
}
processParents(certIndex, policiesCritical,
rejectPolicyQualifiers, rootNode, ANY_POLICY, anyQuals,
true);
}
}
// PKIX: Section 6.1.3: Step (d)(3)
rootNode.prune(certIndex);
if (!rootNode.getChildren().hasNext()) {
rootNode = null;
}
} else if (currCertPolicies == null) {
if (debug != null)
debug.println("PolicyChecker.processPolicies() "
+ "no policies present in cert");
// PKIX: Section 6.1.3: Step (e)
rootNode = null;
}
// We delay PKIX: Section 6.1.3: Step (f) to the end
// because the code that follows may delete some nodes
// resulting in a null tree
if (rootNode != null) {
if (!finalCert) {
// PKIX: Section 6.1.4: Steps (a)-(b)
rootNode = processPolicyMappings(currCert, certIndex,
policyMapping, rootNode, policiesCritical, anyQuals);
}
}
// At this point, we optimize the PKIX algorithm by
// removing those nodes which would later have
// been removed by PKIX: Section 6.1.5: Step (g)(iii)
if (rootNode != null && !initPolicies.contains(ANY_POLICY)) {
rootNode = removeInvalidNodes(rootNode, certIndex,
initPolicies, currCertPolicies);
// PKIX: Section 6.1.5: Step (g)(iii)
if ((rootNode != null) && finalCert) {
// rewrite anyPolicy leaf nodes (see method comments)
rootNode = rewriteLeafNodes(certIndex, initPolicies, rootNode);
}
}
if (finalCert) {
// PKIX: Section 6.1.5: Steps (a) and (b)
explicitPolicy = mergeExplicitPolicy(explicitPolicy, currCert,
true);
}
// PKIX: Section 6.1.3: Step (f)
// verify that either explicit policy is greater than 0 or
// the valid_policy_tree is not equal to NULL
if ((explicitPolicy == 0) && (rootNode == null)) {
throw new CertPathValidatorException
("non-null policy tree required and policy tree is null",
null, null, -1, PKIXReason.INVALID_POLICY);
}
return rootNode;
}
/**
* Rewrite leaf nodes at the end of validation as described in RFC 5280
* section 6.1.5: Step (g)(iii). Leaf nodes with anyPolicy are replaced
* by nodes explicitly representing initial policies not already
* represented by leaf nodes.
*
* This method should only be called when processing the final cert
* and if the policy tree is not null and initial policies is not
* anyPolicy.
*
* @param certIndex the depth of the tree
* @param initPolicies Set of user specified initial policies
* @param rootNode the root of the policy tree
*/
private static PolicyNodeImpl rewriteLeafNodes(int certIndex,
Set initPolicies, PolicyNodeImpl rootNode) {
Set anyNodes =
rootNode.getPolicyNodesValid(certIndex, ANY_POLICY);
if (anyNodes.isEmpty()) {
return rootNode;
}
PolicyNodeImpl anyNode = anyNodes.iterator().next();
PolicyNodeImpl parentNode = (PolicyNodeImpl)anyNode.getParent();
parentNode.deleteChild(anyNode);
// see if there are any initialPolicies not represented by leaf nodes
Set initial = new HashSet<>(initPolicies);
for (PolicyNodeImpl node : rootNode.getPolicyNodes(certIndex)) {
initial.remove(node.getValidPolicy());
}
if (initial.isEmpty()) {
// we deleted the anyPolicy node and have nothing to re-add,
// so we need to prune the tree
rootNode.prune(certIndex);
if (!rootNode.getChildren().hasNext()) {
rootNode = null;
}
} else {
boolean anyCritical = anyNode.isCritical();
Set anyQualifiers =
anyNode.getPolicyQualifiers();
for (String policy : initial) {
Set expectedPolicies = Collections.singleton(policy);
new PolicyNodeImpl(parentNode, policy,
anyQualifiers, anyCritical, expectedPolicies, false);
}
}
return rootNode;
}
/**
* Finds the policy nodes of depth (certIndex-1) where curPolicy
* is in the expected policy set and creates a new child node
* appropriately. If matchAny is true, then a value of ANY_POLICY
* in the expected policy set will match any curPolicy. If matchAny
* is false, then the expected policy set must exactly contain the
* curPolicy to be considered a match. This method returns a boolean
* value indicating whether a match was found.
*
* @param certIndex the index of the certificate whose policy is
* being processed
* @param policiesCritical a boolean indicating whether the certificate
* policies extension is critical
* @param rejectPolicyQualifiers a boolean indicating whether the
* user wants to reject policies that have qualifiers
* @param rootNode the root node of the valid policy tree
* @param curPolicy a String representing the policy being processed
* @param pQuals the policy qualifiers of the policy being processed or an
* empty Set if there are no qualifiers
* @param matchAny a boolean indicating whether a value of ANY_POLICY
* in the expected policy set will be considered a match
* @return a boolean indicating whether a match was found
*/
private static boolean processParents(int certIndex,
boolean policiesCritical, boolean rejectPolicyQualifiers,
PolicyNodeImpl rootNode, String curPolicy,
Set pQuals,
boolean matchAny) {
boolean foundMatch = false;
if (debug != null)
debug.println("PolicyChecker.processParents(): matchAny = "
+ matchAny);
// find matching parents
Set parentNodes =
rootNode.getPolicyNodesExpected(certIndex - 1,
curPolicy, matchAny);
// for each matching parent, extend policy tree
for (PolicyNodeImpl curParent : parentNodes) {
if (debug != null)
debug.println("PolicyChecker.processParents() "
+ "found parent:\n" + curParent.asString());
foundMatch = true;
Set curExpPols;
if (curPolicy.equals(ANY_POLICY)) {
// do step 2
Set parExpPols = curParent.getExpectedPolicies();
parentExplicitPolicies:
for (String curParExpPol : parExpPols) {
Iterator childIter =
curParent.getChildren();
while (childIter.hasNext()) {
PolicyNodeImpl childNode = childIter.next();
String childPolicy = childNode.getValidPolicy();
if (curParExpPol.equals(childPolicy)) {
if (debug != null)
debug.println(childPolicy + " in parent's "
+ "expected policy set already appears in "
+ "child node");
continue parentExplicitPolicies;
}
}
Set expPols = new HashSet<>();
expPols.add(curParExpPol);
new PolicyNodeImpl
(curParent, curParExpPol, pQuals,
policiesCritical, expPols, false);
}
} else {
curExpPols = new HashSet<>();
curExpPols.add(curPolicy);
new PolicyNodeImpl
(curParent, curPolicy, pQuals,
policiesCritical, curExpPols, false);
}
}
return foundMatch;
}
/**
* Processes policy mappings in the certificate.
*
* @param currCert the Certificate to be processed
* @param certIndex the index of the current certificate
* @param policyMapping an integer which indicates if policy
* mapping is inhibited
* @param rootNode the root node of the valid policy tree
* @param policiesCritical a boolean indicating if the certificate policies
* extension is critical
* @param anyQuals the qualifiers associated with ANY-POLICY, or an empty
* Set if there are no qualifiers associated with ANY-POLICY
* @return the root node of the valid policy tree after modification
* @exception CertPathValidatorException exception thrown if an error
* occurs while processing policy mappings
*/
private static PolicyNodeImpl processPolicyMappings(X509CertImpl currCert,
int certIndex, int policyMapping, PolicyNodeImpl rootNode,
boolean policiesCritical, Set anyQuals)
throws CertPathValidatorException
{
PolicyMappingsExtension polMappingsExt
= currCert.getPolicyMappingsExtension();
if (polMappingsExt == null)
return rootNode;
if (debug != null)
debug.println("PolicyChecker.processPolicyMappings() "
+ "inside policyMapping check");
List maps;
maps = polMappingsExt.getMaps();
boolean childDeleted = false;
for (CertificatePolicyMap polMap : maps) {
String issuerDomain
= polMap.getIssuerIdentifier().getIdentifier().toString();
String subjectDomain
= polMap.getSubjectIdentifier().getIdentifier().toString();
if (debug != null) {
debug.println("PolicyChecker.processPolicyMappings() "
+ "issuerDomain = " + issuerDomain);
debug.println("PolicyChecker.processPolicyMappings() "
+ "subjectDomain = " + subjectDomain);
}
if (issuerDomain.equals(ANY_POLICY)) {
throw new CertPathValidatorException
("encountered an issuerDomainPolicy of ANY_POLICY",
null, null, -1, PKIXReason.INVALID_POLICY);
}
if (subjectDomain.equals(ANY_POLICY)) {
throw new CertPathValidatorException
("encountered a subjectDomainPolicy of ANY_POLICY",
null, null, -1, PKIXReason.INVALID_POLICY);
}
Set validNodes =
rootNode.getPolicyNodesValid(certIndex, issuerDomain);
if (!validNodes.isEmpty()) {
for (PolicyNodeImpl curNode : validNodes) {
if ((policyMapping > 0) || (policyMapping == -1)) {
curNode.addExpectedPolicy(subjectDomain);
} else if (policyMapping == 0) {
PolicyNodeImpl parentNode =
(PolicyNodeImpl) curNode.getParent();
if (debug != null)
debug.println("PolicyChecker.processPolicyMappings"
+ "() before deleting: policy tree = "
+ rootNode);
parentNode.deleteChild(curNode);
childDeleted = true;
if (debug != null)
debug.println("PolicyChecker.processPolicyMappings"
+ "() after deleting: policy tree = "
+ rootNode);
}
}
} else { // no node of depth i has a valid policy
if ((policyMapping > 0) || (policyMapping == -1)) {
Set validAnyNodes =
rootNode.getPolicyNodesValid(certIndex, ANY_POLICY);
for (PolicyNodeImpl curAnyNode : validAnyNodes) {
PolicyNodeImpl curAnyNodeParent =
(PolicyNodeImpl) curAnyNode.getParent();
Set expPols = new HashSet<>();
expPols.add(subjectDomain);
new PolicyNodeImpl
(curAnyNodeParent, issuerDomain, anyQuals,
policiesCritical, expPols, true);
}
}
}
}
if (childDeleted) {
rootNode.prune(certIndex);
if (!rootNode.getChildren().hasNext()) {
if (debug != null)
debug.println("setting rootNode to null");
rootNode = null;
}
}
return rootNode;
}
/**
* Removes those nodes which do not intersect with the initial policies
* specified by the user.
*
* @param rootNode the root node of the valid policy tree
* @param certIndex the index of the certificate being processed
* @param initPolicies the Set of policies required by the user
* @param currCertPolicies the CertificatePoliciesExtension of the
* certificate being processed
* @return the root node of the valid policy tree after modification
* @exception CertPathValidatorException Exception thrown if error occurs.
*/
private static PolicyNodeImpl removeInvalidNodes(PolicyNodeImpl rootNode,
int certIndex, Set initPolicies,
CertificatePoliciesExtension currCertPolicies)
throws CertPathValidatorException
{
List policyInfo = currCertPolicies.getCertPolicies();
boolean childDeleted = false;
for (PolicyInformation curPolInfo : policyInfo) {
String curPolicy =
curPolInfo.getPolicyIdentifier().getIdentifier().toString();
if (debug != null)
debug.println("PolicyChecker.processPolicies() "
+ "processing policy second time: " + curPolicy);
Set validNodes =
rootNode.getPolicyNodesValid(certIndex, curPolicy);
for (PolicyNodeImpl curNode : validNodes) {
PolicyNodeImpl parentNode = (PolicyNodeImpl)curNode.getParent();
if (parentNode.getValidPolicy().equals(ANY_POLICY)) {
if ((!initPolicies.contains(curPolicy)) &&
(!curPolicy.equals(ANY_POLICY))) {
if (debug != null)
debug.println("PolicyChecker.processPolicies() "
+ "before deleting: policy tree = " + rootNode);
parentNode.deleteChild(curNode);
childDeleted = true;
if (debug != null)
debug.println("PolicyChecker.processPolicies() "
+ "after deleting: policy tree = " + rootNode);
}
}
}
}
if (childDeleted) {
rootNode.prune(certIndex);
if (!rootNode.getChildren().hasNext()) {
rootNode = null;
}
}
return rootNode;
}
/**
* Gets the root node of the valid policy tree, or null if the
* valid policy tree is null. Marks each node of the returned tree
* immutable and thread-safe.
*
* @return the root node of the valid policy tree, or null if
* the valid policy tree is null
*/
PolicyNode getPolicyTree() {
if (rootNode == null)
return null;
else {
PolicyNodeImpl policyTree = rootNode.copyTree();
policyTree.setImmutable();
return policyTree;
}
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy