Mercurial > trustbridge > nss-cmake-static
comparison nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_publickey.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_pl_publickey.c | |
6 * | |
7 * Certificate Object Functions | |
8 * | |
9 */ | |
10 | |
11 #include "pkix_pl_publickey.h" | |
12 | |
13 /* --Private-Cert-Functions------------------------------------- */ | |
14 | |
15 /* | |
16 * FUNCTION: pkix_pl_PublicKey_ToString_Helper | |
17 * DESCRIPTION: | |
18 * | |
19 * Helper function that creates a string representation of the PublicKey | |
20 * pointed to by "pkixPubKey" and stores it at "pString". | |
21 * | |
22 * PARAMETERS | |
23 * "pkixPubKey" | |
24 * Address of PublicKey whose string representation is desired. | |
25 * Must be non-NULL. | |
26 * "pString" | |
27 * Address where object pointer will be stored. Must be non-NULL. | |
28 * "plContext" - Platform-specific context pointer. | |
29 * THREAD SAFETY: | |
30 * Thread Safe (see Thread Safety Definitions in Programmer's Guide) | |
31 * RETURNS: | |
32 * Returns NULL if the function succeeds. | |
33 * Returns a PublicKey Error if the function fails in a non-fatal way. | |
34 * Returns a Fatal Error if the function fails in an unrecoverable way. | |
35 */ | |
36 static PKIX_Error * | |
37 pkix_pl_PublicKey_ToString_Helper( | |
38 PKIX_PL_PublicKey *pkixPubKey, | |
39 PKIX_PL_String **pString, | |
40 void *plContext) | |
41 { | |
42 SECAlgorithmID algorithm; | |
43 SECOidTag pubKeyTag; | |
44 char *asciiOID = NULL; | |
45 PKIX_Boolean freeAsciiOID = PKIX_FALSE; | |
46 SECItem oidBytes; | |
47 | |
48 PKIX_ENTER(PUBLICKEY, "pkix_pl_PublicKey_ToString_Helper"); | |
49 PKIX_NULLCHECK_THREE(pkixPubKey, pkixPubKey->nssSPKI, pString); | |
50 | |
51 /* | |
52 * XXX for now, we print out public key algorithm's | |
53 * description - add params and bytes later | |
54 */ | |
55 | |
56 /* | |
57 * If the algorithm OID is known to NSS, | |
58 * we print out the ASCII description that is | |
59 * registered with NSS. Otherwise, if unknown, | |
60 * we print out the OID numbers (eg. "1.2.840.3") | |
61 */ | |
62 | |
63 algorithm = pkixPubKey->nssSPKI->algorithm; | |
64 | |
65 PKIX_PUBLICKEY_DEBUG("\t\tCalling SECOID_GetAlgorithmTag).\n"); | |
66 pubKeyTag = SECOID_GetAlgorithmTag(&algorithm); | |
67 if (pubKeyTag != SEC_OID_UNKNOWN){ | |
68 PKIX_PUBLICKEY_DEBUG | |
69 ("\t\tCalling SECOID_FindOIDTagDescription).\n"); | |
70 asciiOID = (char *)SECOID_FindOIDTagDescription(pubKeyTag); | |
71 if (!asciiOID){ | |
72 PKIX_ERROR(PKIX_SECOIDFINDOIDTAGDESCRIPTIONFAILED); | |
73 } | |
74 } else { /* pubKeyTag == SEC_OID_UNKNOWN */ | |
75 oidBytes = algorithm.algorithm; | |
76 PKIX_CHECK(pkix_pl_oidBytes2Ascii | |
77 (&oidBytes, &asciiOID, plContext), | |
78 PKIX_OIDBYTES2ASCIIFAILED); | |
79 freeAsciiOID = PKIX_TRUE; | |
80 } | |
81 | |
82 PKIX_CHECK(PKIX_PL_String_Create | |
83 (PKIX_ESCASCII, (void *)asciiOID, 0, pString, plContext), | |
84 PKIX_UNABLETOCREATEPSTRING); | |
85 | |
86 cleanup: | |
87 | |
88 /* | |
89 * we only free asciiOID if it was malloc'ed by pkix_pl_oidBytes2Ascii | |
90 */ | |
91 if (freeAsciiOID){ | |
92 PKIX_FREE(asciiOID); | |
93 } | |
94 | |
95 PKIX_RETURN(PUBLICKEY); | |
96 } | |
97 | |
98 /* | |
99 * FUNCTION: pkix_pl_DestroySPKI | |
100 * DESCRIPTION: | |
101 * Frees all memory associated with the CERTSubjectPublicKeyInfo pointed to | |
102 * by "nssSPKI". | |
103 * PARAMETERS | |
104 * "nssSPKI" | |
105 * Address of CERTSubjectPublicKeyInfo. Must be non-NULL. | |
106 * "plContext" - Platform-specific context pointer. | |
107 * THREAD SAFETY: | |
108 * Thread Safe (see Thread Safety Definitions in Programmer's Guide) | |
109 * RETURNS: | |
110 * Returns NULL if the function succeeds. | |
111 * Returns an Object Error if the function fails in a non-fatal way. | |
112 * Returns a Fatal Error if the function fails in an unrecoverable way. | |
113 */ | |
114 static PKIX_Error * | |
115 pkix_pl_DestroySPKI( | |
116 CERTSubjectPublicKeyInfo *nssSPKI, | |
117 void *plContext) | |
118 { | |
119 PKIX_ENTER(PUBLICKEY, "pkix_pl_DestroySPKI"); | |
120 | |
121 PKIX_NULLCHECK_ONE(nssSPKI); | |
122 | |
123 PKIX_PUBLICKEY_DEBUG("\t\tCalling SECOID_DestroyAlgorithmID).\n"); | |
124 SECOID_DestroyAlgorithmID(&nssSPKI->algorithm, PKIX_FALSE); | |
125 | |
126 PKIX_PUBLICKEY_DEBUG("\t\tCalling SECITEM_FreeItem).\n"); | |
127 SECITEM_FreeItem(&nssSPKI->subjectPublicKey, PKIX_FALSE); | |
128 | |
129 PKIX_RETURN(PUBLICKEY); | |
130 } | |
131 | |
132 /* | |
133 * FUNCTION: pkix_pl_PublicKey_Destroy | |
134 * (see comments for PKIX_PL_DestructorCallback in pkix_pl_system.h) | |
135 */ | |
136 static PKIX_Error * | |
137 pkix_pl_PublicKey_Destroy( | |
138 PKIX_PL_Object *object, | |
139 void *plContext) | |
140 { | |
141 PKIX_PL_PublicKey *pubKey = NULL; | |
142 | |
143 PKIX_ENTER(PUBLICKEY, "pkix_pl_PublicKey_Destroy"); | |
144 | |
145 PKIX_NULLCHECK_ONE(object); | |
146 | |
147 PKIX_CHECK(pkix_CheckType(object, PKIX_PUBLICKEY_TYPE, plContext), | |
148 PKIX_OBJECTNOTPUBLICKEY); | |
149 | |
150 pubKey = (PKIX_PL_PublicKey *)object; | |
151 | |
152 if (pubKey->nssSPKI) { | |
153 | |
154 PKIX_CHECK(pkix_pl_DestroySPKI(pubKey->nssSPKI, plContext), | |
155 PKIX_DESTROYSPKIFAILED); | |
156 | |
157 PKIX_FREE(pubKey->nssSPKI); | |
158 } | |
159 | |
160 cleanup: | |
161 | |
162 PKIX_RETURN(PUBLICKEY); | |
163 } | |
164 | |
165 /* | |
166 * FUNCTION: pkix_pl_PublicKey_ToString | |
167 * (see comments for PKIX_PL_ToStringCallback in pkix_pl_system.h) | |
168 */ | |
169 static PKIX_Error * | |
170 pkix_pl_PublicKey_ToString( | |
171 PKIX_PL_Object *object, | |
172 PKIX_PL_String **pString, | |
173 void *plContext) | |
174 { | |
175 PKIX_PL_PublicKey *pkixPubKey = NULL; | |
176 PKIX_PL_String *pubKeyString = NULL; | |
177 | |
178 PKIX_ENTER(PUBLICKEY, "pkix_pl_PublicKey_toString"); | |
179 PKIX_NULLCHECK_TWO(object, pString); | |
180 | |
181 PKIX_CHECK(pkix_CheckType(object, PKIX_PUBLICKEY_TYPE, plContext), | |
182 PKIX_OBJECTNOTPUBLICKEY); | |
183 | |
184 pkixPubKey = (PKIX_PL_PublicKey *)object; | |
185 | |
186 PKIX_CHECK(pkix_pl_PublicKey_ToString_Helper | |
187 (pkixPubKey, &pubKeyString, plContext), | |
188 PKIX_PUBLICKEYTOSTRINGHELPERFAILED); | |
189 | |
190 *pString = pubKeyString; | |
191 | |
192 cleanup: | |
193 | |
194 PKIX_RETURN(PUBLICKEY); | |
195 } | |
196 | |
197 /* | |
198 * FUNCTION: pkix_pl_PublicKey_Hashcode | |
199 * (see comments for PKIX_PL_HashcodeCallback in pkix_pl_system.h) | |
200 */ | |
201 static PKIX_Error * | |
202 pkix_pl_PublicKey_Hashcode( | |
203 PKIX_PL_Object *object, | |
204 PKIX_UInt32 *pHashcode, | |
205 void *plContext) | |
206 { | |
207 PKIX_PL_PublicKey *pkixPubKey = NULL; | |
208 SECItem algOID; | |
209 SECItem algParams; | |
210 SECItem nssPubKey; | |
211 PKIX_UInt32 algOIDHash; | |
212 PKIX_UInt32 algParamsHash; | |
213 PKIX_UInt32 pubKeyHash; | |
214 PKIX_UInt32 fullHash; | |
215 | |
216 PKIX_ENTER(PUBLICKEY, "pkix_pl_PublicKey_Hashcode"); | |
217 PKIX_NULLCHECK_TWO(object, pHashcode); | |
218 | |
219 PKIX_CHECK(pkix_CheckType(object, PKIX_PUBLICKEY_TYPE, plContext), | |
220 PKIX_OBJECTNOTPUBLICKEY); | |
221 | |
222 pkixPubKey = (PKIX_PL_PublicKey *)object; | |
223 | |
224 PKIX_NULLCHECK_ONE(pkixPubKey->nssSPKI); | |
225 | |
226 algOID = pkixPubKey->nssSPKI->algorithm.algorithm; | |
227 algParams = pkixPubKey->nssSPKI->algorithm.parameters; | |
228 nssPubKey = pkixPubKey->nssSPKI->subjectPublicKey; | |
229 | |
230 PKIX_CHECK(pkix_hash | |
231 (algOID.data, algOID.len, &algOIDHash, plContext), | |
232 PKIX_HASHFAILED); | |
233 | |
234 PKIX_CHECK(pkix_hash | |
235 (algParams.data, algParams.len, &algParamsHash, plContext), | |
236 PKIX_HASHFAILED); | |
237 | |
238 PKIX_CHECK(pkix_hash | |
239 (nssPubKey.data, nssPubKey.len, &pubKeyHash, plContext), | |
240 PKIX_HASHFAILED); | |
241 | |
242 fullHash = algOIDHash + algParamsHash + pubKeyHash; | |
243 | |
244 *pHashcode = pubKeyHash; | |
245 | |
246 cleanup: | |
247 | |
248 PKIX_RETURN(PUBLICKEY); | |
249 } | |
250 | |
251 | |
252 /* | |
253 * FUNCTION: pkix_pl_PublicKey_Equals | |
254 * (see comments for PKIX_PL_Equals_Callback in pkix_pl_system.h) | |
255 */ | |
256 static PKIX_Error * | |
257 pkix_pl_PublicKey_Equals( | |
258 PKIX_PL_Object *firstObject, | |
259 PKIX_PL_Object *secondObject, | |
260 PKIX_Boolean *pResult, | |
261 void *plContext) | |
262 { | |
263 PKIX_PL_PublicKey *firstPKIXPubKey = NULL; | |
264 PKIX_PL_PublicKey *secondPKIXPubKey = NULL; | |
265 CERTSubjectPublicKeyInfo *firstSPKI = NULL; | |
266 CERTSubjectPublicKeyInfo *secondSPKI = NULL; | |
267 SECComparison cmpResult; | |
268 PKIX_UInt32 secondType; | |
269 | |
270 PKIX_ENTER(PUBLICKEY, "pkix_pl_PublicKey_Equals"); | |
271 PKIX_NULLCHECK_THREE(firstObject, secondObject, pResult); | |
272 | |
273 /* test that firstObject is a PublicKey */ | |
274 PKIX_CHECK(pkix_CheckType(firstObject, PKIX_PUBLICKEY_TYPE, plContext), | |
275 PKIX_FIRSTOBJECTNOTPUBLICKEY); | |
276 | |
277 /* | |
278 * Since we know firstObject is a PublicKey, if both references are | |
279 * identical, they must be equal | |
280 */ | |
281 if (firstObject == secondObject){ | |
282 *pResult = PKIX_TRUE; | |
283 goto cleanup; | |
284 } | |
285 | |
286 /* | |
287 * If secondObject isn't a PublicKey, we don't throw an error. | |
288 * We simply return a Boolean result of FALSE | |
289 */ | |
290 *pResult = PKIX_FALSE; | |
291 PKIX_CHECK(PKIX_PL_Object_GetType | |
292 (secondObject, &secondType, plContext), | |
293 PKIX_COULDNOTGETTYPEOFSECONDARGUMENT); | |
294 if (secondType != PKIX_PUBLICKEY_TYPE) goto cleanup; | |
295 | |
296 firstPKIXPubKey = ((PKIX_PL_PublicKey *)firstObject); | |
297 secondPKIXPubKey = (PKIX_PL_PublicKey *)secondObject; | |
298 | |
299 firstSPKI = firstPKIXPubKey->nssSPKI; | |
300 secondSPKI = secondPKIXPubKey->nssSPKI; | |
301 | |
302 PKIX_NULLCHECK_TWO(firstSPKI, secondSPKI); | |
303 | |
304 PKIX_PL_NSSCALLRV(PUBLICKEY, cmpResult, SECOID_CompareAlgorithmID, | |
305 (&firstSPKI->algorithm, &secondSPKI->algorithm)); | |
306 | |
307 if (cmpResult == SECEqual){ | |
308 PKIX_PUBLICKEY_DEBUG("\t\tCalling SECITEM_CompareItem).\n"); | |
309 cmpResult = SECITEM_CompareItem | |
310 (&firstSPKI->subjectPublicKey, | |
311 &secondSPKI->subjectPublicKey); | |
312 } | |
313 | |
314 *pResult = (cmpResult == SECEqual)?PKIX_TRUE:PKIX_FALSE; | |
315 | |
316 cleanup: | |
317 | |
318 PKIX_RETURN(PUBLICKEY); | |
319 } | |
320 | |
321 /* | |
322 * FUNCTION: pkix_pl_PublicKey_RegisterSelf | |
323 * DESCRIPTION: | |
324 * Registers PKIX_PUBLICKEY_TYPE and its related functions with systemClasses[] | |
325 * THREAD SAFETY: | |
326 * Not Thread Safe - for performance and complexity reasons | |
327 * | |
328 * Since this function is only called by PKIX_PL_Initialize, which should | |
329 * only be called once, it is acceptable that this function is not | |
330 * thread-safe. | |
331 */ | |
332 PKIX_Error * | |
333 pkix_pl_PublicKey_RegisterSelf(void *plContext) | |
334 { | |
335 | |
336 extern pkix_ClassTable_Entry systemClasses[PKIX_NUMTYPES]; | |
337 pkix_ClassTable_Entry entry; | |
338 | |
339 PKIX_ENTER(PUBLICKEY, "pkix_pl_PublicKey_RegisterSelf"); | |
340 | |
341 entry.description = "PublicKey"; | |
342 entry.objCounter = 0; | |
343 entry.typeObjectSize = sizeof(PKIX_PL_PublicKey); | |
344 entry.destructor = pkix_pl_PublicKey_Destroy; | |
345 entry.equalsFunction = pkix_pl_PublicKey_Equals; | |
346 entry.hashcodeFunction = pkix_pl_PublicKey_Hashcode; | |
347 entry.toStringFunction = pkix_pl_PublicKey_ToString; | |
348 entry.comparator = NULL; | |
349 entry.duplicateFunction = pkix_duplicateImmutable; | |
350 systemClasses[PKIX_PUBLICKEY_TYPE] = entry; | |
351 | |
352 PKIX_RETURN(PUBLICKEY); | |
353 } | |
354 | |
355 /* --Public-Functions------------------------------------------------------- */ | |
356 | |
357 /* | |
358 * FUNCTION: PKIX_PL_PublicKey_NeedsDSAParameters | |
359 * (see comments in pkix_pl_pki.h) | |
360 */ | |
361 PKIX_Error * | |
362 PKIX_PL_PublicKey_NeedsDSAParameters( | |
363 PKIX_PL_PublicKey *pubKey, | |
364 PKIX_Boolean *pNeedsParams, | |
365 void *plContext) | |
366 { | |
367 CERTSubjectPublicKeyInfo *nssSPKI = NULL; | |
368 KeyType pubKeyType; | |
369 PKIX_Boolean needsParams = PKIX_FALSE; | |
370 | |
371 PKIX_ENTER(PUBLICKEY, "PKIX_PL_PublicKey_NeedsDSAParameters"); | |
372 PKIX_NULLCHECK_TWO(pubKey, pNeedsParams); | |
373 | |
374 nssSPKI = pubKey->nssSPKI; | |
375 | |
376 PKIX_PUBLICKEY_DEBUG("\t\tCalling CERT_GetCertKeyType).\n"); | |
377 pubKeyType = CERT_GetCertKeyType(nssSPKI); | |
378 if (!pubKeyType){ | |
379 PKIX_ERROR(PKIX_PUBKEYTYPENULLKEY); | |
380 } | |
381 | |
382 if ((pubKeyType == dsaKey) && | |
383 (nssSPKI->algorithm.parameters.len == 0)){ | |
384 needsParams = PKIX_TRUE; | |
385 } | |
386 | |
387 *pNeedsParams = needsParams; | |
388 | |
389 cleanup: | |
390 | |
391 PKIX_RETURN(PUBLICKEY); | |
392 } | |
393 | |
394 /* | |
395 * FUNCTION: PKIX_PL_PublicKey_MakeInheritedDSAPublicKey | |
396 * (see comments in pkix_pl_pki.h) | |
397 */ | |
398 PKIX_Error * | |
399 PKIX_PL_PublicKey_MakeInheritedDSAPublicKey( | |
400 PKIX_PL_PublicKey *firstKey, | |
401 PKIX_PL_PublicKey *secondKey, | |
402 PKIX_PL_PublicKey **pResultKey, | |
403 void *plContext) | |
404 { | |
405 CERTSubjectPublicKeyInfo *firstSPKI = NULL; | |
406 CERTSubjectPublicKeyInfo *secondSPKI = NULL; | |
407 CERTSubjectPublicKeyInfo *thirdSPKI = NULL; | |
408 PKIX_PL_PublicKey *resultKey = NULL; | |
409 KeyType firstPubKeyType; | |
410 KeyType secondPubKeyType; | |
411 SECStatus rv; | |
412 | |
413 PKIX_ENTER(PUBLICKEY, "PKIX_PL_PublicKey_MakeInheritedDSAPublicKey"); | |
414 PKIX_NULLCHECK_THREE(firstKey, secondKey, pResultKey); | |
415 PKIX_NULLCHECK_TWO(firstKey->nssSPKI, secondKey->nssSPKI); | |
416 | |
417 firstSPKI = firstKey->nssSPKI; | |
418 secondSPKI = secondKey->nssSPKI; | |
419 | |
420 PKIX_PUBLICKEY_DEBUG("\t\tCalling CERT_GetCertKeyType).\n"); | |
421 firstPubKeyType = CERT_GetCertKeyType(firstSPKI); | |
422 if (!firstPubKeyType){ | |
423 PKIX_ERROR(PKIX_FIRSTPUBKEYTYPENULLKEY); | |
424 } | |
425 | |
426 PKIX_PUBLICKEY_DEBUG("\t\tCalling CERT_GetCertKeyType).\n"); | |
427 secondPubKeyType = CERT_GetCertKeyType(secondSPKI); | |
428 if (!secondPubKeyType){ | |
429 PKIX_ERROR(PKIX_SECONDPUBKEYTYPENULLKEY); | |
430 } | |
431 | |
432 if ((firstPubKeyType == dsaKey) && | |
433 (firstSPKI->algorithm.parameters.len == 0)){ | |
434 if (secondPubKeyType != dsaKey) { | |
435 PKIX_ERROR(PKIX_SECONDKEYNOTDSAPUBLICKEY); | |
436 } else if (secondSPKI->algorithm.parameters.len == 0) { | |
437 PKIX_ERROR | |
438 (PKIX_SECONDKEYDSAPUBLICKEY); | |
439 } else { | |
440 PKIX_CHECK(PKIX_PL_Calloc | |
441 (1, | |
442 sizeof (CERTSubjectPublicKeyInfo), | |
443 (void **)&thirdSPKI, | |
444 plContext), | |
445 PKIX_CALLOCFAILED); | |
446 | |
447 PKIX_PUBLICKEY_DEBUG | |
448 ("\t\tCalling" | |
449 "SECKEY_CopySubjectPublicKeyInfo).\n"); | |
450 rv = SECKEY_CopySubjectPublicKeyInfo | |
451 (NULL, thirdSPKI, firstSPKI); | |
452 if (rv != SECSuccess) { | |
453 PKIX_ERROR | |
454 (PKIX_SECKEYCOPYSUBJECTPUBLICKEYINFOFAILED); | |
455 } | |
456 | |
457 PKIX_PUBLICKEY_DEBUG | |
458 ("\t\tCalling SECITEM_CopyItem).\n"); | |
459 rv = SECITEM_CopyItem(NULL, | |
460 &thirdSPKI->algorithm.parameters, | |
461 &secondSPKI->algorithm.parameters); | |
462 | |
463 if (rv != SECSuccess) { | |
464 PKIX_ERROR(PKIX_OUTOFMEMORY); | |
465 } | |
466 | |
467 /* create a PKIX_PL_PublicKey object */ | |
468 PKIX_CHECK(PKIX_PL_Object_Alloc | |
469 (PKIX_PUBLICKEY_TYPE, | |
470 sizeof (PKIX_PL_PublicKey), | |
471 (PKIX_PL_Object **)&resultKey, | |
472 plContext), | |
473 PKIX_COULDNOTCREATEOBJECT); | |
474 | |
475 /* populate the SPKI field */ | |
476 resultKey->nssSPKI = thirdSPKI; | |
477 *pResultKey = resultKey; | |
478 } | |
479 } else { | |
480 *pResultKey = NULL; | |
481 } | |
482 | |
483 cleanup: | |
484 | |
485 if (thirdSPKI && PKIX_ERROR_RECEIVED){ | |
486 PKIX_CHECK(pkix_pl_DestroySPKI(thirdSPKI, plContext), | |
487 PKIX_DESTROYSPKIFAILED); | |
488 PKIX_FREE(thirdSPKI); | |
489 } | |
490 | |
491 PKIX_RETURN(PUBLICKEY); | |
492 } |