security/nss/lib/libpkix/pkix/results/pkix_policynode.c

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rwxr-xr-x

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     1 /* This Source Code Form is subject to the terms of the Mozilla Public
     2  * License, v. 2.0. If a copy of the MPL was not distributed with this
     3  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     4 /*
     5  * pkix_policynode.c
     6  *
     7  * Policy Node Object Type Definition
     8  *
     9  */
    11 #include "pkix_policynode.h"
    13 /* --Private-PolicyNode-Functions---------------------------------- */
    15 /*
    16  * FUNCTION: pkix_PolicyNode_GetChildrenMutable
    17  * DESCRIPTION:
    18  *
    19  *  Retrieves the List of PolicyNodes representing the child nodes of the
    20  *  Policy Node pointed to by "node" and stores it at "pChildren". If "node"
    21  *  has no List of child nodes, this function stores NULL at "pChildren".
    22  *
    23  *  Note that the List returned by this function may be mutable. This function
    24  *  differs from the public function PKIX_PolicyNode_GetChildren in that
    25  *  respect. (It also differs in that the public function creates an empty
    26  *  List, if necessary, rather than storing NULL.)
    27  *
    28  *  During certificate processing, children Lists are created and modified.
    29  *  Once the list is accessed using the public call, the List is set immutable.
    30  *
    31  * PARAMETERS:
    32  *  "node"
    33  *      Address of PolicyNode whose child nodes are to be stored.
    34  *      Must be non-NULL.
    35  *  "pChildren"
    36  *      Address where object pointer will be stored. Must be non-NULL.
    37  *  "plContext"
    38  *      Platform-specific context pointer.
    39  * THREAD SAFETY:
    40  *  Conditionally Thread Safe
    41  *  (see Thread Safety Definitions in Programmer's Guide)
    42  * RETURNS:
    43  *  Returns NULL if the function succeeds.
    44  *  Returns a PolicyNode Error if the function fails in a non-fatal way.
    45  *  Returns a Fatal Error if the function fails in an unrecoverable way.
    46  */
    47 PKIX_Error *
    48 pkix_PolicyNode_GetChildrenMutable(
    49         PKIX_PolicyNode *node,
    50         PKIX_List **pChildren,  /* list of PKIX_PolicyNode */
    51         void *plContext)
    52 {
    54         PKIX_ENTER(CERTPOLICYNODE, "pkix_PolicyNode_GetChildrenMutable");
    56         PKIX_NULLCHECK_TWO(node, pChildren);
    58         PKIX_INCREF(node->children);
    60         *pChildren = node->children;
    62 cleanup:
    63         PKIX_RETURN(CERTPOLICYNODE);
    64 }
    66 /*
    67  * FUNCTION: pkix_PolicyNode_Create
    68  * DESCRIPTION:
    69  *
    70  *  Creates a new PolicyNode using the OID pointed to by "validPolicy", the List
    71  *  of CertPolicyQualifiers pointed to by "qualifierSet", the criticality
    72  *  indicated by the Boolean value of "criticality", and the List of OIDs
    73  *  pointed to by "expectedPolicySet", and stores the result at "pObject". The
    74  *  criticality should be derived from whether the certificate policy extension
    75  *  was marked as critical in the certificate that led to creation of this
    76  *  PolicyNode. The "qualifierSet" and "expectedPolicySet" Lists are made
    77  *  immutable. The PolicyNode pointers to parent and to children are initialized
    78  *  to NULL, and the depth is set to zero; those values should be set by using
    79  *  the pkix_PolicyNode_AddToParent function.
    80  *
    81  * PARAMETERS
    82  *  "validPolicy"
    83  *      Address of OID of the valid policy for the path. Must be non-NULL
    84  *  "qualifierSet"
    85  *      Address of List of CertPolicyQualifiers associated with the validpolicy.
    86  *      May be NULL
    87  *  "criticality"
    88  *      Boolean indicator of whether the criticality should be set in this
    89  *      PolicyNode
    90  *  "expectedPolicySet"
    91  *      Address of List of OIDs that would satisfy this policy in the next
    92  *      certificate. Must be non-NULL
    93  *  "pObject"
    94  *      Address where the PolicyNode pointer will be stored. Must be non-NULL.
    95  *  "plContext"
    96  *      Platform-specific context pointer.
    97  * THREAD SAFETY:
    98  *  Thread Safe (see Thread Safety Definitions in Programmer's Guide)
    99  * RETURNS:
   100  *  Returns NULL if the function succeeds.
   101  *  Returns a PolicyNode Error if the function fails  in a non-fatal way.
   102  *  Returns a Fatal Error if the function fails in an unrecoverable way.
   103  */
   104 PKIX_Error *
   105 pkix_PolicyNode_Create(
   106         PKIX_PL_OID *validPolicy,
   107         PKIX_List *qualifierSet,
   108         PKIX_Boolean criticality,
   109         PKIX_List *expectedPolicySet,
   110         PKIX_PolicyNode **pObject,
   111         void *plContext)
   112 {
   113         PKIX_PolicyNode *node = NULL;
   115         PKIX_ENTER(CERTPOLICYNODE, "pkix_PolicyNode_Create");
   117         PKIX_NULLCHECK_THREE(validPolicy, expectedPolicySet, pObject);
   119         PKIX_CHECK(PKIX_PL_Object_Alloc
   120                 (PKIX_CERTPOLICYNODE_TYPE,
   121                 sizeof (PKIX_PolicyNode),
   122                 (PKIX_PL_Object **)&node,
   123                 plContext),
   124                 PKIX_COULDNOTCREATEPOLICYNODEOBJECT);
   126         PKIX_INCREF(validPolicy);
   127         node->validPolicy = validPolicy;
   129         PKIX_INCREF(qualifierSet);
   130         node->qualifierSet = qualifierSet;
   131         if (qualifierSet) {
   132                 PKIX_CHECK(PKIX_List_SetImmutable(qualifierSet, plContext),
   133                         PKIX_LISTSETIMMUTABLEFAILED);
   134         }
   136         node->criticality = criticality;
   138         PKIX_INCREF(expectedPolicySet);
   139         node->expectedPolicySet = expectedPolicySet;
   140         PKIX_CHECK(PKIX_List_SetImmutable(expectedPolicySet, plContext),
   141                 PKIX_LISTSETIMMUTABLEFAILED);
   143         node->parent = NULL;
   144         node->children = NULL;
   145         node->depth = 0;
   147         *pObject = node;
   148         node = NULL;
   150 cleanup:
   152         PKIX_DECREF(node);
   154         PKIX_RETURN(CERTPOLICYNODE);
   155 }
   157 /*
   158  * FUNCTION: pkix_PolicyNode_AddToParent
   159  * DESCRIPTION:
   160  *
   161  *  Adds the PolicyNode pointed to by "child" to the List of children of
   162  *  the PolicyNode pointed to by "parentNode". If "parentNode" had a
   163  *  NULL pointer for the List of children, a new List is created containing
   164  *  "child". Otherwise "child" is appended to the existing List. The
   165  *  parent field in "child" is set to "parent", and the depth field is
   166  *  set to one more than the corresponding value in "parent".
   167  *
   168  *  Depth, in this context, means distance from the root node, which
   169  *  is at depth zero.
   170  *
   171  * PARAMETERS:
   172  *  "parentNode"
   173  *      Address of PolicyNode whose List of child PolicyNodes is to be
   174  *      created or appended to. Must be non-NULL.
   175  *  "child"
   176  *      Address of PolicyNode to be added to parentNode's List. Must be
   177  *      non-NULL.
   178  *  "plContext"
   179  *      Platform-specific context pointer.
   180  * THREAD SAFETY:
   181  *  Not Thread Safe (see Thread Safety Definitions in Programmer's Guide)
   182  * RETURNS:
   183  *  Returns NULL if the function succeeds.
   184  *  Returns a PolicyNode Error if the function fails in a non-fatal way.
   185  *  Returns a Fatal Error if the function fails in an unrecoverable way.
   186  */
   187 PKIX_Error *
   188 pkix_PolicyNode_AddToParent(
   189         PKIX_PolicyNode *parentNode,
   190         PKIX_PolicyNode *child,
   191         void *plContext)
   192 {
   193         PKIX_List *listOfChildren = NULL;
   195         PKIX_ENTER(CERTPOLICYNODE, "pkix_PolicyNode_AddToParent");
   197         PKIX_NULLCHECK_TWO(parentNode, child);
   199         listOfChildren = parentNode->children;
   200         if (listOfChildren == NULL) {
   201                 PKIX_CHECK(PKIX_List_Create(&listOfChildren, plContext),
   202                         PKIX_LISTCREATEFAILED);
   203                 parentNode->children = listOfChildren;
   204         }
   206         /*
   207          * Note: this link is not reference-counted. The link from parent
   208          * to child is counted (actually, the parent "owns" a List which
   209          * "owns" children), but the children do not "own" the parent.
   210          * Otherwise, there would be loops.
   211          */
   212         child->parent = parentNode;
   214         child->depth = 1 + (parentNode->depth);
   216         PKIX_CHECK(PKIX_List_AppendItem
   217                 (listOfChildren, (PKIX_PL_Object *)child, plContext),
   218                 PKIX_COULDNOTAPPENDCHILDTOPARENTSPOLICYNODELIST);
   220         PKIX_CHECK(PKIX_PL_Object_InvalidateCache
   221                 ((PKIX_PL_Object *)parentNode, plContext),
   222                 PKIX_OBJECTINVALIDATECACHEFAILED);
   224         PKIX_CHECK(PKIX_PL_Object_InvalidateCache
   225                 ((PKIX_PL_Object *)child, plContext),
   226                 PKIX_OBJECTINVALIDATECACHEFAILED);
   228 cleanup:
   230         PKIX_RETURN(CERTPOLICYNODE);
   231 }
   233 /*
   234  * FUNCTION: pkix_PolicyNode_Prune
   235  * DESCRIPTION:
   236  *
   237  *  Prunes a tree below the PolicyNode whose address is pointed to by "node",
   238  *  using the UInt32 value of "height" as the distance from the leaf level,
   239  *  and storing at "pDelete" the Boolean value of whether this PolicyNode is,
   240  *  after pruning, childless and should be pruned.
   241  *
   242  *  Any PolicyNode at height 0 is allowed to survive. If the height is greater
   243  *  than zero, pkix_PolicyNode_Prune is called recursively for each child of
   244  *  the current PolicyNode. After this process, a node with no children
   245  *  stores PKIX_TRUE in "pDelete" to indicate that it should be deleted.
   246  *
   247  * PARAMETERS:
   248  *  "node"
   249  *      Address of the PolicyNode to be pruned. Must be non-NULL.
   250  *  "height"
   251  *      UInt32 value for the distance from the leaf level
   252  *  "pDelete"
   253  *      Address to store the Boolean return value of PKIX_TRUE if this node
   254  *      should be pruned, or PKIX_FALSE if there remains at least one
   255  *      branch of the required height. Must be non-NULL.
   256  *  "plContext"
   257  *      Platform-specific context pointer.
   258  * THREAD SAFETY:
   259  *  Not Thread Safe (see Thread Safety Definitions in Programmer's Guide)
   260  * RETURNS:
   261  *  Returns NULL if the function succeeds.
   262  *  Returns a PolicyNode Error if the function fails in a non-fatal way.
   263  *  Returns a Fatal Error if the function fails in an unrecoverable way.
   264  */
   265 PKIX_Error *
   266 pkix_PolicyNode_Prune(
   267         PKIX_PolicyNode *node,
   268         PKIX_UInt32 height,
   269         PKIX_Boolean *pDelete,
   270         void *plContext)
   271 {
   272         PKIX_Boolean childless = PKIX_FALSE;
   273         PKIX_Boolean shouldBePruned = PKIX_FALSE;
   274         PKIX_UInt32 listSize = 0;
   275         PKIX_UInt32 listIndex = 0;
   276         PKIX_PolicyNode *candidate = NULL;
   278         PKIX_ENTER(CERTPOLICYNODE, "pkix_PolicyNode_Prune");
   280         PKIX_NULLCHECK_TWO(node, pDelete);
   282         /* Don't prune at the leaf */
   283         if (height == 0) {
   284                 goto cleanup;
   285         }
   287         /* Above the bottom level, childless nodes get pruned */
   288         if (!(node->children)) {
   289                 childless = PKIX_TRUE;
   290                 goto cleanup;
   291         }
   293         /*
   294          * This node has children. If they are leaf nodes,
   295          * we know they will live. Otherwise, check them out.
   296          */
   297         if (height > 1) {
   298                 PKIX_CHECK(PKIX_List_GetLength
   299                         (node->children, &listSize, plContext),
   300                         PKIX_LISTGETLENGTHFAILED);
   301                 /*
   302                  * By working backwards from the end of the list,
   303                  * we avoid having to worry about possible
   304                  * decreases in the size of the list, as we
   305                  * delete items. The only nuisance is that since the
   306                  * index is UInt32, we can't check for it to reach -1;
   307                  * we have to use the 1-based index, rather than the
   308                  * 0-based index that PKIX_List functions require.
   309                  */
   310                 for (listIndex = listSize; listIndex > 0; listIndex--) {
   311                         PKIX_CHECK(PKIX_List_GetItem
   312                                 (node->children,
   313                                 (listIndex - 1),
   314                                 (PKIX_PL_Object **)&candidate,
   315                                 plContext),
   316                                 PKIX_LISTGETITEMFAILED);
   318                         PKIX_CHECK(pkix_PolicyNode_Prune
   319                                 (candidate,
   320                                 height - 1,
   321                                 &shouldBePruned,
   322                                 plContext),
   323                                 PKIX_POLICYNODEPRUNEFAILED);
   325                         if (shouldBePruned == PKIX_TRUE) {
   326                                 PKIX_CHECK(PKIX_List_DeleteItem
   327                                         (node->children,
   328                                         (listIndex - 1),
   329                                         plContext),
   330                                         PKIX_LISTDELETEITEMFAILED);
   331                         }
   333                         PKIX_DECREF(candidate);
   334                 }
   335         }
   337         /* Prune if this node has *become* childless */
   338         PKIX_CHECK(PKIX_List_GetLength
   339                 (node->children, &listSize, plContext),
   340                 PKIX_LISTGETLENGTHFAILED);
   341         if (listSize == 0) {
   342                 childless = PKIX_TRUE;
   343         }
   345         /*
   346          * Even if we did not change this node, or any of its children,
   347          * maybe a [great-]*grandchild was pruned.
   348          */
   349         PKIX_CHECK(PKIX_PL_Object_InvalidateCache
   350                 ((PKIX_PL_Object *)node, plContext),
   351                 PKIX_OBJECTINVALIDATECACHEFAILED);
   353 cleanup:
   354         *pDelete = childless;
   356         PKIX_DECREF(candidate);
   358         PKIX_RETURN(CERTPOLICYNODE);
   359 }
   361 /*
   362  * FUNCTION: pkix_SinglePolicyNode_ToString
   363  * DESCRIPTION:
   364  *
   365  *  Creates a String representation of the attributes of the PolicyNode
   366  *  pointed to by "node", other than its parents or children, and
   367  *  stores the result at "pString".
   368  *
   369  * PARAMETERS:
   370  *  "node"
   371  *      Address of PolicyNode to be described by the string. Must be non-NULL.
   372  *  "pString"
   373  *      Address where object pointer will be stored. Must be non-NULL.
   374  *  "plContext"
   375  *      Platform-specific context pointer.
   376  * THREAD SAFETY:
   377  *  Conditionally Thread Safe
   378  *  (see Thread Safety Definitions in Programmer's Guide)
   379  * RETURNS:
   380  *  Returns NULL if function succeeds
   381  *  Returns a PolicyNode Error if the function fails in a non-fatal way.
   382  *  Returns a Fatal Error if the function fails in a fatal way
   383  */
   384 PKIX_Error *
   385 pkix_SinglePolicyNode_ToString(
   386         PKIX_PolicyNode *node,
   387         PKIX_PL_String **pString,
   388         void *plContext)
   389 {
   390         PKIX_PL_String *fmtString = NULL;
   391         PKIX_PL_String *validString = NULL;
   392         PKIX_PL_String *qualifierString = NULL;
   393         PKIX_PL_String *criticalityString = NULL;
   394         PKIX_PL_String *expectedString = NULL;
   395         PKIX_PL_String *outString = NULL;
   397         PKIX_ENTER(CERTPOLICYNODE, "pkix_SinglePolicyNode_ToString");
   398         PKIX_NULLCHECK_TWO(node, pString);
   399         PKIX_NULLCHECK_TWO(node->validPolicy, node->expectedPolicySet);
   401         PKIX_CHECK(PKIX_PL_String_Create
   402                 (PKIX_ESCASCII,
   403                 "{%s,%s,%s,%s,%d}",
   404                 0,
   405                 &fmtString,
   406                 plContext),
   407                 PKIX_CANTCREATESTRING);
   409         PKIX_CHECK(PKIX_PL_Object_ToString
   410                 ((PKIX_PL_Object *)(node->validPolicy),
   411                 &validString,
   412                 plContext),
   413                 PKIX_OIDTOSTRINGFAILED);
   415         PKIX_CHECK(PKIX_PL_Object_ToString
   416                 ((PKIX_PL_Object *)(node->expectedPolicySet),
   417                 &expectedString,
   418                 plContext),
   419                 PKIX_LISTTOSTRINGFAILED);
   421         if (node->qualifierSet) {
   422                 PKIX_CHECK(PKIX_PL_Object_ToString
   423                         ((PKIX_PL_Object *)(node->qualifierSet),
   424                         &qualifierString,
   425                         plContext),
   426                         PKIX_LISTTOSTRINGFAILED);
   427         } else {
   428                 PKIX_CHECK(PKIX_PL_String_Create
   429                         (PKIX_ESCASCII,
   430                         "{}",
   431                         0,
   432                         &qualifierString,
   433                         plContext),
   434                         PKIX_CANTCREATESTRING);
   435         }
   437         PKIX_CHECK(PKIX_PL_String_Create
   438                 (PKIX_ESCASCII,
   439                 (node->criticality)?"Critical":"Not Critical",
   440                 0,
   441                 &criticalityString,
   442                 plContext),
   443                 PKIX_CANTCREATESTRING);
   445         PKIX_CHECK(PKIX_PL_Sprintf
   446                 (&outString,
   447                 plContext,
   448                 fmtString,
   449                 validString,
   450                 qualifierString,
   451                 criticalityString,
   452                 expectedString,
   453                 node->depth),
   454                 PKIX_SPRINTFFAILED);
   456         *pString = outString;
   458 cleanup:
   460         PKIX_DECREF(fmtString);
   461         PKIX_DECREF(validString);
   462         PKIX_DECREF(qualifierString);
   463         PKIX_DECREF(criticalityString);
   464         PKIX_DECREF(expectedString);
   465         PKIX_RETURN(CERTPOLICYNODE);
   466 }
   468 /*
   469  * FUNCTION: pkix_PolicyNode_ToString_Helper
   470  * DESCRIPTION:
   471  *
   472  *  Produces a String representation of a PolicyNode tree below the PolicyNode
   473  *  pointed to by "rootNode", with each line of output prefixed by the String
   474  *  pointed to by "indent", and stores the result at "pTreeString". It is
   475  *  called recursively, with ever-increasing indentation, for successively
   476  *  lower nodes on the tree.
   477  *
   478  * PARAMETERS:
   479  *  "rootNode"
   480  *      Address of PolicyNode subtree. Must be non-NULL.
   481  *  "indent"
   482  *      Address of String to be prefixed to each line of output. May be NULL
   483  *      if no indentation is desired
   484  *  "pTreeString"
   485  *      Address where the resulting String will be stored; must be non-NULL
   486  *  "plContext"
   487  *      Platform-specific context pointer.
   488  * THREAD SAFETY:
   489  *  Conditionally Thread Safe
   490  *  (see Thread Safety Definitions in Programmer's Guide)
   491  * RETURNS:
   492  *  Returns NULL if the function succeeds.
   493  *  Returns a PolicyNode Error if the function fails in a non-fatal way.
   494  *  Returns a Fatal Error if the function fails in an unrecoverable way.
   495  */
   496 static PKIX_Error *
   497 pkix_PolicyNode_ToString_Helper(
   498         PKIX_PolicyNode *rootNode,
   499         PKIX_PL_String *indent,
   500         PKIX_PL_String **pTreeString,
   501         void *plContext)
   502 {
   503         PKIX_PL_String *nextIndentFormat = NULL;
   504         PKIX_PL_String *thisNodeFormat = NULL;
   505         PKIX_PL_String *childrenFormat = NULL;
   506         PKIX_PL_String *nextIndentString = NULL;
   507         PKIX_PL_String *resultString = NULL;
   508         PKIX_PL_String *thisItemString = NULL;
   509         PKIX_PL_String *childString = NULL;
   510         PKIX_PolicyNode *childNode = NULL;
   511         PKIX_UInt32 numberOfChildren = 0;
   512         PKIX_UInt32 childIndex = 0;
   514         PKIX_ENTER(CERTPOLICYNODE, "pkix_PolicyNode_ToString_Helper");
   516         PKIX_NULLCHECK_TWO(rootNode, pTreeString);
   518         /* Create a string for this node */
   519         PKIX_CHECK(pkix_SinglePolicyNode_ToString
   520                 (rootNode, &thisItemString, plContext),
   521                 PKIX_ERRORINSINGLEPOLICYNODETOSTRING);
   523         if (indent) {
   524                 PKIX_CHECK(PKIX_PL_String_Create
   525                         (PKIX_ESCASCII,
   526                         "%s%s",
   527                         0,
   528                         &thisNodeFormat,
   529                         plContext),
   530                         PKIX_ERRORCREATINGFORMATSTRING);
   532                 PKIX_CHECK(PKIX_PL_Sprintf
   533                         (&resultString,
   534                         plContext,
   535                         thisNodeFormat,
   536                         indent,
   537                         thisItemString),
   538                         PKIX_ERRORINSPRINTF);
   539         } else {
   540                 PKIX_CHECK(PKIX_PL_String_Create
   541                         (PKIX_ESCASCII,
   542                         "%s",
   543                         0,
   544                         &thisNodeFormat,
   545                         plContext),
   546                         PKIX_ERRORCREATINGFORMATSTRING);
   548                 PKIX_CHECK(PKIX_PL_Sprintf
   549                         (&resultString,
   550                         plContext,
   551                         thisNodeFormat,
   552                         thisItemString),
   553                         PKIX_ERRORINSPRINTF);
   554         }
   556         PKIX_DECREF(thisItemString);
   557         thisItemString = resultString;
   559         /* if no children, we are done */
   560         if (rootNode->children) {
   561                 PKIX_CHECK(PKIX_List_GetLength
   562                         (rootNode->children, &numberOfChildren, plContext),
   563                         PKIX_LISTGETLENGTHFAILED);
   564         }
   566         if (numberOfChildren != 0) {
   567                 /*
   568                  * We create a string for each child in turn,
   569                  * concatenating them to thisItemString.
   570                  */
   572                 /* Prepare an indent string for each child */
   573                 if (indent) {
   574                         PKIX_CHECK(PKIX_PL_String_Create
   575                                 (PKIX_ESCASCII,
   576                                 "%s. ",
   577                                 0,
   578                                 &nextIndentFormat,
   579                                 plContext),
   580                                 PKIX_ERRORCREATINGFORMATSTRING);
   582                         PKIX_CHECK(PKIX_PL_Sprintf
   583                                 (&nextIndentString,
   584                                 plContext,
   585                                 nextIndentFormat,
   586                                 indent),
   587                                 PKIX_ERRORINSPRINTF);
   588                 } else {
   589                         PKIX_CHECK(PKIX_PL_String_Create
   590                                 (PKIX_ESCASCII,
   591                                 ". ",
   592                                 0,
   593                                 &nextIndentString,
   594                                 plContext),
   595                                 PKIX_ERRORCREATINGINDENTSTRING);
   596                 }
   598                 /* Prepare the format for concatenation. */
   599                 PKIX_CHECK(PKIX_PL_String_Create
   600                         (PKIX_ESCASCII,
   601                         "%s\n%s",
   602                         0,
   603                         &childrenFormat,
   604                         plContext),
   605                         PKIX_ERRORCREATINGFORMATSTRING);
   607                 for (childIndex = 0;
   608                         childIndex < numberOfChildren;
   609                         childIndex++) {
   610                         PKIX_CHECK(PKIX_List_GetItem
   611                                 (rootNode->children,
   612                                 childIndex,
   613                                 (PKIX_PL_Object **)&childNode,
   614                                 plContext),
   615                                 PKIX_LISTGETITEMFAILED);
   617                         PKIX_CHECK(pkix_PolicyNode_ToString_Helper
   618                                 (childNode,
   619                                 nextIndentString,
   620                                 &childString,
   621                                 plContext),
   622                                 PKIX_ERRORCREATINGCHILDSTRING);
   625                         PKIX_CHECK(PKIX_PL_Sprintf
   626                                 (&resultString,
   627                                 plContext,
   628                                 childrenFormat,
   629                                 thisItemString,
   630                                 childString),
   631                         PKIX_ERRORINSPRINTF);
   633                         PKIX_DECREF(childNode);
   634                         PKIX_DECREF(childString);
   635                         PKIX_DECREF(thisItemString);
   637                         thisItemString = resultString;
   638                 }
   639         }
   641         *pTreeString = thisItemString;
   643 cleanup:
   644         if (PKIX_ERROR_RECEIVED) {
   645                 PKIX_DECREF(thisItemString);
   646         }
   648         PKIX_DECREF(nextIndentFormat);
   649         PKIX_DECREF(thisNodeFormat);
   650         PKIX_DECREF(childrenFormat);
   651         PKIX_DECREF(nextIndentString);
   652         PKIX_DECREF(childString);
   653         PKIX_DECREF(childNode);
   655         PKIX_RETURN(CERTPOLICYNODE);
   656 }
   658 /*
   659  * FUNCTION: pkix_PolicyNode_ToString
   660  * (see comments for PKIX_PL_ToStringCallback in pkix_pl_system.h)
   661  */
   662 static PKIX_Error *
   663 pkix_PolicyNode_ToString(
   664         PKIX_PL_Object *object,
   665         PKIX_PL_String **pTreeString,
   666         void *plContext)
   667 {
   668         PKIX_PolicyNode *rootNode = NULL;
   669         PKIX_PL_String *resultString = NULL;
   671         PKIX_ENTER(CERTPOLICYNODE, "pkix_PolicyNode_ToString");
   673         PKIX_NULLCHECK_TWO(object, pTreeString);
   675         PKIX_CHECK(pkix_CheckType(object, PKIX_CERTPOLICYNODE_TYPE, plContext),
   676                 PKIX_OBJECTNOTPOLICYNODE);
   678         rootNode = (PKIX_PolicyNode *)object;
   680         PKIX_CHECK(pkix_PolicyNode_ToString_Helper
   681                 (rootNode, NULL, &resultString, plContext),
   682                 PKIX_ERRORCREATINGSUBTREESTRING);
   684         *pTreeString = resultString;
   686 cleanup:
   688         PKIX_RETURN(CERTPOLICYNODE);
   689 }
   691 /*
   692  * FUNCTION: pkix_PolicyNode_Destroy
   693  * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h)
   694  */
   695 static PKIX_Error *
   696 pkix_PolicyNode_Destroy(
   697         PKIX_PL_Object *object,
   698         void *plContext)
   699 {
   700         PKIX_PolicyNode *node = NULL;
   702         PKIX_ENTER(CERTPOLICYNODE, "pkix_PolicyNode_Destroy");
   704         PKIX_NULLCHECK_ONE(object);
   706         PKIX_CHECK(pkix_CheckType(object, PKIX_CERTPOLICYNODE_TYPE, plContext),
   707                 PKIX_OBJECTNOTPOLICYNODE);
   709         node = (PKIX_PolicyNode*)object;
   711         node->criticality = PKIX_FALSE;
   712         PKIX_DECREF(node->validPolicy);
   713         PKIX_DECREF(node->qualifierSet);
   714         PKIX_DECREF(node->expectedPolicySet);
   715         PKIX_DECREF(node->children);
   717         /*
   718          * Note: the link to parent is not reference-counted. See comment
   719          * in pkix_PolicyNode_AddToParent for more details.
   720          */
   721         node->parent = NULL;
   722         node->depth = 0;
   724 cleanup:
   726         PKIX_RETURN(CERTPOLICYNODE);
   727 }
   729 /*
   730  * FUNCTION: pkix_SinglePolicyNode_Hashcode
   731  * DESCRIPTION:
   732  *
   733  *  Computes the hashcode of the attributes of the PolicyNode pointed to by
   734  *  "node", other than its parents and children, and stores the result at
   735  *  "pHashcode".
   736  *
   737  * PARAMETERS:
   738  *  "node"
   739  *      Address of PolicyNode to be hashcoded; must be non-NULL
   740  *  "pHashcode"
   741  *      Address where UInt32 result will be stored; must be non-NULL
   742  *  "plContext"
   743  *      Platform-specific context pointer.
   744  * THREAD SAFETY:
   745  *  Conditionally Thread Safe
   746  *  (see Thread Safety Definitions in Programmer's Guide)
   747  * RETURNS:
   748  *  Returns NULL if function succeeds
   749  *  Returns a PolicyNode Error if the function fails in a non-fatal way.
   750  *  Returns a Fatal Error if the function fails in a fatal way
   751  */
   752 static PKIX_Error *
   753 pkix_SinglePolicyNode_Hashcode(
   754         PKIX_PolicyNode *node,
   755         PKIX_UInt32 *pHashcode,
   756         void *plContext)
   757 {
   758         PKIX_UInt32 componentHash = 0;
   759         PKIX_UInt32 nodeHash = 0;
   761         PKIX_ENTER(CERTPOLICYNODE, "pkix_SinglePolicyNode_Hashcode");
   762         PKIX_NULLCHECK_TWO(node, pHashcode);
   763         PKIX_NULLCHECK_TWO(node->validPolicy, node->expectedPolicySet);
   765         PKIX_HASHCODE
   766                 (node->qualifierSet,
   767                 &nodeHash,
   768                 plContext,
   769                 PKIX_FAILUREHASHINGLISTQUALIFIERSET);
   771         if (PKIX_TRUE == (node->criticality)) {
   772                 nodeHash = 31*nodeHash + 0xff;
   773         } else {
   774                 nodeHash = 31*nodeHash + 0x00;
   775         }
   777         PKIX_CHECK(PKIX_PL_Object_Hashcode
   778                 ((PKIX_PL_Object *)node->validPolicy,
   779                 &componentHash,
   780                 plContext),
   781                 PKIX_FAILUREHASHINGOIDVALIDPOLICY);
   783         nodeHash = 31*nodeHash + componentHash;
   785         PKIX_CHECK(PKIX_PL_Object_Hashcode
   786                 ((PKIX_PL_Object *)node->expectedPolicySet,
   787                 &componentHash,
   788                 plContext),
   789                 PKIX_FAILUREHASHINGLISTEXPECTEDPOLICYSET);
   791         nodeHash = 31*nodeHash + componentHash;
   793         *pHashcode = nodeHash;
   795 cleanup:
   797         PKIX_RETURN(CERTPOLICYNODE);
   798 }
   800 /*
   801  * FUNCTION: pkix_PolicyNode_Hashcode
   802  * (see comments for PKIX_PL_HashcodeCallback in pkix_pl_system.h)
   803  */
   804 static PKIX_Error *
   805 pkix_PolicyNode_Hashcode(
   806         PKIX_PL_Object *object,
   807         PKIX_UInt32 *pHashcode,
   808         void *plContext)
   809 {
   810         PKIX_PolicyNode *node = NULL;
   811         PKIX_UInt32 childrenHash = 0;
   812         PKIX_UInt32 nodeHash = 0;
   814         PKIX_ENTER(CERTPOLICYNODE, "pkix_PolicyNode_Hashcode");
   815         PKIX_NULLCHECK_TWO(object, pHashcode);
   817         PKIX_CHECK(pkix_CheckType
   818                 (object, PKIX_CERTPOLICYNODE_TYPE, plContext),
   819                 PKIX_OBJECTNOTPOLICYNODE);
   821         node = (PKIX_PolicyNode *)object;
   823         PKIX_CHECK(pkix_SinglePolicyNode_Hashcode
   824                 (node, &nodeHash, plContext),
   825                 PKIX_SINGLEPOLICYNODEHASHCODEFAILED);
   827         nodeHash = 31*nodeHash + (PKIX_UInt32)(node->parent);
   829         PKIX_HASHCODE
   830                 (node->children,
   831                 &childrenHash,
   832                 plContext,
   833                 PKIX_OBJECTHASHCODEFAILED);
   835         nodeHash = 31*nodeHash + childrenHash;
   837         *pHashcode = nodeHash;
   839 cleanup:
   841         PKIX_RETURN(CERTPOLICYNODE);
   842 }
   844 /*
   845  * FUNCTION: pkix_SinglePolicyNode_Equals
   846  * DESCRIPTION:
   847  *
   848  *  Compares for equality the components of the PolicyNode pointed to by
   849  *  "firstPN", other than its parents and children, with those of the
   850  *  PolicyNode pointed to by "secondPN" and stores the result at "pResult"
   851  *  (PKIX_TRUE if equal; PKIX_FALSE if not).
   852  *
   853  * PARAMETERS:
   854  *  "firstPN"
   855  *      Address of first of the PolicyNodes to be compared; must be non-NULL
   856  *  "secondPN"
   857  *      Address of second of the PolicyNodes to be compared; must be non-NULL
   858  *  "pResult"
   859  *      Address where Boolean will be stored; must be non-NULL
   860  *  "plContext"
   861  *      Platform-specific context pointer.
   862  * THREAD SAFETY:
   863  *  Conditionally Thread Safe
   864  *  (see Thread Safety Definitions in Programmer's Guide)
   865  * RETURNS:
   866  *  Returns NULL if function succeeds
   867  *  Returns a PolicyNode Error if the function fails in a non-fatal way.
   868  *  Returns a Fatal Error if the function fails in a fatal way
   869  */
   870 static PKIX_Error *
   871 pkix_SinglePolicyNode_Equals(
   872         PKIX_PolicyNode *firstPN,
   873         PKIX_PolicyNode *secondPN,
   874         PKIX_Boolean *pResult,
   875         void *plContext)
   876 {
   877         PKIX_Boolean compResult = PKIX_FALSE;
   879         PKIX_ENTER(CERTPOLICYNODE, "pkix_SinglePolicyNode_Equals");
   880         PKIX_NULLCHECK_THREE(firstPN, secondPN, pResult);
   882         /* If both references are identical, they must be equal */
   883         if (firstPN == secondPN) {
   884                 compResult = PKIX_TRUE;
   885                 goto cleanup;
   886         }
   888         /*
   889          * It seems we have to do the comparisons. Do
   890          * the easiest ones first.
   891          */
   892         if ((firstPN->criticality) != (secondPN->criticality)) {
   893                 goto cleanup;
   894         }
   895         if ((firstPN->depth) != (secondPN->depth)) {
   896                 goto cleanup;
   897         }
   899         PKIX_EQUALS
   900                 (firstPN->qualifierSet,
   901                 secondPN->qualifierSet,
   902                 &compResult,
   903                 plContext,
   904                 PKIX_OBJECTEQUALSFAILED);
   906         if (compResult == PKIX_FALSE) {
   907                 goto cleanup;
   908         }
   910         /* These fields must be non-NULL */
   911         PKIX_NULLCHECK_TWO(firstPN->validPolicy, secondPN->validPolicy);
   913         PKIX_EQUALS
   914                 (firstPN->validPolicy,
   915                 secondPN->validPolicy,
   916                 &compResult,
   917                 plContext,
   918                 PKIX_OBJECTEQUALSFAILED);
   920         if (compResult == PKIX_FALSE) {
   921                 goto cleanup;
   922         }
   924         /* These fields must be non-NULL */
   925         PKIX_NULLCHECK_TWO
   926                 (firstPN->expectedPolicySet, secondPN->expectedPolicySet);
   928         PKIX_EQUALS
   929                 (firstPN->expectedPolicySet,
   930                 secondPN->expectedPolicySet,
   931                 &compResult,
   932                 plContext,
   933                 PKIX_OBJECTEQUALSFAILEDONEXPECTEDPOLICYSETS);
   935 cleanup:
   937         *pResult = compResult;
   939         PKIX_RETURN(CERTPOLICYNODE);
   940 }
   942 /*
   943  * FUNCTION: pkix_PolicyNode_Equals
   944  * (see comments for PKIX_PL_Equals_Callback in pkix_pl_system.h)
   945  */
   946 static PKIX_Error *
   947 pkix_PolicyNode_Equals(
   948         PKIX_PL_Object *firstObject,
   949         PKIX_PL_Object *secondObject,
   950         PKIX_Boolean *pResult,
   951         void *plContext)
   952 {
   953         PKIX_PolicyNode *firstPN = NULL;
   954         PKIX_PolicyNode *secondPN = NULL;
   955         PKIX_UInt32 secondType;
   956         PKIX_Boolean compResult = PKIX_FALSE;
   958         PKIX_ENTER(CERTPOLICYNODE, "pkix_PolicyNode_Equals");
   959         PKIX_NULLCHECK_THREE(firstObject, secondObject, pResult);
   961         /* test that firstObject is a PolicyNode */
   962         PKIX_CHECK(pkix_CheckType
   963                 (firstObject, PKIX_CERTPOLICYNODE_TYPE, plContext),
   964                 PKIX_FIRSTOBJECTNOTPOLICYNODE);
   966         /*
   967          * Since we know firstObject is a PolicyNode,
   968          * if both references are identical, they must be equal
   969          */
   970         if (firstObject == secondObject){
   971                 compResult = PKIX_TRUE;
   972                 goto cleanup;
   973         }
   975         /*
   976          * If secondObject isn't a PolicyNode, we
   977          * don't throw an error. We simply return FALSE.
   978          */
   979         PKIX_CHECK(PKIX_PL_Object_GetType
   980                     (secondObject, &secondType, plContext),
   981                     PKIX_COULDNOTGETTYPEOFSECONDARGUMENT);
   983         if (secondType != PKIX_CERTPOLICYNODE_TYPE) {
   984                 goto cleanup;
   985         }
   987         /*
   988          * Oh, well, we have to do the comparisons. Do
   989          * the easiest ones first.
   990          */
   991         firstPN = (PKIX_PolicyNode *)firstObject;
   992         secondPN = (PKIX_PolicyNode *)secondObject;
   994         /*
   995          * We don't require the parents to be identical. In the
   996          * course of traversing the tree, we will have checked the
   997          * attributes of the parent nodes, and checking the lists
   998          * of children will determine whether they match.
   999          */
  1001         PKIX_EQUALS
  1002                 (firstPN->children,
  1003                 secondPN->children,
  1004                 &compResult,
  1005                 plContext,
  1006                 PKIX_OBJECTEQUALSFAILEDONCHILDREN);
  1008         if (compResult == PKIX_FALSE) {
  1009                 goto cleanup;
  1012         PKIX_CHECK(pkix_SinglePolicyNode_Equals
  1013                 (firstPN, secondPN, &compResult, plContext),
  1014                 PKIX_SINGLEPOLICYNODEEQUALSFAILED);
  1016 cleanup:
  1018         *pResult = compResult;
  1020         PKIX_RETURN(CERTPOLICYNODE);
  1023 /*
  1024  * FUNCTION: pkix_PolicyNode_DuplicateHelper
  1025  * DESCRIPTION:
  1027  *  Duplicates the PolicyNode whose address is pointed to by "original",
  1028  *  and stores the result at "pNewNode", if a non-NULL pointer is provided
  1029  *  for "pNewNode". In addition, the created PolicyNode is added as a child
  1030  *  to "parent", if a non-NULL pointer is provided for "parent". Then this
  1031  *  function is called recursively to duplicate each of the children of
  1032  *  "original". At the top level this function is called with a null
  1033  *  "parent" and a non-NULL "pNewNode". Below the top level "parent" will
  1034  *  be non-NULL and "pNewNode" will be NULL.
  1036  * PARAMETERS:
  1037  *  "original"
  1038  *      Address of PolicyNode to be copied; must be non-NULL
  1039  *  "parent"
  1040  *      Address of PolicyNode to which the created node is to be added as a
  1041  *      child; NULL for the top-level call and non-NULL below the top level
  1042  *  "pNewNode"
  1043  *      Address to store the node created; should be NULL if "parent" is
  1044  *      non-NULL and vice versa
  1045  *  "plContext"
  1046  *      Platform-specific context pointer.
  1047  * THREAD SAFETY:
  1048  *  Conditionally Thread Safe
  1049  *  (see Thread Safety Definitions in Programmer's Guide)
  1050  * RETURNS:
  1051  *  Returns NULL if function succeeds
  1052  *  Returns a PolicyNode Error if the function fails in a non-fatal way.
  1053  *  Returns a Fatal Error if the function fails in a fatal way
  1054  */
  1055 static PKIX_Error *
  1056 pkix_PolicyNode_DuplicateHelper(
  1057         PKIX_PolicyNode *original,
  1058         PKIX_PolicyNode *parent,
  1059         PKIX_PolicyNode **pNewNode,
  1060         void *plContext)
  1062         PKIX_UInt32 numChildren = 0;
  1063         PKIX_UInt32 childIndex = 0;
  1064         PKIX_List *children = NULL; /* List of PKIX_PolicyNode */
  1065         PKIX_PolicyNode *copy = NULL;
  1066         PKIX_PolicyNode *child = NULL;
  1068         PKIX_ENTER(CERTPOLICYNODE, "pkix_PolicyNode_DuplicateHelper");
  1070         PKIX_NULLCHECK_THREE
  1071                 (original, original->validPolicy, original->expectedPolicySet);
  1073         /*
  1074          * These components are immutable, so copying the pointers
  1075          * is sufficient. The create function increments the reference
  1076          * counts as it stores the pointers into the new object.
  1077          */
  1078         PKIX_CHECK(pkix_PolicyNode_Create
  1079                 (original->validPolicy,
  1080                 original->qualifierSet,
  1081                 original->criticality,
  1082                 original->expectedPolicySet,
  1083                 &copy,
  1084                 plContext),
  1085                 PKIX_POLICYNODECREATEFAILED);
  1087         if (parent) {
  1088                 PKIX_CHECK(pkix_PolicyNode_AddToParent(parent, copy, plContext),
  1089                         PKIX_POLICYNODEADDTOPARENTFAILED);
  1092         /* Are there any children to duplicate? */
  1093         children = original->children;
  1095         if (children) {
  1096             PKIX_CHECK(PKIX_List_GetLength(children, &numChildren, plContext),
  1097                 PKIX_LISTGETLENGTHFAILED);
  1100         for (childIndex = 0; childIndex < numChildren; childIndex++) {
  1101                 PKIX_CHECK(PKIX_List_GetItem
  1102                         (children,
  1103                         childIndex,
  1104                         (PKIX_PL_Object **)&child,
  1105                         plContext),
  1106                         PKIX_LISTGETITEMFAILED);
  1108                 PKIX_CHECK(pkix_PolicyNode_DuplicateHelper
  1109                         (child, copy, NULL, plContext),
  1110                         PKIX_POLICYNODEDUPLICATEHELPERFAILED);
  1112                 PKIX_DECREF(child);
  1115         if (pNewNode) {
  1116                 *pNewNode = copy;
  1117                 copy = NULL; /* no DecRef if we give our handle away */
  1120 cleanup:
  1121         PKIX_DECREF(copy);
  1122         PKIX_DECREF(child);
  1124         PKIX_RETURN(CERTPOLICYNODE);
  1127 /*
  1128  * FUNCTION: pkix_PolicyNode_Duplicate
  1129  * (see comments for PKIX_PL_Duplicate_Callback in pkix_pl_system.h)
  1130  */
  1131 static PKIX_Error *
  1132 pkix_PolicyNode_Duplicate(
  1133         PKIX_PL_Object *object,
  1134         PKIX_PL_Object **pNewObject,
  1135         void *plContext)
  1137         PKIX_PolicyNode *original = NULL;
  1138         PKIX_PolicyNode *copy = NULL;
  1140         PKIX_ENTER(CERTPOLICYNODE, "pkix_PolicyNode_Duplicate");
  1142         PKIX_NULLCHECK_TWO(object, pNewObject);
  1144         PKIX_CHECK(pkix_CheckType
  1145                 (object, PKIX_CERTPOLICYNODE_TYPE, plContext),
  1146                 PKIX_OBJECTNOTPOLICYNODE);
  1148         original = (PKIX_PolicyNode *)object;
  1150         PKIX_CHECK(pkix_PolicyNode_DuplicateHelper
  1151                 (original, NULL, &copy, plContext),
  1152                 PKIX_POLICYNODEDUPLICATEHELPERFAILED);
  1154         *pNewObject = (PKIX_PL_Object *)copy;
  1156 cleanup:
  1158         PKIX_RETURN(CERTPOLICYNODE);
  1161 /*
  1162  * FUNCTION: pkix_PolicyNode_RegisterSelf
  1163  * DESCRIPTION:
  1165  *  Registers PKIX_CERTPOLICYNODE_TYPE and its related
  1166  *  functions with systemClasses[]
  1168  * THREAD SAFETY:
  1169  *  Not Thread Safe - for performance and complexity reasons
  1171  *  Since this function is only called by PKIX_PL_Initialize,
  1172  *  which should only be called once, it is acceptable that
  1173  *  this function is not thread-safe.
  1174  */
  1175 PKIX_Error *
  1176 pkix_PolicyNode_RegisterSelf(void *plContext)
  1179         extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES];
  1180         pkix_ClassTable_Entry entry;
  1182         PKIX_ENTER(CERTPOLICYNODE, "pkix_PolicyNode_RegisterSelf");
  1184         entry.description = "PolicyNode";
  1185         entry.objCounter = 0;
  1186         entry.typeObjectSize = sizeof(PKIX_PolicyNode);
  1187         entry.destructor = pkix_PolicyNode_Destroy;
  1188         entry.equalsFunction = pkix_PolicyNode_Equals;
  1189         entry.hashcodeFunction = pkix_PolicyNode_Hashcode;
  1190         entry.toStringFunction = pkix_PolicyNode_ToString;
  1191         entry.comparator = NULL;
  1192         entry.duplicateFunction = pkix_PolicyNode_Duplicate;
  1194         systemClasses[PKIX_CERTPOLICYNODE_TYPE] = entry;
  1196         PKIX_RETURN(CERTPOLICYNODE);
  1200 /* --Public-PolicyNode-Functions----------------------------------- */
  1202 /*
  1203  * FUNCTION: PKIX_PolicyNode_GetChildren
  1204  * (see description of this function in pkix_results.h)
  1205  */
  1206 PKIX_Error *
  1207 PKIX_PolicyNode_GetChildren(
  1208         PKIX_PolicyNode *node,
  1209         PKIX_List **pChildren,  /* list of PKIX_PolicyNode */
  1210         void *plContext)
  1212         PKIX_List *children = NULL;
  1214         PKIX_ENTER(CERTPOLICYNODE, "PKIX_PolicyNode_GetChildren");
  1216         PKIX_NULLCHECK_TWO(node, pChildren);
  1218         PKIX_INCREF(node->children);
  1219         children = node->children;
  1221         if (!children) {
  1222                 PKIX_CHECK(PKIX_List_Create(&children, plContext),
  1223                         PKIX_LISTCREATEFAILED);
  1226         PKIX_CHECK(PKIX_List_SetImmutable(children, plContext),
  1227                 PKIX_LISTSETIMMUTABLEFAILED);
  1229         *pChildren = children;
  1231 cleanup:
  1232         if (PKIX_ERROR_RECEIVED) {
  1233                 PKIX_DECREF(children);
  1236         PKIX_RETURN(CERTPOLICYNODE);
  1239 /*
  1240  * FUNCTION: PKIX_PolicyNode_GetParent
  1241  * (see description of this function in pkix_results.h)
  1242  */
  1243 PKIX_Error *
  1244 PKIX_PolicyNode_GetParent(
  1245         PKIX_PolicyNode *node,
  1246         PKIX_PolicyNode **pParent,
  1247         void *plContext)
  1250         PKIX_ENTER(CERTPOLICYNODE, "PKIX_PolicyNode_GetParent");
  1252         PKIX_NULLCHECK_TWO(node, pParent);
  1254         PKIX_INCREF(node->parent);
  1255         *pParent = node->parent;
  1257 cleanup:
  1258         PKIX_RETURN(CERTPOLICYNODE);
  1261 /*
  1262  * FUNCTION: PKIX_PolicyNode_GetValidPolicy
  1263  * (see description of this function in pkix_results.h)
  1264  */
  1265 PKIX_Error *
  1266 PKIX_PolicyNode_GetValidPolicy(
  1267         PKIX_PolicyNode *node,
  1268         PKIX_PL_OID **pValidPolicy,
  1269         void *plContext)
  1272         PKIX_ENTER(CERTPOLICYNODE, "PKIX_PolicyNode_GetValidPolicy");
  1274         PKIX_NULLCHECK_TWO(node, pValidPolicy);
  1276         PKIX_INCREF(node->validPolicy);
  1277         *pValidPolicy = node->validPolicy;
  1279 cleanup:
  1280         PKIX_RETURN(CERTPOLICYNODE);
  1283 /*
  1284  * FUNCTION: PKIX_PolicyNode_GetPolicyQualifiers
  1285  * (see description of this function in pkix_results.h)
  1286  */
  1287 PKIX_Error *
  1288 PKIX_PolicyNode_GetPolicyQualifiers(
  1289         PKIX_PolicyNode *node,
  1290         PKIX_List **pQualifiers,  /* list of PKIX_PL_CertPolicyQualifier */
  1291         void *plContext)
  1293         PKIX_List *qualifiers = NULL;
  1295         PKIX_ENTER(CERTPOLICYNODE, "PKIX_PolicyNode_GetPolicyQualifiers");
  1297         PKIX_NULLCHECK_TWO(node, pQualifiers);
  1299         PKIX_INCREF(node->qualifierSet);
  1300         qualifiers = node->qualifierSet;
  1302         if (!qualifiers) {
  1303                 PKIX_CHECK(PKIX_List_Create(&qualifiers, plContext),
  1304                         PKIX_LISTCREATEFAILED);
  1307         PKIX_CHECK(PKIX_List_SetImmutable(qualifiers, plContext),
  1308                 PKIX_LISTSETIMMUTABLEFAILED);
  1310         *pQualifiers = qualifiers;
  1312 cleanup:
  1314         PKIX_RETURN(CERTPOLICYNODE);
  1317 /*
  1318  * FUNCTION: PKIX_PolicyNode_GetExpectedPolicies
  1319  * (see description of this function in pkix_results.h)
  1320  */
  1321 PKIX_Error *
  1322 PKIX_PolicyNode_GetExpectedPolicies(
  1323         PKIX_PolicyNode *node,
  1324         PKIX_List **pExpPolicies,  /* list of PKIX_PL_OID */
  1325         void *plContext)
  1328         PKIX_ENTER(CERTPOLICYNODE, "PKIX_PolicyNode_GetExpectedPolicies");
  1330         PKIX_NULLCHECK_TWO(node, pExpPolicies);
  1332         PKIX_INCREF(node->expectedPolicySet);
  1333         *pExpPolicies = node->expectedPolicySet;
  1335 cleanup:
  1336         PKIX_RETURN(CERTPOLICYNODE);
  1339 /*
  1340  * FUNCTION: PKIX_PolicyNode_IsCritical
  1341  * (see description of this function in pkix_results.h)
  1342  */
  1343 PKIX_Error *
  1344 PKIX_PolicyNode_IsCritical(
  1345         PKIX_PolicyNode *node,
  1346         PKIX_Boolean *pCritical,
  1347         void *plContext)
  1350         PKIX_ENTER(CERTPOLICYNODE, "PKIX_PolicyNode_IsCritical");
  1352         PKIX_NULLCHECK_TWO(node, pCritical);
  1354         *pCritical = node->criticality;
  1356         PKIX_RETURN(CERTPOLICYNODE);
  1359 /*
  1360  * FUNCTION: PKIX_PolicyNode_GetDepth
  1361  * (see description of this function in pkix_results.h)
  1362  */
  1363 PKIX_Error *
  1364 PKIX_PolicyNode_GetDepth(
  1365         PKIX_PolicyNode *node,
  1366         PKIX_UInt32 *pDepth,
  1367         void *plContext)
  1370         PKIX_ENTER(CERTPOLICYNODE, "PKIX_PolicyNode_GetDepth");
  1372         PKIX_NULLCHECK_TWO(node, pDepth);
  1374         *pDepth = node->depth;
  1376         PKIX_RETURN(CERTPOLICYNODE);

mercurial