diff nss/lib/libpkix/pkix/results/pkix_verifynode.c @ 0:1e5118fa0cb1

This is NSS with a Cmake Buildsyste To compile a static NSS library for Windows we've used the Chromium-NSS fork and added a Cmake buildsystem to compile it statically for Windows. See README.chromium for chromium changes and README.trustbridge for our modifications.
author Andre Heinecke <andre.heinecke@intevation.de>
date Mon, 28 Jul 2014 10:47:06 +0200
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nss/lib/libpkix/pkix/results/pkix_verifynode.c	Mon Jul 28 10:47:06 2014 +0200
@@ -0,0 +1,1182 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+/*
+ * pkix_verifynode.c
+ *
+ * Verify Node Object Type Definition
+ *
+ */
+
+#include "pkix_verifynode.h"
+
+/* --Private-VerifyNode-Functions---------------------------------- */
+
+/*
+ * FUNCTION: pkix_VerifyNode_Create
+ * DESCRIPTION:
+ *
+ *  This function creates a VerifyNode using the Cert pointed to by "cert",
+ *  the depth given by "depth", and the Error pointed to by "error", storing
+ *  the result at "pObject".
+ *
+ * PARAMETERS
+ *  "cert"
+ *      Address of Cert for the node. Must be non-NULL
+ *  "depth"
+ *      UInt32 value of the depth for this node.
+ *  "error"
+ *      Address of Error for the node.
+ *  "pObject"
+ *      Address where the VerifyNode pointer will be stored. Must be non-NULL.
+ *  "plContext"
+ *      Platform-specific context pointer.
+ * THREAD SAFETY:
+ *  Thread Safe (see Thread Safety Definitions in Programmer's Guide)
+ * RETURNS:
+ *  Returns NULL if the function succeeds.
+ *  Returns a Fatal Error if the function fails in an unrecoverable way.
+ */
+PKIX_Error *
+pkix_VerifyNode_Create(
+        PKIX_PL_Cert *cert,
+        PKIX_UInt32 depth,
+        PKIX_Error *error,
+        PKIX_VerifyNode **pObject,
+        void *plContext)
+{
+        PKIX_VerifyNode *node = NULL;
+
+        PKIX_ENTER(VERIFYNODE, "pkix_VerifyNode_Create");
+        PKIX_NULLCHECK_TWO(cert, pObject);
+
+        PKIX_CHECK(PKIX_PL_Object_Alloc
+                (PKIX_VERIFYNODE_TYPE,
+                sizeof (PKIX_VerifyNode),
+                (PKIX_PL_Object **)&node,
+                plContext),
+                PKIX_COULDNOTCREATEVERIFYNODEOBJECT);
+
+        PKIX_INCREF(cert);
+        node->verifyCert = cert;
+
+        PKIX_INCREF(error);
+        node->error = error;
+
+        node->depth = depth;
+
+        node->children = NULL;
+
+        *pObject = node;
+        node = NULL;
+
+cleanup:
+
+        PKIX_DECREF(node);
+
+        PKIX_RETURN(VERIFYNODE);
+}
+
+/*
+ * FUNCTION: pkix_VerifyNode_AddToChain
+ * DESCRIPTION:
+ *
+ *  Adds the VerifyNode pointed to by "child", at the appropriate depth, to the
+ *  List of children of the VerifyNode pointed to by "parentNode". The chain of
+ *  VerifyNodes is traversed until a VerifyNode is found at a depth one less
+ *  than that specified in "child". An Error is returned if there is no parent
+ *  at a suitable depth.
+ *
+ *  If "parentNode" has a NULL pointer for the List of children, a new List is
+ *  created containing "child". Otherwise "child" is appended to the existing
+ *  List.
+ *
+ *  Depth, in this context, means distance from the root node, which
+ *  is at depth zero.
+ *
+ * PARAMETERS:
+ *  "parentNode"
+ *      Address of VerifyNode whose List of child VerifyNodes is to be
+ *      created or appended to. Must be non-NULL.
+ *  "child"
+ *      Address of VerifyNode to be added to parentNode's List. Must be
+ *      non-NULL.
+ *  "plContext"
+ *      Platform-specific context pointer.
+ * THREAD SAFETY:
+ *  Not Thread Safe (see Thread Safety Definitions in Programmer's Guide)
+ * RETURNS:
+ *  Returns NULL if the function succeeds.
+ *  Returns a VerifyNode Error if the function fails in a non-fatal way.
+ *  Returns a Fatal Error if the function fails in an unrecoverable way.
+ */
+PKIX_Error *
+pkix_VerifyNode_AddToChain(
+        PKIX_VerifyNode *parentNode,
+        PKIX_VerifyNode *child,
+        void *plContext)
+{
+        PKIX_VerifyNode *successor = NULL;
+        PKIX_List *listOfChildren = NULL;
+        PKIX_UInt32 numChildren = 0;
+        PKIX_UInt32 parentDepth = 0;
+
+        PKIX_ENTER(VERIFYNODE, "pkix_VerifyNode_AddToChain");
+        PKIX_NULLCHECK_TWO(parentNode, child);
+
+        parentDepth = parentNode->depth;
+        listOfChildren = parentNode->children;
+        if (listOfChildren == NULL) {
+
+                if (parentDepth != (child->depth - 1)) {
+                        PKIX_ERROR(PKIX_NODESMISSINGFROMCHAIN);
+                }
+
+                PKIX_CHECK(PKIX_List_Create(&listOfChildren, plContext),
+                        PKIX_LISTCREATEFAILED);
+
+                PKIX_CHECK(PKIX_List_AppendItem
+                        (listOfChildren, (PKIX_PL_Object *)child, plContext),
+                        PKIX_COULDNOTAPPENDCHILDTOPARENTSVERIFYNODELIST);
+
+                parentNode->children = listOfChildren;
+        } else {
+                /* get number of children */
+                PKIX_CHECK(PKIX_List_GetLength
+                        (listOfChildren, &numChildren, plContext),
+                        PKIX_LISTGETLENGTHFAILED);
+
+                if (numChildren != 1) {
+                        PKIX_ERROR(PKIX_AMBIGUOUSPARENTAGEOFVERIFYNODE);
+                }
+
+                /* successor = listOfChildren[0] */
+                PKIX_CHECK(PKIX_List_GetItem
+                        (listOfChildren,
+                        0,
+                        (PKIX_PL_Object **)&successor,
+                        plContext),
+                        PKIX_LISTGETITEMFAILED);
+
+                PKIX_CHECK(pkix_VerifyNode_AddToChain
+                        (successor, child, plContext),
+                        PKIX_VERIFYNODEADDTOCHAINFAILED);
+        }
+
+        PKIX_CHECK(PKIX_PL_Object_InvalidateCache
+                ((PKIX_PL_Object *)parentNode, plContext),
+                PKIX_OBJECTINVALIDATECACHEFAILED);
+
+cleanup:
+        PKIX_DECREF(successor);
+
+        PKIX_RETURN(VERIFYNODE);
+}
+
+/*
+ * FUNCTION: pkix_VerifyNode_SetDepth
+ * DESCRIPTION:
+ *
+ *  The function sets the depth field of each VerifyNode in the List "children"
+ *  to the value given by "depth", and recursively sets the depth of any
+ *  successive generations to the successive values.
+ *
+ * PARAMETERS:
+ *  "children"
+ *      The List of VerifyNodes. Must be non-NULL.
+ *  "depth"
+ *      The value of the depth field to be set in members of the List.
+ *  "plContext"
+ *      Platform-specific context pointer.
+ * THREAD SAFETY:
+ *  Thread Safe (see Thread Safety Definitions in Programmer's Guide)
+ * RETURNS:
+ *  Returns NULL if the function succeeds.
+ *  Returns a Fatal Error if the function fails in an unrecoverable way.
+ */
+static PKIX_Error *
+pkix_VerifyNode_SetDepth(PKIX_List *children,
+        PKIX_UInt32 depth,
+        void *plContext)
+{
+        PKIX_UInt32 numChildren = 0;
+        PKIX_UInt32 chIx = 0;
+        PKIX_VerifyNode *child = NULL;
+
+        PKIX_ENTER(VERIFYNODE, "pkix_VerifyNode_SetDepth");
+        PKIX_NULLCHECK_ONE(children);
+
+        PKIX_CHECK(PKIX_List_GetLength(children, &numChildren, plContext),
+                PKIX_LISTGETLENGTHFAILED);
+
+        for (chIx = 0; chIx < numChildren; chIx++) {
+               PKIX_CHECK(PKIX_List_GetItem
+                        (children, chIx, (PKIX_PL_Object **)&child, plContext),
+                        PKIX_LISTGETITEMFAILED);
+
+                child->depth = depth;
+
+                if (child->children != NULL) {
+                        PKIX_CHECK(pkix_VerifyNode_SetDepth
+                                (child->children, depth + 1, plContext),
+                                PKIX_VERIFYNODESETDEPTHFAILED);
+                }
+
+                PKIX_DECREF(child);
+        }
+
+cleanup:
+
+        PKIX_DECREF(child);
+
+        PKIX_RETURN(VERIFYNODE);
+}
+
+/*
+ * FUNCTION: pkix_VerifyNode_AddToTree
+ * DESCRIPTION:
+ *
+ *  Adds the VerifyNode pointed to by "child" to the List of children of the
+ *  VerifyNode pointed to by "parentNode". If "parentNode" has a NULL pointer
+ *  for the List of children, a new List is created containing "child".
+ *  Otherwise "child" is appended to the existing List. The depth field of
+ *  "child" is set to one more than the corresponding value in "parent", and
+ *  if the "child" itself has child nodes, their depth fields are updated
+ *  accordingly.
+ *
+ *  Depth, in this context, means distance from the root node, which
+ *  is at depth zero.
+ *
+ * PARAMETERS:
+ *  "parentNode"
+ *      Address of VerifyNode whose List of child VerifyNodes is to be
+ *      created or appended to. Must be non-NULL.
+ *  "child"
+ *      Address of VerifyNode to be added to parentNode's List. Must be
+ *      non-NULL.
+ *  "plContext"
+ *      Platform-specific context pointer.
+ * THREAD SAFETY:
+ *  Not Thread Safe (see Thread Safety Definitions in Programmer's Guide)
+ * RETURNS:
+ *  Returns NULL if the function succeeds.
+ *  Returns a Fatal Error if the function fails in an unrecoverable way.
+ */
+PKIX_Error *
+pkix_VerifyNode_AddToTree(
+        PKIX_VerifyNode *parentNode,
+        PKIX_VerifyNode *child,
+        void *plContext)
+{
+        PKIX_List *listOfChildren = NULL;
+        PKIX_UInt32 parentDepth = 0;
+
+        PKIX_ENTER(VERIFYNODE, "pkix_VerifyNode_AddToTree");
+        PKIX_NULLCHECK_TWO(parentNode, child);
+
+        parentDepth = parentNode->depth;
+        listOfChildren = parentNode->children;
+        if (listOfChildren == NULL) {
+
+                PKIX_CHECK(PKIX_List_Create(&listOfChildren, plContext),
+                        PKIX_LISTCREATEFAILED);
+
+                parentNode->children = listOfChildren;
+        }
+
+        child->depth = parentDepth + 1;
+
+        PKIX_CHECK(PKIX_List_AppendItem
+                (parentNode->children, (PKIX_PL_Object *)child, plContext),
+                PKIX_COULDNOTAPPENDCHILDTOPARENTSVERIFYNODELIST);
+
+        if (child->children != NULL) {
+                PKIX_CHECK(pkix_VerifyNode_SetDepth
+                        (child->children, child->depth + 1, plContext),
+                        PKIX_VERIFYNODESETDEPTHFAILED);
+        }
+
+
+cleanup:
+
+        PKIX_RETURN(VERIFYNODE);
+}
+
+/*
+ * FUNCTION: pkix_SingleVerifyNode_ToString
+ * DESCRIPTION:
+ *
+ *  Creates a String representation of the attributes of the VerifyNode pointed
+ *  to by "node", other than its children, and stores the result at "pString".
+ *
+ * PARAMETERS:
+ *  "node"
+ *      Address of VerifyNode to be described by the string. Must be non-NULL.
+ *  "pString"
+ *      Address where object pointer will be stored. Must be non-NULL.
+ *  "plContext"
+ *      Platform-specific context pointer.
+ * THREAD SAFETY:
+ *  Conditionally Thread Safe
+ *  (see Thread Safety Definitions in Programmer's Guide)
+ * RETURNS:
+ *  Returns NULL if function succeeds
+ *  Returns a VerifyNode Error if the function fails in a non-fatal way.
+ *  Returns a Fatal Error if the function fails in a fatal way
+ */
+PKIX_Error *
+pkix_SingleVerifyNode_ToString(
+        PKIX_VerifyNode *node,
+        PKIX_PL_String **pString,
+        void *plContext)
+{
+        PKIX_PL_String *fmtString = NULL;
+        PKIX_PL_String *errorString = NULL;
+        PKIX_PL_String *outString = NULL;
+
+        PKIX_PL_X500Name *issuerName = NULL;
+        PKIX_PL_X500Name *subjectName = NULL;
+        PKIX_PL_String *issuerString = NULL;
+        PKIX_PL_String *subjectString = NULL;
+
+        PKIX_ENTER(VERIFYNODE, "pkix_SingleVerifyNode_ToString");
+        PKIX_NULLCHECK_THREE(node, pString, node->verifyCert);
+
+        PKIX_TOSTRING(node->error, &errorString, plContext,
+                PKIX_ERRORTOSTRINGFAILED);
+
+        PKIX_CHECK(PKIX_PL_Cert_GetIssuer
+                (node->verifyCert, &issuerName, plContext),
+                PKIX_CERTGETISSUERFAILED);
+
+        PKIX_TOSTRING(issuerName, &issuerString, plContext,
+                PKIX_X500NAMETOSTRINGFAILED);
+
+        PKIX_CHECK(PKIX_PL_Cert_GetSubject
+                (node->verifyCert, &subjectName, plContext),
+                PKIX_CERTGETSUBJECTFAILED);
+
+        PKIX_TOSTRING(subjectName, &subjectString, plContext,
+                PKIX_X500NAMETOSTRINGFAILED);
+
+        PKIX_CHECK(PKIX_PL_String_Create
+                (PKIX_ESCASCII,
+                "CERT[Issuer:%s, Subject:%s], depth=%d, error=%s",
+                0,
+                &fmtString,
+                plContext),
+                PKIX_CANTCREATESTRING);
+
+        PKIX_CHECK(PKIX_PL_Sprintf
+                (&outString,
+                plContext,
+                fmtString,
+                issuerString,
+                subjectString,
+                node->depth,
+                errorString),
+                PKIX_SPRINTFFAILED);
+
+        *pString = outString;
+
+cleanup:
+
+        PKIX_DECREF(fmtString);
+        PKIX_DECREF(errorString);
+        PKIX_DECREF(issuerName);
+        PKIX_DECREF(subjectName);
+        PKIX_DECREF(issuerString);
+        PKIX_DECREF(subjectString);
+        PKIX_RETURN(VERIFYNODE);
+}
+
+/*
+ * FUNCTION: pkix_VerifyNode_ToString_Helper
+ * DESCRIPTION:
+ *
+ *  Produces a String representation of a VerifyNode tree below the VerifyNode
+ *  pointed to by "rootNode", with each line of output prefixed by the String
+ *  pointed to by "indent", and stores the result at "pTreeString". It is
+ *  called recursively, with ever-increasing indentation, for successively
+ *  lower nodes on the tree.
+ *
+ * PARAMETERS:
+ *  "rootNode"
+ *      Address of VerifyNode subtree. Must be non-NULL.
+ *  "indent"
+ *      Address of String to be prefixed to each line of output. May be NULL
+ *      if no indentation is desired
+ *  "pTreeString"
+ *      Address where the resulting String will be stored; must be non-NULL
+ *  "plContext"
+ *      Platform-specific context pointer.
+ * THREAD SAFETY:
+ *  Conditionally Thread Safe
+ *  (see Thread Safety Definitions in Programmer's Guide)
+ * RETURNS:
+ *  Returns NULL if the function succeeds.
+ *  Returns a VerifyNode Error if the function fails in a non-fatal way.
+ *  Returns a Fatal Error if the function fails in an unrecoverable way.
+ */
+static PKIX_Error *
+pkix_VerifyNode_ToString_Helper(
+        PKIX_VerifyNode *rootNode,
+        PKIX_PL_String *indent,
+        PKIX_PL_String **pTreeString,
+        void *plContext)
+{
+        PKIX_PL_String *nextIndentFormat = NULL;
+        PKIX_PL_String *thisNodeFormat = NULL;
+        PKIX_PL_String *childrenFormat = NULL;
+        PKIX_PL_String *nextIndentString = NULL;
+        PKIX_PL_String *resultString = NULL;
+        PKIX_PL_String *thisItemString = NULL;
+        PKIX_PL_String *childString = NULL;
+        PKIX_VerifyNode *childNode = NULL;
+        PKIX_UInt32 numberOfChildren = 0;
+        PKIX_UInt32 childIndex = 0;
+
+        PKIX_ENTER(VERIFYNODE, "pkix_VerifyNode_ToString_Helper");
+
+        PKIX_NULLCHECK_TWO(rootNode, pTreeString);
+
+        /* Create a string for this node */
+        PKIX_CHECK(pkix_SingleVerifyNode_ToString
+                (rootNode, &thisItemString, plContext),
+                PKIX_ERRORINSINGLEVERIFYNODETOSTRING);
+
+        if (indent) {
+                PKIX_CHECK(PKIX_PL_String_Create
+                        (PKIX_ESCASCII,
+                        "%s%s",
+                        0,
+                        &thisNodeFormat,
+                        plContext),
+                        PKIX_ERRORCREATINGFORMATSTRING);
+
+                PKIX_CHECK(PKIX_PL_Sprintf
+                        (&resultString,
+                        plContext,
+                        thisNodeFormat,
+                        indent,
+                        thisItemString),
+                        PKIX_ERRORINSPRINTF);
+        } else {
+                PKIX_CHECK(PKIX_PL_String_Create
+                        (PKIX_ESCASCII,
+                        "%s",
+                        0,
+                        &thisNodeFormat,
+                        plContext),
+                        PKIX_ERRORCREATINGFORMATSTRING);
+
+                PKIX_CHECK(PKIX_PL_Sprintf
+                        (&resultString,
+                        plContext,
+                        thisNodeFormat,
+                        thisItemString),
+                        PKIX_ERRORINSPRINTF);
+        }
+
+        PKIX_DECREF(thisItemString);
+        thisItemString = resultString;
+
+        /* if no children, we are done */
+        if (rootNode->children) {
+                PKIX_CHECK(PKIX_List_GetLength
+                        (rootNode->children, &numberOfChildren, plContext),
+                        PKIX_LISTGETLENGTHFAILED);
+        }
+
+        if (numberOfChildren != 0) {
+                /*
+                 * We create a string for each child in turn,
+                 * concatenating them to thisItemString.
+                 */
+
+                /* Prepare an indent string for each child */
+                if (indent) {
+                        PKIX_CHECK(PKIX_PL_String_Create
+                                (PKIX_ESCASCII,
+                                "%s. ",
+                                0,
+                                &nextIndentFormat,
+                                plContext),
+                                PKIX_ERRORCREATINGFORMATSTRING);
+
+                        PKIX_CHECK(PKIX_PL_Sprintf
+                                (&nextIndentString,
+                                plContext,
+                                nextIndentFormat,
+                                indent),
+                                PKIX_ERRORINSPRINTF);
+                } else {
+                        PKIX_CHECK(PKIX_PL_String_Create
+                                (PKIX_ESCASCII,
+                                ". ",
+                                0,
+                                &nextIndentString,
+                                plContext),
+                                PKIX_ERRORCREATINGINDENTSTRING);
+                }
+
+                /* Prepare the format for concatenation. */
+                PKIX_CHECK(PKIX_PL_String_Create
+                        (PKIX_ESCASCII,
+                        "%s\n%s",
+                        0,
+                        &childrenFormat,
+                        plContext),
+                        PKIX_ERRORCREATINGFORMATSTRING);
+
+                for (childIndex = 0;
+                        childIndex < numberOfChildren;
+                        childIndex++) {
+                        PKIX_CHECK(PKIX_List_GetItem
+                                (rootNode->children,
+                                childIndex,
+                                (PKIX_PL_Object **)&childNode,
+                                plContext),
+                                PKIX_LISTGETITEMFAILED);
+
+                        PKIX_CHECK(pkix_VerifyNode_ToString_Helper
+                                (childNode,
+                                nextIndentString,
+                                &childString,
+                                plContext),
+                                PKIX_ERRORCREATINGCHILDSTRING);
+
+
+                        PKIX_CHECK(PKIX_PL_Sprintf
+                                (&resultString,
+                                plContext,
+                                childrenFormat,
+                                thisItemString,
+                                childString),
+                        PKIX_ERRORINSPRINTF);
+
+                        PKIX_DECREF(childNode);
+                        PKIX_DECREF(childString);
+                        PKIX_DECREF(thisItemString);
+
+                        thisItemString = resultString;
+                }
+        }
+
+        *pTreeString = thisItemString;
+
+cleanup:
+        if (PKIX_ERROR_RECEIVED) {
+                PKIX_DECREF(thisItemString);
+        }
+
+        PKIX_DECREF(nextIndentFormat);
+        PKIX_DECREF(thisNodeFormat);
+        PKIX_DECREF(childrenFormat);
+        PKIX_DECREF(nextIndentString);
+        PKIX_DECREF(childString);
+        PKIX_DECREF(childNode);
+
+        PKIX_RETURN(VERIFYNODE);
+}
+
+/*
+ * FUNCTION: pkix_VerifyNode_ToString
+ * (see comments for PKIX_PL_ToStringCallback in pkix_pl_system.h)
+ */
+static PKIX_Error *
+pkix_VerifyNode_ToString(
+        PKIX_PL_Object *object,
+        PKIX_PL_String **pTreeString,
+        void *plContext)
+{
+        PKIX_VerifyNode *rootNode = NULL;
+        PKIX_PL_String *resultString = NULL;
+
+        PKIX_ENTER(VERIFYNODE, "pkix_VerifyNode_ToString");
+
+        PKIX_NULLCHECK_TWO(object, pTreeString);
+
+        PKIX_CHECK(pkix_CheckType(object, PKIX_VERIFYNODE_TYPE, plContext),
+                PKIX_OBJECTNOTVERIFYNODE);
+
+        rootNode = (PKIX_VerifyNode *)object;
+
+        PKIX_CHECK(pkix_VerifyNode_ToString_Helper
+                (rootNode, NULL, &resultString, plContext),
+                PKIX_ERRORCREATINGSUBTREESTRING);
+
+        *pTreeString = resultString;
+
+cleanup:
+
+        PKIX_RETURN(VERIFYNODE);
+}
+
+/*
+ * FUNCTION: pkix_VerifyNode_Destroy
+ * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h)
+ */
+static PKIX_Error *
+pkix_VerifyNode_Destroy(
+        PKIX_PL_Object *object,
+        void *plContext)
+{
+        PKIX_VerifyNode *node = NULL;
+
+        PKIX_ENTER(VERIFYNODE, "pkix_VerifyNode_Destroy");
+
+        PKIX_NULLCHECK_ONE(object);
+
+        PKIX_CHECK(pkix_CheckType(object, PKIX_VERIFYNODE_TYPE, plContext),
+                PKIX_OBJECTNOTVERIFYNODE);
+
+        node = (PKIX_VerifyNode*)object;
+
+        PKIX_DECREF(node->verifyCert);
+        PKIX_DECREF(node->children);
+        PKIX_DECREF(node->error);
+
+        node->depth = 0;
+
+cleanup:
+
+        PKIX_RETURN(VERIFYNODE);
+}
+
+/*
+ * FUNCTION: pkix_SingleVerifyNode_Hashcode
+ * DESCRIPTION:
+ *
+ *  Computes the hashcode of the attributes of the VerifyNode pointed to by
+ *  "node", other than its parents and children, and stores the result at
+ *  "pHashcode".
+ *
+ * PARAMETERS:
+ *  "node"
+ *      Address of VerifyNode to be hashcoded; must be non-NULL
+ *  "pHashcode"
+ *      Address where UInt32 result will be stored; must be non-NULL
+ *  "plContext"
+ *      Platform-specific context pointer.
+ * THREAD SAFETY:
+ *  Conditionally Thread Safe
+ *  (see Thread Safety Definitions in Programmer's Guide)
+ * RETURNS:
+ *  Returns NULL if function succeeds
+ *  Returns a VerifyNode Error if the function fails in a non-fatal way.
+ *  Returns a Fatal Error if the function fails in a fatal way
+ */
+static PKIX_Error *
+pkix_SingleVerifyNode_Hashcode(
+        PKIX_VerifyNode *node,
+        PKIX_UInt32 *pHashcode,
+        void *plContext)
+{
+        PKIX_UInt32 errorHash = 0;
+        PKIX_UInt32 nodeHash = 0;
+
+        PKIX_ENTER(VERIFYNODE, "pkix_SingleVerifyNode_Hashcode");
+        PKIX_NULLCHECK_TWO(node, pHashcode);
+
+        PKIX_HASHCODE
+                (node->verifyCert,
+                &nodeHash,
+                plContext,
+                PKIX_FAILUREHASHINGCERT);
+
+        PKIX_CHECK(PKIX_PL_Object_Hashcode
+                ((PKIX_PL_Object *)node->error,
+                &errorHash,
+                plContext),
+                PKIX_FAILUREHASHINGERROR);
+
+        nodeHash = 31*nodeHash + errorHash;
+        *pHashcode = nodeHash;
+
+cleanup:
+
+        PKIX_RETURN(VERIFYNODE);
+}
+
+/*
+ * FUNCTION: pkix_VerifyNode_Hashcode
+ * (see comments for PKIX_PL_HashcodeCallback in pkix_pl_system.h)
+ */
+static PKIX_Error *
+pkix_VerifyNode_Hashcode(
+        PKIX_PL_Object *object,
+        PKIX_UInt32 *pHashcode,
+        void *plContext)
+{
+        PKIX_VerifyNode *node = NULL;
+        PKIX_UInt32 childrenHash = 0;
+        PKIX_UInt32 nodeHash = 0;
+
+        PKIX_ENTER(VERIFYNODE, "pkix_VerifyNode_Hashcode");
+        PKIX_NULLCHECK_TWO(object, pHashcode);
+
+        PKIX_CHECK(pkix_CheckType
+                (object, PKIX_VERIFYNODE_TYPE, plContext),
+                PKIX_OBJECTNOTVERIFYNODE);
+
+        node = (PKIX_VerifyNode *)object;
+
+        PKIX_CHECK(pkix_SingleVerifyNode_Hashcode
+                (node, &nodeHash, plContext),
+                PKIX_SINGLEVERIFYNODEHASHCODEFAILED);
+
+        PKIX_HASHCODE
+                (node->children,
+                &childrenHash,
+                plContext,
+                PKIX_OBJECTHASHCODEFAILED);
+
+        nodeHash = 31*nodeHash + childrenHash;
+
+        *pHashcode = nodeHash;
+
+cleanup:
+
+        PKIX_RETURN(VERIFYNODE);
+}
+
+/*
+ * FUNCTION: pkix_SingleVerifyNode_Equals
+ * DESCRIPTION:
+ *
+ *  Compares for equality the components of the VerifyNode pointed to by
+ *  "firstPN", other than its parents and children, with those of the
+ *  VerifyNode pointed to by "secondPN" and stores the result at "pResult"
+ *  (PKIX_TRUE if equal; PKIX_FALSE if not).
+ *
+ * PARAMETERS:
+ *  "firstPN"
+ *      Address of first of the VerifyNodes to be compared; must be non-NULL
+ *  "secondPN"
+ *      Address of second of the VerifyNodes to be compared; must be non-NULL
+ *  "pResult"
+ *      Address where Boolean will be stored; must be non-NULL
+ *  "plContext"
+ *      Platform-specific context pointer.
+ * THREAD SAFETY:
+ *  Conditionally Thread Safe
+ *  (see Thread Safety Definitions in Programmer's Guide)
+ * RETURNS:
+ *  Returns NULL if function succeeds
+ *  Returns a VerifyNode Error if the function fails in a non-fatal way.
+ *  Returns a Fatal Error if the function fails in a fatal way
+ */
+static PKIX_Error *
+pkix_SingleVerifyNode_Equals(
+        PKIX_VerifyNode *firstVN,
+        PKIX_VerifyNode *secondVN,
+        PKIX_Boolean *pResult,
+        void *plContext)
+{
+        PKIX_Boolean compResult = PKIX_FALSE;
+
+        PKIX_ENTER(VERIFYNODE, "pkix_SingleVerifyNode_Equals");
+        PKIX_NULLCHECK_THREE(firstVN, secondVN, pResult);
+
+        /* If both references are identical, they must be equal */
+        if (firstVN == secondVN) {
+                compResult = PKIX_TRUE;
+                goto cleanup;
+        }
+
+        /*
+         * It seems we have to do the comparisons. Do
+         * the easiest ones first.
+         */
+        if ((firstVN->depth) != (secondVN->depth)) {
+                goto cleanup;
+        }
+
+        /* These fields must be non-NULL */
+        PKIX_NULLCHECK_TWO(firstVN->verifyCert, secondVN->verifyCert);
+
+        PKIX_EQUALS
+                (firstVN->verifyCert,
+                secondVN->verifyCert,
+                &compResult,
+                plContext,
+                PKIX_OBJECTEQUALSFAILED);
+
+        if (compResult == PKIX_FALSE) {
+                goto cleanup;
+        }
+
+        PKIX_EQUALS
+                (firstVN->error,
+                secondVN->error,
+                &compResult,
+                plContext,
+                PKIX_OBJECTEQUALSFAILED);
+
+cleanup:
+
+        *pResult = compResult;
+
+        PKIX_RETURN(VERIFYNODE);
+}
+
+/*
+ * FUNCTION: pkix_VerifyNode_Equals
+ * (see comments for PKIX_PL_Equals_Callback in pkix_pl_system.h)
+ */
+static PKIX_Error *
+pkix_VerifyNode_Equals(
+        PKIX_PL_Object *firstObject,
+        PKIX_PL_Object *secondObject,
+        PKIX_Boolean *pResult,
+        void *plContext)
+{
+        PKIX_VerifyNode *firstVN = NULL;
+        PKIX_VerifyNode *secondVN = NULL;
+        PKIX_UInt32 secondType;
+        PKIX_Boolean compResult = PKIX_FALSE;
+
+        PKIX_ENTER(VERIFYNODE, "pkix_VerifyNode_Equals");
+        PKIX_NULLCHECK_THREE(firstObject, secondObject, pResult);
+
+        /* test that firstObject is a VerifyNode */
+        PKIX_CHECK(pkix_CheckType
+                (firstObject, PKIX_VERIFYNODE_TYPE, plContext),
+                PKIX_FIRSTOBJECTNOTVERIFYNODE);
+
+        /*
+         * Since we know firstObject is a VerifyNode,
+         * if both references are identical, they must be equal
+         */
+        if (firstObject == secondObject){
+                compResult = PKIX_TRUE;
+                goto cleanup;
+        }
+
+        /*
+         * If secondObject isn't a VerifyNode, we
+         * don't throw an error. We simply return FALSE.
+         */
+        PKIX_CHECK(PKIX_PL_Object_GetType
+                    (secondObject, &secondType, plContext),
+                    PKIX_COULDNOTGETTYPEOFSECONDARGUMENT);
+
+        if (secondType != PKIX_VERIFYNODE_TYPE) {
+                goto cleanup;
+        }
+
+        /*
+         * Oh, well, we have to do the comparisons. Do
+         * the easiest ones first.
+         */
+        firstVN = (PKIX_VerifyNode *)firstObject;
+        secondVN = (PKIX_VerifyNode *)secondObject;
+
+        PKIX_CHECK(pkix_SingleVerifyNode_Equals
+                (firstVN, secondVN, &compResult, plContext),
+                PKIX_SINGLEVERIFYNODEEQUALSFAILED);
+
+        if (compResult == PKIX_FALSE) {
+                goto cleanup;
+        }
+
+        PKIX_EQUALS
+                (firstVN->children,
+                secondVN->children,
+                &compResult,
+                plContext,
+                PKIX_OBJECTEQUALSFAILEDONCHILDREN);
+
+cleanup:
+
+        *pResult = compResult;
+
+        PKIX_RETURN(VERIFYNODE);
+}
+
+/*
+ * FUNCTION: pkix_VerifyNode_DuplicateHelper
+ * DESCRIPTION:
+ *
+ *  Duplicates the VerifyNode whose address is pointed to by "original",
+ *  and stores the result at "pNewNode", if a non-NULL pointer is provided
+ *  for "pNewNode". In addition, the created VerifyNode is added as a child
+ *  to "parent", if a non-NULL pointer is provided for "parent". Then this
+ *  function is called recursively to duplicate each of the children of
+ *  "original". At the top level this function is called with a null
+ *  "parent" and a non-NULL "pNewNode". Below the top level "parent" will
+ *  be non-NULL and "pNewNode" will be NULL.
+ *
+ * PARAMETERS:
+ *  "original"
+ *      Address of VerifyNode to be copied; must be non-NULL
+ *  "parent"
+ *      Address of VerifyNode to which the created node is to be added as a
+ *      child; NULL for the top-level call and non-NULL below the top level
+ *  "pNewNode"
+ *      Address to store the node created; should be NULL if "parent" is
+ *      non-NULL and vice versa
+ *  "plContext"
+ *      Platform-specific context pointer.
+ * THREAD SAFETY:
+ *  Conditionally Thread Safe
+ *  (see Thread Safety Definitions in Programmer's Guide)
+ * RETURNS:
+ *  Returns NULL if function succeeds
+ *  Returns a VerifyNode Error if the function fails in a non-fatal way.
+ *  Returns a Fatal Error if the function fails in a fatal way
+ */
+static PKIX_Error *
+pkix_VerifyNode_DuplicateHelper(
+        PKIX_VerifyNode *original,
+        PKIX_VerifyNode *parent,
+        PKIX_VerifyNode **pNewNode,
+        void *plContext)
+{
+        PKIX_UInt32 numChildren = 0;
+        PKIX_UInt32 childIndex = 0;
+        PKIX_List *children = NULL; /* List of PKIX_VerifyNode */
+        PKIX_VerifyNode *copy = NULL;
+        PKIX_VerifyNode *child = NULL;
+
+        PKIX_ENTER(VERIFYNODE, "pkix_VerifyNode_DuplicateHelper");
+
+        PKIX_NULLCHECK_TWO
+                (original, original->verifyCert);
+
+        /*
+         * These components are immutable, so copying the pointers
+         * is sufficient. The create function increments the reference
+         * counts as it stores the pointers into the new object.
+         */
+        PKIX_CHECK(pkix_VerifyNode_Create
+                (original->verifyCert,
+                original->depth,
+                original->error,
+                &copy,
+                plContext),
+                PKIX_VERIFYNODECREATEFAILED);
+
+        /* Are there any children to duplicate? */
+        children = original->children;
+
+        if (children) {
+            PKIX_CHECK(PKIX_List_GetLength(children, &numChildren, plContext),
+                PKIX_LISTGETLENGTHFAILED);
+        }
+
+        for (childIndex = 0; childIndex < numChildren; childIndex++) {
+                PKIX_CHECK(PKIX_List_GetItem
+                        (children,
+                        childIndex,
+                        (PKIX_PL_Object **)&child,
+                        plContext),
+                        PKIX_LISTGETITEMFAILED);
+
+                PKIX_CHECK(pkix_VerifyNode_DuplicateHelper
+                        (child, copy, NULL, plContext),
+                        PKIX_VERIFYNODEDUPLICATEHELPERFAILED);
+
+                PKIX_DECREF(child);
+        }
+
+        if (pNewNode) {
+                *pNewNode = copy;
+                copy = NULL; /* no DecRef if we give our handle away */
+        }
+
+cleanup:
+        PKIX_DECREF(copy);
+        PKIX_DECREF(child);
+
+        PKIX_RETURN(VERIFYNODE);
+}
+
+/*
+ * FUNCTION: pkix_VerifyNode_Duplicate
+ * (see comments for PKIX_PL_Duplicate_Callback in pkix_pl_system.h)
+ */
+static PKIX_Error *
+pkix_VerifyNode_Duplicate(
+        PKIX_PL_Object *object,
+        PKIX_PL_Object **pNewObject,
+        void *plContext)
+{
+        PKIX_VerifyNode *original = NULL;
+        PKIX_VerifyNode *copy = NULL;
+
+        PKIX_ENTER(VERIFYNODE, "pkix_VerifyNode_Duplicate");
+
+        PKIX_NULLCHECK_TWO(object, pNewObject);
+
+        PKIX_CHECK(pkix_CheckType
+                (object, PKIX_VERIFYNODE_TYPE, plContext),
+                PKIX_OBJECTNOTVERIFYNODE);
+
+        original = (PKIX_VerifyNode *)object;
+
+        PKIX_CHECK(pkix_VerifyNode_DuplicateHelper
+                (original, NULL, &copy, plContext),
+                PKIX_VERIFYNODEDUPLICATEHELPERFAILED);
+
+        *pNewObject = (PKIX_PL_Object *)copy;
+
+cleanup:
+
+        PKIX_RETURN(VERIFYNODE);
+}
+
+/*
+ * FUNCTION: pkix_VerifyNode_RegisterSelf
+ * DESCRIPTION:
+ *
+ *  Registers PKIX_VERIFYNODE_TYPE and its related
+ *  functions with systemClasses[]
+ *
+ * THREAD SAFETY:
+ *  Not Thread Safe - for performance and complexity reasons
+ *
+ *  Since this function is only called by PKIX_PL_Initialize,
+ *  which should only be called once, it is acceptable that
+ *  this function is not thread-safe.
+ */
+PKIX_Error *
+pkix_VerifyNode_RegisterSelf(void *plContext)
+{
+
+        extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES];
+        pkix_ClassTable_Entry entry;
+
+        PKIX_ENTER(VERIFYNODE, "pkix_VerifyNode_RegisterSelf");
+
+        entry.description = "VerifyNode";
+        entry.objCounter = 0;
+        entry.typeObjectSize = sizeof(PKIX_VerifyNode);
+        entry.destructor = pkix_VerifyNode_Destroy;
+        entry.equalsFunction = pkix_VerifyNode_Equals;
+        entry.hashcodeFunction = pkix_VerifyNode_Hashcode;
+        entry.toStringFunction = pkix_VerifyNode_ToString;
+        entry.comparator = NULL;
+        entry.duplicateFunction = pkix_VerifyNode_Duplicate;
+
+        systemClasses[PKIX_VERIFYNODE_TYPE] = entry;
+
+        PKIX_RETURN(VERIFYNODE);
+}
+
+/* --Public-VerifyNode-Functions----------------------------------- */
+
+/*
+ * FUNCTION: PKIX_VerifyNode_SetError
+ * DESCRIPTION:
+ *
+ *  This function sets the Error field of the VerifyNode pointed to by "node"
+ *  to contain the Error pointed to by "error".
+ *
+ * PARAMETERS:
+ *  "node"
+ *      The address of the VerifyNode to be modified. Must be non-NULL.
+ *  "error"
+ *      The address of the Error to be stored.
+ *  "plContext"
+ *      Platform-specific context pointer.
+ * THREAD SAFETY:
+ *  Thread Safe (see Thread Safety Definitions in Programmer's Guide)
+ * RETURNS:
+ *  Returns NULL if the function succeeds.
+ *  Returns a Fatal Error if the function fails in an unrecoverable way.
+ */
+PKIX_Error *
+pkix_VerifyNode_SetError(
+        PKIX_VerifyNode *node,
+        PKIX_Error *error,
+        void *plContext)
+{
+
+        PKIX_ENTER(VERIFYNODE, "PKIX_VerifyNode_SetError");
+
+        PKIX_NULLCHECK_TWO(node, error);
+
+        PKIX_DECREF(node->error); /* should have been NULL */
+        PKIX_INCREF(error);
+        node->error = error;
+
+cleanup:
+        PKIX_RETURN(VERIFYNODE);
+}
+
+/*
+ * FUNCTION: PKIX_VerifyNode_FindError
+ * DESCRIPTION:
+ *
+ * Finds meaningful error in the log. For now, just returns the first
+ * error it finds in. In the future the function should be changed to
+ * return a top priority error.
+ *
+ * PARAMETERS:
+ *  "node"
+ *      The address of the VerifyNode to be modified. Must be non-NULL.
+ *  "error"
+ *      The address of a pointer the error will be returned to.
+ *  "plContext"
+ *      Platform-specific context pointer.
+ * THREAD SAFETY:
+ *  Thread Safe (see Thread Safety Definitions in Programmer's Guide)
+ * RETURNS:
+ *  Returns NULL if the function succeeds.
+ *  Returns a Fatal Error if the function fails in an unrecoverable way.
+ */
+PKIX_Error *
+pkix_VerifyNode_FindError(
+        PKIX_VerifyNode *node,
+        PKIX_Error **error,
+        void *plContext)
+{
+    PKIX_VerifyNode *childNode = NULL;
+
+    PKIX_ENTER(VERIFYNODE, "PKIX_VerifyNode_FindError");
+
+    /* Make sure the return address is initialized with NULL */
+    PKIX_DECREF(*error);
+
+    if (!node)
+        goto cleanup;
+    
+    /* First, try to get error from lowest level. */
+    if (node->children) {
+        PKIX_UInt32 length = 0;
+        PKIX_UInt32 index = 0;
+
+        PKIX_CHECK(
+            PKIX_List_GetLength(node->children, &length,
+                                plContext),
+            PKIX_LISTGETLENGTHFAILED);
+        for (index = 0;index < length;index++) {
+            PKIX_CHECK(
+                PKIX_List_GetItem(node->children, index,
+                                  (PKIX_PL_Object**)&childNode, plContext),
+                PKIX_LISTGETITEMFAILED);
+            if (!childNode)
+                continue;
+            PKIX_CHECK(
+                pkix_VerifyNode_FindError(childNode, error,
+                                          plContext),
+                PKIX_VERIFYNODEFINDERRORFAILED);
+            PKIX_DECREF(childNode);
+            if (*error) {
+                goto cleanup;
+            }
+        }
+    }
+    
+    if (node->error && node->error->plErr) {
+        PKIX_INCREF(node->error);
+        *error = node->error;
+    }
+
+cleanup:
+    PKIX_DECREF(childNode);
+    
+    PKIX_RETURN(VERIFYNODE);
+}
This site is hosted by Intevation GmbH (Datenschutzerklärung und Impressum | Privacy Policy and Imprint)