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 }
This site is hosted by Intevation GmbH (Datenschutzerklärung und Impressum | Privacy Policy and Imprint)