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

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rwxr-xr-x

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

michael@0 1 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 2 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 4 /*
michael@0 5 * pkix_verifynode.c
michael@0 6 *
michael@0 7 * Verify Node Object Type Definition
michael@0 8 *
michael@0 9 */
michael@0 10
michael@0 11 #include "pkix_verifynode.h"
michael@0 12
michael@0 13 /* --Private-VerifyNode-Functions---------------------------------- */
michael@0 14
michael@0 15 /*
michael@0 16 * FUNCTION: pkix_VerifyNode_Create
michael@0 17 * DESCRIPTION:
michael@0 18 *
michael@0 19 * This function creates a VerifyNode using the Cert pointed to by "cert",
michael@0 20 * the depth given by "depth", and the Error pointed to by "error", storing
michael@0 21 * the result at "pObject".
michael@0 22 *
michael@0 23 * PARAMETERS
michael@0 24 * "cert"
michael@0 25 * Address of Cert for the node. Must be non-NULL
michael@0 26 * "depth"
michael@0 27 * UInt32 value of the depth for this node.
michael@0 28 * "error"
michael@0 29 * Address of Error for the node.
michael@0 30 * "pObject"
michael@0 31 * Address where the VerifyNode pointer will be stored. Must be non-NULL.
michael@0 32 * "plContext"
michael@0 33 * Platform-specific context pointer.
michael@0 34 * THREAD SAFETY:
michael@0 35 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
michael@0 36 * RETURNS:
michael@0 37 * Returns NULL if the function succeeds.
michael@0 38 * Returns a Fatal Error if the function fails in an unrecoverable way.
michael@0 39 */
michael@0 40 PKIX_Error *
michael@0 41 pkix_VerifyNode_Create(
michael@0 42 PKIX_PL_Cert *cert,
michael@0 43 PKIX_UInt32 depth,
michael@0 44 PKIX_Error *error,
michael@0 45 PKIX_VerifyNode **pObject,
michael@0 46 void *plContext)
michael@0 47 {
michael@0 48 PKIX_VerifyNode *node = NULL;
michael@0 49
michael@0 50 PKIX_ENTER(VERIFYNODE, "pkix_VerifyNode_Create");
michael@0 51 PKIX_NULLCHECK_TWO(cert, pObject);
michael@0 52
michael@0 53 PKIX_CHECK(PKIX_PL_Object_Alloc
michael@0 54 (PKIX_VERIFYNODE_TYPE,
michael@0 55 sizeof (PKIX_VerifyNode),
michael@0 56 (PKIX_PL_Object **)&node,
michael@0 57 plContext),
michael@0 58 PKIX_COULDNOTCREATEVERIFYNODEOBJECT);
michael@0 59
michael@0 60 PKIX_INCREF(cert);
michael@0 61 node->verifyCert = cert;
michael@0 62
michael@0 63 PKIX_INCREF(error);
michael@0 64 node->error = error;
michael@0 65
michael@0 66 node->depth = depth;
michael@0 67
michael@0 68 node->children = NULL;
michael@0 69
michael@0 70 *pObject = node;
michael@0 71 node = NULL;
michael@0 72
michael@0 73 cleanup:
michael@0 74
michael@0 75 PKIX_DECREF(node);
michael@0 76
michael@0 77 PKIX_RETURN(VERIFYNODE);
michael@0 78 }
michael@0 79
michael@0 80 /*
michael@0 81 * FUNCTION: pkix_VerifyNode_AddToChain
michael@0 82 * DESCRIPTION:
michael@0 83 *
michael@0 84 * Adds the VerifyNode pointed to by "child", at the appropriate depth, to the
michael@0 85 * List of children of the VerifyNode pointed to by "parentNode". The chain of
michael@0 86 * VerifyNodes is traversed until a VerifyNode is found at a depth one less
michael@0 87 * than that specified in "child". An Error is returned if there is no parent
michael@0 88 * at a suitable depth.
michael@0 89 *
michael@0 90 * If "parentNode" has a NULL pointer for the List of children, a new List is
michael@0 91 * created containing "child". Otherwise "child" is appended to the existing
michael@0 92 * List.
michael@0 93 *
michael@0 94 * Depth, in this context, means distance from the root node, which
michael@0 95 * is at depth zero.
michael@0 96 *
michael@0 97 * PARAMETERS:
michael@0 98 * "parentNode"
michael@0 99 * Address of VerifyNode whose List of child VerifyNodes is to be
michael@0 100 * created or appended to. Must be non-NULL.
michael@0 101 * "child"
michael@0 102 * Address of VerifyNode to be added to parentNode's List. Must be
michael@0 103 * non-NULL.
michael@0 104 * "plContext"
michael@0 105 * Platform-specific context pointer.
michael@0 106 * THREAD SAFETY:
michael@0 107 * Not Thread Safe (see Thread Safety Definitions in Programmer's Guide)
michael@0 108 * RETURNS:
michael@0 109 * Returns NULL if the function succeeds.
michael@0 110 * Returns a VerifyNode Error if the function fails in a non-fatal way.
michael@0 111 * Returns a Fatal Error if the function fails in an unrecoverable way.
michael@0 112 */
michael@0 113 PKIX_Error *
michael@0 114 pkix_VerifyNode_AddToChain(
michael@0 115 PKIX_VerifyNode *parentNode,
michael@0 116 PKIX_VerifyNode *child,
michael@0 117 void *plContext)
michael@0 118 {
michael@0 119 PKIX_VerifyNode *successor = NULL;
michael@0 120 PKIX_List *listOfChildren = NULL;
michael@0 121 PKIX_UInt32 numChildren = 0;
michael@0 122 PKIX_UInt32 parentDepth = 0;
michael@0 123
michael@0 124 PKIX_ENTER(VERIFYNODE, "pkix_VerifyNode_AddToChain");
michael@0 125 PKIX_NULLCHECK_TWO(parentNode, child);
michael@0 126
michael@0 127 parentDepth = parentNode->depth;
michael@0 128 listOfChildren = parentNode->children;
michael@0 129 if (listOfChildren == NULL) {
michael@0 130
michael@0 131 if (parentDepth != (child->depth - 1)) {
michael@0 132 PKIX_ERROR(PKIX_NODESMISSINGFROMCHAIN);
michael@0 133 }
michael@0 134
michael@0 135 PKIX_CHECK(PKIX_List_Create(&listOfChildren, plContext),
michael@0 136 PKIX_LISTCREATEFAILED);
michael@0 137
michael@0 138 PKIX_CHECK(PKIX_List_AppendItem
michael@0 139 (listOfChildren, (PKIX_PL_Object *)child, plContext),
michael@0 140 PKIX_COULDNOTAPPENDCHILDTOPARENTSVERIFYNODELIST);
michael@0 141
michael@0 142 parentNode->children = listOfChildren;
michael@0 143 } else {
michael@0 144 /* get number of children */
michael@0 145 PKIX_CHECK(PKIX_List_GetLength
michael@0 146 (listOfChildren, &numChildren, plContext),
michael@0 147 PKIX_LISTGETLENGTHFAILED);
michael@0 148
michael@0 149 if (numChildren != 1) {
michael@0 150 PKIX_ERROR(PKIX_AMBIGUOUSPARENTAGEOFVERIFYNODE);
michael@0 151 }
michael@0 152
michael@0 153 /* successor = listOfChildren[0] */
michael@0 154 PKIX_CHECK(PKIX_List_GetItem
michael@0 155 (listOfChildren,
michael@0 156 0,
michael@0 157 (PKIX_PL_Object **)&successor,
michael@0 158 plContext),
michael@0 159 PKIX_LISTGETITEMFAILED);
michael@0 160
michael@0 161 PKIX_CHECK(pkix_VerifyNode_AddToChain
michael@0 162 (successor, child, plContext),
michael@0 163 PKIX_VERIFYNODEADDTOCHAINFAILED);
michael@0 164 }
michael@0 165
michael@0 166 PKIX_CHECK(PKIX_PL_Object_InvalidateCache
michael@0 167 ((PKIX_PL_Object *)parentNode, plContext),
michael@0 168 PKIX_OBJECTINVALIDATECACHEFAILED);
michael@0 169
michael@0 170 cleanup:
michael@0 171 PKIX_DECREF(successor);
michael@0 172
michael@0 173 PKIX_RETURN(VERIFYNODE);
michael@0 174 }
michael@0 175
michael@0 176 /*
michael@0 177 * FUNCTION: pkix_VerifyNode_SetDepth
michael@0 178 * DESCRIPTION:
michael@0 179 *
michael@0 180 * The function sets the depth field of each VerifyNode in the List "children"
michael@0 181 * to the value given by "depth", and recursively sets the depth of any
michael@0 182 * successive generations to the successive values.
michael@0 183 *
michael@0 184 * PARAMETERS:
michael@0 185 * "children"
michael@0 186 * The List of VerifyNodes. Must be non-NULL.
michael@0 187 * "depth"
michael@0 188 * The value of the depth field to be set in members of the List.
michael@0 189 * "plContext"
michael@0 190 * Platform-specific context pointer.
michael@0 191 * THREAD SAFETY:
michael@0 192 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
michael@0 193 * RETURNS:
michael@0 194 * Returns NULL if the function succeeds.
michael@0 195 * Returns a Fatal Error if the function fails in an unrecoverable way.
michael@0 196 */
michael@0 197 static PKIX_Error *
michael@0 198 pkix_VerifyNode_SetDepth(PKIX_List *children,
michael@0 199 PKIX_UInt32 depth,
michael@0 200 void *plContext)
michael@0 201 {
michael@0 202 PKIX_UInt32 numChildren = 0;
michael@0 203 PKIX_UInt32 chIx = 0;
michael@0 204 PKIX_VerifyNode *child = NULL;
michael@0 205
michael@0 206 PKIX_ENTER(VERIFYNODE, "pkix_VerifyNode_SetDepth");
michael@0 207 PKIX_NULLCHECK_ONE(children);
michael@0 208
michael@0 209 PKIX_CHECK(PKIX_List_GetLength(children, &numChildren, plContext),
michael@0 210 PKIX_LISTGETLENGTHFAILED);
michael@0 211
michael@0 212 for (chIx = 0; chIx < numChildren; chIx++) {
michael@0 213 PKIX_CHECK(PKIX_List_GetItem
michael@0 214 (children, chIx, (PKIX_PL_Object **)&child, plContext),
michael@0 215 PKIX_LISTGETITEMFAILED);
michael@0 216
michael@0 217 child->depth = depth;
michael@0 218
michael@0 219 if (child->children != NULL) {
michael@0 220 PKIX_CHECK(pkix_VerifyNode_SetDepth
michael@0 221 (child->children, depth + 1, plContext),
michael@0 222 PKIX_VERIFYNODESETDEPTHFAILED);
michael@0 223 }
michael@0 224
michael@0 225 PKIX_DECREF(child);
michael@0 226 }
michael@0 227
michael@0 228 cleanup:
michael@0 229
michael@0 230 PKIX_DECREF(child);
michael@0 231
michael@0 232 PKIX_RETURN(VERIFYNODE);
michael@0 233 }
michael@0 234
michael@0 235 /*
michael@0 236 * FUNCTION: pkix_VerifyNode_AddToTree
michael@0 237 * DESCRIPTION:
michael@0 238 *
michael@0 239 * Adds the VerifyNode pointed to by "child" to the List of children of the
michael@0 240 * VerifyNode pointed to by "parentNode". If "parentNode" has a NULL pointer
michael@0 241 * for the List of children, a new List is created containing "child".
michael@0 242 * Otherwise "child" is appended to the existing List. The depth field of
michael@0 243 * "child" is set to one more than the corresponding value in "parent", and
michael@0 244 * if the "child" itself has child nodes, their depth fields are updated
michael@0 245 * accordingly.
michael@0 246 *
michael@0 247 * Depth, in this context, means distance from the root node, which
michael@0 248 * is at depth zero.
michael@0 249 *
michael@0 250 * PARAMETERS:
michael@0 251 * "parentNode"
michael@0 252 * Address of VerifyNode whose List of child VerifyNodes is to be
michael@0 253 * created or appended to. Must be non-NULL.
michael@0 254 * "child"
michael@0 255 * Address of VerifyNode to be added to parentNode's List. Must be
michael@0 256 * non-NULL.
michael@0 257 * "plContext"
michael@0 258 * Platform-specific context pointer.
michael@0 259 * THREAD SAFETY:
michael@0 260 * Not Thread Safe (see Thread Safety Definitions in Programmer's Guide)
michael@0 261 * RETURNS:
michael@0 262 * Returns NULL if the function succeeds.
michael@0 263 * Returns a Fatal Error if the function fails in an unrecoverable way.
michael@0 264 */
michael@0 265 PKIX_Error *
michael@0 266 pkix_VerifyNode_AddToTree(
michael@0 267 PKIX_VerifyNode *parentNode,
michael@0 268 PKIX_VerifyNode *child,
michael@0 269 void *plContext)
michael@0 270 {
michael@0 271 PKIX_List *listOfChildren = NULL;
michael@0 272 PKIX_UInt32 parentDepth = 0;
michael@0 273
michael@0 274 PKIX_ENTER(VERIFYNODE, "pkix_VerifyNode_AddToTree");
michael@0 275 PKIX_NULLCHECK_TWO(parentNode, child);
michael@0 276
michael@0 277 parentDepth = parentNode->depth;
michael@0 278 listOfChildren = parentNode->children;
michael@0 279 if (listOfChildren == NULL) {
michael@0 280
michael@0 281 PKIX_CHECK(PKIX_List_Create(&listOfChildren, plContext),
michael@0 282 PKIX_LISTCREATEFAILED);
michael@0 283
michael@0 284 parentNode->children = listOfChildren;
michael@0 285 }
michael@0 286
michael@0 287 child->depth = parentDepth + 1;
michael@0 288
michael@0 289 PKIX_CHECK(PKIX_List_AppendItem
michael@0 290 (parentNode->children, (PKIX_PL_Object *)child, plContext),
michael@0 291 PKIX_COULDNOTAPPENDCHILDTOPARENTSVERIFYNODELIST);
michael@0 292
michael@0 293 if (child->children != NULL) {
michael@0 294 PKIX_CHECK(pkix_VerifyNode_SetDepth
michael@0 295 (child->children, child->depth + 1, plContext),
michael@0 296 PKIX_VERIFYNODESETDEPTHFAILED);
michael@0 297 }
michael@0 298
michael@0 299
michael@0 300 cleanup:
michael@0 301
michael@0 302 PKIX_RETURN(VERIFYNODE);
michael@0 303 }
michael@0 304
michael@0 305 /*
michael@0 306 * FUNCTION: pkix_SingleVerifyNode_ToString
michael@0 307 * DESCRIPTION:
michael@0 308 *
michael@0 309 * Creates a String representation of the attributes of the VerifyNode pointed
michael@0 310 * to by "node", other than its children, and stores the result at "pString".
michael@0 311 *
michael@0 312 * PARAMETERS:
michael@0 313 * "node"
michael@0 314 * Address of VerifyNode to be described by the string. Must be non-NULL.
michael@0 315 * "pString"
michael@0 316 * Address where object pointer will be stored. Must be non-NULL.
michael@0 317 * "plContext"
michael@0 318 * Platform-specific context pointer.
michael@0 319 * THREAD SAFETY:
michael@0 320 * Conditionally Thread Safe
michael@0 321 * (see Thread Safety Definitions in Programmer's Guide)
michael@0 322 * RETURNS:
michael@0 323 * Returns NULL if function succeeds
michael@0 324 * Returns a VerifyNode Error if the function fails in a non-fatal way.
michael@0 325 * Returns a Fatal Error if the function fails in a fatal way
michael@0 326 */
michael@0 327 PKIX_Error *
michael@0 328 pkix_SingleVerifyNode_ToString(
michael@0 329 PKIX_VerifyNode *node,
michael@0 330 PKIX_PL_String **pString,
michael@0 331 void *plContext)
michael@0 332 {
michael@0 333 PKIX_PL_String *fmtString = NULL;
michael@0 334 PKIX_PL_String *errorString = NULL;
michael@0 335 PKIX_PL_String *outString = NULL;
michael@0 336
michael@0 337 PKIX_PL_X500Name *issuerName = NULL;
michael@0 338 PKIX_PL_X500Name *subjectName = NULL;
michael@0 339 PKIX_PL_String *issuerString = NULL;
michael@0 340 PKIX_PL_String *subjectString = NULL;
michael@0 341
michael@0 342 PKIX_ENTER(VERIFYNODE, "pkix_SingleVerifyNode_ToString");
michael@0 343 PKIX_NULLCHECK_THREE(node, pString, node->verifyCert);
michael@0 344
michael@0 345 PKIX_TOSTRING(node->error, &errorString, plContext,
michael@0 346 PKIX_ERRORTOSTRINGFAILED);
michael@0 347
michael@0 348 PKIX_CHECK(PKIX_PL_Cert_GetIssuer
michael@0 349 (node->verifyCert, &issuerName, plContext),
michael@0 350 PKIX_CERTGETISSUERFAILED);
michael@0 351
michael@0 352 PKIX_TOSTRING(issuerName, &issuerString, plContext,
michael@0 353 PKIX_X500NAMETOSTRINGFAILED);
michael@0 354
michael@0 355 PKIX_CHECK(PKIX_PL_Cert_GetSubject
michael@0 356 (node->verifyCert, &subjectName, plContext),
michael@0 357 PKIX_CERTGETSUBJECTFAILED);
michael@0 358
michael@0 359 PKIX_TOSTRING(subjectName, &subjectString, plContext,
michael@0 360 PKIX_X500NAMETOSTRINGFAILED);
michael@0 361
michael@0 362 PKIX_CHECK(PKIX_PL_String_Create
michael@0 363 (PKIX_ESCASCII,
michael@0 364 "CERT[Issuer:%s, Subject:%s], depth=%d, error=%s",
michael@0 365 0,
michael@0 366 &fmtString,
michael@0 367 plContext),
michael@0 368 PKIX_CANTCREATESTRING);
michael@0 369
michael@0 370 PKIX_CHECK(PKIX_PL_Sprintf
michael@0 371 (&outString,
michael@0 372 plContext,
michael@0 373 fmtString,
michael@0 374 issuerString,
michael@0 375 subjectString,
michael@0 376 node->depth,
michael@0 377 errorString),
michael@0 378 PKIX_SPRINTFFAILED);
michael@0 379
michael@0 380 *pString = outString;
michael@0 381
michael@0 382 cleanup:
michael@0 383
michael@0 384 PKIX_DECREF(fmtString);
michael@0 385 PKIX_DECREF(errorString);
michael@0 386 PKIX_DECREF(issuerName);
michael@0 387 PKIX_DECREF(subjectName);
michael@0 388 PKIX_DECREF(issuerString);
michael@0 389 PKIX_DECREF(subjectString);
michael@0 390 PKIX_RETURN(VERIFYNODE);
michael@0 391 }
michael@0 392
michael@0 393 /*
michael@0 394 * FUNCTION: pkix_VerifyNode_ToString_Helper
michael@0 395 * DESCRIPTION:
michael@0 396 *
michael@0 397 * Produces a String representation of a VerifyNode tree below the VerifyNode
michael@0 398 * pointed to by "rootNode", with each line of output prefixed by the String
michael@0 399 * pointed to by "indent", and stores the result at "pTreeString". It is
michael@0 400 * called recursively, with ever-increasing indentation, for successively
michael@0 401 * lower nodes on the tree.
michael@0 402 *
michael@0 403 * PARAMETERS:
michael@0 404 * "rootNode"
michael@0 405 * Address of VerifyNode subtree. Must be non-NULL.
michael@0 406 * "indent"
michael@0 407 * Address of String to be prefixed to each line of output. May be NULL
michael@0 408 * if no indentation is desired
michael@0 409 * "pTreeString"
michael@0 410 * Address where the resulting String will be stored; must be non-NULL
michael@0 411 * "plContext"
michael@0 412 * Platform-specific context pointer.
michael@0 413 * THREAD SAFETY:
michael@0 414 * Conditionally Thread Safe
michael@0 415 * (see Thread Safety Definitions in Programmer's Guide)
michael@0 416 * RETURNS:
michael@0 417 * Returns NULL if the function succeeds.
michael@0 418 * Returns a VerifyNode Error if the function fails in a non-fatal way.
michael@0 419 * Returns a Fatal Error if the function fails in an unrecoverable way.
michael@0 420 */
michael@0 421 static PKIX_Error *
michael@0 422 pkix_VerifyNode_ToString_Helper(
michael@0 423 PKIX_VerifyNode *rootNode,
michael@0 424 PKIX_PL_String *indent,
michael@0 425 PKIX_PL_String **pTreeString,
michael@0 426 void *plContext)
michael@0 427 {
michael@0 428 PKIX_PL_String *nextIndentFormat = NULL;
michael@0 429 PKIX_PL_String *thisNodeFormat = NULL;
michael@0 430 PKIX_PL_String *childrenFormat = NULL;
michael@0 431 PKIX_PL_String *nextIndentString = NULL;
michael@0 432 PKIX_PL_String *resultString = NULL;
michael@0 433 PKIX_PL_String *thisItemString = NULL;
michael@0 434 PKIX_PL_String *childString = NULL;
michael@0 435 PKIX_VerifyNode *childNode = NULL;
michael@0 436 PKIX_UInt32 numberOfChildren = 0;
michael@0 437 PKIX_UInt32 childIndex = 0;
michael@0 438
michael@0 439 PKIX_ENTER(VERIFYNODE, "pkix_VerifyNode_ToString_Helper");
michael@0 440
michael@0 441 PKIX_NULLCHECK_TWO(rootNode, pTreeString);
michael@0 442
michael@0 443 /* Create a string for this node */
michael@0 444 PKIX_CHECK(pkix_SingleVerifyNode_ToString
michael@0 445 (rootNode, &thisItemString, plContext),
michael@0 446 PKIX_ERRORINSINGLEVERIFYNODETOSTRING);
michael@0 447
michael@0 448 if (indent) {
michael@0 449 PKIX_CHECK(PKIX_PL_String_Create
michael@0 450 (PKIX_ESCASCII,
michael@0 451 "%s%s",
michael@0 452 0,
michael@0 453 &thisNodeFormat,
michael@0 454 plContext),
michael@0 455 PKIX_ERRORCREATINGFORMATSTRING);
michael@0 456
michael@0 457 PKIX_CHECK(PKIX_PL_Sprintf
michael@0 458 (&resultString,
michael@0 459 plContext,
michael@0 460 thisNodeFormat,
michael@0 461 indent,
michael@0 462 thisItemString),
michael@0 463 PKIX_ERRORINSPRINTF);
michael@0 464 } else {
michael@0 465 PKIX_CHECK(PKIX_PL_String_Create
michael@0 466 (PKIX_ESCASCII,
michael@0 467 "%s",
michael@0 468 0,
michael@0 469 &thisNodeFormat,
michael@0 470 plContext),
michael@0 471 PKIX_ERRORCREATINGFORMATSTRING);
michael@0 472
michael@0 473 PKIX_CHECK(PKIX_PL_Sprintf
michael@0 474 (&resultString,
michael@0 475 plContext,
michael@0 476 thisNodeFormat,
michael@0 477 thisItemString),
michael@0 478 PKIX_ERRORINSPRINTF);
michael@0 479 }
michael@0 480
michael@0 481 PKIX_DECREF(thisItemString);
michael@0 482 thisItemString = resultString;
michael@0 483
michael@0 484 /* if no children, we are done */
michael@0 485 if (rootNode->children) {
michael@0 486 PKIX_CHECK(PKIX_List_GetLength
michael@0 487 (rootNode->children, &numberOfChildren, plContext),
michael@0 488 PKIX_LISTGETLENGTHFAILED);
michael@0 489 }
michael@0 490
michael@0 491 if (numberOfChildren != 0) {
michael@0 492 /*
michael@0 493 * We create a string for each child in turn,
michael@0 494 * concatenating them to thisItemString.
michael@0 495 */
michael@0 496
michael@0 497 /* Prepare an indent string for each child */
michael@0 498 if (indent) {
michael@0 499 PKIX_CHECK(PKIX_PL_String_Create
michael@0 500 (PKIX_ESCASCII,
michael@0 501 "%s. ",
michael@0 502 0,
michael@0 503 &nextIndentFormat,
michael@0 504 plContext),
michael@0 505 PKIX_ERRORCREATINGFORMATSTRING);
michael@0 506
michael@0 507 PKIX_CHECK(PKIX_PL_Sprintf
michael@0 508 (&nextIndentString,
michael@0 509 plContext,
michael@0 510 nextIndentFormat,
michael@0 511 indent),
michael@0 512 PKIX_ERRORINSPRINTF);
michael@0 513 } else {
michael@0 514 PKIX_CHECK(PKIX_PL_String_Create
michael@0 515 (PKIX_ESCASCII,
michael@0 516 ". ",
michael@0 517 0,
michael@0 518 &nextIndentString,
michael@0 519 plContext),
michael@0 520 PKIX_ERRORCREATINGINDENTSTRING);
michael@0 521 }
michael@0 522
michael@0 523 /* Prepare the format for concatenation. */
michael@0 524 PKIX_CHECK(PKIX_PL_String_Create
michael@0 525 (PKIX_ESCASCII,
michael@0 526 "%s\n%s",
michael@0 527 0,
michael@0 528 &childrenFormat,
michael@0 529 plContext),
michael@0 530 PKIX_ERRORCREATINGFORMATSTRING);
michael@0 531
michael@0 532 for (childIndex = 0;
michael@0 533 childIndex < numberOfChildren;
michael@0 534 childIndex++) {
michael@0 535 PKIX_CHECK(PKIX_List_GetItem
michael@0 536 (rootNode->children,
michael@0 537 childIndex,
michael@0 538 (PKIX_PL_Object **)&childNode,
michael@0 539 plContext),
michael@0 540 PKIX_LISTGETITEMFAILED);
michael@0 541
michael@0 542 PKIX_CHECK(pkix_VerifyNode_ToString_Helper
michael@0 543 (childNode,
michael@0 544 nextIndentString,
michael@0 545 &childString,
michael@0 546 plContext),
michael@0 547 PKIX_ERRORCREATINGCHILDSTRING);
michael@0 548
michael@0 549
michael@0 550 PKIX_CHECK(PKIX_PL_Sprintf
michael@0 551 (&resultString,
michael@0 552 plContext,
michael@0 553 childrenFormat,
michael@0 554 thisItemString,
michael@0 555 childString),
michael@0 556 PKIX_ERRORINSPRINTF);
michael@0 557
michael@0 558 PKIX_DECREF(childNode);
michael@0 559 PKIX_DECREF(childString);
michael@0 560 PKIX_DECREF(thisItemString);
michael@0 561
michael@0 562 thisItemString = resultString;
michael@0 563 }
michael@0 564 }
michael@0 565
michael@0 566 *pTreeString = thisItemString;
michael@0 567
michael@0 568 cleanup:
michael@0 569 if (PKIX_ERROR_RECEIVED) {
michael@0 570 PKIX_DECREF(thisItemString);
michael@0 571 }
michael@0 572
michael@0 573 PKIX_DECREF(nextIndentFormat);
michael@0 574 PKIX_DECREF(thisNodeFormat);
michael@0 575 PKIX_DECREF(childrenFormat);
michael@0 576 PKIX_DECREF(nextIndentString);
michael@0 577 PKIX_DECREF(childString);
michael@0 578 PKIX_DECREF(childNode);
michael@0 579
michael@0 580 PKIX_RETURN(VERIFYNODE);
michael@0 581 }
michael@0 582
michael@0 583 /*
michael@0 584 * FUNCTION: pkix_VerifyNode_ToString
michael@0 585 * (see comments for PKIX_PL_ToStringCallback in pkix_pl_system.h)
michael@0 586 */
michael@0 587 static PKIX_Error *
michael@0 588 pkix_VerifyNode_ToString(
michael@0 589 PKIX_PL_Object *object,
michael@0 590 PKIX_PL_String **pTreeString,
michael@0 591 void *plContext)
michael@0 592 {
michael@0 593 PKIX_VerifyNode *rootNode = NULL;
michael@0 594 PKIX_PL_String *resultString = NULL;
michael@0 595
michael@0 596 PKIX_ENTER(VERIFYNODE, "pkix_VerifyNode_ToString");
michael@0 597
michael@0 598 PKIX_NULLCHECK_TWO(object, pTreeString);
michael@0 599
michael@0 600 PKIX_CHECK(pkix_CheckType(object, PKIX_VERIFYNODE_TYPE, plContext),
michael@0 601 PKIX_OBJECTNOTVERIFYNODE);
michael@0 602
michael@0 603 rootNode = (PKIX_VerifyNode *)object;
michael@0 604
michael@0 605 PKIX_CHECK(pkix_VerifyNode_ToString_Helper
michael@0 606 (rootNode, NULL, &resultString, plContext),
michael@0 607 PKIX_ERRORCREATINGSUBTREESTRING);
michael@0 608
michael@0 609 *pTreeString = resultString;
michael@0 610
michael@0 611 cleanup:
michael@0 612
michael@0 613 PKIX_RETURN(VERIFYNODE);
michael@0 614 }
michael@0 615
michael@0 616 /*
michael@0 617 * FUNCTION: pkix_VerifyNode_Destroy
michael@0 618 * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h)
michael@0 619 */
michael@0 620 static PKIX_Error *
michael@0 621 pkix_VerifyNode_Destroy(
michael@0 622 PKIX_PL_Object *object,
michael@0 623 void *plContext)
michael@0 624 {
michael@0 625 PKIX_VerifyNode *node = NULL;
michael@0 626
michael@0 627 PKIX_ENTER(VERIFYNODE, "pkix_VerifyNode_Destroy");
michael@0 628
michael@0 629 PKIX_NULLCHECK_ONE(object);
michael@0 630
michael@0 631 PKIX_CHECK(pkix_CheckType(object, PKIX_VERIFYNODE_TYPE, plContext),
michael@0 632 PKIX_OBJECTNOTVERIFYNODE);
michael@0 633
michael@0 634 node = (PKIX_VerifyNode*)object;
michael@0 635
michael@0 636 PKIX_DECREF(node->verifyCert);
michael@0 637 PKIX_DECREF(node->children);
michael@0 638 PKIX_DECREF(node->error);
michael@0 639
michael@0 640 node->depth = 0;
michael@0 641
michael@0 642 cleanup:
michael@0 643
michael@0 644 PKIX_RETURN(VERIFYNODE);
michael@0 645 }
michael@0 646
michael@0 647 /*
michael@0 648 * FUNCTION: pkix_SingleVerifyNode_Hashcode
michael@0 649 * DESCRIPTION:
michael@0 650 *
michael@0 651 * Computes the hashcode of the attributes of the VerifyNode pointed to by
michael@0 652 * "node", other than its parents and children, and stores the result at
michael@0 653 * "pHashcode".
michael@0 654 *
michael@0 655 * PARAMETERS:
michael@0 656 * "node"
michael@0 657 * Address of VerifyNode to be hashcoded; must be non-NULL
michael@0 658 * "pHashcode"
michael@0 659 * Address where UInt32 result will be stored; must be non-NULL
michael@0 660 * "plContext"
michael@0 661 * Platform-specific context pointer.
michael@0 662 * THREAD SAFETY:
michael@0 663 * Conditionally Thread Safe
michael@0 664 * (see Thread Safety Definitions in Programmer's Guide)
michael@0 665 * RETURNS:
michael@0 666 * Returns NULL if function succeeds
michael@0 667 * Returns a VerifyNode Error if the function fails in a non-fatal way.
michael@0 668 * Returns a Fatal Error if the function fails in a fatal way
michael@0 669 */
michael@0 670 static PKIX_Error *
michael@0 671 pkix_SingleVerifyNode_Hashcode(
michael@0 672 PKIX_VerifyNode *node,
michael@0 673 PKIX_UInt32 *pHashcode,
michael@0 674 void *plContext)
michael@0 675 {
michael@0 676 PKIX_UInt32 errorHash = 0;
michael@0 677 PKIX_UInt32 nodeHash = 0;
michael@0 678
michael@0 679 PKIX_ENTER(VERIFYNODE, "pkix_SingleVerifyNode_Hashcode");
michael@0 680 PKIX_NULLCHECK_TWO(node, pHashcode);
michael@0 681
michael@0 682 PKIX_HASHCODE
michael@0 683 (node->verifyCert,
michael@0 684 &nodeHash,
michael@0 685 plContext,
michael@0 686 PKIX_FAILUREHASHINGCERT);
michael@0 687
michael@0 688 PKIX_CHECK(PKIX_PL_Object_Hashcode
michael@0 689 ((PKIX_PL_Object *)node->error,
michael@0 690 &errorHash,
michael@0 691 plContext),
michael@0 692 PKIX_FAILUREHASHINGERROR);
michael@0 693
michael@0 694 nodeHash = 31*nodeHash + errorHash;
michael@0 695 *pHashcode = nodeHash;
michael@0 696
michael@0 697 cleanup:
michael@0 698
michael@0 699 PKIX_RETURN(VERIFYNODE);
michael@0 700 }
michael@0 701
michael@0 702 /*
michael@0 703 * FUNCTION: pkix_VerifyNode_Hashcode
michael@0 704 * (see comments for PKIX_PL_HashcodeCallback in pkix_pl_system.h)
michael@0 705 */
michael@0 706 static PKIX_Error *
michael@0 707 pkix_VerifyNode_Hashcode(
michael@0 708 PKIX_PL_Object *object,
michael@0 709 PKIX_UInt32 *pHashcode,
michael@0 710 void *plContext)
michael@0 711 {
michael@0 712 PKIX_VerifyNode *node = NULL;
michael@0 713 PKIX_UInt32 childrenHash = 0;
michael@0 714 PKIX_UInt32 nodeHash = 0;
michael@0 715
michael@0 716 PKIX_ENTER(VERIFYNODE, "pkix_VerifyNode_Hashcode");
michael@0 717 PKIX_NULLCHECK_TWO(object, pHashcode);
michael@0 718
michael@0 719 PKIX_CHECK(pkix_CheckType
michael@0 720 (object, PKIX_VERIFYNODE_TYPE, plContext),
michael@0 721 PKIX_OBJECTNOTVERIFYNODE);
michael@0 722
michael@0 723 node = (PKIX_VerifyNode *)object;
michael@0 724
michael@0 725 PKIX_CHECK(pkix_SingleVerifyNode_Hashcode
michael@0 726 (node, &nodeHash, plContext),
michael@0 727 PKIX_SINGLEVERIFYNODEHASHCODEFAILED);
michael@0 728
michael@0 729 PKIX_HASHCODE
michael@0 730 (node->children,
michael@0 731 &childrenHash,
michael@0 732 plContext,
michael@0 733 PKIX_OBJECTHASHCODEFAILED);
michael@0 734
michael@0 735 nodeHash = 31*nodeHash + childrenHash;
michael@0 736
michael@0 737 *pHashcode = nodeHash;
michael@0 738
michael@0 739 cleanup:
michael@0 740
michael@0 741 PKIX_RETURN(VERIFYNODE);
michael@0 742 }
michael@0 743
michael@0 744 /*
michael@0 745 * FUNCTION: pkix_SingleVerifyNode_Equals
michael@0 746 * DESCRIPTION:
michael@0 747 *
michael@0 748 * Compares for equality the components of the VerifyNode pointed to by
michael@0 749 * "firstPN", other than its parents and children, with those of the
michael@0 750 * VerifyNode pointed to by "secondPN" and stores the result at "pResult"
michael@0 751 * (PKIX_TRUE if equal; PKIX_FALSE if not).
michael@0 752 *
michael@0 753 * PARAMETERS:
michael@0 754 * "firstPN"
michael@0 755 * Address of first of the VerifyNodes to be compared; must be non-NULL
michael@0 756 * "secondPN"
michael@0 757 * Address of second of the VerifyNodes to be compared; must be non-NULL
michael@0 758 * "pResult"
michael@0 759 * Address where Boolean will be stored; must be non-NULL
michael@0 760 * "plContext"
michael@0 761 * Platform-specific context pointer.
michael@0 762 * THREAD SAFETY:
michael@0 763 * Conditionally Thread Safe
michael@0 764 * (see Thread Safety Definitions in Programmer's Guide)
michael@0 765 * RETURNS:
michael@0 766 * Returns NULL if function succeeds
michael@0 767 * Returns a VerifyNode Error if the function fails in a non-fatal way.
michael@0 768 * Returns a Fatal Error if the function fails in a fatal way
michael@0 769 */
michael@0 770 static PKIX_Error *
michael@0 771 pkix_SingleVerifyNode_Equals(
michael@0 772 PKIX_VerifyNode *firstVN,
michael@0 773 PKIX_VerifyNode *secondVN,
michael@0 774 PKIX_Boolean *pResult,
michael@0 775 void *plContext)
michael@0 776 {
michael@0 777 PKIX_Boolean compResult = PKIX_FALSE;
michael@0 778
michael@0 779 PKIX_ENTER(VERIFYNODE, "pkix_SingleVerifyNode_Equals");
michael@0 780 PKIX_NULLCHECK_THREE(firstVN, secondVN, pResult);
michael@0 781
michael@0 782 /* If both references are identical, they must be equal */
michael@0 783 if (firstVN == secondVN) {
michael@0 784 compResult = PKIX_TRUE;
michael@0 785 goto cleanup;
michael@0 786 }
michael@0 787
michael@0 788 /*
michael@0 789 * It seems we have to do the comparisons. Do
michael@0 790 * the easiest ones first.
michael@0 791 */
michael@0 792 if ((firstVN->depth) != (secondVN->depth)) {
michael@0 793 goto cleanup;
michael@0 794 }
michael@0 795
michael@0 796 /* These fields must be non-NULL */
michael@0 797 PKIX_NULLCHECK_TWO(firstVN->verifyCert, secondVN->verifyCert);
michael@0 798
michael@0 799 PKIX_EQUALS
michael@0 800 (firstVN->verifyCert,
michael@0 801 secondVN->verifyCert,
michael@0 802 &compResult,
michael@0 803 plContext,
michael@0 804 PKIX_OBJECTEQUALSFAILED);
michael@0 805
michael@0 806 if (compResult == PKIX_FALSE) {
michael@0 807 goto cleanup;
michael@0 808 }
michael@0 809
michael@0 810 PKIX_EQUALS
michael@0 811 (firstVN->error,
michael@0 812 secondVN->error,
michael@0 813 &compResult,
michael@0 814 plContext,
michael@0 815 PKIX_OBJECTEQUALSFAILED);
michael@0 816
michael@0 817 cleanup:
michael@0 818
michael@0 819 *pResult = compResult;
michael@0 820
michael@0 821 PKIX_RETURN(VERIFYNODE);
michael@0 822 }
michael@0 823
michael@0 824 /*
michael@0 825 * FUNCTION: pkix_VerifyNode_Equals
michael@0 826 * (see comments for PKIX_PL_Equals_Callback in pkix_pl_system.h)
michael@0 827 */
michael@0 828 static PKIX_Error *
michael@0 829 pkix_VerifyNode_Equals(
michael@0 830 PKIX_PL_Object *firstObject,
michael@0 831 PKIX_PL_Object *secondObject,
michael@0 832 PKIX_Boolean *pResult,
michael@0 833 void *plContext)
michael@0 834 {
michael@0 835 PKIX_VerifyNode *firstVN = NULL;
michael@0 836 PKIX_VerifyNode *secondVN = NULL;
michael@0 837 PKIX_UInt32 secondType;
michael@0 838 PKIX_Boolean compResult = PKIX_FALSE;
michael@0 839
michael@0 840 PKIX_ENTER(VERIFYNODE, "pkix_VerifyNode_Equals");
michael@0 841 PKIX_NULLCHECK_THREE(firstObject, secondObject, pResult);
michael@0 842
michael@0 843 /* test that firstObject is a VerifyNode */
michael@0 844 PKIX_CHECK(pkix_CheckType
michael@0 845 (firstObject, PKIX_VERIFYNODE_TYPE, plContext),
michael@0 846 PKIX_FIRSTOBJECTNOTVERIFYNODE);
michael@0 847
michael@0 848 /*
michael@0 849 * Since we know firstObject is a VerifyNode,
michael@0 850 * if both references are identical, they must be equal
michael@0 851 */
michael@0 852 if (firstObject == secondObject){
michael@0 853 compResult = PKIX_TRUE;
michael@0 854 goto cleanup;
michael@0 855 }
michael@0 856
michael@0 857 /*
michael@0 858 * If secondObject isn't a VerifyNode, we
michael@0 859 * don't throw an error. We simply return FALSE.
michael@0 860 */
michael@0 861 PKIX_CHECK(PKIX_PL_Object_GetType
michael@0 862 (secondObject, &secondType, plContext),
michael@0 863 PKIX_COULDNOTGETTYPEOFSECONDARGUMENT);
michael@0 864
michael@0 865 if (secondType != PKIX_VERIFYNODE_TYPE) {
michael@0 866 goto cleanup;
michael@0 867 }
michael@0 868
michael@0 869 /*
michael@0 870 * Oh, well, we have to do the comparisons. Do
michael@0 871 * the easiest ones first.
michael@0 872 */
michael@0 873 firstVN = (PKIX_VerifyNode *)firstObject;
michael@0 874 secondVN = (PKIX_VerifyNode *)secondObject;
michael@0 875
michael@0 876 PKIX_CHECK(pkix_SingleVerifyNode_Equals
michael@0 877 (firstVN, secondVN, &compResult, plContext),
michael@0 878 PKIX_SINGLEVERIFYNODEEQUALSFAILED);
michael@0 879
michael@0 880 if (compResult == PKIX_FALSE) {
michael@0 881 goto cleanup;
michael@0 882 }
michael@0 883
michael@0 884 PKIX_EQUALS
michael@0 885 (firstVN->children,
michael@0 886 secondVN->children,
michael@0 887 &compResult,
michael@0 888 plContext,
michael@0 889 PKIX_OBJECTEQUALSFAILEDONCHILDREN);
michael@0 890
michael@0 891 cleanup:
michael@0 892
michael@0 893 *pResult = compResult;
michael@0 894
michael@0 895 PKIX_RETURN(VERIFYNODE);
michael@0 896 }
michael@0 897
michael@0 898 /*
michael@0 899 * FUNCTION: pkix_VerifyNode_DuplicateHelper
michael@0 900 * DESCRIPTION:
michael@0 901 *
michael@0 902 * Duplicates the VerifyNode whose address is pointed to by "original",
michael@0 903 * and stores the result at "pNewNode", if a non-NULL pointer is provided
michael@0 904 * for "pNewNode". In addition, the created VerifyNode is added as a child
michael@0 905 * to "parent", if a non-NULL pointer is provided for "parent". Then this
michael@0 906 * function is called recursively to duplicate each of the children of
michael@0 907 * "original". At the top level this function is called with a null
michael@0 908 * "parent" and a non-NULL "pNewNode". Below the top level "parent" will
michael@0 909 * be non-NULL and "pNewNode" will be NULL.
michael@0 910 *
michael@0 911 * PARAMETERS:
michael@0 912 * "original"
michael@0 913 * Address of VerifyNode to be copied; must be non-NULL
michael@0 914 * "parent"
michael@0 915 * Address of VerifyNode to which the created node is to be added as a
michael@0 916 * child; NULL for the top-level call and non-NULL below the top level
michael@0 917 * "pNewNode"
michael@0 918 * Address to store the node created; should be NULL if "parent" is
michael@0 919 * non-NULL and vice versa
michael@0 920 * "plContext"
michael@0 921 * Platform-specific context pointer.
michael@0 922 * THREAD SAFETY:
michael@0 923 * Conditionally Thread Safe
michael@0 924 * (see Thread Safety Definitions in Programmer's Guide)
michael@0 925 * RETURNS:
michael@0 926 * Returns NULL if function succeeds
michael@0 927 * Returns a VerifyNode Error if the function fails in a non-fatal way.
michael@0 928 * Returns a Fatal Error if the function fails in a fatal way
michael@0 929 */
michael@0 930 static PKIX_Error *
michael@0 931 pkix_VerifyNode_DuplicateHelper(
michael@0 932 PKIX_VerifyNode *original,
michael@0 933 PKIX_VerifyNode *parent,
michael@0 934 PKIX_VerifyNode **pNewNode,
michael@0 935 void *plContext)
michael@0 936 {
michael@0 937 PKIX_UInt32 numChildren = 0;
michael@0 938 PKIX_UInt32 childIndex = 0;
michael@0 939 PKIX_List *children = NULL; /* List of PKIX_VerifyNode */
michael@0 940 PKIX_VerifyNode *copy = NULL;
michael@0 941 PKIX_VerifyNode *child = NULL;
michael@0 942
michael@0 943 PKIX_ENTER(VERIFYNODE, "pkix_VerifyNode_DuplicateHelper");
michael@0 944
michael@0 945 PKIX_NULLCHECK_TWO
michael@0 946 (original, original->verifyCert);
michael@0 947
michael@0 948 /*
michael@0 949 * These components are immutable, so copying the pointers
michael@0 950 * is sufficient. The create function increments the reference
michael@0 951 * counts as it stores the pointers into the new object.
michael@0 952 */
michael@0 953 PKIX_CHECK(pkix_VerifyNode_Create
michael@0 954 (original->verifyCert,
michael@0 955 original->depth,
michael@0 956 original->error,
michael@0 957 &copy,
michael@0 958 plContext),
michael@0 959 PKIX_VERIFYNODECREATEFAILED);
michael@0 960
michael@0 961 /* Are there any children to duplicate? */
michael@0 962 children = original->children;
michael@0 963
michael@0 964 if (children) {
michael@0 965 PKIX_CHECK(PKIX_List_GetLength(children, &numChildren, plContext),
michael@0 966 PKIX_LISTGETLENGTHFAILED);
michael@0 967 }
michael@0 968
michael@0 969 for (childIndex = 0; childIndex < numChildren; childIndex++) {
michael@0 970 PKIX_CHECK(PKIX_List_GetItem
michael@0 971 (children,
michael@0 972 childIndex,
michael@0 973 (PKIX_PL_Object **)&child,
michael@0 974 plContext),
michael@0 975 PKIX_LISTGETITEMFAILED);
michael@0 976
michael@0 977 PKIX_CHECK(pkix_VerifyNode_DuplicateHelper
michael@0 978 (child, copy, NULL, plContext),
michael@0 979 PKIX_VERIFYNODEDUPLICATEHELPERFAILED);
michael@0 980
michael@0 981 PKIX_DECREF(child);
michael@0 982 }
michael@0 983
michael@0 984 if (pNewNode) {
michael@0 985 *pNewNode = copy;
michael@0 986 copy = NULL; /* no DecRef if we give our handle away */
michael@0 987 }
michael@0 988
michael@0 989 cleanup:
michael@0 990 PKIX_DECREF(copy);
michael@0 991 PKIX_DECREF(child);
michael@0 992
michael@0 993 PKIX_RETURN(VERIFYNODE);
michael@0 994 }
michael@0 995
michael@0 996 /*
michael@0 997 * FUNCTION: pkix_VerifyNode_Duplicate
michael@0 998 * (see comments for PKIX_PL_Duplicate_Callback in pkix_pl_system.h)
michael@0 999 */
michael@0 1000 static PKIX_Error *
michael@0 1001 pkix_VerifyNode_Duplicate(
michael@0 1002 PKIX_PL_Object *object,
michael@0 1003 PKIX_PL_Object **pNewObject,
michael@0 1004 void *plContext)
michael@0 1005 {
michael@0 1006 PKIX_VerifyNode *original = NULL;
michael@0 1007 PKIX_VerifyNode *copy = NULL;
michael@0 1008
michael@0 1009 PKIX_ENTER(VERIFYNODE, "pkix_VerifyNode_Duplicate");
michael@0 1010
michael@0 1011 PKIX_NULLCHECK_TWO(object, pNewObject);
michael@0 1012
michael@0 1013 PKIX_CHECK(pkix_CheckType
michael@0 1014 (object, PKIX_VERIFYNODE_TYPE, plContext),
michael@0 1015 PKIX_OBJECTNOTVERIFYNODE);
michael@0 1016
michael@0 1017 original = (PKIX_VerifyNode *)object;
michael@0 1018
michael@0 1019 PKIX_CHECK(pkix_VerifyNode_DuplicateHelper
michael@0 1020 (original, NULL, &copy, plContext),
michael@0 1021 PKIX_VERIFYNODEDUPLICATEHELPERFAILED);
michael@0 1022
michael@0 1023 *pNewObject = (PKIX_PL_Object *)copy;
michael@0 1024
michael@0 1025 cleanup:
michael@0 1026
michael@0 1027 PKIX_RETURN(VERIFYNODE);
michael@0 1028 }
michael@0 1029
michael@0 1030 /*
michael@0 1031 * FUNCTION: pkix_VerifyNode_RegisterSelf
michael@0 1032 * DESCRIPTION:
michael@0 1033 *
michael@0 1034 * Registers PKIX_VERIFYNODE_TYPE and its related
michael@0 1035 * functions with systemClasses[]
michael@0 1036 *
michael@0 1037 * THREAD SAFETY:
michael@0 1038 * Not Thread Safe - for performance and complexity reasons
michael@0 1039 *
michael@0 1040 * Since this function is only called by PKIX_PL_Initialize,
michael@0 1041 * which should only be called once, it is acceptable that
michael@0 1042 * this function is not thread-safe.
michael@0 1043 */
michael@0 1044 PKIX_Error *
michael@0 1045 pkix_VerifyNode_RegisterSelf(void *plContext)
michael@0 1046 {
michael@0 1047
michael@0 1048 extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES];
michael@0 1049 pkix_ClassTable_Entry entry;
michael@0 1050
michael@0 1051 PKIX_ENTER(VERIFYNODE, "pkix_VerifyNode_RegisterSelf");
michael@0 1052
michael@0 1053 entry.description = "VerifyNode";
michael@0 1054 entry.objCounter = 0;
michael@0 1055 entry.typeObjectSize = sizeof(PKIX_VerifyNode);
michael@0 1056 entry.destructor = pkix_VerifyNode_Destroy;
michael@0 1057 entry.equalsFunction = pkix_VerifyNode_Equals;
michael@0 1058 entry.hashcodeFunction = pkix_VerifyNode_Hashcode;
michael@0 1059 entry.toStringFunction = pkix_VerifyNode_ToString;
michael@0 1060 entry.comparator = NULL;
michael@0 1061 entry.duplicateFunction = pkix_VerifyNode_Duplicate;
michael@0 1062
michael@0 1063 systemClasses[PKIX_VERIFYNODE_TYPE] = entry;
michael@0 1064
michael@0 1065 PKIX_RETURN(VERIFYNODE);
michael@0 1066 }
michael@0 1067
michael@0 1068 /* --Public-VerifyNode-Functions----------------------------------- */
michael@0 1069
michael@0 1070 /*
michael@0 1071 * FUNCTION: PKIX_VerifyNode_SetError
michael@0 1072 * DESCRIPTION:
michael@0 1073 *
michael@0 1074 * This function sets the Error field of the VerifyNode pointed to by "node"
michael@0 1075 * to contain the Error pointed to by "error".
michael@0 1076 *
michael@0 1077 * PARAMETERS:
michael@0 1078 * "node"
michael@0 1079 * The address of the VerifyNode to be modified. Must be non-NULL.
michael@0 1080 * "error"
michael@0 1081 * The address of the Error to be stored.
michael@0 1082 * "plContext"
michael@0 1083 * Platform-specific context pointer.
michael@0 1084 * THREAD SAFETY:
michael@0 1085 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
michael@0 1086 * RETURNS:
michael@0 1087 * Returns NULL if the function succeeds.
michael@0 1088 * Returns a Fatal Error if the function fails in an unrecoverable way.
michael@0 1089 */
michael@0 1090 PKIX_Error *
michael@0 1091 pkix_VerifyNode_SetError(
michael@0 1092 PKIX_VerifyNode *node,
michael@0 1093 PKIX_Error *error,
michael@0 1094 void *plContext)
michael@0 1095 {
michael@0 1096
michael@0 1097 PKIX_ENTER(VERIFYNODE, "PKIX_VerifyNode_SetError");
michael@0 1098
michael@0 1099 PKIX_NULLCHECK_TWO(node, error);
michael@0 1100
michael@0 1101 PKIX_DECREF(node->error); /* should have been NULL */
michael@0 1102 PKIX_INCREF(error);
michael@0 1103 node->error = error;
michael@0 1104
michael@0 1105 cleanup:
michael@0 1106 PKIX_RETURN(VERIFYNODE);
michael@0 1107 }
michael@0 1108
michael@0 1109 /*
michael@0 1110 * FUNCTION: PKIX_VerifyNode_FindError
michael@0 1111 * DESCRIPTION:
michael@0 1112 *
michael@0 1113 * Finds meaningful error in the log. For now, just returns the first
michael@0 1114 * error it finds in. In the future the function should be changed to
michael@0 1115 * return a top priority error.
michael@0 1116 *
michael@0 1117 * PARAMETERS:
michael@0 1118 * "node"
michael@0 1119 * The address of the VerifyNode to be modified. Must be non-NULL.
michael@0 1120 * "error"
michael@0 1121 * The address of a pointer the error will be returned to.
michael@0 1122 * "plContext"
michael@0 1123 * Platform-specific context pointer.
michael@0 1124 * THREAD SAFETY:
michael@0 1125 * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
michael@0 1126 * RETURNS:
michael@0 1127 * Returns NULL if the function succeeds.
michael@0 1128 * Returns a Fatal Error if the function fails in an unrecoverable way.
michael@0 1129 */
michael@0 1130 PKIX_Error *
michael@0 1131 pkix_VerifyNode_FindError(
michael@0 1132 PKIX_VerifyNode *node,
michael@0 1133 PKIX_Error **error,
michael@0 1134 void *plContext)
michael@0 1135 {
michael@0 1136 PKIX_VerifyNode *childNode = NULL;
michael@0 1137
michael@0 1138 PKIX_ENTER(VERIFYNODE, "PKIX_VerifyNode_FindError");
michael@0 1139
michael@0 1140 /* Make sure the return address is initialized with NULL */
michael@0 1141 PKIX_DECREF(*error);
michael@0 1142
michael@0 1143 if (!node)
michael@0 1144 goto cleanup;
michael@0 1145
michael@0 1146 /* First, try to get error from lowest level. */
michael@0 1147 if (node->children) {
michael@0 1148 PKIX_UInt32 length = 0;
michael@0 1149 PKIX_UInt32 index = 0;
michael@0 1150
michael@0 1151 PKIX_CHECK(
michael@0 1152 PKIX_List_GetLength(node->children, &length,
michael@0 1153 plContext),
michael@0 1154 PKIX_LISTGETLENGTHFAILED);
michael@0 1155 for (index = 0;index < length;index++) {
michael@0 1156 PKIX_CHECK(
michael@0 1157 PKIX_List_GetItem(node->children, index,
michael@0 1158 (PKIX_PL_Object**)&childNode, plContext),
michael@0 1159 PKIX_LISTGETITEMFAILED);
michael@0 1160 if (!childNode)
michael@0 1161 continue;
michael@0 1162 PKIX_CHECK(
michael@0 1163 pkix_VerifyNode_FindError(childNode, error,
michael@0 1164 plContext),
michael@0 1165 PKIX_VERIFYNODEFINDERRORFAILED);
michael@0 1166 PKIX_DECREF(childNode);
michael@0 1167 if (*error) {
michael@0 1168 goto cleanup;
michael@0 1169 }
michael@0 1170 }
michael@0 1171 }
michael@0 1172
michael@0 1173 if (node->error && node->error->plErr) {
michael@0 1174 PKIX_INCREF(node->error);
michael@0 1175 *error = node->error;
michael@0 1176 }
michael@0 1177
michael@0 1178 cleanup:
michael@0 1179 PKIX_DECREF(childNode);
michael@0 1180
michael@0 1181 PKIX_RETURN(VERIFYNODE);
michael@0 1182 }

mercurial