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

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

mercurial