Save This Page
Home » openjdk-7 » sun.security » provider » certpath » [javadoc | source]
    1   /*
    2    * Copyright (c) 2000, 2006, Oracle and/or its affiliates. All rights reserved.
    3    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    4    *
    5    * This code is free software; you can redistribute it and/or modify it
    6    * under the terms of the GNU General Public License version 2 only, as
    7    * published by the Free Software Foundation.  Oracle designates this
    8    * particular file as subject to the "Classpath" exception as provided
    9    * by Oracle in the LICENSE file that accompanied this code.
   10    *
   11    * This code is distributed in the hope that it will be useful, but WITHOUT
   12    * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   13    * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   14    * version 2 for more details (a copy is included in the LICENSE file that
   15    * accompanied this code).
   16    *
   17    * You should have received a copy of the GNU General Public License version
   18    * 2 along with this work; if not, write to the Free Software Foundation,
   19    * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   20    *
   21    * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   22    * or visit www.oracle.com if you need additional information or have any
   23    * questions.
   24    */
   25   
   26   package sun.security.provider.certpath;
   27   
   28   import java.util.Collections;
   29   import java.util.HashSet;
   30   import java.util.Iterator;
   31   import java.util.Set;
   32   
   33   import java.security.cert;
   34   
   35   /**
   36    * Implements the <code>PolicyNode</code> interface.
   37    * <p>
   38    * This class provides an implementation of the <code>PolicyNode</code>
   39    * interface, and is used internally to build and search Policy Trees.
   40    * While the implementation is mutable during construction, it is immutable
   41    * before returning to a client and no mutable public or protected methods
   42    * are exposed by this implementation, as per the contract of PolicyNode.
   43    *
   44    * @since       1.4
   45    * @author      Seth Proctor
   46    * @author      Sean Mullan
   47    */
   48   final class PolicyNodeImpl implements PolicyNode {
   49   
   50       /**
   51        * Use to specify the special policy "Any Policy"
   52        */
   53       private static final String ANY_POLICY = "2.5.29.32.0";
   54   
   55       // every node has one parent, and zero or more children
   56       private PolicyNodeImpl mParent;
   57       private HashSet<PolicyNodeImpl> mChildren;
   58   
   59       // the 4 fields specified by RFC 3280
   60       private String mValidPolicy;
   61       private HashSet<PolicyQualifierInfo> mQualifierSet;
   62       private boolean mCriticalityIndicator;
   63       private HashSet<String> mExpectedPolicySet;
   64       private boolean mOriginalExpectedPolicySet;
   65   
   66       // the tree depth
   67       private int mDepth;
   68       // immutability flag
   69       private boolean isImmutable = false;
   70   
   71       /**
   72        * Constructor which takes a <code>PolicyNodeImpl</code> representing the
   73        * parent in the Policy Tree to this node. If null, this is the
   74        * root of the tree. The constructor also takes the associated data
   75        * for this node, as found in the certificate. It also takes a boolean
   76        * argument specifying whether this node is being created as a result
   77        * of policy mapping.
   78        *
   79        * @param parent the PolicyNode above this in the tree, or null if this
   80        *               node is the tree's root node
   81        * @param validPolicy a String representing this node's valid policy OID
   82        * @param qualifierSet the Set of qualifiers for this policy
   83        * @param criticalityIndicator a boolean representing whether or not the
   84        *                             extension is critical
   85        * @param expectedPolicySet a Set of expected policies
   86        * @param generatedByPolicyMapping a boolean indicating whether this
   87        * node was generated by a policy mapping
   88        */
   89       PolicyNodeImpl(PolicyNodeImpl parent, String validPolicy,
   90                   Set<PolicyQualifierInfo> qualifierSet,
   91                   boolean criticalityIndicator, Set<String> expectedPolicySet,
   92                   boolean generatedByPolicyMapping) {
   93           mParent = parent;
   94           mChildren = new HashSet<PolicyNodeImpl>();
   95   
   96           if (validPolicy != null)
   97               mValidPolicy = validPolicy;
   98           else
   99               mValidPolicy = "";
  100   
  101           if (qualifierSet != null)
  102               mQualifierSet = new HashSet<PolicyQualifierInfo>(qualifierSet);
  103           else
  104               mQualifierSet = new HashSet<PolicyQualifierInfo>();
  105   
  106           mCriticalityIndicator = criticalityIndicator;
  107   
  108           if (expectedPolicySet != null)
  109               mExpectedPolicySet = new HashSet<String>(expectedPolicySet);
  110           else
  111               mExpectedPolicySet = new HashSet<String>();
  112   
  113           mOriginalExpectedPolicySet = !generatedByPolicyMapping;
  114   
  115           // see if we're the root, and act appropriately
  116           if (mParent != null) {
  117               mDepth = mParent.getDepth() + 1;
  118               mParent.addChild(this);
  119           } else {
  120               mDepth = 0;
  121           }
  122       }
  123   
  124       /**
  125        * Alternate constructor which makes a new node with the policy data
  126        * in an existing <code>PolicyNodeImpl</code>.
  127        *
  128        * @param parent a PolicyNode that's the new parent of the node, or
  129        *               null if this is the root node
  130        * @param node a PolicyNode containing the policy data to copy
  131        */
  132       PolicyNodeImpl(PolicyNodeImpl parent, PolicyNodeImpl node) {
  133           this(parent, node.mValidPolicy, node.mQualifierSet,
  134                node.mCriticalityIndicator, node.mExpectedPolicySet, false);
  135       }
  136   
  137       public PolicyNode getParent() {
  138           return mParent;
  139       }
  140   
  141       public Iterator<PolicyNodeImpl> getChildren() {
  142           return Collections.unmodifiableSet(mChildren).iterator();
  143       }
  144   
  145       public int getDepth() {
  146           return mDepth;
  147       }
  148   
  149       public String getValidPolicy() {
  150           return mValidPolicy;
  151       }
  152   
  153       public Set<PolicyQualifierInfo> getPolicyQualifiers() {
  154           return Collections.unmodifiableSet(mQualifierSet);
  155       }
  156   
  157       public Set<String> getExpectedPolicies() {
  158           return Collections.unmodifiableSet(mExpectedPolicySet);
  159       }
  160   
  161       public boolean isCritical() {
  162           return mCriticalityIndicator;
  163       }
  164   
  165       /**
  166        * Return a printable representation of the PolicyNode.
  167        * Starting at the node on which this method is called,
  168        * it recurses through the tree and prints out each node.
  169        *
  170        * @return a String describing the contents of the Policy Node
  171        */
  172       public String toString() {
  173           StringBuffer buffer = new StringBuffer(this.asString());
  174   
  175           Iterator<PolicyNodeImpl> it = getChildren();
  176           while (it.hasNext()) {
  177               buffer.append(it.next());
  178           }
  179           return buffer.toString();
  180       }
  181   
  182       // private methods and package private operations
  183   
  184       boolean isImmutable() {
  185           return isImmutable;
  186       }
  187   
  188       /**
  189        * Sets the immutability flag of this node and all of its children
  190        * to true.
  191        */
  192       void setImmutable() {
  193           if (isImmutable)
  194               return;
  195           for (PolicyNodeImpl node : mChildren) {
  196               node.setImmutable();
  197           }
  198           isImmutable = true;
  199       }
  200   
  201       /**
  202        * Private method sets a child node. This is called from the child's
  203        * constructor.
  204        *
  205        * @param child new <code>PolicyNodeImpl</code> child node
  206        */
  207       private void addChild(PolicyNodeImpl child) {
  208           if (isImmutable) {
  209               throw new IllegalStateException("PolicyNode is immutable");
  210           }
  211           mChildren.add(child);
  212       }
  213   
  214       /**
  215        * Adds an expectedPolicy to the expected policy set.
  216        * If this is the original expected policy set initialized
  217        * by the constructor, then the expected policy set is cleared
  218        * before the expected policy is added.
  219        *
  220        * @param expectedPolicy a String representing an expected policy.
  221        */
  222       void addExpectedPolicy(String expectedPolicy) {
  223           if (isImmutable) {
  224               throw new IllegalStateException("PolicyNode is immutable");
  225           }
  226           if (mOriginalExpectedPolicySet) {
  227               mExpectedPolicySet.clear();
  228               mOriginalExpectedPolicySet = false;
  229           }
  230           mExpectedPolicySet.add(expectedPolicy);
  231       }
  232   
  233       /**
  234        * Removes all paths which don't reach the specified depth.
  235        *
  236        * @param depth an int representing the desired minimum depth of all paths
  237        */
  238       void prune(int depth) {
  239           if (isImmutable)
  240               throw new IllegalStateException("PolicyNode is immutable");
  241   
  242           // if we have no children, we can't prune below us...
  243           if (mChildren.size() == 0)
  244               return;
  245   
  246           Iterator<PolicyNodeImpl> it = mChildren.iterator();
  247           while (it.hasNext()) {
  248               PolicyNodeImpl node = it.next();
  249               node.prune(depth);
  250               // now that we've called prune on the child, see if we should
  251               // remove it from the tree
  252               if ((node.mChildren.size() == 0) && (depth > mDepth + 1))
  253                   it.remove();
  254           }
  255       }
  256   
  257       /**
  258        * Deletes the specified child node of this node, if it exists.
  259        *
  260        * @param childNode the child node to be deleted
  261        */
  262       void deleteChild(PolicyNode childNode) {
  263           if (isImmutable) {
  264               throw new IllegalStateException("PolicyNode is immutable");
  265           }
  266           mChildren.remove(childNode);
  267       }
  268   
  269       /**
  270        * Returns a copy of the tree, without copying the policy-related data,
  271        * rooted at the node on which this was called.
  272        *
  273        * @return a copy of the tree
  274        */
  275       PolicyNodeImpl copyTree() {
  276           return copyTree(null);
  277       }
  278   
  279       private PolicyNodeImpl copyTree(PolicyNodeImpl parent) {
  280           PolicyNodeImpl newNode = new PolicyNodeImpl(parent, this);
  281   
  282           for (PolicyNodeImpl node : mChildren) {
  283               node.copyTree(newNode);
  284           }
  285   
  286           return newNode;
  287       }
  288   
  289       /**
  290        * Returns all nodes at the specified depth in the tree.
  291        *
  292        * @param depth an int representing the depth of the desired nodes
  293        * @return a <code>Set</code> of all nodes at the specified depth
  294        */
  295       Set<PolicyNodeImpl> getPolicyNodes(int depth) {
  296           Set<PolicyNodeImpl> set = new HashSet<PolicyNodeImpl>();
  297           getPolicyNodes(depth, set);
  298           return set;
  299       }
  300   
  301       /**
  302        * Add all nodes at depth depth to set and return the Set.
  303        * Internal recursion helper.
  304        */
  305       private void getPolicyNodes(int depth, Set<PolicyNodeImpl> set) {
  306           // if we've reached the desired depth, then return ourself
  307           if (mDepth == depth) {
  308               set.add(this);
  309           } else {
  310               for (PolicyNodeImpl node : mChildren) {
  311                   node.getPolicyNodes(depth, set);
  312               }
  313           }
  314       }
  315   
  316       /**
  317        * Finds all nodes at the specified depth whose expected_policy_set
  318        * contains the specified expected OID (if matchAny is false)
  319        * or the special OID "any value" (if matchAny is true).
  320        *
  321        * @param depth an int representing the desired depth
  322        * @param expectedOID a String encoding the valid OID to match
  323        * @param matchAny a boolean indicating whether an expected_policy_set
  324        * containing ANY_POLICY should be considered a match
  325        * @return a Set of matched <code>PolicyNode</code>s
  326        */
  327       Set<PolicyNodeImpl> getPolicyNodesExpected(int depth,
  328           String expectedOID, boolean matchAny) {
  329   
  330           if (expectedOID.equals(ANY_POLICY)) {
  331               return getPolicyNodes(depth);
  332           } else {
  333               return getPolicyNodesExpectedHelper(depth, expectedOID, matchAny);
  334           }
  335       }
  336   
  337       private Set<PolicyNodeImpl> getPolicyNodesExpectedHelper(int depth,
  338           String expectedOID, boolean matchAny) {
  339   
  340           HashSet<PolicyNodeImpl> set = new HashSet<PolicyNodeImpl>();
  341   
  342           if (mDepth < depth) {
  343               for (PolicyNodeImpl node : mChildren) {
  344                   set.addAll(node.getPolicyNodesExpectedHelper(depth,
  345                                                                expectedOID,
  346                                                                matchAny));
  347               }
  348           } else {
  349               if (matchAny) {
  350                   if (mExpectedPolicySet.contains(ANY_POLICY))
  351                       set.add(this);
  352               } else {
  353                   if (mExpectedPolicySet.contains(expectedOID))
  354                       set.add(this);
  355               }
  356           }
  357   
  358           return set;
  359       }
  360   
  361       /**
  362        * Finds all nodes at the specified depth that contains the
  363        * specified valid OID
  364        *
  365        * @param depth an int representing the desired depth
  366        * @param validOID a String encoding the valid OID to match
  367        * @return a Set of matched <code>PolicyNode</code>s
  368        */
  369       Set<PolicyNodeImpl> getPolicyNodesValid(int depth, String validOID) {
  370           HashSet<PolicyNodeImpl> set = new HashSet<PolicyNodeImpl>();
  371   
  372           if (mDepth < depth) {
  373               for (PolicyNodeImpl node : mChildren) {
  374                   set.addAll(node.getPolicyNodesValid(depth, validOID));
  375               }
  376           } else {
  377               if (mValidPolicy.equals(validOID))
  378                   set.add(this);
  379           }
  380   
  381           return set;
  382       }
  383   
  384       private static String policyToString(String oid) {
  385           if (oid.equals(ANY_POLICY)) {
  386               return "anyPolicy";
  387           } else {
  388               return oid;
  389           }
  390       }
  391   
  392       /**
  393        * Prints out some data on this node.
  394        */
  395       String asString() {
  396           if (mParent == null) {
  397               return "anyPolicy  ROOT\n";
  398           } else {
  399               StringBuffer sb = new StringBuffer();
  400               for (int i = 0, n = getDepth(); i < n; i++) {
  401                   sb.append("  ");
  402               }
  403               sb.append(policyToString(getValidPolicy()));
  404               sb.append("  CRIT: ");
  405               sb.append(isCritical());
  406               sb.append("  EP: ");
  407               for (String policy : getExpectedPolicies()) {
  408                   sb.append(policyToString(policy));
  409                   sb.append(" ");
  410               }
  411               sb.append(" (");
  412               sb.append(getDepth());
  413               sb.append(")\n");
  414               return sb.toString();
  415           }
  416       }
  417   }

Save This Page
Home » openjdk-7 » sun.security » provider » certpath » [javadoc | source]