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