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

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rwxr-xr-x

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

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

mercurial