1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/security/nss/lib/libpkix/pkix/results/pkix_policynode.c Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,1377 @@ 1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.6 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.7 +/* 1.8 + * pkix_policynode.c 1.9 + * 1.10 + * Policy Node Object Type Definition 1.11 + * 1.12 + */ 1.13 + 1.14 +#include "pkix_policynode.h" 1.15 + 1.16 +/* --Private-PolicyNode-Functions---------------------------------- */ 1.17 + 1.18 +/* 1.19 + * FUNCTION: pkix_PolicyNode_GetChildrenMutable 1.20 + * DESCRIPTION: 1.21 + * 1.22 + * Retrieves the List of PolicyNodes representing the child nodes of the 1.23 + * Policy Node pointed to by "node" and stores it at "pChildren". If "node" 1.24 + * has no List of child nodes, this function stores NULL at "pChildren". 1.25 + * 1.26 + * Note that the List returned by this function may be mutable. This function 1.27 + * differs from the public function PKIX_PolicyNode_GetChildren in that 1.28 + * respect. (It also differs in that the public function creates an empty 1.29 + * List, if necessary, rather than storing NULL.) 1.30 + * 1.31 + * During certificate processing, children Lists are created and modified. 1.32 + * Once the list is accessed using the public call, the List is set immutable. 1.33 + * 1.34 + * PARAMETERS: 1.35 + * "node" 1.36 + * Address of PolicyNode whose child nodes are to be stored. 1.37 + * Must be non-NULL. 1.38 + * "pChildren" 1.39 + * Address where object pointer will be stored. Must be non-NULL. 1.40 + * "plContext" 1.41 + * Platform-specific context pointer. 1.42 + * THREAD SAFETY: 1.43 + * Conditionally Thread Safe 1.44 + * (see Thread Safety Definitions in Programmer's Guide) 1.45 + * RETURNS: 1.46 + * Returns NULL if the function succeeds. 1.47 + * Returns a PolicyNode Error if the function fails in a non-fatal way. 1.48 + * Returns a Fatal Error if the function fails in an unrecoverable way. 1.49 + */ 1.50 +PKIX_Error * 1.51 +pkix_PolicyNode_GetChildrenMutable( 1.52 + PKIX_PolicyNode *node, 1.53 + PKIX_List **pChildren, /* list of PKIX_PolicyNode */ 1.54 + void *plContext) 1.55 +{ 1.56 + 1.57 + PKIX_ENTER(CERTPOLICYNODE, "pkix_PolicyNode_GetChildrenMutable"); 1.58 + 1.59 + PKIX_NULLCHECK_TWO(node, pChildren); 1.60 + 1.61 + PKIX_INCREF(node->children); 1.62 + 1.63 + *pChildren = node->children; 1.64 + 1.65 +cleanup: 1.66 + PKIX_RETURN(CERTPOLICYNODE); 1.67 +} 1.68 + 1.69 +/* 1.70 + * FUNCTION: pkix_PolicyNode_Create 1.71 + * DESCRIPTION: 1.72 + * 1.73 + * Creates a new PolicyNode using the OID pointed to by "validPolicy", the List 1.74 + * of CertPolicyQualifiers pointed to by "qualifierSet", the criticality 1.75 + * indicated by the Boolean value of "criticality", and the List of OIDs 1.76 + * pointed to by "expectedPolicySet", and stores the result at "pObject". The 1.77 + * criticality should be derived from whether the certificate policy extension 1.78 + * was marked as critical in the certificate that led to creation of this 1.79 + * PolicyNode. The "qualifierSet" and "expectedPolicySet" Lists are made 1.80 + * immutable. The PolicyNode pointers to parent and to children are initialized 1.81 + * to NULL, and the depth is set to zero; those values should be set by using 1.82 + * the pkix_PolicyNode_AddToParent function. 1.83 + * 1.84 + * PARAMETERS 1.85 + * "validPolicy" 1.86 + * Address of OID of the valid policy for the path. Must be non-NULL 1.87 + * "qualifierSet" 1.88 + * Address of List of CertPolicyQualifiers associated with the validpolicy. 1.89 + * May be NULL 1.90 + * "criticality" 1.91 + * Boolean indicator of whether the criticality should be set in this 1.92 + * PolicyNode 1.93 + * "expectedPolicySet" 1.94 + * Address of List of OIDs that would satisfy this policy in the next 1.95 + * certificate. Must be non-NULL 1.96 + * "pObject" 1.97 + * Address where the PolicyNode pointer will be stored. Must be non-NULL. 1.98 + * "plContext" 1.99 + * Platform-specific context pointer. 1.100 + * THREAD SAFETY: 1.101 + * Thread Safe (see Thread Safety Definitions in Programmer's Guide) 1.102 + * RETURNS: 1.103 + * Returns NULL if the function succeeds. 1.104 + * Returns a PolicyNode Error if the function fails in a non-fatal way. 1.105 + * Returns a Fatal Error if the function fails in an unrecoverable way. 1.106 + */ 1.107 +PKIX_Error * 1.108 +pkix_PolicyNode_Create( 1.109 + PKIX_PL_OID *validPolicy, 1.110 + PKIX_List *qualifierSet, 1.111 + PKIX_Boolean criticality, 1.112 + PKIX_List *expectedPolicySet, 1.113 + PKIX_PolicyNode **pObject, 1.114 + void *plContext) 1.115 +{ 1.116 + PKIX_PolicyNode *node = NULL; 1.117 + 1.118 + PKIX_ENTER(CERTPOLICYNODE, "pkix_PolicyNode_Create"); 1.119 + 1.120 + PKIX_NULLCHECK_THREE(validPolicy, expectedPolicySet, pObject); 1.121 + 1.122 + PKIX_CHECK(PKIX_PL_Object_Alloc 1.123 + (PKIX_CERTPOLICYNODE_TYPE, 1.124 + sizeof (PKIX_PolicyNode), 1.125 + (PKIX_PL_Object **)&node, 1.126 + plContext), 1.127 + PKIX_COULDNOTCREATEPOLICYNODEOBJECT); 1.128 + 1.129 + PKIX_INCREF(validPolicy); 1.130 + node->validPolicy = validPolicy; 1.131 + 1.132 + PKIX_INCREF(qualifierSet); 1.133 + node->qualifierSet = qualifierSet; 1.134 + if (qualifierSet) { 1.135 + PKIX_CHECK(PKIX_List_SetImmutable(qualifierSet, plContext), 1.136 + PKIX_LISTSETIMMUTABLEFAILED); 1.137 + } 1.138 + 1.139 + node->criticality = criticality; 1.140 + 1.141 + PKIX_INCREF(expectedPolicySet); 1.142 + node->expectedPolicySet = expectedPolicySet; 1.143 + PKIX_CHECK(PKIX_List_SetImmutable(expectedPolicySet, plContext), 1.144 + PKIX_LISTSETIMMUTABLEFAILED); 1.145 + 1.146 + node->parent = NULL; 1.147 + node->children = NULL; 1.148 + node->depth = 0; 1.149 + 1.150 + *pObject = node; 1.151 + node = NULL; 1.152 + 1.153 +cleanup: 1.154 + 1.155 + PKIX_DECREF(node); 1.156 + 1.157 + PKIX_RETURN(CERTPOLICYNODE); 1.158 +} 1.159 + 1.160 +/* 1.161 + * FUNCTION: pkix_PolicyNode_AddToParent 1.162 + * DESCRIPTION: 1.163 + * 1.164 + * Adds the PolicyNode pointed to by "child" to the List of children of 1.165 + * the PolicyNode pointed to by "parentNode". If "parentNode" had a 1.166 + * NULL pointer for the List of children, a new List is created containing 1.167 + * "child". Otherwise "child" is appended to the existing List. The 1.168 + * parent field in "child" is set to "parent", and the depth field is 1.169 + * set to one more than the corresponding value in "parent". 1.170 + * 1.171 + * Depth, in this context, means distance from the root node, which 1.172 + * is at depth zero. 1.173 + * 1.174 + * PARAMETERS: 1.175 + * "parentNode" 1.176 + * Address of PolicyNode whose List of child PolicyNodes is to be 1.177 + * created or appended to. Must be non-NULL. 1.178 + * "child" 1.179 + * Address of PolicyNode to be added to parentNode's List. Must be 1.180 + * non-NULL. 1.181 + * "plContext" 1.182 + * Platform-specific context pointer. 1.183 + * THREAD SAFETY: 1.184 + * Not Thread Safe (see Thread Safety Definitions in Programmer's Guide) 1.185 + * RETURNS: 1.186 + * Returns NULL if the function succeeds. 1.187 + * Returns a PolicyNode Error if the function fails in a non-fatal way. 1.188 + * Returns a Fatal Error if the function fails in an unrecoverable way. 1.189 + */ 1.190 +PKIX_Error * 1.191 +pkix_PolicyNode_AddToParent( 1.192 + PKIX_PolicyNode *parentNode, 1.193 + PKIX_PolicyNode *child, 1.194 + void *plContext) 1.195 +{ 1.196 + PKIX_List *listOfChildren = NULL; 1.197 + 1.198 + PKIX_ENTER(CERTPOLICYNODE, "pkix_PolicyNode_AddToParent"); 1.199 + 1.200 + PKIX_NULLCHECK_TWO(parentNode, child); 1.201 + 1.202 + listOfChildren = parentNode->children; 1.203 + if (listOfChildren == NULL) { 1.204 + PKIX_CHECK(PKIX_List_Create(&listOfChildren, plContext), 1.205 + PKIX_LISTCREATEFAILED); 1.206 + parentNode->children = listOfChildren; 1.207 + } 1.208 + 1.209 + /* 1.210 + * Note: this link is not reference-counted. The link from parent 1.211 + * to child is counted (actually, the parent "owns" a List which 1.212 + * "owns" children), but the children do not "own" the parent. 1.213 + * Otherwise, there would be loops. 1.214 + */ 1.215 + child->parent = parentNode; 1.216 + 1.217 + child->depth = 1 + (parentNode->depth); 1.218 + 1.219 + PKIX_CHECK(PKIX_List_AppendItem 1.220 + (listOfChildren, (PKIX_PL_Object *)child, plContext), 1.221 + PKIX_COULDNOTAPPENDCHILDTOPARENTSPOLICYNODELIST); 1.222 + 1.223 + PKIX_CHECK(PKIX_PL_Object_InvalidateCache 1.224 + ((PKIX_PL_Object *)parentNode, plContext), 1.225 + PKIX_OBJECTINVALIDATECACHEFAILED); 1.226 + 1.227 + PKIX_CHECK(PKIX_PL_Object_InvalidateCache 1.228 + ((PKIX_PL_Object *)child, plContext), 1.229 + PKIX_OBJECTINVALIDATECACHEFAILED); 1.230 + 1.231 +cleanup: 1.232 + 1.233 + PKIX_RETURN(CERTPOLICYNODE); 1.234 +} 1.235 + 1.236 +/* 1.237 + * FUNCTION: pkix_PolicyNode_Prune 1.238 + * DESCRIPTION: 1.239 + * 1.240 + * Prunes a tree below the PolicyNode whose address is pointed to by "node", 1.241 + * using the UInt32 value of "height" as the distance from the leaf level, 1.242 + * and storing at "pDelete" the Boolean value of whether this PolicyNode is, 1.243 + * after pruning, childless and should be pruned. 1.244 + * 1.245 + * Any PolicyNode at height 0 is allowed to survive. If the height is greater 1.246 + * than zero, pkix_PolicyNode_Prune is called recursively for each child of 1.247 + * the current PolicyNode. After this process, a node with no children 1.248 + * stores PKIX_TRUE in "pDelete" to indicate that it should be deleted. 1.249 + * 1.250 + * PARAMETERS: 1.251 + * "node" 1.252 + * Address of the PolicyNode to be pruned. Must be non-NULL. 1.253 + * "height" 1.254 + * UInt32 value for the distance from the leaf level 1.255 + * "pDelete" 1.256 + * Address to store the Boolean return value of PKIX_TRUE if this node 1.257 + * should be pruned, or PKIX_FALSE if there remains at least one 1.258 + * branch of the required height. Must be non-NULL. 1.259 + * "plContext" 1.260 + * Platform-specific context pointer. 1.261 + * THREAD SAFETY: 1.262 + * Not Thread Safe (see Thread Safety Definitions in Programmer's Guide) 1.263 + * RETURNS: 1.264 + * Returns NULL if the function succeeds. 1.265 + * Returns a PolicyNode Error if the function fails in a non-fatal way. 1.266 + * Returns a Fatal Error if the function fails in an unrecoverable way. 1.267 + */ 1.268 +PKIX_Error * 1.269 +pkix_PolicyNode_Prune( 1.270 + PKIX_PolicyNode *node, 1.271 + PKIX_UInt32 height, 1.272 + PKIX_Boolean *pDelete, 1.273 + void *plContext) 1.274 +{ 1.275 + PKIX_Boolean childless = PKIX_FALSE; 1.276 + PKIX_Boolean shouldBePruned = PKIX_FALSE; 1.277 + PKIX_UInt32 listSize = 0; 1.278 + PKIX_UInt32 listIndex = 0; 1.279 + PKIX_PolicyNode *candidate = NULL; 1.280 + 1.281 + PKIX_ENTER(CERTPOLICYNODE, "pkix_PolicyNode_Prune"); 1.282 + 1.283 + PKIX_NULLCHECK_TWO(node, pDelete); 1.284 + 1.285 + /* Don't prune at the leaf */ 1.286 + if (height == 0) { 1.287 + goto cleanup; 1.288 + } 1.289 + 1.290 + /* Above the bottom level, childless nodes get pruned */ 1.291 + if (!(node->children)) { 1.292 + childless = PKIX_TRUE; 1.293 + goto cleanup; 1.294 + } 1.295 + 1.296 + /* 1.297 + * This node has children. If they are leaf nodes, 1.298 + * we know they will live. Otherwise, check them out. 1.299 + */ 1.300 + if (height > 1) { 1.301 + PKIX_CHECK(PKIX_List_GetLength 1.302 + (node->children, &listSize, plContext), 1.303 + PKIX_LISTGETLENGTHFAILED); 1.304 + /* 1.305 + * By working backwards from the end of the list, 1.306 + * we avoid having to worry about possible 1.307 + * decreases in the size of the list, as we 1.308 + * delete items. The only nuisance is that since the 1.309 + * index is UInt32, we can't check for it to reach -1; 1.310 + * we have to use the 1-based index, rather than the 1.311 + * 0-based index that PKIX_List functions require. 1.312 + */ 1.313 + for (listIndex = listSize; listIndex > 0; listIndex--) { 1.314 + PKIX_CHECK(PKIX_List_GetItem 1.315 + (node->children, 1.316 + (listIndex - 1), 1.317 + (PKIX_PL_Object **)&candidate, 1.318 + plContext), 1.319 + PKIX_LISTGETITEMFAILED); 1.320 + 1.321 + PKIX_CHECK(pkix_PolicyNode_Prune 1.322 + (candidate, 1.323 + height - 1, 1.324 + &shouldBePruned, 1.325 + plContext), 1.326 + PKIX_POLICYNODEPRUNEFAILED); 1.327 + 1.328 + if (shouldBePruned == PKIX_TRUE) { 1.329 + PKIX_CHECK(PKIX_List_DeleteItem 1.330 + (node->children, 1.331 + (listIndex - 1), 1.332 + plContext), 1.333 + PKIX_LISTDELETEITEMFAILED); 1.334 + } 1.335 + 1.336 + PKIX_DECREF(candidate); 1.337 + } 1.338 + } 1.339 + 1.340 + /* Prune if this node has *become* childless */ 1.341 + PKIX_CHECK(PKIX_List_GetLength 1.342 + (node->children, &listSize, plContext), 1.343 + PKIX_LISTGETLENGTHFAILED); 1.344 + if (listSize == 0) { 1.345 + childless = PKIX_TRUE; 1.346 + } 1.347 + 1.348 + /* 1.349 + * Even if we did not change this node, or any of its children, 1.350 + * maybe a [great-]*grandchild was pruned. 1.351 + */ 1.352 + PKIX_CHECK(PKIX_PL_Object_InvalidateCache 1.353 + ((PKIX_PL_Object *)node, plContext), 1.354 + PKIX_OBJECTINVALIDATECACHEFAILED); 1.355 + 1.356 +cleanup: 1.357 + *pDelete = childless; 1.358 + 1.359 + PKIX_DECREF(candidate); 1.360 + 1.361 + PKIX_RETURN(CERTPOLICYNODE); 1.362 +} 1.363 + 1.364 +/* 1.365 + * FUNCTION: pkix_SinglePolicyNode_ToString 1.366 + * DESCRIPTION: 1.367 + * 1.368 + * Creates a String representation of the attributes of the PolicyNode 1.369 + * pointed to by "node", other than its parents or children, and 1.370 + * stores the result at "pString". 1.371 + * 1.372 + * PARAMETERS: 1.373 + * "node" 1.374 + * Address of PolicyNode to be described by the string. Must be non-NULL. 1.375 + * "pString" 1.376 + * Address where object pointer will be stored. Must be non-NULL. 1.377 + * "plContext" 1.378 + * Platform-specific context pointer. 1.379 + * THREAD SAFETY: 1.380 + * Conditionally Thread Safe 1.381 + * (see Thread Safety Definitions in Programmer's Guide) 1.382 + * RETURNS: 1.383 + * Returns NULL if function succeeds 1.384 + * Returns a PolicyNode Error if the function fails in a non-fatal way. 1.385 + * Returns a Fatal Error if the function fails in a fatal way 1.386 + */ 1.387 +PKIX_Error * 1.388 +pkix_SinglePolicyNode_ToString( 1.389 + PKIX_PolicyNode *node, 1.390 + PKIX_PL_String **pString, 1.391 + void *plContext) 1.392 +{ 1.393 + PKIX_PL_String *fmtString = NULL; 1.394 + PKIX_PL_String *validString = NULL; 1.395 + PKIX_PL_String *qualifierString = NULL; 1.396 + PKIX_PL_String *criticalityString = NULL; 1.397 + PKIX_PL_String *expectedString = NULL; 1.398 + PKIX_PL_String *outString = NULL; 1.399 + 1.400 + PKIX_ENTER(CERTPOLICYNODE, "pkix_SinglePolicyNode_ToString"); 1.401 + PKIX_NULLCHECK_TWO(node, pString); 1.402 + PKIX_NULLCHECK_TWO(node->validPolicy, node->expectedPolicySet); 1.403 + 1.404 + PKIX_CHECK(PKIX_PL_String_Create 1.405 + (PKIX_ESCASCII, 1.406 + "{%s,%s,%s,%s,%d}", 1.407 + 0, 1.408 + &fmtString, 1.409 + plContext), 1.410 + PKIX_CANTCREATESTRING); 1.411 + 1.412 + PKIX_CHECK(PKIX_PL_Object_ToString 1.413 + ((PKIX_PL_Object *)(node->validPolicy), 1.414 + &validString, 1.415 + plContext), 1.416 + PKIX_OIDTOSTRINGFAILED); 1.417 + 1.418 + PKIX_CHECK(PKIX_PL_Object_ToString 1.419 + ((PKIX_PL_Object *)(node->expectedPolicySet), 1.420 + &expectedString, 1.421 + plContext), 1.422 + PKIX_LISTTOSTRINGFAILED); 1.423 + 1.424 + if (node->qualifierSet) { 1.425 + PKIX_CHECK(PKIX_PL_Object_ToString 1.426 + ((PKIX_PL_Object *)(node->qualifierSet), 1.427 + &qualifierString, 1.428 + plContext), 1.429 + PKIX_LISTTOSTRINGFAILED); 1.430 + } else { 1.431 + PKIX_CHECK(PKIX_PL_String_Create 1.432 + (PKIX_ESCASCII, 1.433 + "{}", 1.434 + 0, 1.435 + &qualifierString, 1.436 + plContext), 1.437 + PKIX_CANTCREATESTRING); 1.438 + } 1.439 + 1.440 + PKIX_CHECK(PKIX_PL_String_Create 1.441 + (PKIX_ESCASCII, 1.442 + (node->criticality)?"Critical":"Not Critical", 1.443 + 0, 1.444 + &criticalityString, 1.445 + plContext), 1.446 + PKIX_CANTCREATESTRING); 1.447 + 1.448 + PKIX_CHECK(PKIX_PL_Sprintf 1.449 + (&outString, 1.450 + plContext, 1.451 + fmtString, 1.452 + validString, 1.453 + qualifierString, 1.454 + criticalityString, 1.455 + expectedString, 1.456 + node->depth), 1.457 + PKIX_SPRINTFFAILED); 1.458 + 1.459 + *pString = outString; 1.460 + 1.461 +cleanup: 1.462 + 1.463 + PKIX_DECREF(fmtString); 1.464 + PKIX_DECREF(validString); 1.465 + PKIX_DECREF(qualifierString); 1.466 + PKIX_DECREF(criticalityString); 1.467 + PKIX_DECREF(expectedString); 1.468 + PKIX_RETURN(CERTPOLICYNODE); 1.469 +} 1.470 + 1.471 +/* 1.472 + * FUNCTION: pkix_PolicyNode_ToString_Helper 1.473 + * DESCRIPTION: 1.474 + * 1.475 + * Produces a String representation of a PolicyNode tree below the PolicyNode 1.476 + * pointed to by "rootNode", with each line of output prefixed by the String 1.477 + * pointed to by "indent", and stores the result at "pTreeString". It is 1.478 + * called recursively, with ever-increasing indentation, for successively 1.479 + * lower nodes on the tree. 1.480 + * 1.481 + * PARAMETERS: 1.482 + * "rootNode" 1.483 + * Address of PolicyNode subtree. Must be non-NULL. 1.484 + * "indent" 1.485 + * Address of String to be prefixed to each line of output. May be NULL 1.486 + * if no indentation is desired 1.487 + * "pTreeString" 1.488 + * Address where the resulting String will be stored; must be non-NULL 1.489 + * "plContext" 1.490 + * Platform-specific context pointer. 1.491 + * THREAD SAFETY: 1.492 + * Conditionally Thread Safe 1.493 + * (see Thread Safety Definitions in Programmer's Guide) 1.494 + * RETURNS: 1.495 + * Returns NULL if the function succeeds. 1.496 + * Returns a PolicyNode Error if the function fails in a non-fatal way. 1.497 + * Returns a Fatal Error if the function fails in an unrecoverable way. 1.498 + */ 1.499 +static PKIX_Error * 1.500 +pkix_PolicyNode_ToString_Helper( 1.501 + PKIX_PolicyNode *rootNode, 1.502 + PKIX_PL_String *indent, 1.503 + PKIX_PL_String **pTreeString, 1.504 + void *plContext) 1.505 +{ 1.506 + PKIX_PL_String *nextIndentFormat = NULL; 1.507 + PKIX_PL_String *thisNodeFormat = NULL; 1.508 + PKIX_PL_String *childrenFormat = NULL; 1.509 + PKIX_PL_String *nextIndentString = NULL; 1.510 + PKIX_PL_String *resultString = NULL; 1.511 + PKIX_PL_String *thisItemString = NULL; 1.512 + PKIX_PL_String *childString = NULL; 1.513 + PKIX_PolicyNode *childNode = NULL; 1.514 + PKIX_UInt32 numberOfChildren = 0; 1.515 + PKIX_UInt32 childIndex = 0; 1.516 + 1.517 + PKIX_ENTER(CERTPOLICYNODE, "pkix_PolicyNode_ToString_Helper"); 1.518 + 1.519 + PKIX_NULLCHECK_TWO(rootNode, pTreeString); 1.520 + 1.521 + /* Create a string for this node */ 1.522 + PKIX_CHECK(pkix_SinglePolicyNode_ToString 1.523 + (rootNode, &thisItemString, plContext), 1.524 + PKIX_ERRORINSINGLEPOLICYNODETOSTRING); 1.525 + 1.526 + if (indent) { 1.527 + PKIX_CHECK(PKIX_PL_String_Create 1.528 + (PKIX_ESCASCII, 1.529 + "%s%s", 1.530 + 0, 1.531 + &thisNodeFormat, 1.532 + plContext), 1.533 + PKIX_ERRORCREATINGFORMATSTRING); 1.534 + 1.535 + PKIX_CHECK(PKIX_PL_Sprintf 1.536 + (&resultString, 1.537 + plContext, 1.538 + thisNodeFormat, 1.539 + indent, 1.540 + thisItemString), 1.541 + PKIX_ERRORINSPRINTF); 1.542 + } else { 1.543 + PKIX_CHECK(PKIX_PL_String_Create 1.544 + (PKIX_ESCASCII, 1.545 + "%s", 1.546 + 0, 1.547 + &thisNodeFormat, 1.548 + plContext), 1.549 + PKIX_ERRORCREATINGFORMATSTRING); 1.550 + 1.551 + PKIX_CHECK(PKIX_PL_Sprintf 1.552 + (&resultString, 1.553 + plContext, 1.554 + thisNodeFormat, 1.555 + thisItemString), 1.556 + PKIX_ERRORINSPRINTF); 1.557 + } 1.558 + 1.559 + PKIX_DECREF(thisItemString); 1.560 + thisItemString = resultString; 1.561 + 1.562 + /* if no children, we are done */ 1.563 + if (rootNode->children) { 1.564 + PKIX_CHECK(PKIX_List_GetLength 1.565 + (rootNode->children, &numberOfChildren, plContext), 1.566 + PKIX_LISTGETLENGTHFAILED); 1.567 + } 1.568 + 1.569 + if (numberOfChildren != 0) { 1.570 + /* 1.571 + * We create a string for each child in turn, 1.572 + * concatenating them to thisItemString. 1.573 + */ 1.574 + 1.575 + /* Prepare an indent string for each child */ 1.576 + if (indent) { 1.577 + PKIX_CHECK(PKIX_PL_String_Create 1.578 + (PKIX_ESCASCII, 1.579 + "%s. ", 1.580 + 0, 1.581 + &nextIndentFormat, 1.582 + plContext), 1.583 + PKIX_ERRORCREATINGFORMATSTRING); 1.584 + 1.585 + PKIX_CHECK(PKIX_PL_Sprintf 1.586 + (&nextIndentString, 1.587 + plContext, 1.588 + nextIndentFormat, 1.589 + indent), 1.590 + PKIX_ERRORINSPRINTF); 1.591 + } else { 1.592 + PKIX_CHECK(PKIX_PL_String_Create 1.593 + (PKIX_ESCASCII, 1.594 + ". ", 1.595 + 0, 1.596 + &nextIndentString, 1.597 + plContext), 1.598 + PKIX_ERRORCREATINGINDENTSTRING); 1.599 + } 1.600 + 1.601 + /* Prepare the format for concatenation. */ 1.602 + PKIX_CHECK(PKIX_PL_String_Create 1.603 + (PKIX_ESCASCII, 1.604 + "%s\n%s", 1.605 + 0, 1.606 + &childrenFormat, 1.607 + plContext), 1.608 + PKIX_ERRORCREATINGFORMATSTRING); 1.609 + 1.610 + for (childIndex = 0; 1.611 + childIndex < numberOfChildren; 1.612 + childIndex++) { 1.613 + PKIX_CHECK(PKIX_List_GetItem 1.614 + (rootNode->children, 1.615 + childIndex, 1.616 + (PKIX_PL_Object **)&childNode, 1.617 + plContext), 1.618 + PKIX_LISTGETITEMFAILED); 1.619 + 1.620 + PKIX_CHECK(pkix_PolicyNode_ToString_Helper 1.621 + (childNode, 1.622 + nextIndentString, 1.623 + &childString, 1.624 + plContext), 1.625 + PKIX_ERRORCREATINGCHILDSTRING); 1.626 + 1.627 + 1.628 + PKIX_CHECK(PKIX_PL_Sprintf 1.629 + (&resultString, 1.630 + plContext, 1.631 + childrenFormat, 1.632 + thisItemString, 1.633 + childString), 1.634 + PKIX_ERRORINSPRINTF); 1.635 + 1.636 + PKIX_DECREF(childNode); 1.637 + PKIX_DECREF(childString); 1.638 + PKIX_DECREF(thisItemString); 1.639 + 1.640 + thisItemString = resultString; 1.641 + } 1.642 + } 1.643 + 1.644 + *pTreeString = thisItemString; 1.645 + 1.646 +cleanup: 1.647 + if (PKIX_ERROR_RECEIVED) { 1.648 + PKIX_DECREF(thisItemString); 1.649 + } 1.650 + 1.651 + PKIX_DECREF(nextIndentFormat); 1.652 + PKIX_DECREF(thisNodeFormat); 1.653 + PKIX_DECREF(childrenFormat); 1.654 + PKIX_DECREF(nextIndentString); 1.655 + PKIX_DECREF(childString); 1.656 + PKIX_DECREF(childNode); 1.657 + 1.658 + PKIX_RETURN(CERTPOLICYNODE); 1.659 +} 1.660 + 1.661 +/* 1.662 + * FUNCTION: pkix_PolicyNode_ToString 1.663 + * (see comments for PKIX_PL_ToStringCallback in pkix_pl_system.h) 1.664 + */ 1.665 +static PKIX_Error * 1.666 +pkix_PolicyNode_ToString( 1.667 + PKIX_PL_Object *object, 1.668 + PKIX_PL_String **pTreeString, 1.669 + void *plContext) 1.670 +{ 1.671 + PKIX_PolicyNode *rootNode = NULL; 1.672 + PKIX_PL_String *resultString = NULL; 1.673 + 1.674 + PKIX_ENTER(CERTPOLICYNODE, "pkix_PolicyNode_ToString"); 1.675 + 1.676 + PKIX_NULLCHECK_TWO(object, pTreeString); 1.677 + 1.678 + PKIX_CHECK(pkix_CheckType(object, PKIX_CERTPOLICYNODE_TYPE, plContext), 1.679 + PKIX_OBJECTNOTPOLICYNODE); 1.680 + 1.681 + rootNode = (PKIX_PolicyNode *)object; 1.682 + 1.683 + PKIX_CHECK(pkix_PolicyNode_ToString_Helper 1.684 + (rootNode, NULL, &resultString, plContext), 1.685 + PKIX_ERRORCREATINGSUBTREESTRING); 1.686 + 1.687 + *pTreeString = resultString; 1.688 + 1.689 +cleanup: 1.690 + 1.691 + PKIX_RETURN(CERTPOLICYNODE); 1.692 +} 1.693 + 1.694 +/* 1.695 + * FUNCTION: pkix_PolicyNode_Destroy 1.696 + * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h) 1.697 + */ 1.698 +static PKIX_Error * 1.699 +pkix_PolicyNode_Destroy( 1.700 + PKIX_PL_Object *object, 1.701 + void *plContext) 1.702 +{ 1.703 + PKIX_PolicyNode *node = NULL; 1.704 + 1.705 + PKIX_ENTER(CERTPOLICYNODE, "pkix_PolicyNode_Destroy"); 1.706 + 1.707 + PKIX_NULLCHECK_ONE(object); 1.708 + 1.709 + PKIX_CHECK(pkix_CheckType(object, PKIX_CERTPOLICYNODE_TYPE, plContext), 1.710 + PKIX_OBJECTNOTPOLICYNODE); 1.711 + 1.712 + node = (PKIX_PolicyNode*)object; 1.713 + 1.714 + node->criticality = PKIX_FALSE; 1.715 + PKIX_DECREF(node->validPolicy); 1.716 + PKIX_DECREF(node->qualifierSet); 1.717 + PKIX_DECREF(node->expectedPolicySet); 1.718 + PKIX_DECREF(node->children); 1.719 + 1.720 + /* 1.721 + * Note: the link to parent is not reference-counted. See comment 1.722 + * in pkix_PolicyNode_AddToParent for more details. 1.723 + */ 1.724 + node->parent = NULL; 1.725 + node->depth = 0; 1.726 + 1.727 +cleanup: 1.728 + 1.729 + PKIX_RETURN(CERTPOLICYNODE); 1.730 +} 1.731 + 1.732 +/* 1.733 + * FUNCTION: pkix_SinglePolicyNode_Hashcode 1.734 + * DESCRIPTION: 1.735 + * 1.736 + * Computes the hashcode of the attributes of the PolicyNode pointed to by 1.737 + * "node", other than its parents and children, and stores the result at 1.738 + * "pHashcode". 1.739 + * 1.740 + * PARAMETERS: 1.741 + * "node" 1.742 + * Address of PolicyNode to be hashcoded; must be non-NULL 1.743 + * "pHashcode" 1.744 + * Address where UInt32 result will be stored; must be non-NULL 1.745 + * "plContext" 1.746 + * Platform-specific context pointer. 1.747 + * THREAD SAFETY: 1.748 + * Conditionally Thread Safe 1.749 + * (see Thread Safety Definitions in Programmer's Guide) 1.750 + * RETURNS: 1.751 + * Returns NULL if function succeeds 1.752 + * Returns a PolicyNode Error if the function fails in a non-fatal way. 1.753 + * Returns a Fatal Error if the function fails in a fatal way 1.754 + */ 1.755 +static PKIX_Error * 1.756 +pkix_SinglePolicyNode_Hashcode( 1.757 + PKIX_PolicyNode *node, 1.758 + PKIX_UInt32 *pHashcode, 1.759 + void *plContext) 1.760 +{ 1.761 + PKIX_UInt32 componentHash = 0; 1.762 + PKIX_UInt32 nodeHash = 0; 1.763 + 1.764 + PKIX_ENTER(CERTPOLICYNODE, "pkix_SinglePolicyNode_Hashcode"); 1.765 + PKIX_NULLCHECK_TWO(node, pHashcode); 1.766 + PKIX_NULLCHECK_TWO(node->validPolicy, node->expectedPolicySet); 1.767 + 1.768 + PKIX_HASHCODE 1.769 + (node->qualifierSet, 1.770 + &nodeHash, 1.771 + plContext, 1.772 + PKIX_FAILUREHASHINGLISTQUALIFIERSET); 1.773 + 1.774 + if (PKIX_TRUE == (node->criticality)) { 1.775 + nodeHash = 31*nodeHash + 0xff; 1.776 + } else { 1.777 + nodeHash = 31*nodeHash + 0x00; 1.778 + } 1.779 + 1.780 + PKIX_CHECK(PKIX_PL_Object_Hashcode 1.781 + ((PKIX_PL_Object *)node->validPolicy, 1.782 + &componentHash, 1.783 + plContext), 1.784 + PKIX_FAILUREHASHINGOIDVALIDPOLICY); 1.785 + 1.786 + nodeHash = 31*nodeHash + componentHash; 1.787 + 1.788 + PKIX_CHECK(PKIX_PL_Object_Hashcode 1.789 + ((PKIX_PL_Object *)node->expectedPolicySet, 1.790 + &componentHash, 1.791 + plContext), 1.792 + PKIX_FAILUREHASHINGLISTEXPECTEDPOLICYSET); 1.793 + 1.794 + nodeHash = 31*nodeHash + componentHash; 1.795 + 1.796 + *pHashcode = nodeHash; 1.797 + 1.798 +cleanup: 1.799 + 1.800 + PKIX_RETURN(CERTPOLICYNODE); 1.801 +} 1.802 + 1.803 +/* 1.804 + * FUNCTION: pkix_PolicyNode_Hashcode 1.805 + * (see comments for PKIX_PL_HashcodeCallback in pkix_pl_system.h) 1.806 + */ 1.807 +static PKIX_Error * 1.808 +pkix_PolicyNode_Hashcode( 1.809 + PKIX_PL_Object *object, 1.810 + PKIX_UInt32 *pHashcode, 1.811 + void *plContext) 1.812 +{ 1.813 + PKIX_PolicyNode *node = NULL; 1.814 + PKIX_UInt32 childrenHash = 0; 1.815 + PKIX_UInt32 nodeHash = 0; 1.816 + 1.817 + PKIX_ENTER(CERTPOLICYNODE, "pkix_PolicyNode_Hashcode"); 1.818 + PKIX_NULLCHECK_TWO(object, pHashcode); 1.819 + 1.820 + PKIX_CHECK(pkix_CheckType 1.821 + (object, PKIX_CERTPOLICYNODE_TYPE, plContext), 1.822 + PKIX_OBJECTNOTPOLICYNODE); 1.823 + 1.824 + node = (PKIX_PolicyNode *)object; 1.825 + 1.826 + PKIX_CHECK(pkix_SinglePolicyNode_Hashcode 1.827 + (node, &nodeHash, plContext), 1.828 + PKIX_SINGLEPOLICYNODEHASHCODEFAILED); 1.829 + 1.830 + nodeHash = 31*nodeHash + (PKIX_UInt32)(node->parent); 1.831 + 1.832 + PKIX_HASHCODE 1.833 + (node->children, 1.834 + &childrenHash, 1.835 + plContext, 1.836 + PKIX_OBJECTHASHCODEFAILED); 1.837 + 1.838 + nodeHash = 31*nodeHash + childrenHash; 1.839 + 1.840 + *pHashcode = nodeHash; 1.841 + 1.842 +cleanup: 1.843 + 1.844 + PKIX_RETURN(CERTPOLICYNODE); 1.845 +} 1.846 + 1.847 +/* 1.848 + * FUNCTION: pkix_SinglePolicyNode_Equals 1.849 + * DESCRIPTION: 1.850 + * 1.851 + * Compares for equality the components of the PolicyNode pointed to by 1.852 + * "firstPN", other than its parents and children, with those of the 1.853 + * PolicyNode pointed to by "secondPN" and stores the result at "pResult" 1.854 + * (PKIX_TRUE if equal; PKIX_FALSE if not). 1.855 + * 1.856 + * PARAMETERS: 1.857 + * "firstPN" 1.858 + * Address of first of the PolicyNodes to be compared; must be non-NULL 1.859 + * "secondPN" 1.860 + * Address of second of the PolicyNodes to be compared; must be non-NULL 1.861 + * "pResult" 1.862 + * Address where Boolean will be stored; must be non-NULL 1.863 + * "plContext" 1.864 + * Platform-specific context pointer. 1.865 + * THREAD SAFETY: 1.866 + * Conditionally Thread Safe 1.867 + * (see Thread Safety Definitions in Programmer's Guide) 1.868 + * RETURNS: 1.869 + * Returns NULL if function succeeds 1.870 + * Returns a PolicyNode Error if the function fails in a non-fatal way. 1.871 + * Returns a Fatal Error if the function fails in a fatal way 1.872 + */ 1.873 +static PKIX_Error * 1.874 +pkix_SinglePolicyNode_Equals( 1.875 + PKIX_PolicyNode *firstPN, 1.876 + PKIX_PolicyNode *secondPN, 1.877 + PKIX_Boolean *pResult, 1.878 + void *plContext) 1.879 +{ 1.880 + PKIX_Boolean compResult = PKIX_FALSE; 1.881 + 1.882 + PKIX_ENTER(CERTPOLICYNODE, "pkix_SinglePolicyNode_Equals"); 1.883 + PKIX_NULLCHECK_THREE(firstPN, secondPN, pResult); 1.884 + 1.885 + /* If both references are identical, they must be equal */ 1.886 + if (firstPN == secondPN) { 1.887 + compResult = PKIX_TRUE; 1.888 + goto cleanup; 1.889 + } 1.890 + 1.891 + /* 1.892 + * It seems we have to do the comparisons. Do 1.893 + * the easiest ones first. 1.894 + */ 1.895 + if ((firstPN->criticality) != (secondPN->criticality)) { 1.896 + goto cleanup; 1.897 + } 1.898 + if ((firstPN->depth) != (secondPN->depth)) { 1.899 + goto cleanup; 1.900 + } 1.901 + 1.902 + PKIX_EQUALS 1.903 + (firstPN->qualifierSet, 1.904 + secondPN->qualifierSet, 1.905 + &compResult, 1.906 + plContext, 1.907 + PKIX_OBJECTEQUALSFAILED); 1.908 + 1.909 + if (compResult == PKIX_FALSE) { 1.910 + goto cleanup; 1.911 + } 1.912 + 1.913 + /* These fields must be non-NULL */ 1.914 + PKIX_NULLCHECK_TWO(firstPN->validPolicy, secondPN->validPolicy); 1.915 + 1.916 + PKIX_EQUALS 1.917 + (firstPN->validPolicy, 1.918 + secondPN->validPolicy, 1.919 + &compResult, 1.920 + plContext, 1.921 + PKIX_OBJECTEQUALSFAILED); 1.922 + 1.923 + if (compResult == PKIX_FALSE) { 1.924 + goto cleanup; 1.925 + } 1.926 + 1.927 + /* These fields must be non-NULL */ 1.928 + PKIX_NULLCHECK_TWO 1.929 + (firstPN->expectedPolicySet, secondPN->expectedPolicySet); 1.930 + 1.931 + PKIX_EQUALS 1.932 + (firstPN->expectedPolicySet, 1.933 + secondPN->expectedPolicySet, 1.934 + &compResult, 1.935 + plContext, 1.936 + PKIX_OBJECTEQUALSFAILEDONEXPECTEDPOLICYSETS); 1.937 + 1.938 +cleanup: 1.939 + 1.940 + *pResult = compResult; 1.941 + 1.942 + PKIX_RETURN(CERTPOLICYNODE); 1.943 +} 1.944 + 1.945 +/* 1.946 + * FUNCTION: pkix_PolicyNode_Equals 1.947 + * (see comments for PKIX_PL_Equals_Callback in pkix_pl_system.h) 1.948 + */ 1.949 +static PKIX_Error * 1.950 +pkix_PolicyNode_Equals( 1.951 + PKIX_PL_Object *firstObject, 1.952 + PKIX_PL_Object *secondObject, 1.953 + PKIX_Boolean *pResult, 1.954 + void *plContext) 1.955 +{ 1.956 + PKIX_PolicyNode *firstPN = NULL; 1.957 + PKIX_PolicyNode *secondPN = NULL; 1.958 + PKIX_UInt32 secondType; 1.959 + PKIX_Boolean compResult = PKIX_FALSE; 1.960 + 1.961 + PKIX_ENTER(CERTPOLICYNODE, "pkix_PolicyNode_Equals"); 1.962 + PKIX_NULLCHECK_THREE(firstObject, secondObject, pResult); 1.963 + 1.964 + /* test that firstObject is a PolicyNode */ 1.965 + PKIX_CHECK(pkix_CheckType 1.966 + (firstObject, PKIX_CERTPOLICYNODE_TYPE, plContext), 1.967 + PKIX_FIRSTOBJECTNOTPOLICYNODE); 1.968 + 1.969 + /* 1.970 + * Since we know firstObject is a PolicyNode, 1.971 + * if both references are identical, they must be equal 1.972 + */ 1.973 + if (firstObject == secondObject){ 1.974 + compResult = PKIX_TRUE; 1.975 + goto cleanup; 1.976 + } 1.977 + 1.978 + /* 1.979 + * If secondObject isn't a PolicyNode, we 1.980 + * don't throw an error. We simply return FALSE. 1.981 + */ 1.982 + PKIX_CHECK(PKIX_PL_Object_GetType 1.983 + (secondObject, &secondType, plContext), 1.984 + PKIX_COULDNOTGETTYPEOFSECONDARGUMENT); 1.985 + 1.986 + if (secondType != PKIX_CERTPOLICYNODE_TYPE) { 1.987 + goto cleanup; 1.988 + } 1.989 + 1.990 + /* 1.991 + * Oh, well, we have to do the comparisons. Do 1.992 + * the easiest ones first. 1.993 + */ 1.994 + firstPN = (PKIX_PolicyNode *)firstObject; 1.995 + secondPN = (PKIX_PolicyNode *)secondObject; 1.996 + 1.997 + /* 1.998 + * We don't require the parents to be identical. In the 1.999 + * course of traversing the tree, we will have checked the 1.1000 + * attributes of the parent nodes, and checking the lists 1.1001 + * of children will determine whether they match. 1.1002 + */ 1.1003 + 1.1004 + PKIX_EQUALS 1.1005 + (firstPN->children, 1.1006 + secondPN->children, 1.1007 + &compResult, 1.1008 + plContext, 1.1009 + PKIX_OBJECTEQUALSFAILEDONCHILDREN); 1.1010 + 1.1011 + if (compResult == PKIX_FALSE) { 1.1012 + goto cleanup; 1.1013 + } 1.1014 + 1.1015 + PKIX_CHECK(pkix_SinglePolicyNode_Equals 1.1016 + (firstPN, secondPN, &compResult, plContext), 1.1017 + PKIX_SINGLEPOLICYNODEEQUALSFAILED); 1.1018 + 1.1019 +cleanup: 1.1020 + 1.1021 + *pResult = compResult; 1.1022 + 1.1023 + PKIX_RETURN(CERTPOLICYNODE); 1.1024 +} 1.1025 + 1.1026 +/* 1.1027 + * FUNCTION: pkix_PolicyNode_DuplicateHelper 1.1028 + * DESCRIPTION: 1.1029 + * 1.1030 + * Duplicates the PolicyNode whose address is pointed to by "original", 1.1031 + * and stores the result at "pNewNode", if a non-NULL pointer is provided 1.1032 + * for "pNewNode". In addition, the created PolicyNode is added as a child 1.1033 + * to "parent", if a non-NULL pointer is provided for "parent". Then this 1.1034 + * function is called recursively to duplicate each of the children of 1.1035 + * "original". At the top level this function is called with a null 1.1036 + * "parent" and a non-NULL "pNewNode". Below the top level "parent" will 1.1037 + * be non-NULL and "pNewNode" will be NULL. 1.1038 + * 1.1039 + * PARAMETERS: 1.1040 + * "original" 1.1041 + * Address of PolicyNode to be copied; must be non-NULL 1.1042 + * "parent" 1.1043 + * Address of PolicyNode to which the created node is to be added as a 1.1044 + * child; NULL for the top-level call and non-NULL below the top level 1.1045 + * "pNewNode" 1.1046 + * Address to store the node created; should be NULL if "parent" is 1.1047 + * non-NULL and vice versa 1.1048 + * "plContext" 1.1049 + * Platform-specific context pointer. 1.1050 + * THREAD SAFETY: 1.1051 + * Conditionally Thread Safe 1.1052 + * (see Thread Safety Definitions in Programmer's Guide) 1.1053 + * RETURNS: 1.1054 + * Returns NULL if function succeeds 1.1055 + * Returns a PolicyNode Error if the function fails in a non-fatal way. 1.1056 + * Returns a Fatal Error if the function fails in a fatal way 1.1057 + */ 1.1058 +static PKIX_Error * 1.1059 +pkix_PolicyNode_DuplicateHelper( 1.1060 + PKIX_PolicyNode *original, 1.1061 + PKIX_PolicyNode *parent, 1.1062 + PKIX_PolicyNode **pNewNode, 1.1063 + void *plContext) 1.1064 +{ 1.1065 + PKIX_UInt32 numChildren = 0; 1.1066 + PKIX_UInt32 childIndex = 0; 1.1067 + PKIX_List *children = NULL; /* List of PKIX_PolicyNode */ 1.1068 + PKIX_PolicyNode *copy = NULL; 1.1069 + PKIX_PolicyNode *child = NULL; 1.1070 + 1.1071 + PKIX_ENTER(CERTPOLICYNODE, "pkix_PolicyNode_DuplicateHelper"); 1.1072 + 1.1073 + PKIX_NULLCHECK_THREE 1.1074 + (original, original->validPolicy, original->expectedPolicySet); 1.1075 + 1.1076 + /* 1.1077 + * These components are immutable, so copying the pointers 1.1078 + * is sufficient. The create function increments the reference 1.1079 + * counts as it stores the pointers into the new object. 1.1080 + */ 1.1081 + PKIX_CHECK(pkix_PolicyNode_Create 1.1082 + (original->validPolicy, 1.1083 + original->qualifierSet, 1.1084 + original->criticality, 1.1085 + original->expectedPolicySet, 1.1086 + ©, 1.1087 + plContext), 1.1088 + PKIX_POLICYNODECREATEFAILED); 1.1089 + 1.1090 + if (parent) { 1.1091 + PKIX_CHECK(pkix_PolicyNode_AddToParent(parent, copy, plContext), 1.1092 + PKIX_POLICYNODEADDTOPARENTFAILED); 1.1093 + } 1.1094 + 1.1095 + /* Are there any children to duplicate? */ 1.1096 + children = original->children; 1.1097 + 1.1098 + if (children) { 1.1099 + PKIX_CHECK(PKIX_List_GetLength(children, &numChildren, plContext), 1.1100 + PKIX_LISTGETLENGTHFAILED); 1.1101 + } 1.1102 + 1.1103 + for (childIndex = 0; childIndex < numChildren; childIndex++) { 1.1104 + PKIX_CHECK(PKIX_List_GetItem 1.1105 + (children, 1.1106 + childIndex, 1.1107 + (PKIX_PL_Object **)&child, 1.1108 + plContext), 1.1109 + PKIX_LISTGETITEMFAILED); 1.1110 + 1.1111 + PKIX_CHECK(pkix_PolicyNode_DuplicateHelper 1.1112 + (child, copy, NULL, plContext), 1.1113 + PKIX_POLICYNODEDUPLICATEHELPERFAILED); 1.1114 + 1.1115 + PKIX_DECREF(child); 1.1116 + } 1.1117 + 1.1118 + if (pNewNode) { 1.1119 + *pNewNode = copy; 1.1120 + copy = NULL; /* no DecRef if we give our handle away */ 1.1121 + } 1.1122 + 1.1123 +cleanup: 1.1124 + PKIX_DECREF(copy); 1.1125 + PKIX_DECREF(child); 1.1126 + 1.1127 + PKIX_RETURN(CERTPOLICYNODE); 1.1128 +} 1.1129 + 1.1130 +/* 1.1131 + * FUNCTION: pkix_PolicyNode_Duplicate 1.1132 + * (see comments for PKIX_PL_Duplicate_Callback in pkix_pl_system.h) 1.1133 + */ 1.1134 +static PKIX_Error * 1.1135 +pkix_PolicyNode_Duplicate( 1.1136 + PKIX_PL_Object *object, 1.1137 + PKIX_PL_Object **pNewObject, 1.1138 + void *plContext) 1.1139 +{ 1.1140 + PKIX_PolicyNode *original = NULL; 1.1141 + PKIX_PolicyNode *copy = NULL; 1.1142 + 1.1143 + PKIX_ENTER(CERTPOLICYNODE, "pkix_PolicyNode_Duplicate"); 1.1144 + 1.1145 + PKIX_NULLCHECK_TWO(object, pNewObject); 1.1146 + 1.1147 + PKIX_CHECK(pkix_CheckType 1.1148 + (object, PKIX_CERTPOLICYNODE_TYPE, plContext), 1.1149 + PKIX_OBJECTNOTPOLICYNODE); 1.1150 + 1.1151 + original = (PKIX_PolicyNode *)object; 1.1152 + 1.1153 + PKIX_CHECK(pkix_PolicyNode_DuplicateHelper 1.1154 + (original, NULL, ©, plContext), 1.1155 + PKIX_POLICYNODEDUPLICATEHELPERFAILED); 1.1156 + 1.1157 + *pNewObject = (PKIX_PL_Object *)copy; 1.1158 + 1.1159 +cleanup: 1.1160 + 1.1161 + PKIX_RETURN(CERTPOLICYNODE); 1.1162 +} 1.1163 + 1.1164 +/* 1.1165 + * FUNCTION: pkix_PolicyNode_RegisterSelf 1.1166 + * DESCRIPTION: 1.1167 + * 1.1168 + * Registers PKIX_CERTPOLICYNODE_TYPE and its related 1.1169 + * functions with systemClasses[] 1.1170 + * 1.1171 + * THREAD SAFETY: 1.1172 + * Not Thread Safe - for performance and complexity reasons 1.1173 + * 1.1174 + * Since this function is only called by PKIX_PL_Initialize, 1.1175 + * which should only be called once, it is acceptable that 1.1176 + * this function is not thread-safe. 1.1177 + */ 1.1178 +PKIX_Error * 1.1179 +pkix_PolicyNode_RegisterSelf(void *plContext) 1.1180 +{ 1.1181 + 1.1182 + extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES]; 1.1183 + pkix_ClassTable_Entry entry; 1.1184 + 1.1185 + PKIX_ENTER(CERTPOLICYNODE, "pkix_PolicyNode_RegisterSelf"); 1.1186 + 1.1187 + entry.description = "PolicyNode"; 1.1188 + entry.objCounter = 0; 1.1189 + entry.typeObjectSize = sizeof(PKIX_PolicyNode); 1.1190 + entry.destructor = pkix_PolicyNode_Destroy; 1.1191 + entry.equalsFunction = pkix_PolicyNode_Equals; 1.1192 + entry.hashcodeFunction = pkix_PolicyNode_Hashcode; 1.1193 + entry.toStringFunction = pkix_PolicyNode_ToString; 1.1194 + entry.comparator = NULL; 1.1195 + entry.duplicateFunction = pkix_PolicyNode_Duplicate; 1.1196 + 1.1197 + systemClasses[PKIX_CERTPOLICYNODE_TYPE] = entry; 1.1198 + 1.1199 + PKIX_RETURN(CERTPOLICYNODE); 1.1200 +} 1.1201 + 1.1202 + 1.1203 +/* --Public-PolicyNode-Functions----------------------------------- */ 1.1204 + 1.1205 +/* 1.1206 + * FUNCTION: PKIX_PolicyNode_GetChildren 1.1207 + * (see description of this function in pkix_results.h) 1.1208 + */ 1.1209 +PKIX_Error * 1.1210 +PKIX_PolicyNode_GetChildren( 1.1211 + PKIX_PolicyNode *node, 1.1212 + PKIX_List **pChildren, /* list of PKIX_PolicyNode */ 1.1213 + void *plContext) 1.1214 +{ 1.1215 + PKIX_List *children = NULL; 1.1216 + 1.1217 + PKIX_ENTER(CERTPOLICYNODE, "PKIX_PolicyNode_GetChildren"); 1.1218 + 1.1219 + PKIX_NULLCHECK_TWO(node, pChildren); 1.1220 + 1.1221 + PKIX_INCREF(node->children); 1.1222 + children = node->children; 1.1223 + 1.1224 + if (!children) { 1.1225 + PKIX_CHECK(PKIX_List_Create(&children, plContext), 1.1226 + PKIX_LISTCREATEFAILED); 1.1227 + } 1.1228 + 1.1229 + PKIX_CHECK(PKIX_List_SetImmutable(children, plContext), 1.1230 + PKIX_LISTSETIMMUTABLEFAILED); 1.1231 + 1.1232 + *pChildren = children; 1.1233 + 1.1234 +cleanup: 1.1235 + if (PKIX_ERROR_RECEIVED) { 1.1236 + PKIX_DECREF(children); 1.1237 + } 1.1238 + 1.1239 + PKIX_RETURN(CERTPOLICYNODE); 1.1240 +} 1.1241 + 1.1242 +/* 1.1243 + * FUNCTION: PKIX_PolicyNode_GetParent 1.1244 + * (see description of this function in pkix_results.h) 1.1245 + */ 1.1246 +PKIX_Error * 1.1247 +PKIX_PolicyNode_GetParent( 1.1248 + PKIX_PolicyNode *node, 1.1249 + PKIX_PolicyNode **pParent, 1.1250 + void *plContext) 1.1251 +{ 1.1252 + 1.1253 + PKIX_ENTER(CERTPOLICYNODE, "PKIX_PolicyNode_GetParent"); 1.1254 + 1.1255 + PKIX_NULLCHECK_TWO(node, pParent); 1.1256 + 1.1257 + PKIX_INCREF(node->parent); 1.1258 + *pParent = node->parent; 1.1259 + 1.1260 +cleanup: 1.1261 + PKIX_RETURN(CERTPOLICYNODE); 1.1262 +} 1.1263 + 1.1264 +/* 1.1265 + * FUNCTION: PKIX_PolicyNode_GetValidPolicy 1.1266 + * (see description of this function in pkix_results.h) 1.1267 + */ 1.1268 +PKIX_Error * 1.1269 +PKIX_PolicyNode_GetValidPolicy( 1.1270 + PKIX_PolicyNode *node, 1.1271 + PKIX_PL_OID **pValidPolicy, 1.1272 + void *plContext) 1.1273 +{ 1.1274 + 1.1275 + PKIX_ENTER(CERTPOLICYNODE, "PKIX_PolicyNode_GetValidPolicy"); 1.1276 + 1.1277 + PKIX_NULLCHECK_TWO(node, pValidPolicy); 1.1278 + 1.1279 + PKIX_INCREF(node->validPolicy); 1.1280 + *pValidPolicy = node->validPolicy; 1.1281 + 1.1282 +cleanup: 1.1283 + PKIX_RETURN(CERTPOLICYNODE); 1.1284 +} 1.1285 + 1.1286 +/* 1.1287 + * FUNCTION: PKIX_PolicyNode_GetPolicyQualifiers 1.1288 + * (see description of this function in pkix_results.h) 1.1289 + */ 1.1290 +PKIX_Error * 1.1291 +PKIX_PolicyNode_GetPolicyQualifiers( 1.1292 + PKIX_PolicyNode *node, 1.1293 + PKIX_List **pQualifiers, /* list of PKIX_PL_CertPolicyQualifier */ 1.1294 + void *plContext) 1.1295 +{ 1.1296 + PKIX_List *qualifiers = NULL; 1.1297 + 1.1298 + PKIX_ENTER(CERTPOLICYNODE, "PKIX_PolicyNode_GetPolicyQualifiers"); 1.1299 + 1.1300 + PKIX_NULLCHECK_TWO(node, pQualifiers); 1.1301 + 1.1302 + PKIX_INCREF(node->qualifierSet); 1.1303 + qualifiers = node->qualifierSet; 1.1304 + 1.1305 + if (!qualifiers) { 1.1306 + PKIX_CHECK(PKIX_List_Create(&qualifiers, plContext), 1.1307 + PKIX_LISTCREATEFAILED); 1.1308 + } 1.1309 + 1.1310 + PKIX_CHECK(PKIX_List_SetImmutable(qualifiers, plContext), 1.1311 + PKIX_LISTSETIMMUTABLEFAILED); 1.1312 + 1.1313 + *pQualifiers = qualifiers; 1.1314 + 1.1315 +cleanup: 1.1316 + 1.1317 + PKIX_RETURN(CERTPOLICYNODE); 1.1318 +} 1.1319 + 1.1320 +/* 1.1321 + * FUNCTION: PKIX_PolicyNode_GetExpectedPolicies 1.1322 + * (see description of this function in pkix_results.h) 1.1323 + */ 1.1324 +PKIX_Error * 1.1325 +PKIX_PolicyNode_GetExpectedPolicies( 1.1326 + PKIX_PolicyNode *node, 1.1327 + PKIX_List **pExpPolicies, /* list of PKIX_PL_OID */ 1.1328 + void *plContext) 1.1329 +{ 1.1330 + 1.1331 + PKIX_ENTER(CERTPOLICYNODE, "PKIX_PolicyNode_GetExpectedPolicies"); 1.1332 + 1.1333 + PKIX_NULLCHECK_TWO(node, pExpPolicies); 1.1334 + 1.1335 + PKIX_INCREF(node->expectedPolicySet); 1.1336 + *pExpPolicies = node->expectedPolicySet; 1.1337 + 1.1338 +cleanup: 1.1339 + PKIX_RETURN(CERTPOLICYNODE); 1.1340 +} 1.1341 + 1.1342 +/* 1.1343 + * FUNCTION: PKIX_PolicyNode_IsCritical 1.1344 + * (see description of this function in pkix_results.h) 1.1345 + */ 1.1346 +PKIX_Error * 1.1347 +PKIX_PolicyNode_IsCritical( 1.1348 + PKIX_PolicyNode *node, 1.1349 + PKIX_Boolean *pCritical, 1.1350 + void *plContext) 1.1351 +{ 1.1352 + 1.1353 + PKIX_ENTER(CERTPOLICYNODE, "PKIX_PolicyNode_IsCritical"); 1.1354 + 1.1355 + PKIX_NULLCHECK_TWO(node, pCritical); 1.1356 + 1.1357 + *pCritical = node->criticality; 1.1358 + 1.1359 + PKIX_RETURN(CERTPOLICYNODE); 1.1360 +} 1.1361 + 1.1362 +/* 1.1363 + * FUNCTION: PKIX_PolicyNode_GetDepth 1.1364 + * (see description of this function in pkix_results.h) 1.1365 + */ 1.1366 +PKIX_Error * 1.1367 +PKIX_PolicyNode_GetDepth( 1.1368 + PKIX_PolicyNode *node, 1.1369 + PKIX_UInt32 *pDepth, 1.1370 + void *plContext) 1.1371 +{ 1.1372 + 1.1373 + PKIX_ENTER(CERTPOLICYNODE, "PKIX_PolicyNode_GetDepth"); 1.1374 + 1.1375 + PKIX_NULLCHECK_TWO(node, pDepth); 1.1376 + 1.1377 + *pDepth = node->depth; 1.1378 + 1.1379 + PKIX_RETURN(CERTPOLICYNODE); 1.1380 +}