|
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_trustanchor.c |
|
6 * |
|
7 * TrustAnchor Object Functions |
|
8 * |
|
9 */ |
|
10 |
|
11 #include "pkix_trustanchor.h" |
|
12 |
|
13 /* --Private-Functions-------------------------------------------- */ |
|
14 |
|
15 /* |
|
16 * FUNCTION: pkix_TrustAnchor_Destroy |
|
17 * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h) |
|
18 */ |
|
19 static PKIX_Error * |
|
20 pkix_TrustAnchor_Destroy( |
|
21 PKIX_PL_Object *object, |
|
22 void *plContext) |
|
23 { |
|
24 PKIX_TrustAnchor *anchor = NULL; |
|
25 |
|
26 PKIX_ENTER(TRUSTANCHOR, "pkix_TrustAnchor_Destroy"); |
|
27 PKIX_NULLCHECK_ONE(object); |
|
28 |
|
29 /* Check that this object is a trust anchor */ |
|
30 PKIX_CHECK(pkix_CheckType(object, PKIX_TRUSTANCHOR_TYPE, plContext), |
|
31 PKIX_OBJECTNOTTRUSTANCHOR); |
|
32 |
|
33 anchor = (PKIX_TrustAnchor *)object; |
|
34 |
|
35 PKIX_DECREF(anchor->trustedCert); |
|
36 PKIX_DECREF(anchor->caName); |
|
37 PKIX_DECREF(anchor->caPubKey); |
|
38 PKIX_DECREF(anchor->nameConstraints); |
|
39 |
|
40 cleanup: |
|
41 |
|
42 PKIX_RETURN(TRUSTANCHOR); |
|
43 } |
|
44 |
|
45 /* |
|
46 * FUNCTION: pkix_TrustAnchor_Equals |
|
47 * (see comments for PKIX_PL_EqualsCallback in pkix_pl_system.h) |
|
48 */ |
|
49 static PKIX_Error * |
|
50 pkix_TrustAnchor_Equals( |
|
51 PKIX_PL_Object *first, |
|
52 PKIX_PL_Object *second, |
|
53 PKIX_Boolean *pResult, |
|
54 void *plContext) |
|
55 { |
|
56 PKIX_UInt32 secondType; |
|
57 PKIX_Boolean cmpResult; |
|
58 PKIX_TrustAnchor *firstAnchor = NULL; |
|
59 PKIX_TrustAnchor *secondAnchor = NULL; |
|
60 PKIX_PL_Cert *firstCert = NULL; |
|
61 PKIX_PL_Cert *secondCert = NULL; |
|
62 |
|
63 PKIX_ENTER(TRUSTANCHOR, "pkix_TrustAnchor_Equals"); |
|
64 PKIX_NULLCHECK_THREE(first, second, pResult); |
|
65 |
|
66 PKIX_CHECK(pkix_CheckType(first, PKIX_TRUSTANCHOR_TYPE, plContext), |
|
67 PKIX_FIRSTOBJECTNOTTRUSTANCHOR); |
|
68 |
|
69 PKIX_CHECK(PKIX_PL_Object_GetType(second, &secondType, plContext), |
|
70 PKIX_COULDNOTGETTYPEOFSECONDARGUMENT); |
|
71 |
|
72 *pResult = PKIX_FALSE; |
|
73 |
|
74 if (secondType != PKIX_TRUSTANCHOR_TYPE) goto cleanup; |
|
75 |
|
76 firstAnchor = (PKIX_TrustAnchor *)first; |
|
77 secondAnchor = (PKIX_TrustAnchor *)second; |
|
78 |
|
79 firstCert = firstAnchor->trustedCert; |
|
80 secondCert = secondAnchor->trustedCert; |
|
81 |
|
82 if ((firstCert && !secondCert) || (!firstCert && secondCert)){ |
|
83 goto cleanup; |
|
84 } |
|
85 |
|
86 if (firstCert && secondCert){ |
|
87 PKIX_CHECK(PKIX_PL_Object_Equals |
|
88 ((PKIX_PL_Object *)firstCert, |
|
89 (PKIX_PL_Object *)secondCert, |
|
90 &cmpResult, |
|
91 plContext), |
|
92 PKIX_OBJECTEQUALSFAILED); |
|
93 } else { |
|
94 PKIX_CHECK(PKIX_PL_Object_Equals |
|
95 ((PKIX_PL_Object *)firstAnchor->caName, |
|
96 (PKIX_PL_Object *)secondAnchor->caName, |
|
97 &cmpResult, |
|
98 plContext), |
|
99 PKIX_OBJECTEQUALSFAILED); |
|
100 |
|
101 if (!cmpResult) goto cleanup; |
|
102 |
|
103 PKIX_CHECK(PKIX_PL_Object_Equals |
|
104 ((PKIX_PL_Object *)firstAnchor->caPubKey, |
|
105 (PKIX_PL_Object *)secondAnchor->caPubKey, |
|
106 &cmpResult, |
|
107 plContext), |
|
108 PKIX_OBJECTEQUALSFAILED); |
|
109 |
|
110 if (!cmpResult) goto cleanup; |
|
111 |
|
112 PKIX_EQUALS |
|
113 (firstAnchor->nameConstraints, |
|
114 secondAnchor->nameConstraints, |
|
115 &cmpResult, |
|
116 plContext, |
|
117 PKIX_OBJECTEQUALSFAILED); |
|
118 |
|
119 if (!cmpResult) goto cleanup; |
|
120 |
|
121 } |
|
122 |
|
123 *pResult = cmpResult; |
|
124 |
|
125 cleanup: |
|
126 |
|
127 PKIX_RETURN(TRUSTANCHOR); |
|
128 } |
|
129 |
|
130 /* |
|
131 * FUNCTION: pkix_TrustAnchor_Hashcode |
|
132 * (see comments for PKIX_PL_HashcodeCallback in pkix_pl_system.h) |
|
133 */ |
|
134 static PKIX_Error * |
|
135 pkix_TrustAnchor_Hashcode( |
|
136 PKIX_PL_Object *object, |
|
137 PKIX_UInt32 *pHashcode, |
|
138 void *plContext) |
|
139 { |
|
140 PKIX_TrustAnchor *anchor = NULL; |
|
141 PKIX_PL_Cert *cert = NULL; |
|
142 PKIX_UInt32 hash = 0; |
|
143 PKIX_UInt32 certHash = 0; |
|
144 PKIX_UInt32 nameHash = 0; |
|
145 PKIX_UInt32 pubKeyHash = 0; |
|
146 PKIX_UInt32 ncHash = 0; |
|
147 |
|
148 PKIX_ENTER(TRUSTANCHOR, "pkix_TrustAnchor_Hashcode"); |
|
149 PKIX_NULLCHECK_TWO(object, pHashcode); |
|
150 |
|
151 PKIX_CHECK(pkix_CheckType(object, PKIX_TRUSTANCHOR_TYPE, plContext), |
|
152 PKIX_OBJECTNOTTRUSTANCHOR); |
|
153 |
|
154 anchor = (PKIX_TrustAnchor*)object; |
|
155 cert = anchor->trustedCert; |
|
156 |
|
157 if (cert){ |
|
158 PKIX_CHECK(PKIX_PL_Object_Hashcode |
|
159 ((PKIX_PL_Object *)cert, |
|
160 &certHash, |
|
161 plContext), |
|
162 PKIX_OBJECTHASHCODEFAILED); |
|
163 |
|
164 hash = certHash; |
|
165 |
|
166 } else { |
|
167 PKIX_CHECK(PKIX_PL_Object_Hashcode |
|
168 ((PKIX_PL_Object *)anchor->caName, |
|
169 &nameHash, |
|
170 plContext), |
|
171 PKIX_OBJECTHASHCODEFAILED); |
|
172 |
|
173 PKIX_CHECK(PKIX_PL_Object_Hashcode |
|
174 ((PKIX_PL_Object *)anchor->caPubKey, |
|
175 &pubKeyHash, |
|
176 plContext), |
|
177 PKIX_OBJECTHASHCODEFAILED); |
|
178 |
|
179 PKIX_HASHCODE(anchor->nameConstraints, &ncHash, plContext, |
|
180 PKIX_OBJECTHASHCODEFAILED); |
|
181 |
|
182 hash = 31 * nameHash + pubKeyHash + ncHash; |
|
183 |
|
184 } |
|
185 |
|
186 *pHashcode = hash; |
|
187 |
|
188 cleanup: |
|
189 |
|
190 PKIX_RETURN(TRUSTANCHOR); |
|
191 } |
|
192 |
|
193 /* |
|
194 * FUNCTION: pkix_TrustAnchor_ToString |
|
195 * (see comments for PKIX_PL_ToStringCallback in pkix_pl_system.h) |
|
196 */ |
|
197 static PKIX_Error * |
|
198 pkix_TrustAnchor_ToString( |
|
199 PKIX_PL_Object *object, |
|
200 PKIX_PL_String **pString, |
|
201 void *plContext) |
|
202 { |
|
203 PKIX_TrustAnchor *anchor = NULL; |
|
204 char *asciiFormat = NULL; |
|
205 PKIX_PL_String *formatString = NULL; |
|
206 PKIX_PL_String *anchorString = NULL; |
|
207 PKIX_PL_String *certString = NULL; |
|
208 PKIX_PL_String *nameString = NULL; |
|
209 PKIX_PL_String *pubKeyString = NULL; |
|
210 PKIX_PL_String *nameConstraintsString = NULL; |
|
211 |
|
212 PKIX_ENTER(TRUSTANCHOR, "pkix_TrustAnchor_ToString"); |
|
213 PKIX_NULLCHECK_TWO(object, pString); |
|
214 |
|
215 PKIX_CHECK(pkix_CheckType(object, PKIX_TRUSTANCHOR_TYPE, plContext), |
|
216 PKIX_OBJECTNOTTRUSTANCHOR); |
|
217 |
|
218 anchor = (PKIX_TrustAnchor*)object; |
|
219 |
|
220 if (anchor->trustedCert){ |
|
221 asciiFormat = |
|
222 "[\n" |
|
223 "\tTrusted Cert: %s\n" |
|
224 "]\n"; |
|
225 |
|
226 PKIX_CHECK(PKIX_PL_String_Create |
|
227 (PKIX_ESCASCII, |
|
228 asciiFormat, |
|
229 0, |
|
230 &formatString, |
|
231 plContext), |
|
232 PKIX_STRINGCREATEFAILED); |
|
233 |
|
234 PKIX_CHECK(PKIX_PL_Object_ToString |
|
235 ((PKIX_PL_Object *)anchor->trustedCert, |
|
236 &certString, |
|
237 plContext), |
|
238 PKIX_OBJECTTOSTRINGFAILED); |
|
239 |
|
240 PKIX_CHECK(PKIX_PL_Sprintf |
|
241 (&anchorString, |
|
242 plContext, |
|
243 formatString, |
|
244 certString), |
|
245 PKIX_SPRINTFFAILED); |
|
246 } else { |
|
247 asciiFormat = |
|
248 "[\n" |
|
249 "\tTrusted CA Name: %s\n" |
|
250 "\tTrusted CA PublicKey: %s\n" |
|
251 "\tInitial Name Constraints:%s\n" |
|
252 "]\n"; |
|
253 |
|
254 PKIX_CHECK(PKIX_PL_String_Create |
|
255 (PKIX_ESCASCII, |
|
256 asciiFormat, |
|
257 0, |
|
258 &formatString, |
|
259 plContext), |
|
260 PKIX_STRINGCREATEFAILED); |
|
261 |
|
262 PKIX_CHECK(PKIX_PL_Object_ToString |
|
263 ((PKIX_PL_Object *)anchor->caName, |
|
264 &nameString, |
|
265 plContext), |
|
266 PKIX_OBJECTTOSTRINGFAILED); |
|
267 |
|
268 PKIX_CHECK(PKIX_PL_Object_ToString |
|
269 ((PKIX_PL_Object *)anchor->caPubKey, |
|
270 &pubKeyString, |
|
271 plContext), |
|
272 PKIX_OBJECTTOSTRINGFAILED); |
|
273 |
|
274 PKIX_TOSTRING |
|
275 (anchor->nameConstraints, |
|
276 &nameConstraintsString, |
|
277 plContext, |
|
278 PKIX_OBJECTTOSTRINGFAILED); |
|
279 |
|
280 PKIX_CHECK(PKIX_PL_Sprintf |
|
281 (&anchorString, |
|
282 plContext, |
|
283 formatString, |
|
284 nameString, |
|
285 pubKeyString, |
|
286 nameConstraintsString), |
|
287 PKIX_SPRINTFFAILED); |
|
288 } |
|
289 |
|
290 *pString = anchorString; |
|
291 |
|
292 cleanup: |
|
293 |
|
294 PKIX_DECREF(formatString); |
|
295 PKIX_DECREF(certString); |
|
296 PKIX_DECREF(nameString); |
|
297 PKIX_DECREF(pubKeyString); |
|
298 PKIX_DECREF(nameConstraintsString); |
|
299 |
|
300 PKIX_RETURN(TRUSTANCHOR); |
|
301 } |
|
302 |
|
303 /* |
|
304 * FUNCTION: pkix_TrustAnchor_RegisterSelf |
|
305 * DESCRIPTION: |
|
306 * Registers PKIX_TRUSTANCHOR_TYPE and its related functions with |
|
307 * systemClasses[] |
|
308 * THREAD SAFETY: |
|
309 * Not Thread Safe - for performance and complexity reasons |
|
310 * |
|
311 * Since this function is only called by PKIX_PL_Initialize, which should |
|
312 * only be called once, it is acceptable that this function is not |
|
313 * thread-safe. |
|
314 */ |
|
315 PKIX_Error * |
|
316 pkix_TrustAnchor_RegisterSelf(void *plContext) |
|
317 { |
|
318 extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES]; |
|
319 pkix_ClassTable_Entry entry; |
|
320 |
|
321 PKIX_ENTER(TRUSTANCHOR, "pkix_TrustAnchor_RegisterSelf"); |
|
322 |
|
323 entry.description = "TrustAnchor"; |
|
324 entry.objCounter = 0; |
|
325 entry.typeObjectSize = sizeof(PKIX_TrustAnchor); |
|
326 entry.destructor = pkix_TrustAnchor_Destroy; |
|
327 entry.equalsFunction = pkix_TrustAnchor_Equals; |
|
328 entry.hashcodeFunction = pkix_TrustAnchor_Hashcode; |
|
329 entry.toStringFunction = pkix_TrustAnchor_ToString; |
|
330 entry.comparator = NULL; |
|
331 entry.duplicateFunction = pkix_duplicateImmutable; |
|
332 |
|
333 systemClasses[PKIX_TRUSTANCHOR_TYPE] = entry; |
|
334 |
|
335 PKIX_RETURN(TRUSTANCHOR); |
|
336 } |
|
337 |
|
338 /* --Public-Functions--------------------------------------------- */ |
|
339 |
|
340 |
|
341 /* |
|
342 * FUNCTION: PKIX_TrustAnchor_CreateWithCert (see comments in pkix_params.h) |
|
343 */ |
|
344 PKIX_Error * |
|
345 PKIX_TrustAnchor_CreateWithCert( |
|
346 PKIX_PL_Cert *cert, |
|
347 PKIX_TrustAnchor **pAnchor, |
|
348 void *plContext) |
|
349 { |
|
350 PKIX_TrustAnchor *anchor = NULL; |
|
351 |
|
352 PKIX_ENTER(TRUSTANCHOR, "PKIX_TrustAnchor_CreateWithCert"); |
|
353 PKIX_NULLCHECK_TWO(cert, pAnchor); |
|
354 |
|
355 PKIX_CHECK(PKIX_PL_Object_Alloc |
|
356 (PKIX_TRUSTANCHOR_TYPE, |
|
357 sizeof (PKIX_TrustAnchor), |
|
358 (PKIX_PL_Object **)&anchor, |
|
359 plContext), |
|
360 PKIX_COULDNOTCREATETRUSTANCHOROBJECT); |
|
361 |
|
362 /* initialize fields */ |
|
363 PKIX_CHECK( |
|
364 PKIX_PL_Cert_SetAsTrustAnchor(cert, plContext), |
|
365 PKIX_CERTSETASTRUSTANCHORFAILED); |
|
366 |
|
367 PKIX_INCREF(cert); |
|
368 anchor->trustedCert = cert; |
|
369 |
|
370 anchor->caName = NULL; |
|
371 anchor->caPubKey = NULL; |
|
372 |
|
373 PKIX_CHECK(PKIX_PL_Cert_GetNameConstraints |
|
374 (anchor->trustedCert, &anchor->nameConstraints, plContext), |
|
375 PKIX_CERTGETNAMECONSTRAINTSFAILED); |
|
376 |
|
377 |
|
378 *pAnchor = anchor; |
|
379 anchor = NULL; |
|
380 |
|
381 cleanup: |
|
382 |
|
383 PKIX_DECREF(anchor); |
|
384 |
|
385 PKIX_RETURN(TRUSTANCHOR); |
|
386 |
|
387 } |
|
388 |
|
389 /* |
|
390 * FUNCTION: PKIX_TrustAnchor_CreateWithNameKeyPair |
|
391 * (see comments in pkix_params.h) |
|
392 */ |
|
393 PKIX_Error * |
|
394 PKIX_TrustAnchor_CreateWithNameKeyPair( |
|
395 PKIX_PL_X500Name *name, |
|
396 PKIX_PL_PublicKey *pubKey, |
|
397 PKIX_PL_CertNameConstraints *nameConstraints, |
|
398 PKIX_TrustAnchor **pAnchor, |
|
399 void *plContext) |
|
400 { |
|
401 PKIX_TrustAnchor *anchor = NULL; |
|
402 |
|
403 PKIX_ENTER(TRUSTANCHOR, "PKIX_TrustAnchor_CreateWithNameKeyPair"); |
|
404 |
|
405 #ifndef BUILD_LIBPKIX_TESTS |
|
406 /* Nss creates trust anchors by using PKIX_TrustAnchor_CreateWithCert |
|
407 * function as the complete trusted cert structure, and not only cert |
|
408 * public key, is required for chain building and validation processes. |
|
409 * Restricting this function for been used only in libpkix unit |
|
410 * tests. */ |
|
411 PKIX_ERROR(PKIX_FUNCTIONMUSTNOTBEUSED); |
|
412 #endif |
|
413 |
|
414 PKIX_NULLCHECK_THREE(name, pubKey, pAnchor); |
|
415 |
|
416 PKIX_CHECK(PKIX_PL_Object_Alloc |
|
417 (PKIX_TRUSTANCHOR_TYPE, |
|
418 sizeof (PKIX_TrustAnchor), |
|
419 (PKIX_PL_Object **)&anchor, |
|
420 plContext), |
|
421 PKIX_COULDNOTCREATETRUSTANCHOROBJECT); |
|
422 |
|
423 /* initialize fields */ |
|
424 anchor->trustedCert = NULL; |
|
425 |
|
426 PKIX_INCREF(name); |
|
427 anchor->caName = name; |
|
428 |
|
429 PKIX_INCREF(pubKey); |
|
430 anchor->caPubKey = pubKey; |
|
431 |
|
432 PKIX_INCREF(nameConstraints); |
|
433 anchor->nameConstraints = nameConstraints; |
|
434 |
|
435 *pAnchor = anchor; |
|
436 anchor = NULL; |
|
437 cleanup: |
|
438 |
|
439 PKIX_DECREF(anchor); |
|
440 |
|
441 PKIX_RETURN(TRUSTANCHOR); |
|
442 } |
|
443 |
|
444 /* |
|
445 * FUNCTION: PKIX_TrustAnchor_GetTrustedCert (see comments in pkix_params.h) |
|
446 */ |
|
447 PKIX_Error * |
|
448 PKIX_TrustAnchor_GetTrustedCert( |
|
449 PKIX_TrustAnchor *anchor, |
|
450 PKIX_PL_Cert **pCert, |
|
451 void *plContext) |
|
452 { |
|
453 PKIX_ENTER(TRUSTANCHOR, "PKIX_TrustAnchor_GetTrustedCert"); |
|
454 PKIX_NULLCHECK_TWO(anchor, pCert); |
|
455 |
|
456 PKIX_INCREF(anchor->trustedCert); |
|
457 |
|
458 *pCert = anchor->trustedCert; |
|
459 |
|
460 cleanup: |
|
461 PKIX_RETURN(TRUSTANCHOR); |
|
462 |
|
463 } |
|
464 |
|
465 /* |
|
466 * FUNCTION: PKIX_TrustAnchor_GetCAName (see comments in pkix_params.h) |
|
467 */ |
|
468 PKIX_Error * |
|
469 PKIX_TrustAnchor_GetCAName( |
|
470 PKIX_TrustAnchor *anchor, |
|
471 PKIX_PL_X500Name **pCAName, |
|
472 void *plContext) |
|
473 { |
|
474 PKIX_ENTER(TRUSTANCHOR, "PKIX_TrustAnchor_GetCAName"); |
|
475 PKIX_NULLCHECK_TWO(anchor, pCAName); |
|
476 |
|
477 PKIX_INCREF(anchor->caName); |
|
478 |
|
479 *pCAName = anchor->caName; |
|
480 |
|
481 cleanup: |
|
482 PKIX_RETURN(TRUSTANCHOR); |
|
483 |
|
484 } |
|
485 |
|
486 /* |
|
487 * FUNCTION: PKIX_TrustAnchor_GetCAPublicKey (see comments in pkix_params.h) |
|
488 */ |
|
489 PKIX_Error * |
|
490 PKIX_TrustAnchor_GetCAPublicKey( |
|
491 PKIX_TrustAnchor *anchor, |
|
492 PKIX_PL_PublicKey **pPubKey, |
|
493 void *plContext) |
|
494 { |
|
495 PKIX_ENTER(TRUSTANCHOR, "PKIX_TrustAnchor_GetCAPublicKey"); |
|
496 PKIX_NULLCHECK_TWO(anchor, pPubKey); |
|
497 |
|
498 PKIX_INCREF(anchor->caPubKey); |
|
499 |
|
500 *pPubKey = anchor->caPubKey; |
|
501 |
|
502 cleanup: |
|
503 PKIX_RETURN(TRUSTANCHOR); |
|
504 } |
|
505 |
|
506 /* |
|
507 * FUNCTION: PKIX_TrustAnchor_GetNameConstraints |
|
508 * (see comments in pkix_params.h) |
|
509 */ |
|
510 PKIX_Error * |
|
511 PKIX_TrustAnchor_GetNameConstraints( |
|
512 PKIX_TrustAnchor *anchor, |
|
513 PKIX_PL_CertNameConstraints **pNameConstraints, |
|
514 void *plContext) |
|
515 { |
|
516 PKIX_ENTER(TRUSTANCHOR, "PKIX_TrustAnchor_GetNameConstraints"); |
|
517 PKIX_NULLCHECK_TWO(anchor, pNameConstraints); |
|
518 |
|
519 PKIX_INCREF(anchor->nameConstraints); |
|
520 |
|
521 *pNameConstraints = anchor->nameConstraints; |
|
522 |
|
523 cleanup: |
|
524 PKIX_RETURN(TRUSTANCHOR); |
|
525 } |