1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/security/nss/lib/libpkix/pkix/results/pkix_verifynode.c Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,1182 @@ 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_verifynode.c 1.9 + * 1.10 + * Verify Node Object Type Definition 1.11 + * 1.12 + */ 1.13 + 1.14 +#include "pkix_verifynode.h" 1.15 + 1.16 +/* --Private-VerifyNode-Functions---------------------------------- */ 1.17 + 1.18 +/* 1.19 + * FUNCTION: pkix_VerifyNode_Create 1.20 + * DESCRIPTION: 1.21 + * 1.22 + * This function creates a VerifyNode using the Cert pointed to by "cert", 1.23 + * the depth given by "depth", and the Error pointed to by "error", storing 1.24 + * the result at "pObject". 1.25 + * 1.26 + * PARAMETERS 1.27 + * "cert" 1.28 + * Address of Cert for the node. Must be non-NULL 1.29 + * "depth" 1.30 + * UInt32 value of the depth for this node. 1.31 + * "error" 1.32 + * Address of Error for the node. 1.33 + * "pObject" 1.34 + * Address where the VerifyNode pointer will be stored. Must be non-NULL. 1.35 + * "plContext" 1.36 + * Platform-specific context pointer. 1.37 + * THREAD SAFETY: 1.38 + * Thread Safe (see Thread Safety Definitions in Programmer's Guide) 1.39 + * RETURNS: 1.40 + * Returns NULL if the function succeeds. 1.41 + * Returns a Fatal Error if the function fails in an unrecoverable way. 1.42 + */ 1.43 +PKIX_Error * 1.44 +pkix_VerifyNode_Create( 1.45 + PKIX_PL_Cert *cert, 1.46 + PKIX_UInt32 depth, 1.47 + PKIX_Error *error, 1.48 + PKIX_VerifyNode **pObject, 1.49 + void *plContext) 1.50 +{ 1.51 + PKIX_VerifyNode *node = NULL; 1.52 + 1.53 + PKIX_ENTER(VERIFYNODE, "pkix_VerifyNode_Create"); 1.54 + PKIX_NULLCHECK_TWO(cert, pObject); 1.55 + 1.56 + PKIX_CHECK(PKIX_PL_Object_Alloc 1.57 + (PKIX_VERIFYNODE_TYPE, 1.58 + sizeof (PKIX_VerifyNode), 1.59 + (PKIX_PL_Object **)&node, 1.60 + plContext), 1.61 + PKIX_COULDNOTCREATEVERIFYNODEOBJECT); 1.62 + 1.63 + PKIX_INCREF(cert); 1.64 + node->verifyCert = cert; 1.65 + 1.66 + PKIX_INCREF(error); 1.67 + node->error = error; 1.68 + 1.69 + node->depth = depth; 1.70 + 1.71 + node->children = NULL; 1.72 + 1.73 + *pObject = node; 1.74 + node = NULL; 1.75 + 1.76 +cleanup: 1.77 + 1.78 + PKIX_DECREF(node); 1.79 + 1.80 + PKIX_RETURN(VERIFYNODE); 1.81 +} 1.82 + 1.83 +/* 1.84 + * FUNCTION: pkix_VerifyNode_AddToChain 1.85 + * DESCRIPTION: 1.86 + * 1.87 + * Adds the VerifyNode pointed to by "child", at the appropriate depth, to the 1.88 + * List of children of the VerifyNode pointed to by "parentNode". The chain of 1.89 + * VerifyNodes is traversed until a VerifyNode is found at a depth one less 1.90 + * than that specified in "child". An Error is returned if there is no parent 1.91 + * at a suitable depth. 1.92 + * 1.93 + * If "parentNode" has a NULL pointer for the List of children, a new List is 1.94 + * created containing "child". Otherwise "child" is appended to the existing 1.95 + * List. 1.96 + * 1.97 + * Depth, in this context, means distance from the root node, which 1.98 + * is at depth zero. 1.99 + * 1.100 + * PARAMETERS: 1.101 + * "parentNode" 1.102 + * Address of VerifyNode whose List of child VerifyNodes is to be 1.103 + * created or appended to. Must be non-NULL. 1.104 + * "child" 1.105 + * Address of VerifyNode to be added to parentNode's List. Must be 1.106 + * non-NULL. 1.107 + * "plContext" 1.108 + * Platform-specific context pointer. 1.109 + * THREAD SAFETY: 1.110 + * Not Thread Safe (see Thread Safety Definitions in Programmer's Guide) 1.111 + * RETURNS: 1.112 + * Returns NULL if the function succeeds. 1.113 + * Returns a VerifyNode Error if the function fails in a non-fatal way. 1.114 + * Returns a Fatal Error if the function fails in an unrecoverable way. 1.115 + */ 1.116 +PKIX_Error * 1.117 +pkix_VerifyNode_AddToChain( 1.118 + PKIX_VerifyNode *parentNode, 1.119 + PKIX_VerifyNode *child, 1.120 + void *plContext) 1.121 +{ 1.122 + PKIX_VerifyNode *successor = NULL; 1.123 + PKIX_List *listOfChildren = NULL; 1.124 + PKIX_UInt32 numChildren = 0; 1.125 + PKIX_UInt32 parentDepth = 0; 1.126 + 1.127 + PKIX_ENTER(VERIFYNODE, "pkix_VerifyNode_AddToChain"); 1.128 + PKIX_NULLCHECK_TWO(parentNode, child); 1.129 + 1.130 + parentDepth = parentNode->depth; 1.131 + listOfChildren = parentNode->children; 1.132 + if (listOfChildren == NULL) { 1.133 + 1.134 + if (parentDepth != (child->depth - 1)) { 1.135 + PKIX_ERROR(PKIX_NODESMISSINGFROMCHAIN); 1.136 + } 1.137 + 1.138 + PKIX_CHECK(PKIX_List_Create(&listOfChildren, plContext), 1.139 + PKIX_LISTCREATEFAILED); 1.140 + 1.141 + PKIX_CHECK(PKIX_List_AppendItem 1.142 + (listOfChildren, (PKIX_PL_Object *)child, plContext), 1.143 + PKIX_COULDNOTAPPENDCHILDTOPARENTSVERIFYNODELIST); 1.144 + 1.145 + parentNode->children = listOfChildren; 1.146 + } else { 1.147 + /* get number of children */ 1.148 + PKIX_CHECK(PKIX_List_GetLength 1.149 + (listOfChildren, &numChildren, plContext), 1.150 + PKIX_LISTGETLENGTHFAILED); 1.151 + 1.152 + if (numChildren != 1) { 1.153 + PKIX_ERROR(PKIX_AMBIGUOUSPARENTAGEOFVERIFYNODE); 1.154 + } 1.155 + 1.156 + /* successor = listOfChildren[0] */ 1.157 + PKIX_CHECK(PKIX_List_GetItem 1.158 + (listOfChildren, 1.159 + 0, 1.160 + (PKIX_PL_Object **)&successor, 1.161 + plContext), 1.162 + PKIX_LISTGETITEMFAILED); 1.163 + 1.164 + PKIX_CHECK(pkix_VerifyNode_AddToChain 1.165 + (successor, child, plContext), 1.166 + PKIX_VERIFYNODEADDTOCHAINFAILED); 1.167 + } 1.168 + 1.169 + PKIX_CHECK(PKIX_PL_Object_InvalidateCache 1.170 + ((PKIX_PL_Object *)parentNode, plContext), 1.171 + PKIX_OBJECTINVALIDATECACHEFAILED); 1.172 + 1.173 +cleanup: 1.174 + PKIX_DECREF(successor); 1.175 + 1.176 + PKIX_RETURN(VERIFYNODE); 1.177 +} 1.178 + 1.179 +/* 1.180 + * FUNCTION: pkix_VerifyNode_SetDepth 1.181 + * DESCRIPTION: 1.182 + * 1.183 + * The function sets the depth field of each VerifyNode in the List "children" 1.184 + * to the value given by "depth", and recursively sets the depth of any 1.185 + * successive generations to the successive values. 1.186 + * 1.187 + * PARAMETERS: 1.188 + * "children" 1.189 + * The List of VerifyNodes. Must be non-NULL. 1.190 + * "depth" 1.191 + * The value of the depth field to be set in members of the List. 1.192 + * "plContext" 1.193 + * Platform-specific context pointer. 1.194 + * THREAD SAFETY: 1.195 + * Thread Safe (see Thread Safety Definitions in Programmer's Guide) 1.196 + * RETURNS: 1.197 + * Returns NULL if the function succeeds. 1.198 + * Returns a Fatal Error if the function fails in an unrecoverable way. 1.199 + */ 1.200 +static PKIX_Error * 1.201 +pkix_VerifyNode_SetDepth(PKIX_List *children, 1.202 + PKIX_UInt32 depth, 1.203 + void *plContext) 1.204 +{ 1.205 + PKIX_UInt32 numChildren = 0; 1.206 + PKIX_UInt32 chIx = 0; 1.207 + PKIX_VerifyNode *child = NULL; 1.208 + 1.209 + PKIX_ENTER(VERIFYNODE, "pkix_VerifyNode_SetDepth"); 1.210 + PKIX_NULLCHECK_ONE(children); 1.211 + 1.212 + PKIX_CHECK(PKIX_List_GetLength(children, &numChildren, plContext), 1.213 + PKIX_LISTGETLENGTHFAILED); 1.214 + 1.215 + for (chIx = 0; chIx < numChildren; chIx++) { 1.216 + PKIX_CHECK(PKIX_List_GetItem 1.217 + (children, chIx, (PKIX_PL_Object **)&child, plContext), 1.218 + PKIX_LISTGETITEMFAILED); 1.219 + 1.220 + child->depth = depth; 1.221 + 1.222 + if (child->children != NULL) { 1.223 + PKIX_CHECK(pkix_VerifyNode_SetDepth 1.224 + (child->children, depth + 1, plContext), 1.225 + PKIX_VERIFYNODESETDEPTHFAILED); 1.226 + } 1.227 + 1.228 + PKIX_DECREF(child); 1.229 + } 1.230 + 1.231 +cleanup: 1.232 + 1.233 + PKIX_DECREF(child); 1.234 + 1.235 + PKIX_RETURN(VERIFYNODE); 1.236 +} 1.237 + 1.238 +/* 1.239 + * FUNCTION: pkix_VerifyNode_AddToTree 1.240 + * DESCRIPTION: 1.241 + * 1.242 + * Adds the VerifyNode pointed to by "child" to the List of children of the 1.243 + * VerifyNode pointed to by "parentNode". If "parentNode" has a NULL pointer 1.244 + * for the List of children, a new List is created containing "child". 1.245 + * Otherwise "child" is appended to the existing List. The depth field of 1.246 + * "child" is set to one more than the corresponding value in "parent", and 1.247 + * if the "child" itself has child nodes, their depth fields are updated 1.248 + * accordingly. 1.249 + * 1.250 + * Depth, in this context, means distance from the root node, which 1.251 + * is at depth zero. 1.252 + * 1.253 + * PARAMETERS: 1.254 + * "parentNode" 1.255 + * Address of VerifyNode whose List of child VerifyNodes is to be 1.256 + * created or appended to. Must be non-NULL. 1.257 + * "child" 1.258 + * Address of VerifyNode to be added to parentNode's List. Must be 1.259 + * non-NULL. 1.260 + * "plContext" 1.261 + * Platform-specific context pointer. 1.262 + * THREAD SAFETY: 1.263 + * Not Thread Safe (see Thread Safety Definitions in Programmer's Guide) 1.264 + * RETURNS: 1.265 + * Returns NULL if the function succeeds. 1.266 + * Returns a Fatal Error if the function fails in an unrecoverable way. 1.267 + */ 1.268 +PKIX_Error * 1.269 +pkix_VerifyNode_AddToTree( 1.270 + PKIX_VerifyNode *parentNode, 1.271 + PKIX_VerifyNode *child, 1.272 + void *plContext) 1.273 +{ 1.274 + PKIX_List *listOfChildren = NULL; 1.275 + PKIX_UInt32 parentDepth = 0; 1.276 + 1.277 + PKIX_ENTER(VERIFYNODE, "pkix_VerifyNode_AddToTree"); 1.278 + PKIX_NULLCHECK_TWO(parentNode, child); 1.279 + 1.280 + parentDepth = parentNode->depth; 1.281 + listOfChildren = parentNode->children; 1.282 + if (listOfChildren == NULL) { 1.283 + 1.284 + PKIX_CHECK(PKIX_List_Create(&listOfChildren, plContext), 1.285 + PKIX_LISTCREATEFAILED); 1.286 + 1.287 + parentNode->children = listOfChildren; 1.288 + } 1.289 + 1.290 + child->depth = parentDepth + 1; 1.291 + 1.292 + PKIX_CHECK(PKIX_List_AppendItem 1.293 + (parentNode->children, (PKIX_PL_Object *)child, plContext), 1.294 + PKIX_COULDNOTAPPENDCHILDTOPARENTSVERIFYNODELIST); 1.295 + 1.296 + if (child->children != NULL) { 1.297 + PKIX_CHECK(pkix_VerifyNode_SetDepth 1.298 + (child->children, child->depth + 1, plContext), 1.299 + PKIX_VERIFYNODESETDEPTHFAILED); 1.300 + } 1.301 + 1.302 + 1.303 +cleanup: 1.304 + 1.305 + PKIX_RETURN(VERIFYNODE); 1.306 +} 1.307 + 1.308 +/* 1.309 + * FUNCTION: pkix_SingleVerifyNode_ToString 1.310 + * DESCRIPTION: 1.311 + * 1.312 + * Creates a String representation of the attributes of the VerifyNode pointed 1.313 + * to by "node", other than its children, and stores the result at "pString". 1.314 + * 1.315 + * PARAMETERS: 1.316 + * "node" 1.317 + * Address of VerifyNode to be described by the string. Must be non-NULL. 1.318 + * "pString" 1.319 + * Address where object pointer will be stored. Must be non-NULL. 1.320 + * "plContext" 1.321 + * Platform-specific context pointer. 1.322 + * THREAD SAFETY: 1.323 + * Conditionally Thread Safe 1.324 + * (see Thread Safety Definitions in Programmer's Guide) 1.325 + * RETURNS: 1.326 + * Returns NULL if function succeeds 1.327 + * Returns a VerifyNode Error if the function fails in a non-fatal way. 1.328 + * Returns a Fatal Error if the function fails in a fatal way 1.329 + */ 1.330 +PKIX_Error * 1.331 +pkix_SingleVerifyNode_ToString( 1.332 + PKIX_VerifyNode *node, 1.333 + PKIX_PL_String **pString, 1.334 + void *plContext) 1.335 +{ 1.336 + PKIX_PL_String *fmtString = NULL; 1.337 + PKIX_PL_String *errorString = NULL; 1.338 + PKIX_PL_String *outString = NULL; 1.339 + 1.340 + PKIX_PL_X500Name *issuerName = NULL; 1.341 + PKIX_PL_X500Name *subjectName = NULL; 1.342 + PKIX_PL_String *issuerString = NULL; 1.343 + PKIX_PL_String *subjectString = NULL; 1.344 + 1.345 + PKIX_ENTER(VERIFYNODE, "pkix_SingleVerifyNode_ToString"); 1.346 + PKIX_NULLCHECK_THREE(node, pString, node->verifyCert); 1.347 + 1.348 + PKIX_TOSTRING(node->error, &errorString, plContext, 1.349 + PKIX_ERRORTOSTRINGFAILED); 1.350 + 1.351 + PKIX_CHECK(PKIX_PL_Cert_GetIssuer 1.352 + (node->verifyCert, &issuerName, plContext), 1.353 + PKIX_CERTGETISSUERFAILED); 1.354 + 1.355 + PKIX_TOSTRING(issuerName, &issuerString, plContext, 1.356 + PKIX_X500NAMETOSTRINGFAILED); 1.357 + 1.358 + PKIX_CHECK(PKIX_PL_Cert_GetSubject 1.359 + (node->verifyCert, &subjectName, plContext), 1.360 + PKIX_CERTGETSUBJECTFAILED); 1.361 + 1.362 + PKIX_TOSTRING(subjectName, &subjectString, plContext, 1.363 + PKIX_X500NAMETOSTRINGFAILED); 1.364 + 1.365 + PKIX_CHECK(PKIX_PL_String_Create 1.366 + (PKIX_ESCASCII, 1.367 + "CERT[Issuer:%s, Subject:%s], depth=%d, error=%s", 1.368 + 0, 1.369 + &fmtString, 1.370 + plContext), 1.371 + PKIX_CANTCREATESTRING); 1.372 + 1.373 + PKIX_CHECK(PKIX_PL_Sprintf 1.374 + (&outString, 1.375 + plContext, 1.376 + fmtString, 1.377 + issuerString, 1.378 + subjectString, 1.379 + node->depth, 1.380 + errorString), 1.381 + PKIX_SPRINTFFAILED); 1.382 + 1.383 + *pString = outString; 1.384 + 1.385 +cleanup: 1.386 + 1.387 + PKIX_DECREF(fmtString); 1.388 + PKIX_DECREF(errorString); 1.389 + PKIX_DECREF(issuerName); 1.390 + PKIX_DECREF(subjectName); 1.391 + PKIX_DECREF(issuerString); 1.392 + PKIX_DECREF(subjectString); 1.393 + PKIX_RETURN(VERIFYNODE); 1.394 +} 1.395 + 1.396 +/* 1.397 + * FUNCTION: pkix_VerifyNode_ToString_Helper 1.398 + * DESCRIPTION: 1.399 + * 1.400 + * Produces a String representation of a VerifyNode tree below the VerifyNode 1.401 + * pointed to by "rootNode", with each line of output prefixed by the String 1.402 + * pointed to by "indent", and stores the result at "pTreeString". It is 1.403 + * called recursively, with ever-increasing indentation, for successively 1.404 + * lower nodes on the tree. 1.405 + * 1.406 + * PARAMETERS: 1.407 + * "rootNode" 1.408 + * Address of VerifyNode subtree. Must be non-NULL. 1.409 + * "indent" 1.410 + * Address of String to be prefixed to each line of output. May be NULL 1.411 + * if no indentation is desired 1.412 + * "pTreeString" 1.413 + * Address where the resulting String will be stored; must be non-NULL 1.414 + * "plContext" 1.415 + * Platform-specific context pointer. 1.416 + * THREAD SAFETY: 1.417 + * Conditionally Thread Safe 1.418 + * (see Thread Safety Definitions in Programmer's Guide) 1.419 + * RETURNS: 1.420 + * Returns NULL if the function succeeds. 1.421 + * Returns a VerifyNode Error if the function fails in a non-fatal way. 1.422 + * Returns a Fatal Error if the function fails in an unrecoverable way. 1.423 + */ 1.424 +static PKIX_Error * 1.425 +pkix_VerifyNode_ToString_Helper( 1.426 + PKIX_VerifyNode *rootNode, 1.427 + PKIX_PL_String *indent, 1.428 + PKIX_PL_String **pTreeString, 1.429 + void *plContext) 1.430 +{ 1.431 + PKIX_PL_String *nextIndentFormat = NULL; 1.432 + PKIX_PL_String *thisNodeFormat = NULL; 1.433 + PKIX_PL_String *childrenFormat = NULL; 1.434 + PKIX_PL_String *nextIndentString = NULL; 1.435 + PKIX_PL_String *resultString = NULL; 1.436 + PKIX_PL_String *thisItemString = NULL; 1.437 + PKIX_PL_String *childString = NULL; 1.438 + PKIX_VerifyNode *childNode = NULL; 1.439 + PKIX_UInt32 numberOfChildren = 0; 1.440 + PKIX_UInt32 childIndex = 0; 1.441 + 1.442 + PKIX_ENTER(VERIFYNODE, "pkix_VerifyNode_ToString_Helper"); 1.443 + 1.444 + PKIX_NULLCHECK_TWO(rootNode, pTreeString); 1.445 + 1.446 + /* Create a string for this node */ 1.447 + PKIX_CHECK(pkix_SingleVerifyNode_ToString 1.448 + (rootNode, &thisItemString, plContext), 1.449 + PKIX_ERRORINSINGLEVERIFYNODETOSTRING); 1.450 + 1.451 + if (indent) { 1.452 + PKIX_CHECK(PKIX_PL_String_Create 1.453 + (PKIX_ESCASCII, 1.454 + "%s%s", 1.455 + 0, 1.456 + &thisNodeFormat, 1.457 + plContext), 1.458 + PKIX_ERRORCREATINGFORMATSTRING); 1.459 + 1.460 + PKIX_CHECK(PKIX_PL_Sprintf 1.461 + (&resultString, 1.462 + plContext, 1.463 + thisNodeFormat, 1.464 + indent, 1.465 + thisItemString), 1.466 + PKIX_ERRORINSPRINTF); 1.467 + } else { 1.468 + PKIX_CHECK(PKIX_PL_String_Create 1.469 + (PKIX_ESCASCII, 1.470 + "%s", 1.471 + 0, 1.472 + &thisNodeFormat, 1.473 + plContext), 1.474 + PKIX_ERRORCREATINGFORMATSTRING); 1.475 + 1.476 + PKIX_CHECK(PKIX_PL_Sprintf 1.477 + (&resultString, 1.478 + plContext, 1.479 + thisNodeFormat, 1.480 + thisItemString), 1.481 + PKIX_ERRORINSPRINTF); 1.482 + } 1.483 + 1.484 + PKIX_DECREF(thisItemString); 1.485 + thisItemString = resultString; 1.486 + 1.487 + /* if no children, we are done */ 1.488 + if (rootNode->children) { 1.489 + PKIX_CHECK(PKIX_List_GetLength 1.490 + (rootNode->children, &numberOfChildren, plContext), 1.491 + PKIX_LISTGETLENGTHFAILED); 1.492 + } 1.493 + 1.494 + if (numberOfChildren != 0) { 1.495 + /* 1.496 + * We create a string for each child in turn, 1.497 + * concatenating them to thisItemString. 1.498 + */ 1.499 + 1.500 + /* Prepare an indent string for each child */ 1.501 + if (indent) { 1.502 + PKIX_CHECK(PKIX_PL_String_Create 1.503 + (PKIX_ESCASCII, 1.504 + "%s. ", 1.505 + 0, 1.506 + &nextIndentFormat, 1.507 + plContext), 1.508 + PKIX_ERRORCREATINGFORMATSTRING); 1.509 + 1.510 + PKIX_CHECK(PKIX_PL_Sprintf 1.511 + (&nextIndentString, 1.512 + plContext, 1.513 + nextIndentFormat, 1.514 + indent), 1.515 + PKIX_ERRORINSPRINTF); 1.516 + } else { 1.517 + PKIX_CHECK(PKIX_PL_String_Create 1.518 + (PKIX_ESCASCII, 1.519 + ". ", 1.520 + 0, 1.521 + &nextIndentString, 1.522 + plContext), 1.523 + PKIX_ERRORCREATINGINDENTSTRING); 1.524 + } 1.525 + 1.526 + /* Prepare the format for concatenation. */ 1.527 + PKIX_CHECK(PKIX_PL_String_Create 1.528 + (PKIX_ESCASCII, 1.529 + "%s\n%s", 1.530 + 0, 1.531 + &childrenFormat, 1.532 + plContext), 1.533 + PKIX_ERRORCREATINGFORMATSTRING); 1.534 + 1.535 + for (childIndex = 0; 1.536 + childIndex < numberOfChildren; 1.537 + childIndex++) { 1.538 + PKIX_CHECK(PKIX_List_GetItem 1.539 + (rootNode->children, 1.540 + childIndex, 1.541 + (PKIX_PL_Object **)&childNode, 1.542 + plContext), 1.543 + PKIX_LISTGETITEMFAILED); 1.544 + 1.545 + PKIX_CHECK(pkix_VerifyNode_ToString_Helper 1.546 + (childNode, 1.547 + nextIndentString, 1.548 + &childString, 1.549 + plContext), 1.550 + PKIX_ERRORCREATINGCHILDSTRING); 1.551 + 1.552 + 1.553 + PKIX_CHECK(PKIX_PL_Sprintf 1.554 + (&resultString, 1.555 + plContext, 1.556 + childrenFormat, 1.557 + thisItemString, 1.558 + childString), 1.559 + PKIX_ERRORINSPRINTF); 1.560 + 1.561 + PKIX_DECREF(childNode); 1.562 + PKIX_DECREF(childString); 1.563 + PKIX_DECREF(thisItemString); 1.564 + 1.565 + thisItemString = resultString; 1.566 + } 1.567 + } 1.568 + 1.569 + *pTreeString = thisItemString; 1.570 + 1.571 +cleanup: 1.572 + if (PKIX_ERROR_RECEIVED) { 1.573 + PKIX_DECREF(thisItemString); 1.574 + } 1.575 + 1.576 + PKIX_DECREF(nextIndentFormat); 1.577 + PKIX_DECREF(thisNodeFormat); 1.578 + PKIX_DECREF(childrenFormat); 1.579 + PKIX_DECREF(nextIndentString); 1.580 + PKIX_DECREF(childString); 1.581 + PKIX_DECREF(childNode); 1.582 + 1.583 + PKIX_RETURN(VERIFYNODE); 1.584 +} 1.585 + 1.586 +/* 1.587 + * FUNCTION: pkix_VerifyNode_ToString 1.588 + * (see comments for PKIX_PL_ToStringCallback in pkix_pl_system.h) 1.589 + */ 1.590 +static PKIX_Error * 1.591 +pkix_VerifyNode_ToString( 1.592 + PKIX_PL_Object *object, 1.593 + PKIX_PL_String **pTreeString, 1.594 + void *plContext) 1.595 +{ 1.596 + PKIX_VerifyNode *rootNode = NULL; 1.597 + PKIX_PL_String *resultString = NULL; 1.598 + 1.599 + PKIX_ENTER(VERIFYNODE, "pkix_VerifyNode_ToString"); 1.600 + 1.601 + PKIX_NULLCHECK_TWO(object, pTreeString); 1.602 + 1.603 + PKIX_CHECK(pkix_CheckType(object, PKIX_VERIFYNODE_TYPE, plContext), 1.604 + PKIX_OBJECTNOTVERIFYNODE); 1.605 + 1.606 + rootNode = (PKIX_VerifyNode *)object; 1.607 + 1.608 + PKIX_CHECK(pkix_VerifyNode_ToString_Helper 1.609 + (rootNode, NULL, &resultString, plContext), 1.610 + PKIX_ERRORCREATINGSUBTREESTRING); 1.611 + 1.612 + *pTreeString = resultString; 1.613 + 1.614 +cleanup: 1.615 + 1.616 + PKIX_RETURN(VERIFYNODE); 1.617 +} 1.618 + 1.619 +/* 1.620 + * FUNCTION: pkix_VerifyNode_Destroy 1.621 + * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h) 1.622 + */ 1.623 +static PKIX_Error * 1.624 +pkix_VerifyNode_Destroy( 1.625 + PKIX_PL_Object *object, 1.626 + void *plContext) 1.627 +{ 1.628 + PKIX_VerifyNode *node = NULL; 1.629 + 1.630 + PKIX_ENTER(VERIFYNODE, "pkix_VerifyNode_Destroy"); 1.631 + 1.632 + PKIX_NULLCHECK_ONE(object); 1.633 + 1.634 + PKIX_CHECK(pkix_CheckType(object, PKIX_VERIFYNODE_TYPE, plContext), 1.635 + PKIX_OBJECTNOTVERIFYNODE); 1.636 + 1.637 + node = (PKIX_VerifyNode*)object; 1.638 + 1.639 + PKIX_DECREF(node->verifyCert); 1.640 + PKIX_DECREF(node->children); 1.641 + PKIX_DECREF(node->error); 1.642 + 1.643 + node->depth = 0; 1.644 + 1.645 +cleanup: 1.646 + 1.647 + PKIX_RETURN(VERIFYNODE); 1.648 +} 1.649 + 1.650 +/* 1.651 + * FUNCTION: pkix_SingleVerifyNode_Hashcode 1.652 + * DESCRIPTION: 1.653 + * 1.654 + * Computes the hashcode of the attributes of the VerifyNode pointed to by 1.655 + * "node", other than its parents and children, and stores the result at 1.656 + * "pHashcode". 1.657 + * 1.658 + * PARAMETERS: 1.659 + * "node" 1.660 + * Address of VerifyNode to be hashcoded; must be non-NULL 1.661 + * "pHashcode" 1.662 + * Address where UInt32 result will be stored; must be non-NULL 1.663 + * "plContext" 1.664 + * Platform-specific context pointer. 1.665 + * THREAD SAFETY: 1.666 + * Conditionally Thread Safe 1.667 + * (see Thread Safety Definitions in Programmer's Guide) 1.668 + * RETURNS: 1.669 + * Returns NULL if function succeeds 1.670 + * Returns a VerifyNode Error if the function fails in a non-fatal way. 1.671 + * Returns a Fatal Error if the function fails in a fatal way 1.672 + */ 1.673 +static PKIX_Error * 1.674 +pkix_SingleVerifyNode_Hashcode( 1.675 + PKIX_VerifyNode *node, 1.676 + PKIX_UInt32 *pHashcode, 1.677 + void *plContext) 1.678 +{ 1.679 + PKIX_UInt32 errorHash = 0; 1.680 + PKIX_UInt32 nodeHash = 0; 1.681 + 1.682 + PKIX_ENTER(VERIFYNODE, "pkix_SingleVerifyNode_Hashcode"); 1.683 + PKIX_NULLCHECK_TWO(node, pHashcode); 1.684 + 1.685 + PKIX_HASHCODE 1.686 + (node->verifyCert, 1.687 + &nodeHash, 1.688 + plContext, 1.689 + PKIX_FAILUREHASHINGCERT); 1.690 + 1.691 + PKIX_CHECK(PKIX_PL_Object_Hashcode 1.692 + ((PKIX_PL_Object *)node->error, 1.693 + &errorHash, 1.694 + plContext), 1.695 + PKIX_FAILUREHASHINGERROR); 1.696 + 1.697 + nodeHash = 31*nodeHash + errorHash; 1.698 + *pHashcode = nodeHash; 1.699 + 1.700 +cleanup: 1.701 + 1.702 + PKIX_RETURN(VERIFYNODE); 1.703 +} 1.704 + 1.705 +/* 1.706 + * FUNCTION: pkix_VerifyNode_Hashcode 1.707 + * (see comments for PKIX_PL_HashcodeCallback in pkix_pl_system.h) 1.708 + */ 1.709 +static PKIX_Error * 1.710 +pkix_VerifyNode_Hashcode( 1.711 + PKIX_PL_Object *object, 1.712 + PKIX_UInt32 *pHashcode, 1.713 + void *plContext) 1.714 +{ 1.715 + PKIX_VerifyNode *node = NULL; 1.716 + PKIX_UInt32 childrenHash = 0; 1.717 + PKIX_UInt32 nodeHash = 0; 1.718 + 1.719 + PKIX_ENTER(VERIFYNODE, "pkix_VerifyNode_Hashcode"); 1.720 + PKIX_NULLCHECK_TWO(object, pHashcode); 1.721 + 1.722 + PKIX_CHECK(pkix_CheckType 1.723 + (object, PKIX_VERIFYNODE_TYPE, plContext), 1.724 + PKIX_OBJECTNOTVERIFYNODE); 1.725 + 1.726 + node = (PKIX_VerifyNode *)object; 1.727 + 1.728 + PKIX_CHECK(pkix_SingleVerifyNode_Hashcode 1.729 + (node, &nodeHash, plContext), 1.730 + PKIX_SINGLEVERIFYNODEHASHCODEFAILED); 1.731 + 1.732 + PKIX_HASHCODE 1.733 + (node->children, 1.734 + &childrenHash, 1.735 + plContext, 1.736 + PKIX_OBJECTHASHCODEFAILED); 1.737 + 1.738 + nodeHash = 31*nodeHash + childrenHash; 1.739 + 1.740 + *pHashcode = nodeHash; 1.741 + 1.742 +cleanup: 1.743 + 1.744 + PKIX_RETURN(VERIFYNODE); 1.745 +} 1.746 + 1.747 +/* 1.748 + * FUNCTION: pkix_SingleVerifyNode_Equals 1.749 + * DESCRIPTION: 1.750 + * 1.751 + * Compares for equality the components of the VerifyNode pointed to by 1.752 + * "firstPN", other than its parents and children, with those of the 1.753 + * VerifyNode pointed to by "secondPN" and stores the result at "pResult" 1.754 + * (PKIX_TRUE if equal; PKIX_FALSE if not). 1.755 + * 1.756 + * PARAMETERS: 1.757 + * "firstPN" 1.758 + * Address of first of the VerifyNodes to be compared; must be non-NULL 1.759 + * "secondPN" 1.760 + * Address of second of the VerifyNodes to be compared; must be non-NULL 1.761 + * "pResult" 1.762 + * Address where Boolean will be stored; must be non-NULL 1.763 + * "plContext" 1.764 + * Platform-specific context pointer. 1.765 + * THREAD SAFETY: 1.766 + * Conditionally Thread Safe 1.767 + * (see Thread Safety Definitions in Programmer's Guide) 1.768 + * RETURNS: 1.769 + * Returns NULL if function succeeds 1.770 + * Returns a VerifyNode Error if the function fails in a non-fatal way. 1.771 + * Returns a Fatal Error if the function fails in a fatal way 1.772 + */ 1.773 +static PKIX_Error * 1.774 +pkix_SingleVerifyNode_Equals( 1.775 + PKIX_VerifyNode *firstVN, 1.776 + PKIX_VerifyNode *secondVN, 1.777 + PKIX_Boolean *pResult, 1.778 + void *plContext) 1.779 +{ 1.780 + PKIX_Boolean compResult = PKIX_FALSE; 1.781 + 1.782 + PKIX_ENTER(VERIFYNODE, "pkix_SingleVerifyNode_Equals"); 1.783 + PKIX_NULLCHECK_THREE(firstVN, secondVN, pResult); 1.784 + 1.785 + /* If both references are identical, they must be equal */ 1.786 + if (firstVN == secondVN) { 1.787 + compResult = PKIX_TRUE; 1.788 + goto cleanup; 1.789 + } 1.790 + 1.791 + /* 1.792 + * It seems we have to do the comparisons. Do 1.793 + * the easiest ones first. 1.794 + */ 1.795 + if ((firstVN->depth) != (secondVN->depth)) { 1.796 + goto cleanup; 1.797 + } 1.798 + 1.799 + /* These fields must be non-NULL */ 1.800 + PKIX_NULLCHECK_TWO(firstVN->verifyCert, secondVN->verifyCert); 1.801 + 1.802 + PKIX_EQUALS 1.803 + (firstVN->verifyCert, 1.804 + secondVN->verifyCert, 1.805 + &compResult, 1.806 + plContext, 1.807 + PKIX_OBJECTEQUALSFAILED); 1.808 + 1.809 + if (compResult == PKIX_FALSE) { 1.810 + goto cleanup; 1.811 + } 1.812 + 1.813 + PKIX_EQUALS 1.814 + (firstVN->error, 1.815 + secondVN->error, 1.816 + &compResult, 1.817 + plContext, 1.818 + PKIX_OBJECTEQUALSFAILED); 1.819 + 1.820 +cleanup: 1.821 + 1.822 + *pResult = compResult; 1.823 + 1.824 + PKIX_RETURN(VERIFYNODE); 1.825 +} 1.826 + 1.827 +/* 1.828 + * FUNCTION: pkix_VerifyNode_Equals 1.829 + * (see comments for PKIX_PL_Equals_Callback in pkix_pl_system.h) 1.830 + */ 1.831 +static PKIX_Error * 1.832 +pkix_VerifyNode_Equals( 1.833 + PKIX_PL_Object *firstObject, 1.834 + PKIX_PL_Object *secondObject, 1.835 + PKIX_Boolean *pResult, 1.836 + void *plContext) 1.837 +{ 1.838 + PKIX_VerifyNode *firstVN = NULL; 1.839 + PKIX_VerifyNode *secondVN = NULL; 1.840 + PKIX_UInt32 secondType; 1.841 + PKIX_Boolean compResult = PKIX_FALSE; 1.842 + 1.843 + PKIX_ENTER(VERIFYNODE, "pkix_VerifyNode_Equals"); 1.844 + PKIX_NULLCHECK_THREE(firstObject, secondObject, pResult); 1.845 + 1.846 + /* test that firstObject is a VerifyNode */ 1.847 + PKIX_CHECK(pkix_CheckType 1.848 + (firstObject, PKIX_VERIFYNODE_TYPE, plContext), 1.849 + PKIX_FIRSTOBJECTNOTVERIFYNODE); 1.850 + 1.851 + /* 1.852 + * Since we know firstObject is a VerifyNode, 1.853 + * if both references are identical, they must be equal 1.854 + */ 1.855 + if (firstObject == secondObject){ 1.856 + compResult = PKIX_TRUE; 1.857 + goto cleanup; 1.858 + } 1.859 + 1.860 + /* 1.861 + * If secondObject isn't a VerifyNode, we 1.862 + * don't throw an error. We simply return FALSE. 1.863 + */ 1.864 + PKIX_CHECK(PKIX_PL_Object_GetType 1.865 + (secondObject, &secondType, plContext), 1.866 + PKIX_COULDNOTGETTYPEOFSECONDARGUMENT); 1.867 + 1.868 + if (secondType != PKIX_VERIFYNODE_TYPE) { 1.869 + goto cleanup; 1.870 + } 1.871 + 1.872 + /* 1.873 + * Oh, well, we have to do the comparisons. Do 1.874 + * the easiest ones first. 1.875 + */ 1.876 + firstVN = (PKIX_VerifyNode *)firstObject; 1.877 + secondVN = (PKIX_VerifyNode *)secondObject; 1.878 + 1.879 + PKIX_CHECK(pkix_SingleVerifyNode_Equals 1.880 + (firstVN, secondVN, &compResult, plContext), 1.881 + PKIX_SINGLEVERIFYNODEEQUALSFAILED); 1.882 + 1.883 + if (compResult == PKIX_FALSE) { 1.884 + goto cleanup; 1.885 + } 1.886 + 1.887 + PKIX_EQUALS 1.888 + (firstVN->children, 1.889 + secondVN->children, 1.890 + &compResult, 1.891 + plContext, 1.892 + PKIX_OBJECTEQUALSFAILEDONCHILDREN); 1.893 + 1.894 +cleanup: 1.895 + 1.896 + *pResult = compResult; 1.897 + 1.898 + PKIX_RETURN(VERIFYNODE); 1.899 +} 1.900 + 1.901 +/* 1.902 + * FUNCTION: pkix_VerifyNode_DuplicateHelper 1.903 + * DESCRIPTION: 1.904 + * 1.905 + * Duplicates the VerifyNode whose address is pointed to by "original", 1.906 + * and stores the result at "pNewNode", if a non-NULL pointer is provided 1.907 + * for "pNewNode". In addition, the created VerifyNode is added as a child 1.908 + * to "parent", if a non-NULL pointer is provided for "parent". Then this 1.909 + * function is called recursively to duplicate each of the children of 1.910 + * "original". At the top level this function is called with a null 1.911 + * "parent" and a non-NULL "pNewNode". Below the top level "parent" will 1.912 + * be non-NULL and "pNewNode" will be NULL. 1.913 + * 1.914 + * PARAMETERS: 1.915 + * "original" 1.916 + * Address of VerifyNode to be copied; must be non-NULL 1.917 + * "parent" 1.918 + * Address of VerifyNode to which the created node is to be added as a 1.919 + * child; NULL for the top-level call and non-NULL below the top level 1.920 + * "pNewNode" 1.921 + * Address to store the node created; should be NULL if "parent" is 1.922 + * non-NULL and vice versa 1.923 + * "plContext" 1.924 + * Platform-specific context pointer. 1.925 + * THREAD SAFETY: 1.926 + * Conditionally Thread Safe 1.927 + * (see Thread Safety Definitions in Programmer's Guide) 1.928 + * RETURNS: 1.929 + * Returns NULL if function succeeds 1.930 + * Returns a VerifyNode Error if the function fails in a non-fatal way. 1.931 + * Returns a Fatal Error if the function fails in a fatal way 1.932 + */ 1.933 +static PKIX_Error * 1.934 +pkix_VerifyNode_DuplicateHelper( 1.935 + PKIX_VerifyNode *original, 1.936 + PKIX_VerifyNode *parent, 1.937 + PKIX_VerifyNode **pNewNode, 1.938 + void *plContext) 1.939 +{ 1.940 + PKIX_UInt32 numChildren = 0; 1.941 + PKIX_UInt32 childIndex = 0; 1.942 + PKIX_List *children = NULL; /* List of PKIX_VerifyNode */ 1.943 + PKIX_VerifyNode *copy = NULL; 1.944 + PKIX_VerifyNode *child = NULL; 1.945 + 1.946 + PKIX_ENTER(VERIFYNODE, "pkix_VerifyNode_DuplicateHelper"); 1.947 + 1.948 + PKIX_NULLCHECK_TWO 1.949 + (original, original->verifyCert); 1.950 + 1.951 + /* 1.952 + * These components are immutable, so copying the pointers 1.953 + * is sufficient. The create function increments the reference 1.954 + * counts as it stores the pointers into the new object. 1.955 + */ 1.956 + PKIX_CHECK(pkix_VerifyNode_Create 1.957 + (original->verifyCert, 1.958 + original->depth, 1.959 + original->error, 1.960 + ©, 1.961 + plContext), 1.962 + PKIX_VERIFYNODECREATEFAILED); 1.963 + 1.964 + /* Are there any children to duplicate? */ 1.965 + children = original->children; 1.966 + 1.967 + if (children) { 1.968 + PKIX_CHECK(PKIX_List_GetLength(children, &numChildren, plContext), 1.969 + PKIX_LISTGETLENGTHFAILED); 1.970 + } 1.971 + 1.972 + for (childIndex = 0; childIndex < numChildren; childIndex++) { 1.973 + PKIX_CHECK(PKIX_List_GetItem 1.974 + (children, 1.975 + childIndex, 1.976 + (PKIX_PL_Object **)&child, 1.977 + plContext), 1.978 + PKIX_LISTGETITEMFAILED); 1.979 + 1.980 + PKIX_CHECK(pkix_VerifyNode_DuplicateHelper 1.981 + (child, copy, NULL, plContext), 1.982 + PKIX_VERIFYNODEDUPLICATEHELPERFAILED); 1.983 + 1.984 + PKIX_DECREF(child); 1.985 + } 1.986 + 1.987 + if (pNewNode) { 1.988 + *pNewNode = copy; 1.989 + copy = NULL; /* no DecRef if we give our handle away */ 1.990 + } 1.991 + 1.992 +cleanup: 1.993 + PKIX_DECREF(copy); 1.994 + PKIX_DECREF(child); 1.995 + 1.996 + PKIX_RETURN(VERIFYNODE); 1.997 +} 1.998 + 1.999 +/* 1.1000 + * FUNCTION: pkix_VerifyNode_Duplicate 1.1001 + * (see comments for PKIX_PL_Duplicate_Callback in pkix_pl_system.h) 1.1002 + */ 1.1003 +static PKIX_Error * 1.1004 +pkix_VerifyNode_Duplicate( 1.1005 + PKIX_PL_Object *object, 1.1006 + PKIX_PL_Object **pNewObject, 1.1007 + void *plContext) 1.1008 +{ 1.1009 + PKIX_VerifyNode *original = NULL; 1.1010 + PKIX_VerifyNode *copy = NULL; 1.1011 + 1.1012 + PKIX_ENTER(VERIFYNODE, "pkix_VerifyNode_Duplicate"); 1.1013 + 1.1014 + PKIX_NULLCHECK_TWO(object, pNewObject); 1.1015 + 1.1016 + PKIX_CHECK(pkix_CheckType 1.1017 + (object, PKIX_VERIFYNODE_TYPE, plContext), 1.1018 + PKIX_OBJECTNOTVERIFYNODE); 1.1019 + 1.1020 + original = (PKIX_VerifyNode *)object; 1.1021 + 1.1022 + PKIX_CHECK(pkix_VerifyNode_DuplicateHelper 1.1023 + (original, NULL, ©, plContext), 1.1024 + PKIX_VERIFYNODEDUPLICATEHELPERFAILED); 1.1025 + 1.1026 + *pNewObject = (PKIX_PL_Object *)copy; 1.1027 + 1.1028 +cleanup: 1.1029 + 1.1030 + PKIX_RETURN(VERIFYNODE); 1.1031 +} 1.1032 + 1.1033 +/* 1.1034 + * FUNCTION: pkix_VerifyNode_RegisterSelf 1.1035 + * DESCRIPTION: 1.1036 + * 1.1037 + * Registers PKIX_VERIFYNODE_TYPE and its related 1.1038 + * functions with systemClasses[] 1.1039 + * 1.1040 + * THREAD SAFETY: 1.1041 + * Not Thread Safe - for performance and complexity reasons 1.1042 + * 1.1043 + * Since this function is only called by PKIX_PL_Initialize, 1.1044 + * which should only be called once, it is acceptable that 1.1045 + * this function is not thread-safe. 1.1046 + */ 1.1047 +PKIX_Error * 1.1048 +pkix_VerifyNode_RegisterSelf(void *plContext) 1.1049 +{ 1.1050 + 1.1051 + extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES]; 1.1052 + pkix_ClassTable_Entry entry; 1.1053 + 1.1054 + PKIX_ENTER(VERIFYNODE, "pkix_VerifyNode_RegisterSelf"); 1.1055 + 1.1056 + entry.description = "VerifyNode"; 1.1057 + entry.objCounter = 0; 1.1058 + entry.typeObjectSize = sizeof(PKIX_VerifyNode); 1.1059 + entry.destructor = pkix_VerifyNode_Destroy; 1.1060 + entry.equalsFunction = pkix_VerifyNode_Equals; 1.1061 + entry.hashcodeFunction = pkix_VerifyNode_Hashcode; 1.1062 + entry.toStringFunction = pkix_VerifyNode_ToString; 1.1063 + entry.comparator = NULL; 1.1064 + entry.duplicateFunction = pkix_VerifyNode_Duplicate; 1.1065 + 1.1066 + systemClasses[PKIX_VERIFYNODE_TYPE] = entry; 1.1067 + 1.1068 + PKIX_RETURN(VERIFYNODE); 1.1069 +} 1.1070 + 1.1071 +/* --Public-VerifyNode-Functions----------------------------------- */ 1.1072 + 1.1073 +/* 1.1074 + * FUNCTION: PKIX_VerifyNode_SetError 1.1075 + * DESCRIPTION: 1.1076 + * 1.1077 + * This function sets the Error field of the VerifyNode pointed to by "node" 1.1078 + * to contain the Error pointed to by "error". 1.1079 + * 1.1080 + * PARAMETERS: 1.1081 + * "node" 1.1082 + * The address of the VerifyNode to be modified. Must be non-NULL. 1.1083 + * "error" 1.1084 + * The address of the Error to be stored. 1.1085 + * "plContext" 1.1086 + * Platform-specific context pointer. 1.1087 + * THREAD SAFETY: 1.1088 + * Thread Safe (see Thread Safety Definitions in Programmer's Guide) 1.1089 + * RETURNS: 1.1090 + * Returns NULL if the function succeeds. 1.1091 + * Returns a Fatal Error if the function fails in an unrecoverable way. 1.1092 + */ 1.1093 +PKIX_Error * 1.1094 +pkix_VerifyNode_SetError( 1.1095 + PKIX_VerifyNode *node, 1.1096 + PKIX_Error *error, 1.1097 + void *plContext) 1.1098 +{ 1.1099 + 1.1100 + PKIX_ENTER(VERIFYNODE, "PKIX_VerifyNode_SetError"); 1.1101 + 1.1102 + PKIX_NULLCHECK_TWO(node, error); 1.1103 + 1.1104 + PKIX_DECREF(node->error); /* should have been NULL */ 1.1105 + PKIX_INCREF(error); 1.1106 + node->error = error; 1.1107 + 1.1108 +cleanup: 1.1109 + PKIX_RETURN(VERIFYNODE); 1.1110 +} 1.1111 + 1.1112 +/* 1.1113 + * FUNCTION: PKIX_VerifyNode_FindError 1.1114 + * DESCRIPTION: 1.1115 + * 1.1116 + * Finds meaningful error in the log. For now, just returns the first 1.1117 + * error it finds in. In the future the function should be changed to 1.1118 + * return a top priority error. 1.1119 + * 1.1120 + * PARAMETERS: 1.1121 + * "node" 1.1122 + * The address of the VerifyNode to be modified. Must be non-NULL. 1.1123 + * "error" 1.1124 + * The address of a pointer the error will be returned to. 1.1125 + * "plContext" 1.1126 + * Platform-specific context pointer. 1.1127 + * THREAD SAFETY: 1.1128 + * Thread Safe (see Thread Safety Definitions in Programmer's Guide) 1.1129 + * RETURNS: 1.1130 + * Returns NULL if the function succeeds. 1.1131 + * Returns a Fatal Error if the function fails in an unrecoverable way. 1.1132 + */ 1.1133 +PKIX_Error * 1.1134 +pkix_VerifyNode_FindError( 1.1135 + PKIX_VerifyNode *node, 1.1136 + PKIX_Error **error, 1.1137 + void *plContext) 1.1138 +{ 1.1139 + PKIX_VerifyNode *childNode = NULL; 1.1140 + 1.1141 + PKIX_ENTER(VERIFYNODE, "PKIX_VerifyNode_FindError"); 1.1142 + 1.1143 + /* Make sure the return address is initialized with NULL */ 1.1144 + PKIX_DECREF(*error); 1.1145 + 1.1146 + if (!node) 1.1147 + goto cleanup; 1.1148 + 1.1149 + /* First, try to get error from lowest level. */ 1.1150 + if (node->children) { 1.1151 + PKIX_UInt32 length = 0; 1.1152 + PKIX_UInt32 index = 0; 1.1153 + 1.1154 + PKIX_CHECK( 1.1155 + PKIX_List_GetLength(node->children, &length, 1.1156 + plContext), 1.1157 + PKIX_LISTGETLENGTHFAILED); 1.1158 + for (index = 0;index < length;index++) { 1.1159 + PKIX_CHECK( 1.1160 + PKIX_List_GetItem(node->children, index, 1.1161 + (PKIX_PL_Object**)&childNode, plContext), 1.1162 + PKIX_LISTGETITEMFAILED); 1.1163 + if (!childNode) 1.1164 + continue; 1.1165 + PKIX_CHECK( 1.1166 + pkix_VerifyNode_FindError(childNode, error, 1.1167 + plContext), 1.1168 + PKIX_VERIFYNODEFINDERRORFAILED); 1.1169 + PKIX_DECREF(childNode); 1.1170 + if (*error) { 1.1171 + goto cleanup; 1.1172 + } 1.1173 + } 1.1174 + } 1.1175 + 1.1176 + if (node->error && node->error->plErr) { 1.1177 + PKIX_INCREF(node->error); 1.1178 + *error = node->error; 1.1179 + } 1.1180 + 1.1181 +cleanup: 1.1182 + PKIX_DECREF(childNode); 1.1183 + 1.1184 + PKIX_RETURN(VERIFYNODE); 1.1185 +}