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

This is NSS with a Cmake Buildsyste To compile a static NSS library for Windows we've used the Chromium-NSS fork and added a Cmake buildsystem to compile it statically for Windows. See README.chromium for chromium changes and README.trustbridge for our modifications.
author Andre Heinecke <andre.heinecke@intevation.de>
date Mon, 28 Jul 2014 10:47:06 +0200
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:1e5118fa0cb1
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 */
10
11 #include "pkix_verifynode.h"
12
13 /* --Private-VerifyNode-Functions---------------------------------- */
14
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;
49
50 PKIX_ENTER(VERIFYNODE, "pkix_VerifyNode_Create");
51 PKIX_NULLCHECK_TWO(cert, pObject);
52
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);
59
60 PKIX_INCREF(cert);
61 node->verifyCert = cert;
62
63 PKIX_INCREF(error);
64 node->error = error;
65
66 node->depth = depth;
67
68 node->children = NULL;
69
70 *pObject = node;
71 node = NULL;
72
73 cleanup:
74
75 PKIX_DECREF(node);
76
77 PKIX_RETURN(VERIFYNODE);
78 }
79
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;
123
124 PKIX_ENTER(VERIFYNODE, "pkix_VerifyNode_AddToChain");
125 PKIX_NULLCHECK_TWO(parentNode, child);
126
127 parentDepth = parentNode->depth;
128 listOfChildren = parentNode->children;
129 if (listOfChildren == NULL) {
130
131 if (parentDepth != (child->depth - 1)) {
132 PKIX_ERROR(PKIX_NODESMISSINGFROMCHAIN);
133 }
134
135 PKIX_CHECK(PKIX_List_Create(&listOfChildren, plContext),
136 PKIX_LISTCREATEFAILED);
137
138 PKIX_CHECK(PKIX_List_AppendItem
139 (listOfChildren, (PKIX_PL_Object *)child, plContext),
140 PKIX_COULDNOTAPPENDCHILDTOPARENTSVERIFYNODELIST);
141
142 parentNode->children = listOfChildren;
143 } else {
144 /* get number of children */
145 PKIX_CHECK(PKIX_List_GetLength
146 (listOfChildren, &numChildren, plContext),
147 PKIX_LISTGETLENGTHFAILED);
148
149 if (numChildren != 1) {
150 PKIX_ERROR(PKIX_AMBIGUOUSPARENTAGEOFVERIFYNODE);
151 }
152
153 /* successor = listOfChildren[0] */
154 PKIX_CHECK(PKIX_List_GetItem
155 (listOfChildren,
156 0,
157 (PKIX_PL_Object **)&successor,
158 plContext),
159 PKIX_LISTGETITEMFAILED);
160
161 PKIX_CHECK(pkix_VerifyNode_AddToChain
162 (successor, child, plContext),
163 PKIX_VERIFYNODEADDTOCHAINFAILED);
164 }
165
166 PKIX_CHECK(PKIX_PL_Object_InvalidateCache
167 ((PKIX_PL_Object *)parentNode, plContext),
168 PKIX_OBJECTINVALIDATECACHEFAILED);
169
170 cleanup:
171 PKIX_DECREF(successor);
172
173 PKIX_RETURN(VERIFYNODE);
174 }
175
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;
205
206 PKIX_ENTER(VERIFYNODE, "pkix_VerifyNode_SetDepth");
207 PKIX_NULLCHECK_ONE(children);
208
209 PKIX_CHECK(PKIX_List_GetLength(children, &numChildren, plContext),
210 PKIX_LISTGETLENGTHFAILED);
211
212 for (chIx = 0; chIx < numChildren; chIx++) {
213 PKIX_CHECK(PKIX_List_GetItem
214 (children, chIx, (PKIX_PL_Object **)&child, plContext),
215 PKIX_LISTGETITEMFAILED);
216
217 child->depth = depth;
218
219 if (child->children != NULL) {
220 PKIX_CHECK(pkix_VerifyNode_SetDepth
221 (child->children, depth + 1, plContext),
222 PKIX_VERIFYNODESETDEPTHFAILED);
223 }
224
225 PKIX_DECREF(child);
226 }
227
228 cleanup:
229
230 PKIX_DECREF(child);
231
232 PKIX_RETURN(VERIFYNODE);
233 }
234
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;
273
274 PKIX_ENTER(VERIFYNODE, "pkix_VerifyNode_AddToTree");
275 PKIX_NULLCHECK_TWO(parentNode, child);
276
277 parentDepth = parentNode->depth;
278 listOfChildren = parentNode->children;
279 if (listOfChildren == NULL) {
280
281 PKIX_CHECK(PKIX_List_Create(&listOfChildren, plContext),
282 PKIX_LISTCREATEFAILED);
283
284 parentNode->children = listOfChildren;
285 }
286
287 child->depth = parentDepth + 1;
288
289 PKIX_CHECK(PKIX_List_AppendItem
290 (parentNode->children, (PKIX_PL_Object *)child, plContext),
291 PKIX_COULDNOTAPPENDCHILDTOPARENTSVERIFYNODELIST);
292
293 if (child->children != NULL) {
294 PKIX_CHECK(pkix_VerifyNode_SetDepth
295 (child->children, child->depth + 1, plContext),
296 PKIX_VERIFYNODESETDEPTHFAILED);
297 }
298
299
300 cleanup:
301
302 PKIX_RETURN(VERIFYNODE);
303 }
304
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;
336
337 PKIX_PL_X500Name *issuerName = NULL;
338 PKIX_PL_X500Name *subjectName = NULL;
339 PKIX_PL_String *issuerString = NULL;
340 PKIX_PL_String *subjectString = NULL;
341
342 PKIX_ENTER(VERIFYNODE, "pkix_SingleVerifyNode_ToString");
343 PKIX_NULLCHECK_THREE(node, pString, node->verifyCert);
344
345 PKIX_TOSTRING(node->error, &errorString, plContext,
346 PKIX_ERRORTOSTRINGFAILED);
347
348 PKIX_CHECK(PKIX_PL_Cert_GetIssuer
349 (node->verifyCert, &issuerName, plContext),
350 PKIX_CERTGETISSUERFAILED);
351
352 PKIX_TOSTRING(issuerName, &issuerString, plContext,
353 PKIX_X500NAMETOSTRINGFAILED);
354
355 PKIX_CHECK(PKIX_PL_Cert_GetSubject
356 (node->verifyCert, &subjectName, plContext),
357 PKIX_CERTGETSUBJECTFAILED);
358
359 PKIX_TOSTRING(subjectName, &subjectString, plContext,
360 PKIX_X500NAMETOSTRINGFAILED);
361
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);
369
370 PKIX_CHECK(PKIX_PL_Sprintf
371 (&outString,
372 plContext,
373 fmtString,
374 issuerString,
375 subjectString,
376 node->depth,
377 errorString),
378 PKIX_SPRINTFFAILED);
379
380 *pString = outString;
381
382 cleanup:
383
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 }
392
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;
438
439 PKIX_ENTER(VERIFYNODE, "pkix_VerifyNode_ToString_Helper");
440
441 PKIX_NULLCHECK_TWO(rootNode, pTreeString);
442
443 /* Create a string for this node */
444 PKIX_CHECK(pkix_SingleVerifyNode_ToString
445 (rootNode, &thisItemString, plContext),
446 PKIX_ERRORINSINGLEVERIFYNODETOSTRING);
447
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);
456
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);
472
473 PKIX_CHECK(PKIX_PL_Sprintf
474 (&resultString,
475 plContext,
476 thisNodeFormat,
477 thisItemString),
478 PKIX_ERRORINSPRINTF);
479 }
480
481 PKIX_DECREF(thisItemString);
482 thisItemString = resultString;
483
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 }
490
491 if (numberOfChildren != 0) {
492 /*
493 * We create a string for each child in turn,
494 * concatenating them to thisItemString.
495 */
496
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);
506
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 }
522
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);
531
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);
541
542 PKIX_CHECK(pkix_VerifyNode_ToString_Helper
543 (childNode,
544 nextIndentString,
545 &childString,
546 plContext),
547 PKIX_ERRORCREATINGCHILDSTRING);
548
549
550 PKIX_CHECK(PKIX_PL_Sprintf
551 (&resultString,
552 plContext,
553 childrenFormat,
554 thisItemString,
555 childString),
556 PKIX_ERRORINSPRINTF);
557
558 PKIX_DECREF(childNode);
559 PKIX_DECREF(childString);
560 PKIX_DECREF(thisItemString);
561
562 thisItemString = resultString;
563 }
564 }
565
566 *pTreeString = thisItemString;
567
568 cleanup:
569 if (PKIX_ERROR_RECEIVED) {
570 PKIX_DECREF(thisItemString);
571 }
572
573 PKIX_DECREF(nextIndentFormat);
574 PKIX_DECREF(thisNodeFormat);
575 PKIX_DECREF(childrenFormat);
576 PKIX_DECREF(nextIndentString);
577 PKIX_DECREF(childString);
578 PKIX_DECREF(childNode);
579
580 PKIX_RETURN(VERIFYNODE);
581 }
582
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;
595
596 PKIX_ENTER(VERIFYNODE, "pkix_VerifyNode_ToString");
597
598 PKIX_NULLCHECK_TWO(object, pTreeString);
599
600 PKIX_CHECK(pkix_CheckType(object, PKIX_VERIFYNODE_TYPE, plContext),
601 PKIX_OBJECTNOTVERIFYNODE);
602
603 rootNode = (PKIX_VerifyNode *)object;
604
605 PKIX_CHECK(pkix_VerifyNode_ToString_Helper
606 (rootNode, NULL, &resultString, plContext),
607 PKIX_ERRORCREATINGSUBTREESTRING);
608
609 *pTreeString = resultString;
610
611 cleanup:
612
613 PKIX_RETURN(VERIFYNODE);
614 }
615
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;
626
627 PKIX_ENTER(VERIFYNODE, "pkix_VerifyNode_Destroy");
628
629 PKIX_NULLCHECK_ONE(object);
630
631 PKIX_CHECK(pkix_CheckType(object, PKIX_VERIFYNODE_TYPE, plContext),
632 PKIX_OBJECTNOTVERIFYNODE);
633
634 node = (PKIX_VerifyNode*)object;
635
636 PKIX_DECREF(node->verifyCert);
637 PKIX_DECREF(node->children);
638 PKIX_DECREF(node->error);
639
640 node->depth = 0;
641
642 cleanup:
643
644 PKIX_RETURN(VERIFYNODE);
645 }
646
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;
678
679 PKIX_ENTER(VERIFYNODE, "pkix_SingleVerifyNode_Hashcode");
680 PKIX_NULLCHECK_TWO(node, pHashcode);
681
682 PKIX_HASHCODE
683 (node->verifyCert,
684 &nodeHash,
685 plContext,
686 PKIX_FAILUREHASHINGCERT);
687
688 PKIX_CHECK(PKIX_PL_Object_Hashcode
689 ((PKIX_PL_Object *)node->error,
690 &errorHash,
691 plContext),
692 PKIX_FAILUREHASHINGERROR);
693
694 nodeHash = 31*nodeHash + errorHash;
695 *pHashcode = nodeHash;
696
697 cleanup:
698
699 PKIX_RETURN(VERIFYNODE);
700 }
701
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;
715
716 PKIX_ENTER(VERIFYNODE, "pkix_VerifyNode_Hashcode");
717 PKIX_NULLCHECK_TWO(object, pHashcode);
718
719 PKIX_CHECK(pkix_CheckType
720 (object, PKIX_VERIFYNODE_TYPE, plContext),
721 PKIX_OBJECTNOTVERIFYNODE);
722
723 node = (PKIX_VerifyNode *)object;
724
725 PKIX_CHECK(pkix_SingleVerifyNode_Hashcode
726 (node, &nodeHash, plContext),
727 PKIX_SINGLEVERIFYNODEHASHCODEFAILED);
728
729 PKIX_HASHCODE
730 (node->children,
731 &childrenHash,
732 plContext,
733 PKIX_OBJECTHASHCODEFAILED);
734
735 nodeHash = 31*nodeHash + childrenHash;
736
737 *pHashcode = nodeHash;
738
739 cleanup:
740
741 PKIX_RETURN(VERIFYNODE);
742 }
743
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;
778
779 PKIX_ENTER(VERIFYNODE, "pkix_SingleVerifyNode_Equals");
780 PKIX_NULLCHECK_THREE(firstVN, secondVN, pResult);
781
782 /* If both references are identical, they must be equal */
783 if (firstVN == secondVN) {
784 compResult = PKIX_TRUE;
785 goto cleanup;
786 }
787
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 }
795
796 /* These fields must be non-NULL */
797 PKIX_NULLCHECK_TWO(firstVN->verifyCert, secondVN->verifyCert);
798
799 PKIX_EQUALS
800 (firstVN->verifyCert,
801 secondVN->verifyCert,
802 &compResult,
803 plContext,
804 PKIX_OBJECTEQUALSFAILED);
805
806 if (compResult == PKIX_FALSE) {
807 goto cleanup;
808 }
809
810 PKIX_EQUALS
811 (firstVN->error,
812 secondVN->error,
813 &compResult,
814 plContext,
815 PKIX_OBJECTEQUALSFAILED);
816
817 cleanup:
818
819 *pResult = compResult;
820
821 PKIX_RETURN(VERIFYNODE);
822 }
823
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;
839
840 PKIX_ENTER(VERIFYNODE, "pkix_VerifyNode_Equals");
841 PKIX_NULLCHECK_THREE(firstObject, secondObject, pResult);
842
843 /* test that firstObject is a VerifyNode */
844 PKIX_CHECK(pkix_CheckType
845 (firstObject, PKIX_VERIFYNODE_TYPE, plContext),
846 PKIX_FIRSTOBJECTNOTVERIFYNODE);
847
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 }
856
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);
864
865 if (secondType != PKIX_VERIFYNODE_TYPE) {
866 goto cleanup;
867 }
868
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;
875
876 PKIX_CHECK(pkix_SingleVerifyNode_Equals
877 (firstVN, secondVN, &compResult, plContext),
878 PKIX_SINGLEVERIFYNODEEQUALSFAILED);
879
880 if (compResult == PKIX_FALSE) {
881 goto cleanup;
882 }
883
884 PKIX_EQUALS
885 (firstVN->children,
886 secondVN->children,
887 &compResult,
888 plContext,
889 PKIX_OBJECTEQUALSFAILEDONCHILDREN);
890
891 cleanup:
892
893 *pResult = compResult;
894
895 PKIX_RETURN(VERIFYNODE);
896 }
897
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;
942
943 PKIX_ENTER(VERIFYNODE, "pkix_VerifyNode_DuplicateHelper");
944
945 PKIX_NULLCHECK_TWO
946 (original, original->verifyCert);
947
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);
960
961 /* Are there any children to duplicate? */
962 children = original->children;
963
964 if (children) {
965 PKIX_CHECK(PKIX_List_GetLength(children, &numChildren, plContext),
966 PKIX_LISTGETLENGTHFAILED);
967 }
968
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);
976
977 PKIX_CHECK(pkix_VerifyNode_DuplicateHelper
978 (child, copy, NULL, plContext),
979 PKIX_VERIFYNODEDUPLICATEHELPERFAILED);
980
981 PKIX_DECREF(child);
982 }
983
984 if (pNewNode) {
985 *pNewNode = copy;
986 copy = NULL; /* no DecRef if we give our handle away */
987 }
988
989 cleanup:
990 PKIX_DECREF(copy);
991 PKIX_DECREF(child);
992
993 PKIX_RETURN(VERIFYNODE);
994 }
995
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)
1005 {
1006 PKIX_VerifyNode *original = NULL;
1007 PKIX_VerifyNode *copy = NULL;
1008
1009 PKIX_ENTER(VERIFYNODE, "pkix_VerifyNode_Duplicate");
1010
1011 PKIX_NULLCHECK_TWO(object, pNewObject);
1012
1013 PKIX_CHECK(pkix_CheckType
1014 (object, PKIX_VERIFYNODE_TYPE, plContext),
1015 PKIX_OBJECTNOTVERIFYNODE);
1016
1017 original = (PKIX_VerifyNode *)object;
1018
1019 PKIX_CHECK(pkix_VerifyNode_DuplicateHelper
1020 (original, NULL, &copy, plContext),
1021 PKIX_VERIFYNODEDUPLICATEHELPERFAILED);
1022
1023 *pNewObject = (PKIX_PL_Object *)copy;
1024
1025 cleanup:
1026
1027 PKIX_RETURN(VERIFYNODE);
1028 }
1029
1030 /*
1031 * FUNCTION: pkix_VerifyNode_RegisterSelf
1032 * DESCRIPTION:
1033 *
1034 * Registers PKIX_VERIFYNODE_TYPE and its related
1035 * functions with systemClasses[]
1036 *
1037 * THREAD SAFETY:
1038 * Not Thread Safe - for performance and complexity reasons
1039 *
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)
1046 {
1047
1048 extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES];
1049 pkix_ClassTable_Entry entry;
1050
1051 PKIX_ENTER(VERIFYNODE, "pkix_VerifyNode_RegisterSelf");
1052
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;
1062
1063 systemClasses[PKIX_VERIFYNODE_TYPE] = entry;
1064
1065 PKIX_RETURN(VERIFYNODE);
1066 }
1067
1068 /* --Public-VerifyNode-Functions----------------------------------- */
1069
1070 /*
1071 * FUNCTION: PKIX_VerifyNode_SetError
1072 * DESCRIPTION:
1073 *
1074 * This function sets the Error field of the VerifyNode pointed to by "node"
1075 * to contain the Error pointed to by "error".
1076 *
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)
1095 {
1096
1097 PKIX_ENTER(VERIFYNODE, "PKIX_VerifyNode_SetError");
1098
1099 PKIX_NULLCHECK_TWO(node, error);
1100
1101 PKIX_DECREF(node->error); /* should have been NULL */
1102 PKIX_INCREF(error);
1103 node->error = error;
1104
1105 cleanup:
1106 PKIX_RETURN(VERIFYNODE);
1107 }
1108
1109 /*
1110 * FUNCTION: PKIX_VerifyNode_FindError
1111 * DESCRIPTION:
1112 *
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.
1116 *
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)
1135 {
1136 PKIX_VerifyNode *childNode = NULL;
1137
1138 PKIX_ENTER(VERIFYNODE, "PKIX_VerifyNode_FindError");
1139
1140 /* Make sure the return address is initialized with NULL */
1141 PKIX_DECREF(*error);
1142
1143 if (!node)
1144 goto cleanup;
1145
1146 /* First, try to get error from lowest level. */
1147 if (node->children) {
1148 PKIX_UInt32 length = 0;
1149 PKIX_UInt32 index = 0;
1150
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;
1169 }
1170 }
1171 }
1172
1173 if (node->error && node->error->plErr) {
1174 PKIX_INCREF(node->error);
1175 *error = node->error;
1176 }
1177
1178 cleanup:
1179 PKIX_DECREF(childNode);
1180
1181 PKIX_RETURN(VERIFYNODE);
1182 }
This site is hosted by Intevation GmbH (Datenschutzerklärung und Impressum | Privacy Policy and Imprint)