Wed, 31 Dec 2014 06:09:35 +0100
Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.
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 */
11 #include "pkix_trustanchor.h"
13 /* --Private-Functions-------------------------------------------- */
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;
26 PKIX_ENTER(TRUSTANCHOR, "pkix_TrustAnchor_Destroy");
27 PKIX_NULLCHECK_ONE(object);
29 /* Check that this object is a trust anchor */
30 PKIX_CHECK(pkix_CheckType(object, PKIX_TRUSTANCHOR_TYPE, plContext),
31 PKIX_OBJECTNOTTRUSTANCHOR);
33 anchor = (PKIX_TrustAnchor *)object;
35 PKIX_DECREF(anchor->trustedCert);
36 PKIX_DECREF(anchor->caName);
37 PKIX_DECREF(anchor->caPubKey);
38 PKIX_DECREF(anchor->nameConstraints);
40 cleanup:
42 PKIX_RETURN(TRUSTANCHOR);
43 }
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;
63 PKIX_ENTER(TRUSTANCHOR, "pkix_TrustAnchor_Equals");
64 PKIX_NULLCHECK_THREE(first, second, pResult);
66 PKIX_CHECK(pkix_CheckType(first, PKIX_TRUSTANCHOR_TYPE, plContext),
67 PKIX_FIRSTOBJECTNOTTRUSTANCHOR);
69 PKIX_CHECK(PKIX_PL_Object_GetType(second, &secondType, plContext),
70 PKIX_COULDNOTGETTYPEOFSECONDARGUMENT);
72 *pResult = PKIX_FALSE;
74 if (secondType != PKIX_TRUSTANCHOR_TYPE) goto cleanup;
76 firstAnchor = (PKIX_TrustAnchor *)first;
77 secondAnchor = (PKIX_TrustAnchor *)second;
79 firstCert = firstAnchor->trustedCert;
80 secondCert = secondAnchor->trustedCert;
82 if ((firstCert && !secondCert) || (!firstCert && secondCert)){
83 goto cleanup;
84 }
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);
101 if (!cmpResult) goto cleanup;
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);
110 if (!cmpResult) goto cleanup;
112 PKIX_EQUALS
113 (firstAnchor->nameConstraints,
114 secondAnchor->nameConstraints,
115 &cmpResult,
116 plContext,
117 PKIX_OBJECTEQUALSFAILED);
119 if (!cmpResult) goto cleanup;
121 }
123 *pResult = cmpResult;
125 cleanup:
127 PKIX_RETURN(TRUSTANCHOR);
128 }
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;
148 PKIX_ENTER(TRUSTANCHOR, "pkix_TrustAnchor_Hashcode");
149 PKIX_NULLCHECK_TWO(object, pHashcode);
151 PKIX_CHECK(pkix_CheckType(object, PKIX_TRUSTANCHOR_TYPE, plContext),
152 PKIX_OBJECTNOTTRUSTANCHOR);
154 anchor = (PKIX_TrustAnchor*)object;
155 cert = anchor->trustedCert;
157 if (cert){
158 PKIX_CHECK(PKIX_PL_Object_Hashcode
159 ((PKIX_PL_Object *)cert,
160 &certHash,
161 plContext),
162 PKIX_OBJECTHASHCODEFAILED);
164 hash = certHash;
166 } else {
167 PKIX_CHECK(PKIX_PL_Object_Hashcode
168 ((PKIX_PL_Object *)anchor->caName,
169 &nameHash,
170 plContext),
171 PKIX_OBJECTHASHCODEFAILED);
173 PKIX_CHECK(PKIX_PL_Object_Hashcode
174 ((PKIX_PL_Object *)anchor->caPubKey,
175 &pubKeyHash,
176 plContext),
177 PKIX_OBJECTHASHCODEFAILED);
179 PKIX_HASHCODE(anchor->nameConstraints, &ncHash, plContext,
180 PKIX_OBJECTHASHCODEFAILED);
182 hash = 31 * nameHash + pubKeyHash + ncHash;
184 }
186 *pHashcode = hash;
188 cleanup:
190 PKIX_RETURN(TRUSTANCHOR);
191 }
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;
212 PKIX_ENTER(TRUSTANCHOR, "pkix_TrustAnchor_ToString");
213 PKIX_NULLCHECK_TWO(object, pString);
215 PKIX_CHECK(pkix_CheckType(object, PKIX_TRUSTANCHOR_TYPE, plContext),
216 PKIX_OBJECTNOTTRUSTANCHOR);
218 anchor = (PKIX_TrustAnchor*)object;
220 if (anchor->trustedCert){
221 asciiFormat =
222 "[\n"
223 "\tTrusted Cert: %s\n"
224 "]\n";
226 PKIX_CHECK(PKIX_PL_String_Create
227 (PKIX_ESCASCII,
228 asciiFormat,
229 0,
230 &formatString,
231 plContext),
232 PKIX_STRINGCREATEFAILED);
234 PKIX_CHECK(PKIX_PL_Object_ToString
235 ((PKIX_PL_Object *)anchor->trustedCert,
236 &certString,
237 plContext),
238 PKIX_OBJECTTOSTRINGFAILED);
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";
254 PKIX_CHECK(PKIX_PL_String_Create
255 (PKIX_ESCASCII,
256 asciiFormat,
257 0,
258 &formatString,
259 plContext),
260 PKIX_STRINGCREATEFAILED);
262 PKIX_CHECK(PKIX_PL_Object_ToString
263 ((PKIX_PL_Object *)anchor->caName,
264 &nameString,
265 plContext),
266 PKIX_OBJECTTOSTRINGFAILED);
268 PKIX_CHECK(PKIX_PL_Object_ToString
269 ((PKIX_PL_Object *)anchor->caPubKey,
270 &pubKeyString,
271 plContext),
272 PKIX_OBJECTTOSTRINGFAILED);
274 PKIX_TOSTRING
275 (anchor->nameConstraints,
276 &nameConstraintsString,
277 plContext,
278 PKIX_OBJECTTOSTRINGFAILED);
280 PKIX_CHECK(PKIX_PL_Sprintf
281 (&anchorString,
282 plContext,
283 formatString,
284 nameString,
285 pubKeyString,
286 nameConstraintsString),
287 PKIX_SPRINTFFAILED);
288 }
290 *pString = anchorString;
292 cleanup:
294 PKIX_DECREF(formatString);
295 PKIX_DECREF(certString);
296 PKIX_DECREF(nameString);
297 PKIX_DECREF(pubKeyString);
298 PKIX_DECREF(nameConstraintsString);
300 PKIX_RETURN(TRUSTANCHOR);
301 }
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;
321 PKIX_ENTER(TRUSTANCHOR, "pkix_TrustAnchor_RegisterSelf");
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;
333 systemClasses[PKIX_TRUSTANCHOR_TYPE] = entry;
335 PKIX_RETURN(TRUSTANCHOR);
336 }
338 /* --Public-Functions--------------------------------------------- */
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;
352 PKIX_ENTER(TRUSTANCHOR, "PKIX_TrustAnchor_CreateWithCert");
353 PKIX_NULLCHECK_TWO(cert, pAnchor);
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);
362 /* initialize fields */
363 PKIX_CHECK(
364 PKIX_PL_Cert_SetAsTrustAnchor(cert, plContext),
365 PKIX_CERTSETASTRUSTANCHORFAILED);
367 PKIX_INCREF(cert);
368 anchor->trustedCert = cert;
370 anchor->caName = NULL;
371 anchor->caPubKey = NULL;
373 PKIX_CHECK(PKIX_PL_Cert_GetNameConstraints
374 (anchor->trustedCert, &anchor->nameConstraints, plContext),
375 PKIX_CERTGETNAMECONSTRAINTSFAILED);
378 *pAnchor = anchor;
379 anchor = NULL;
381 cleanup:
383 PKIX_DECREF(anchor);
385 PKIX_RETURN(TRUSTANCHOR);
387 }
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;
403 PKIX_ENTER(TRUSTANCHOR, "PKIX_TrustAnchor_CreateWithNameKeyPair");
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
414 PKIX_NULLCHECK_THREE(name, pubKey, pAnchor);
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);
423 /* initialize fields */
424 anchor->trustedCert = NULL;
426 PKIX_INCREF(name);
427 anchor->caName = name;
429 PKIX_INCREF(pubKey);
430 anchor->caPubKey = pubKey;
432 PKIX_INCREF(nameConstraints);
433 anchor->nameConstraints = nameConstraints;
435 *pAnchor = anchor;
436 anchor = NULL;
437 cleanup:
439 PKIX_DECREF(anchor);
441 PKIX_RETURN(TRUSTANCHOR);
442 }
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);
456 PKIX_INCREF(anchor->trustedCert);
458 *pCert = anchor->trustedCert;
460 cleanup:
461 PKIX_RETURN(TRUSTANCHOR);
463 }
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);
477 PKIX_INCREF(anchor->caName);
479 *pCAName = anchor->caName;
481 cleanup:
482 PKIX_RETURN(TRUSTANCHOR);
484 }
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);
498 PKIX_INCREF(anchor->caPubKey);
500 *pPubKey = anchor->caPubKey;
502 cleanup:
503 PKIX_RETURN(TRUSTANCHOR);
504 }
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);
519 PKIX_INCREF(anchor->nameConstraints);
521 *pNameConstraints = anchor->nameConstraints;
523 cleanup:
524 PKIX_RETURN(TRUSTANCHOR);
525 }