Quellcodebibliothek Statistik Leitseite products/sources/formale Sprachen/C/Firefox/security/nss/lib/libpkix/pkix/results/   (Browser von der Mozilla Stiftung Version 136.0.1©)  Datei vom 10.2.2025 mit Größe 35 kB image not shown  

Quelle  pkix_verifynode.c   Sprache: C

 
/* 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,
                ©,
                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, ©, 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);
}

Messung V0.5
C=95 H=90 G=92

¤ Dauer der Verarbeitung: 0.4 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.