summaryrefslogtreecommitdiffstats
path: root/security/nss/lib/libpkix/pkix/results/pkix_verifynode.c
diff options
context:
space:
mode:
Diffstat (limited to 'security/nss/lib/libpkix/pkix/results/pkix_verifynode.c')
-rw-r--r--security/nss/lib/libpkix/pkix/results/pkix_verifynode.c1182
1 files changed, 1182 insertions, 0 deletions
diff --git a/security/nss/lib/libpkix/pkix/results/pkix_verifynode.c b/security/nss/lib/libpkix/pkix/results/pkix_verifynode.c
new file mode 100644
index 0000000000..b52f83fcab
--- /dev/null
+++ b/security/nss/lib/libpkix/pkix/results/pkix_verifynode.c
@@ -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);
+}