Mercurial > trustbridge > nss-cmake-static
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 ©, | |
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, ©, 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 } |