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_valresult.c
6  *
7  * ValidateResult Object Functions
8  *
9  */
10 
11 #include "pkix_valresult.h"
12 
13 /* --Private-Functions-------------------------------------------- */
14 
15 /*
16  * FUNCTION: pkix_ValidateResult_Destroy
17  * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h)
18  */
19 static PKIX_Error *
pkix_ValidateResult_Destroy(PKIX_PL_Object * object,void * plContext)20 pkix_ValidateResult_Destroy(
21         PKIX_PL_Object *object,
22         void *plContext)
23 {
24         PKIX_ValidateResult *result = NULL;
25 
26         PKIX_ENTER(VALIDATERESULT, "pkix_ValidateResult_Destroy");
27         PKIX_NULLCHECK_ONE(object);
28 
29         /* Check that this object is a validate result object */
30         PKIX_CHECK(pkix_CheckType(object, PKIX_VALIDATERESULT_TYPE, plContext),
31                 PKIX_OBJECTNOTVALIDATERESULT);
32 
33         result = (PKIX_ValidateResult *)object;
34 
35         PKIX_DECREF(result->anchor);
36         PKIX_DECREF(result->pubKey);
37         PKIX_DECREF(result->policyTree);
38 
39 cleanup:
40 
41         PKIX_RETURN(VALIDATERESULT);
42 }
43 
44 /*
45  * FUNCTION: pkix_ValidateResult_Equals
46  * (see comments for PKIX_PL_EqualsCallback in pkix_pl_system.h)
47  */
48 static PKIX_Error *
pkix_ValidateResult_Equals(PKIX_PL_Object * first,PKIX_PL_Object * second,PKIX_Boolean * pResult,void * plContext)49 pkix_ValidateResult_Equals(
50         PKIX_PL_Object *first,
51         PKIX_PL_Object *second,
52         PKIX_Boolean *pResult,
53         void *plContext)
54 {
55         PKIX_UInt32 secondType;
56         PKIX_Boolean cmpResult;
57         PKIX_ValidateResult *firstValResult = NULL;
58         PKIX_ValidateResult *secondValResult = NULL;
59         PKIX_TrustAnchor *firstAnchor = NULL;
60         PKIX_TrustAnchor *secondAnchor = NULL;
61         PKIX_PolicyNode *firstTree = NULL;
62         PKIX_PolicyNode *secondTree = NULL;
63 
64         PKIX_ENTER(VALIDATERESULT, "pkix_ValidateResult_Equals");
65         PKIX_NULLCHECK_THREE(first, second, pResult);
66 
67         PKIX_CHECK(pkix_CheckType(first, PKIX_VALIDATERESULT_TYPE, plContext),
68                 PKIX_FIRSTOBJECTNOTVALIDATERESULT);
69 
70         PKIX_CHECK(PKIX_PL_Object_GetType(second, &secondType, plContext),
71                 PKIX_COULDNOTGETTYPEOFSECONDARGUMENT);
72 
73         *pResult = PKIX_FALSE;
74 
75         if (secondType != PKIX_VALIDATERESULT_TYPE) goto cleanup;
76 
77         firstValResult = (PKIX_ValidateResult *)first;
78         secondValResult = (PKIX_ValidateResult *)second;
79 
80         PKIX_CHECK(PKIX_PL_Object_Equals
81                 ((PKIX_PL_Object *)firstValResult->pubKey,
82                 (PKIX_PL_Object *)secondValResult->pubKey,
83                 &cmpResult,
84                 plContext),
85                 PKIX_OBJECTEQUALSFAILED);
86 
87         if (!cmpResult) goto cleanup;
88 
89         firstAnchor = firstValResult->anchor;
90         secondAnchor = secondValResult->anchor;
91 
92         if ((firstAnchor != NULL) && (secondAnchor != NULL)) {
93                 PKIX_CHECK(PKIX_PL_Object_Equals
94                         ((PKIX_PL_Object *)firstAnchor,
95                         (PKIX_PL_Object *)secondAnchor,
96                         &cmpResult,
97                         plContext),
98                         PKIX_OBJECTEQUALSFAILED);
99         } else {
100                 cmpResult = (firstAnchor == secondAnchor);
101         }
102 
103         if (!cmpResult) goto cleanup;
104 
105         firstTree = firstValResult->policyTree;
106         secondTree = secondValResult->policyTree;
107 
108         if ((firstTree != NULL) && (secondTree != NULL)) {
109                 PKIX_CHECK(PKIX_PL_Object_Equals
110                         ((PKIX_PL_Object *)firstTree,
111                         (PKIX_PL_Object *)secondTree,
112                         &cmpResult,
113                         plContext),
114                         PKIX_OBJECTEQUALSFAILED);
115         } else {
116                 cmpResult = (firstTree == secondTree);
117         }
118 
119         *pResult = cmpResult;
120 
121 cleanup:
122 
123         PKIX_RETURN(VALIDATERESULT);
124 }
125 
126 /*
127  * FUNCTION: pkix_ValidateResult_Hashcode
128  * (see comments for PKIX_PL_HashcodeCallback in pkix_pl_system.h)
129  */
130 static PKIX_Error *
pkix_ValidateResult_Hashcode(PKIX_PL_Object * object,PKIX_UInt32 * pHashcode,void * plContext)131 pkix_ValidateResult_Hashcode(
132         PKIX_PL_Object *object,
133         PKIX_UInt32 *pHashcode,
134         void *plContext)
135 {
136         PKIX_ValidateResult *valResult = NULL;
137         PKIX_UInt32 hash = 0;
138         PKIX_UInt32 pubKeyHash = 0;
139         PKIX_UInt32 anchorHash = 0;
140         PKIX_UInt32 policyTreeHash = 0;
141 
142         PKIX_ENTER(VALIDATERESULT, "pkix_ValidateResult_Hashcode");
143         PKIX_NULLCHECK_TWO(object, pHashcode);
144 
145         PKIX_CHECK(pkix_CheckType(object, PKIX_VALIDATERESULT_TYPE, plContext),
146                 PKIX_OBJECTNOTVALIDATERESULT);
147 
148         valResult = (PKIX_ValidateResult*)object;
149 
150         PKIX_CHECK(PKIX_PL_Object_Hashcode
151                 ((PKIX_PL_Object *)valResult->pubKey, &pubKeyHash, plContext),
152                 PKIX_OBJECTHASHCODEFAILED);
153 
154         if (valResult->anchor) {
155                 PKIX_CHECK(PKIX_PL_Object_Hashcode
156                         ((PKIX_PL_Object *)valResult->anchor,
157                         &anchorHash,
158                         plContext),
159                         PKIX_OBJECTHASHCODEFAILED);
160         }
161 
162         if (valResult->policyTree) {
163                 PKIX_CHECK(PKIX_PL_Object_Hashcode
164                         ((PKIX_PL_Object *)valResult->policyTree,
165                         &policyTreeHash,
166                         plContext),
167                         PKIX_OBJECTHASHCODEFAILED);
168         }
169 
170         hash = 31*(31 * pubKeyHash + anchorHash) + policyTreeHash;
171 
172         *pHashcode = hash;
173 
174 cleanup:
175 
176         PKIX_RETURN(VALIDATERESULT);
177 }
178 
179 /*
180  * FUNCTION: pkix_ValidateResult_ToString
181  * (see comments for PKIX_PL_ToStringCallback in pkix_pl_system.h)
182  */
183 static PKIX_Error *
pkix_ValidateResult_ToString(PKIX_PL_Object * object,PKIX_PL_String ** pString,void * plContext)184 pkix_ValidateResult_ToString(
185         PKIX_PL_Object *object,
186         PKIX_PL_String **pString,
187         void *plContext)
188 {
189         PKIX_ValidateResult *valResult = NULL;
190         PKIX_PL_String *formatString = NULL;
191         PKIX_PL_String *valResultString = NULL;
192 
193         PKIX_TrustAnchor *anchor = NULL;
194         PKIX_PL_PublicKey *pubKey = NULL;
195         PKIX_PolicyNode *policyTree = NULL;
196 
197         PKIX_PL_String *anchorString = NULL;
198         PKIX_PL_String *pubKeyString = NULL;
199         PKIX_PL_String *treeString = NULL;
200         char *asciiNullString = "(null)";
201         char *asciiFormat =
202                 "[\n"
203                 "\tTrustAnchor: \t\t%s"
204                 "\tPubKey:    \t\t%s\n"
205                 "\tPolicyTree:  \t\t%s\n"
206                 "]\n";
207 
208         PKIX_ENTER(VALIDATERESULT, "pkix_ValidateResult_ToString");
209         PKIX_NULLCHECK_TWO(object, pString);
210 
211         PKIX_CHECK(pkix_CheckType(object, PKIX_VALIDATERESULT_TYPE, plContext),
212                 PKIX_OBJECTNOTVALIDATERESULT);
213 
214         PKIX_CHECK(PKIX_PL_String_Create
215                 (PKIX_ESCASCII, asciiFormat, 0, &formatString, plContext),
216                 PKIX_STRINGCREATEFAILED);
217 
218         valResult = (PKIX_ValidateResult*)object;
219 
220         anchor = valResult->anchor;
221 
222         if (anchor) {
223                 PKIX_CHECK(PKIX_PL_Object_ToString
224                         ((PKIX_PL_Object *)anchor, &anchorString, plContext),
225                         PKIX_OBJECTTOSTRINGFAILED);
226         } else {
227                 PKIX_CHECK(PKIX_PL_String_Create
228                         (PKIX_ESCASCII,
229                         asciiNullString,
230                         0,
231                         &anchorString,
232                         plContext),
233                         PKIX_STRINGCREATEFAILED);
234         }
235 
236         pubKey = valResult->pubKey;
237 
238         PKIX_CHECK(PKIX_PL_Object_ToString
239                 ((PKIX_PL_Object *)pubKey, &pubKeyString, plContext),
240                 PKIX_OBJECTTOSTRINGFAILED);
241 
242         policyTree = valResult->policyTree;
243 
244         if (policyTree) {
245                 PKIX_CHECK(PKIX_PL_Object_ToString
246                         ((PKIX_PL_Object *)policyTree, &treeString, plContext),
247                         PKIX_OBJECTTOSTRINGFAILED);
248         } else {
249                 PKIX_CHECK(PKIX_PL_String_Create
250                         (PKIX_ESCASCII,
251                         asciiNullString,
252                         0,
253                         &treeString,
254                         plContext),
255                         PKIX_STRINGCREATEFAILED);
256         }
257 
258         PKIX_CHECK(PKIX_PL_Sprintf
259                 (&valResultString,
260                 plContext,
261                 formatString,
262                 anchorString,
263                 pubKeyString,
264                 treeString),
265                 PKIX_SPRINTFFAILED);
266 
267         *pString = valResultString;
268 
269 cleanup:
270 
271         PKIX_DECREF(formatString);
272         PKIX_DECREF(anchorString);
273         PKIX_DECREF(pubKeyString);
274         PKIX_DECREF(treeString);
275 
276         PKIX_RETURN(VALIDATERESULT);
277 }
278 
279 /*
280  * FUNCTION: pkix_ValidateResult_RegisterSelf
281  * DESCRIPTION:
282  *  Registers PKIX_VALIDATERESULT_TYPE and its related functions with
283  *  systemClasses[]
284  * THREAD SAFETY:
285  *  Not Thread Safe - for performance and complexity reasons
286  *
287  *  Since this function is only called by PKIX_PL_Initialize, which should
288  *  only be called once, it is acceptable that this function is not
289  *  thread-safe.
290  */
291 PKIX_Error *
pkix_ValidateResult_RegisterSelf(void * plContext)292 pkix_ValidateResult_RegisterSelf(void *plContext)
293 {
294 
295         extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES];
296         pkix_ClassTable_Entry entry;
297 
298         PKIX_ENTER(VALIDATERESULT, "pkix_ValidateResult_RegisterSelf");
299 
300         entry.description = "ValidateResult";
301         entry.objCounter = 0;
302         entry.typeObjectSize = sizeof(PKIX_ValidateResult);
303         entry.destructor = pkix_ValidateResult_Destroy;
304         entry.equalsFunction = pkix_ValidateResult_Equals;
305         entry.hashcodeFunction = pkix_ValidateResult_Hashcode;
306         entry.toStringFunction = pkix_ValidateResult_ToString;
307         entry.comparator = NULL;
308         entry.duplicateFunction = pkix_duplicateImmutable;
309 
310         systemClasses[PKIX_VALIDATERESULT_TYPE] = entry;
311 
312         PKIX_RETURN(VALIDATERESULT);
313 }
314 
315 /*
316  * FUNCTION: pkix_ValidateResult_Create
317  * DESCRIPTION:
318  *
319  *  Creates a new ValidateResult Object using the PublicKey pointed to by
320  *  "pubKey", the TrustAnchor pointed to by "anchor", and the PolicyNode
321  *  pointed to by "policyTree", and stores it at "pResult".
322  *
323  * PARAMETERS
324  *  "pubKey"
325  *      PublicKey of the desired ValidateResult. Must be non-NULL.
326  *  "anchor"
327  *      TrustAnchor of the desired Validateresult. May be NULL.
328  *  "policyTree"
329  *      PolicyNode of the desired ValidateResult; may be NULL
330  *  "pResult"
331  *      Address where object pointer will be stored. Must be non-NULL.
332  *  "plContext"
333  *      Platform-specific context pointer.
334  * THREAD SAFETY:
335  *  Thread Safe (see Thread Safety Definitions in Programmer's Guide)
336  * RETURNS:
337  *  Returns NULL if the function succeeds.
338  *  Returns a Fatal Error if the function fails in an unrecoverable way.
339  */
340 PKIX_Error *
pkix_ValidateResult_Create(PKIX_PL_PublicKey * pubKey,PKIX_TrustAnchor * anchor,PKIX_PolicyNode * policyTree,PKIX_ValidateResult ** pResult,void * plContext)341 pkix_ValidateResult_Create(
342         PKIX_PL_PublicKey *pubKey,
343         PKIX_TrustAnchor *anchor,
344         PKIX_PolicyNode *policyTree,
345         PKIX_ValidateResult **pResult,
346         void *plContext)
347 {
348         PKIX_ValidateResult *result = NULL;
349 
350         PKIX_ENTER(VALIDATERESULT, "pkix_ValidateResult_Create");
351         PKIX_NULLCHECK_TWO(pubKey, pResult);
352 
353         PKIX_CHECK(PKIX_PL_Object_Alloc
354                     (PKIX_VALIDATERESULT_TYPE,
355                     sizeof (PKIX_ValidateResult),
356                     (PKIX_PL_Object **)&result,
357                     plContext),
358                     PKIX_COULDNOTCREATEVALIDATERESULTOBJECT);
359 
360         /* initialize fields */
361 
362         PKIX_INCREF(pubKey);
363         result->pubKey = pubKey;
364 
365         PKIX_INCREF(anchor);
366         result->anchor = anchor;
367 
368         PKIX_INCREF(policyTree);
369         result->policyTree = policyTree;
370 
371         *pResult = result;
372         result = NULL;
373 
374 cleanup:
375 
376         PKIX_DECREF(result);
377 
378         PKIX_RETURN(VALIDATERESULT);
379 
380 }
381 
382 /* --Public-Functions--------------------------------------------- */
383 
384 /*
385  * FUNCTION: PKIX_ValidateResult_GetPublicKey
386  *      (see comments in pkix_result.h)
387  */
388 PKIX_Error *
PKIX_ValidateResult_GetPublicKey(PKIX_ValidateResult * result,PKIX_PL_PublicKey ** pPublicKey,void * plContext)389 PKIX_ValidateResult_GetPublicKey(
390         PKIX_ValidateResult *result,
391         PKIX_PL_PublicKey **pPublicKey,
392         void *plContext)
393 {
394         PKIX_ENTER(VALIDATERESULT, "PKIX_ValidateResult_GetPublicKey");
395         PKIX_NULLCHECK_TWO(result, pPublicKey);
396 
397         PKIX_INCREF(result->pubKey);
398         *pPublicKey = result->pubKey;
399 
400 cleanup:
401         PKIX_RETURN(VALIDATERESULT);
402 }
403 
404 /*
405  * FUNCTION: PKIX_ValidateResult_GetTrustAnchor
406  *      (see comments in pkix_result.h)
407  */
408 PKIX_Error *
PKIX_ValidateResult_GetTrustAnchor(PKIX_ValidateResult * result,PKIX_TrustAnchor ** pTrustAnchor,void * plContext)409 PKIX_ValidateResult_GetTrustAnchor(
410         PKIX_ValidateResult *result,
411         PKIX_TrustAnchor **pTrustAnchor,
412         void *plContext)
413 {
414         PKIX_ENTER(VALIDATERESULT, "PKIX_ValidateResult_GetTrustAnchor");
415         PKIX_NULLCHECK_TWO(result, pTrustAnchor);
416 
417         PKIX_INCREF(result->anchor);
418         *pTrustAnchor = result->anchor;
419 
420 cleanup:
421         PKIX_RETURN(VALIDATERESULT);
422 }
423 
424 /*
425  * FUNCTION: PKIX_ValidateResult_GetPolicyTree
426  *      (see comments in pkix_result.h)
427  */
428 PKIX_Error *
PKIX_ValidateResult_GetPolicyTree(PKIX_ValidateResult * result,PKIX_PolicyNode ** pPolicyTree,void * plContext)429 PKIX_ValidateResult_GetPolicyTree(
430         PKIX_ValidateResult *result,
431         PKIX_PolicyNode **pPolicyTree,
432         void *plContext)
433 {
434         PKIX_ENTER(VALIDATERESULT, "PKIX_ValidateResult_GetPolicyTree");
435         PKIX_NULLCHECK_TWO(result, pPolicyTree);
436 
437         PKIX_INCREF(result->policyTree);
438         (*pPolicyTree) = result->policyTree;
439 
440 cleanup:
441         PKIX_RETURN(VALIDATERESULT);
442 }
443