comparison nss/lib/pk11wrap/pk11akey.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 * This file contains functions to manage asymetric keys, (public and
6 * private keys).
7 */
8 #include "seccomon.h"
9 #include "secmod.h"
10 #include "secmodi.h"
11 #include "secmodti.h"
12 #include "pkcs11.h"
13 #include "pkcs11t.h"
14 #include "pk11func.h"
15 #include "cert.h"
16 #include "key.h"
17 #include "secitem.h"
18 #include "secasn1.h"
19 #include "secoid.h"
20 #include "secerr.h"
21 #include "sslerr.h"
22 #include "sechash.h"
23
24 #include "secpkcs5.h"
25 #include "blapit.h"
26
27 static SECItem *
28 pk11_MakeIDFromPublicKey(SECKEYPublicKey *pubKey)
29 {
30 /* set the ID to the public key so we can find it again */
31 SECItem *pubKeyIndex = NULL;
32 switch (pubKey->keyType) {
33 case rsaKey:
34 pubKeyIndex = &pubKey->u.rsa.modulus;
35 break;
36 case dsaKey:
37 pubKeyIndex = &pubKey->u.dsa.publicValue;
38 break;
39 case dhKey:
40 pubKeyIndex = &pubKey->u.dh.publicValue;
41 break;
42 case ecKey:
43 pubKeyIndex = &pubKey->u.ec.publicValue;
44 break;
45 default:
46 return NULL;
47 }
48 PORT_Assert(pubKeyIndex != NULL);
49
50 return PK11_MakeIDFromPubKey(pubKeyIndex);
51 }
52
53 /*
54 * import a public key into the desired slot
55 *
56 * This function takes a public key structure and creates a public key in a
57 * given slot. If isToken is set, then a persistant public key is created.
58 *
59 * Note: it is possible for this function to return a handle for a key which
60 * is persistant, even if isToken is not set.
61 */
62 CK_OBJECT_HANDLE
63 PK11_ImportPublicKey(PK11SlotInfo *slot, SECKEYPublicKey *pubKey,
64 PRBool isToken)
65 {
66 CK_BBOOL cktrue = CK_TRUE;
67 CK_BBOOL ckfalse = CK_FALSE;
68 CK_OBJECT_CLASS keyClass = CKO_PUBLIC_KEY;
69 CK_KEY_TYPE keyType = CKK_GENERIC_SECRET;
70 CK_OBJECT_HANDLE objectID;
71 CK_ATTRIBUTE theTemplate[11];
72 CK_ATTRIBUTE *signedattr = NULL;
73 CK_ATTRIBUTE *attrs = theTemplate;
74 SECItem *ckaId = NULL;
75 SECItem *pubValue = NULL;
76 int signedcount = 0;
77 int templateCount = 0;
78 SECStatus rv;
79
80 /* if we already have an object in the desired slot, use it */
81 if (!isToken && pubKey->pkcs11Slot == slot) {
82 return pubKey->pkcs11ID;
83 }
84
85 /* free the existing key */
86 if (pubKey->pkcs11Slot != NULL) {
87 PK11SlotInfo *oSlot = pubKey->pkcs11Slot;
88 if (!PK11_IsPermObject(pubKey->pkcs11Slot,pubKey->pkcs11ID)) {
89 PK11_EnterSlotMonitor(oSlot);
90 (void) PK11_GETTAB(oSlot)->C_DestroyObject(oSlot->session,
91 pubKey->pkcs11ID);
92 PK11_ExitSlotMonitor(oSlot);
93 }
94 PK11_FreeSlot(oSlot);
95 pubKey->pkcs11Slot = NULL;
96 }
97 PK11_SETATTRS(attrs, CKA_CLASS, &keyClass, sizeof(keyClass) ); attrs++;
98 PK11_SETATTRS(attrs, CKA_KEY_TYPE, &keyType, sizeof(keyType) ); attrs++;
99 PK11_SETATTRS(attrs, CKA_TOKEN, isToken ? &cktrue : &ckfalse,
100 sizeof(CK_BBOOL) ); attrs++;
101 if (isToken) {
102 ckaId = pk11_MakeIDFromPublicKey(pubKey);
103 if (ckaId == NULL) {
104 PORT_SetError( SEC_ERROR_BAD_KEY );
105 return CK_INVALID_HANDLE;
106 }
107 PK11_SETATTRS(attrs, CKA_ID, ckaId->data, ckaId->len); attrs++;
108 }
109
110 /* now import the key */
111 {
112 switch (pubKey->keyType) {
113 case rsaKey:
114 keyType = CKK_RSA;
115 PK11_SETATTRS(attrs, CKA_WRAP, &cktrue, sizeof(CK_BBOOL) ); attrs++;
116 PK11_SETATTRS(attrs, CKA_ENCRYPT, &cktrue,
117 sizeof(CK_BBOOL) ); attrs++;
118 PK11_SETATTRS(attrs, CKA_VERIFY, &cktrue, sizeof(CK_BBOOL)); attrs++;
119 signedattr = attrs;
120 PK11_SETATTRS(attrs, CKA_MODULUS, pubKey->u.rsa.modulus.data,
121 pubKey->u.rsa.modulus.len); attrs++;
122 PK11_SETATTRS(attrs, CKA_PUBLIC_EXPONENT,
123 pubKey->u.rsa.publicExponent.data,
124 pubKey->u.rsa.publicExponent.len); attrs++;
125 break;
126 case dsaKey:
127 keyType = CKK_DSA;
128 PK11_SETATTRS(attrs, CKA_VERIFY, &cktrue, sizeof(CK_BBOOL));attrs++;
129 signedattr = attrs;
130 PK11_SETATTRS(attrs, CKA_PRIME, pubKey->u.dsa.params.prime.data,
131 pubKey->u.dsa.params.prime.len); attrs++;
132 PK11_SETATTRS(attrs,CKA_SUBPRIME,pubKey->u.dsa.params.subPrime.data,
133 pubKey->u.dsa.params.subPrime.len); attrs++;
134 PK11_SETATTRS(attrs, CKA_BASE, pubKey->u.dsa.params.base.data,
135 pubKey->u.dsa.params.base.len); attrs++;
136 PK11_SETATTRS(attrs, CKA_VALUE, pubKey->u.dsa.publicValue.data,
137 pubKey->u.dsa.publicValue.len); attrs++;
138 break;
139 case dhKey:
140 keyType = CKK_DH;
141 PK11_SETATTRS(attrs, CKA_DERIVE, &cktrue, sizeof(CK_BBOOL));attrs++;
142 signedattr = attrs;
143 PK11_SETATTRS(attrs, CKA_PRIME, pubKey->u.dh.prime.data,
144 pubKey->u.dh.prime.len); attrs++;
145 PK11_SETATTRS(attrs, CKA_BASE, pubKey->u.dh.base.data,
146 pubKey->u.dh.base.len); attrs++;
147 PK11_SETATTRS(attrs, CKA_VALUE, pubKey->u.dh.publicValue.data,
148 pubKey->u.dh.publicValue.len); attrs++;
149 break;
150 case ecKey:
151 keyType = CKK_EC;
152 PK11_SETATTRS(attrs, CKA_VERIFY, &cktrue, sizeof(CK_BBOOL));attrs++;
153 PK11_SETATTRS(attrs, CKA_DERIVE, &cktrue, sizeof(CK_BBOOL));attrs++;
154 signedattr = attrs;
155 PK11_SETATTRS(attrs, CKA_EC_PARAMS,
156 pubKey->u.ec.DEREncodedParams.data,
157 pubKey->u.ec.DEREncodedParams.len); attrs++;
158 if (PR_GetEnv("NSS_USE_DECODED_CKA_EC_POINT")) {
159 PK11_SETATTRS(attrs, CKA_EC_POINT,
160 pubKey->u.ec.publicValue.data,
161 pubKey->u.ec.publicValue.len); attrs++;
162 } else {
163 pubValue = SEC_ASN1EncodeItem(NULL, NULL,
164 &pubKey->u.ec.publicValue,
165 SEC_ASN1_GET(SEC_OctetStringTemplate));
166 if (pubValue == NULL) {
167 if (ckaId) {
168 SECITEM_FreeItem(ckaId,PR_TRUE);
169 }
170 return CK_INVALID_HANDLE;
171 }
172 PK11_SETATTRS(attrs, CKA_EC_POINT,
173 pubValue->data, pubValue->len); attrs++;
174 }
175 break;
176 default:
177 if (ckaId) {
178 SECITEM_FreeItem(ckaId,PR_TRUE);
179 }
180 PORT_SetError( SEC_ERROR_BAD_KEY );
181 return CK_INVALID_HANDLE;
182 }
183
184 templateCount = attrs - theTemplate;
185 signedcount = attrs - signedattr;
186 PORT_Assert(templateCount <= (sizeof(theTemplate)/sizeof(CK_ATTRIBUTE)));
187 for (attrs=signedattr; signedcount; attrs++, signedcount--) {
188 pk11_SignedToUnsigned(attrs);
189 }
190 rv = PK11_CreateNewObject(slot, CK_INVALID_SESSION, theTemplate,
191 templateCount, isToken, &objectID);
192 if (ckaId) {
193 SECITEM_FreeItem(ckaId,PR_TRUE);
194 }
195 if (pubValue) {
196 SECITEM_FreeItem(pubValue,PR_TRUE);
197 }
198 if ( rv != SECSuccess) {
199 /* CKR_ATTRIBUTE_VALUE_INVALID is mapped to SEC_ERROR_BAD_DATA */
200 if (PORT_GetError() == SEC_ERROR_BAD_DATA) {
201 PORT_SetError( SEC_ERROR_BAD_KEY );
202 }
203 return CK_INVALID_HANDLE;
204 }
205 }
206
207 pubKey->pkcs11ID = objectID;
208 pubKey->pkcs11Slot = PK11_ReferenceSlot(slot);
209
210 return objectID;
211 }
212
213 /*
214 * take an attribute and copy it into a secitem
215 */
216 static CK_RV
217 pk11_Attr2SecItem(PLArenaPool *arena, const CK_ATTRIBUTE *attr, SECItem *item)
218 {
219 item->data = NULL;
220
221 (void)SECITEM_AllocItem(arena, item, attr->ulValueLen);
222 if (item->data == NULL) {
223 return CKR_HOST_MEMORY;
224 }
225 PORT_Memcpy(item->data, attr->pValue, item->len);
226 return CKR_OK;
227 }
228
229
230 /*
231 * get a curve length from a set of ecParams.
232 *
233 * We need this so we can reliably determine if the ecPoint passed to us
234 * was encoded or not. With out this, for many curves, we would incorrectly
235 * identify an unencoded curve as an encoded curve 1 in 65536 times, and for
236 * a few we would make that same mistake 1 in 32768 times. These are bad
237 * numbers since they are rare enough to pass tests, but common enough to
238 * be tripped over in the field.
239 *
240 * This function will only work for curves we recognized as of March 2009.
241 * The assumption is curves in use after March of 2009 would be supplied by
242 * PKCS #11 modules that already pass the correct encoding to us.
243 *
244 * Point length = (Roundup(curveLenInBits/8)*2+1)
245 */
246 static int
247 pk11_get_EC_PointLenInBytes(PLArenaPool *arena, const SECItem *ecParams)
248 {
249 SECItem oid;
250 SECOidTag tag;
251 SECStatus rv;
252
253 /* decode the OID tag */
254 rv = SEC_QuickDERDecodeItem(arena, &oid,
255 SEC_ASN1_GET(SEC_ObjectIDTemplate), ecParams);
256 if (rv != SECSuccess) {
257 /* could be explict curves, allow them to work if the
258 * PKCS #11 module support them. If we try to parse the
259 * explicit curve value in the future, we may return -1 here
260 * to indicate an invalid parameter if the explicit curve
261 * decode fails. */
262 return 0;
263 }
264
265 tag = SECOID_FindOIDTag(&oid);
266 switch (tag) {
267 case SEC_OID_SECG_EC_SECP112R1:
268 case SEC_OID_SECG_EC_SECP112R2:
269 return 29; /* curve len in bytes = 14 bytes */
270 case SEC_OID_SECG_EC_SECT113R1:
271 case SEC_OID_SECG_EC_SECT113R2:
272 return 31; /* curve len in bytes = 15 bytes */
273 case SEC_OID_SECG_EC_SECP128R1:
274 case SEC_OID_SECG_EC_SECP128R2:
275 return 33; /* curve len in bytes = 16 bytes */
276 case SEC_OID_SECG_EC_SECT131R1:
277 case SEC_OID_SECG_EC_SECT131R2:
278 return 35; /* curve len in bytes = 17 bytes */
279 case SEC_OID_SECG_EC_SECP160K1:
280 case SEC_OID_SECG_EC_SECP160R1:
281 case SEC_OID_SECG_EC_SECP160R2:
282 return 41; /* curve len in bytes = 20 bytes */
283 case SEC_OID_SECG_EC_SECT163K1:
284 case SEC_OID_SECG_EC_SECT163R1:
285 case SEC_OID_SECG_EC_SECT163R2:
286 case SEC_OID_ANSIX962_EC_C2PNB163V1:
287 case SEC_OID_ANSIX962_EC_C2PNB163V2:
288 case SEC_OID_ANSIX962_EC_C2PNB163V3:
289 return 43; /* curve len in bytes = 21 bytes */
290 case SEC_OID_ANSIX962_EC_C2PNB176V1:
291 return 45; /* curve len in bytes = 22 bytes */
292 case SEC_OID_ANSIX962_EC_C2TNB191V1:
293 case SEC_OID_ANSIX962_EC_C2TNB191V2:
294 case SEC_OID_ANSIX962_EC_C2TNB191V3:
295 case SEC_OID_SECG_EC_SECP192K1:
296 case SEC_OID_ANSIX962_EC_PRIME192V1:
297 case SEC_OID_ANSIX962_EC_PRIME192V2:
298 case SEC_OID_ANSIX962_EC_PRIME192V3:
299 return 49; /*curve len in bytes = 24 bytes */
300 case SEC_OID_SECG_EC_SECT193R1:
301 case SEC_OID_SECG_EC_SECT193R2:
302 return 51; /*curve len in bytes = 25 bytes */
303 case SEC_OID_ANSIX962_EC_C2PNB208W1:
304 return 53; /*curve len in bytes = 26 bytes */
305 case SEC_OID_SECG_EC_SECP224K1:
306 case SEC_OID_SECG_EC_SECP224R1:
307 return 57; /*curve len in bytes = 28 bytes */
308 case SEC_OID_SECG_EC_SECT233K1:
309 case SEC_OID_SECG_EC_SECT233R1:
310 case SEC_OID_SECG_EC_SECT239K1:
311 case SEC_OID_ANSIX962_EC_PRIME239V1:
312 case SEC_OID_ANSIX962_EC_PRIME239V2:
313 case SEC_OID_ANSIX962_EC_PRIME239V3:
314 case SEC_OID_ANSIX962_EC_C2TNB239V1:
315 case SEC_OID_ANSIX962_EC_C2TNB239V2:
316 case SEC_OID_ANSIX962_EC_C2TNB239V3:
317 return 61; /*curve len in bytes = 30 bytes */
318 case SEC_OID_ANSIX962_EC_PRIME256V1:
319 case SEC_OID_SECG_EC_SECP256K1:
320 return 65; /*curve len in bytes = 32 bytes */
321 case SEC_OID_ANSIX962_EC_C2PNB272W1:
322 return 69; /*curve len in bytes = 34 bytes */
323 case SEC_OID_SECG_EC_SECT283K1:
324 case SEC_OID_SECG_EC_SECT283R1:
325 return 73; /*curve len in bytes = 36 bytes */
326 case SEC_OID_ANSIX962_EC_C2PNB304W1:
327 return 77; /*curve len in bytes = 38 bytes */
328 case SEC_OID_ANSIX962_EC_C2TNB359V1:
329 return 91; /*curve len in bytes = 45 bytes */
330 case SEC_OID_ANSIX962_EC_C2PNB368W1:
331 return 93; /*curve len in bytes = 46 bytes */
332 case SEC_OID_SECG_EC_SECP384R1:
333 return 97; /*curve len in bytes = 48 bytes */
334 case SEC_OID_SECG_EC_SECT409K1:
335 case SEC_OID_SECG_EC_SECT409R1:
336 return 105; /*curve len in bytes = 52 bytes */
337 case SEC_OID_ANSIX962_EC_C2TNB431R1:
338 return 109; /*curve len in bytes = 54 bytes */
339 case SEC_OID_SECG_EC_SECP521R1:
340 return 133; /*curve len in bytes = 66 bytes */
341 case SEC_OID_SECG_EC_SECT571K1:
342 case SEC_OID_SECG_EC_SECT571R1:
343 return 145; /*curve len in bytes = 72 bytes */
344 /* unknown or unrecognized OIDs. return unknown length */
345 default:
346 break;
347 }
348 return 0;
349 }
350
351 /*
352 * returns the decoded point. In some cases the point may already be decoded.
353 * this function tries to detect those cases and return the point in
354 * publicKeyValue. In other cases it's DER encoded. In those cases the point
355 * is first decoded and returned. Space for the point is allocated out of
356 * the passed in arena.
357 */
358 static CK_RV
359 pk11_get_Decoded_ECPoint(PLArenaPool *arena, const SECItem *ecParams,
360 const CK_ATTRIBUTE *ecPoint, SECItem *publicKeyValue)
361 {
362 SECItem encodedPublicValue;
363 SECStatus rv;
364 int keyLen;
365
366 if (ecPoint->ulValueLen == 0) {
367 return CKR_ATTRIBUTE_VALUE_INVALID;
368 }
369
370 /*
371 * The PKCS #11 spec requires ecPoints to be encoded as a DER OCTET String.
372 * NSS has mistakenly passed unencoded values, and some PKCS #11 vendors
373 * followed that mistake. Now we need to detect which encoding we were
374 * passed in. The task is made more complicated by the fact the the
375 * DER encoding byte (SEC_ASN_OCTET_STRING) is the same as the
376 * EC_POINT_FORM_UNCOMPRESSED byte (0x04), so we can't use that to
377 * determine which curve we are using.
378 */
379
380 /* get the expected key length for the passed in curve.
381 * pk11_get_EC_PointLenInBytes only returns valid values for curves
382 * NSS has traditionally recognized. If the curve is not recognized,
383 * it will return '0', and we have to figure out if the key was
384 * encoded or not heuristically. If the ecParams are invalid, it
385 * will return -1 for the keyLen.
386 */
387 keyLen = pk11_get_EC_PointLenInBytes(arena, ecParams);
388 if (keyLen < 0) {
389 return CKR_ATTRIBUTE_VALUE_INVALID;
390 }
391
392
393 /* If the point is uncompressed and the lengths match, it
394 * must be an unencoded point */
395 if ((*((char *)ecPoint->pValue) == EC_POINT_FORM_UNCOMPRESSED)
396 && (ecPoint->ulValueLen == keyLen)) {
397 return pk11_Attr2SecItem(arena, ecPoint, publicKeyValue);
398 }
399
400 /* now assume the key passed to us was encoded and decode it */
401 if (*((char *)ecPoint->pValue) == SEC_ASN1_OCTET_STRING) {
402 /* OK, now let's try to decode it and see if it's valid */
403 encodedPublicValue.data = ecPoint->pValue;
404 encodedPublicValue.len = ecPoint->ulValueLen;
405 rv = SEC_QuickDERDecodeItem(arena, publicKeyValue,
406 SEC_ASN1_GET(SEC_OctetStringTemplate), &encodedPublicValue);
407
408 /* it coded correctly & we know the key length (and they match)
409 * then we are done, return the results. */
410 if (keyLen && rv == SECSuccess && publicKeyValue->len == keyLen) {
411 return CKR_OK;
412 }
413
414 /* if we know the key length, one of the above tests should have
415 * succeded. If it doesn't the module gave us bad data */
416 if (keyLen) {
417 return CKR_ATTRIBUTE_VALUE_INVALID;
418 }
419
420
421 /* We don't know the key length, so we don't know deterministically
422 * which encoding was used. We now will try to pick the most likely
423 * form that's correct, with a preference for the encoded form if we
424 * can't determine for sure. We do this by checking the key we got
425 * back from SEC_QuickDERDecodeItem for defects. If no defects are
426 * found, we assume the encoded parameter was was passed to us.
427 * our defect tests include:
428 * 1) it didn't decode.
429 * 2) The decode key had an invalid length (must be odd).
430 * 3) The decoded key wasn't an UNCOMPRESSED key.
431 * 4) The decoded key didn't include the entire encoded block
432 * except the DER encoding values. (fixing DER length to one
433 * particular value).
434 */
435 if ((rv != SECSuccess)
436 || ((publicKeyValue->len & 1) != 1)
437 || (publicKeyValue->data[0] != EC_POINT_FORM_UNCOMPRESSED)
438 || (PORT_Memcmp(&encodedPublicValue.data[encodedPublicValue.len -
439 publicKeyValue->len], publicKeyValue->data,
440 publicKeyValue->len) != 0)) {
441 /* The decoded public key was flawed, the original key must have
442 * already been in decoded form. Do a quick sanity check then
443 * return the original key value.
444 */
445 if ((encodedPublicValue.len & 1) == 0) {
446 return CKR_ATTRIBUTE_VALUE_INVALID;
447 }
448 return pk11_Attr2SecItem(arena, ecPoint, publicKeyValue);
449 }
450
451 /* as best we can figure, the passed in key was encoded, and we've
452 * now decoded it. Note: there is a chance this could be wrong if the
453 * following conditions hold:
454 * 1) The first byte or bytes of the X point looks like a valid length
455 * of precisely the right size (2*curveSize -1). this means for curves
456 * less than 512 bits (64 bytes), this will happen 1 in 256 times*.
457 * for curves between 512 and 1024, this will happen 1 in 65,536 times*
458 * for curves between 1024 and 256K this will happen 1 in 16 million*
459 * 2) The length of the 'DER length field' is odd
460 * (making both the encoded and decode
461 * values an odd length. this is true of all curves less than 512,
462 * as well as curves between 1024 and 256K).
463 * 3) The X[length of the 'DER length field'] == 0x04, 1 in 256.
464 *
465 * (* assuming all values are equally likely in the first byte,
466 * This isn't true if the curve length is not a multiple of 8. In these
467 * cases, if the DER length is possible, it's more likely,
468 * if it's not possible, then we have no false decodes).
469 *
470 * For reference here are the odds for the various curves we currently
471 * have support for (and the only curves SSL will negotiate at this
472 * time). NOTE: None of the supported curves will show up here
473 * because we return a valid length for all of these curves.
474 * The only way to get here is to have some application (not SSL)
475 * which supports some unknown curve and have some vendor supplied
476 * PKCS #11 module support that curve. NOTE: in this case, one
477 * presumes that that pkcs #11 module is likely to be using the
478 * correct encodings.
479 *
480 * Prime Curves (GFp):
481 * Bit False Odds of
482 * Size DER Len False Decode Positive
483 * 112 27 1 in 65536
484 * 128 31 1 in 65536
485 * 160 39 1 in 65536
486 * 192 47 1 in 65536
487 * 224 55 1 in 65536
488 * 239 59 1 in 32768 (top byte can only be 0-127)
489 * 256 63 1 in 65536
490 * 521 129,131 0 (decoded value would be even)
491 *
492 * Binary curves (GF2m).
493 * Bit False Odds of
494 * Size DER Len False Decode Positive
495 * 131 33 0 (top byte can only be 0-7)
496 * 163 41 0 (top byte can only be 0-7)
497 * 176 43 1 in 65536
498 * 191 47 1 in 32768 (top byte can only be 0-127)
499 * 193 49 0 (top byte can only be 0-1)
500 * 208 51 1 in 65536
501 * 233 59 0 (top byte can only be 0-1)
502 * 239 59 1 in 32768 (top byte can only be 0-127)
503 * 272 67 1 in 65536
504 * 283 71 0 (top byte can only be 0-7)
505 * 304 75 1 in 65536
506 * 359 89 1 in 32768 (top byte can only be 0-127)
507 * 368 91 1 in 65536
508 * 409 103 0 (top byte can only be 0-1)
509 * 431 107 1 in 32768 (top byte can only be 0-127)
510 * 571 129,143 0 (decoded value would be even)
511 *
512 */
513
514 return CKR_OK;
515 }
516
517 /* In theory, we should handle the case where the curve == 0 and
518 * the first byte is EC_POINT_FORM_UNCOMPRESSED, (which would be
519 * handled by doing a santity check on the key length and returning
520 * pk11_Attr2SecItem() to copy the ecPoint to the publicKeyValue).
521 *
522 * This test is unnecessary, however, due to the fact that
523 * EC_POINT_FORM_UNCOMPRESSED == SEC_ASIN1_OCTET_STRING, that case is
524 * handled in the above if. That means if we get here, the initial
525 * byte of our ecPoint value was invalid, so we can safely return.
526 * invalid attribute.
527 */
528
529 return CKR_ATTRIBUTE_VALUE_INVALID;
530 }
531
532 /*
533 * extract a public key from a slot and id
534 */
535 SECKEYPublicKey *
536 PK11_ExtractPublicKey(PK11SlotInfo *slot,KeyType keyType,CK_OBJECT_HANDLE id)
537 {
538 CK_OBJECT_CLASS keyClass = CKO_PUBLIC_KEY;
539 PLArenaPool *arena;
540 PLArenaPool *tmp_arena;
541 SECKEYPublicKey *pubKey;
542 int templateCount = 0;
543 CK_KEY_TYPE pk11KeyType;
544 CK_RV crv;
545 CK_ATTRIBUTE template[8];
546 CK_ATTRIBUTE *attrs= template;
547 CK_ATTRIBUTE *modulus,*exponent,*base,*prime,*subprime,*value;
548 CK_ATTRIBUTE *ecparams;
549
550 /* if we didn't know the key type, get it */
551 if (keyType== nullKey) {
552
553 pk11KeyType = PK11_ReadULongAttribute(slot,id,CKA_KEY_TYPE);
554 if (pk11KeyType == CK_UNAVAILABLE_INFORMATION) {
555 return NULL;
556 }
557 switch (pk11KeyType) {
558 case CKK_RSA:
559 keyType = rsaKey;
560 break;
561 case CKK_DSA:
562 keyType = dsaKey;
563 break;
564 case CKK_DH:
565 keyType = dhKey;
566 break;
567 case CKK_EC:
568 keyType = ecKey;
569 break;
570 default:
571 PORT_SetError( SEC_ERROR_BAD_KEY );
572 return NULL;
573 }
574 }
575
576
577 /* now we need to create space for the public key */
578 arena = PORT_NewArena( DER_DEFAULT_CHUNKSIZE);
579 if (arena == NULL) return NULL;
580 tmp_arena = PORT_NewArena( DER_DEFAULT_CHUNKSIZE);
581 if (tmp_arena == NULL) {
582 PORT_FreeArena (arena, PR_FALSE);
583 return NULL;
584 }
585
586
587 pubKey = (SECKEYPublicKey *)
588 PORT_ArenaZAlloc(arena, sizeof(SECKEYPublicKey));
589 if (pubKey == NULL) {
590 PORT_FreeArena (arena, PR_FALSE);
591 PORT_FreeArena (tmp_arena, PR_FALSE);
592 return NULL;
593 }
594
595 pubKey->arena = arena;
596 pubKey->keyType = keyType;
597 pubKey->pkcs11Slot = PK11_ReferenceSlot(slot);
598 pubKey->pkcs11ID = id;
599 PK11_SETATTRS(attrs, CKA_CLASS, &keyClass,
600 sizeof(keyClass)); attrs++;
601 PK11_SETATTRS(attrs, CKA_KEY_TYPE, &pk11KeyType,
602 sizeof(pk11KeyType) ); attrs++;
603 switch (pubKey->keyType) {
604 case rsaKey:
605 modulus = attrs;
606 PK11_SETATTRS(attrs, CKA_MODULUS, NULL, 0); attrs++;
607 exponent = attrs;
608 PK11_SETATTRS(attrs, CKA_PUBLIC_EXPONENT, NULL, 0); attrs++;
609
610 templateCount = attrs - template;
611 PR_ASSERT(templateCount <= sizeof(template)/sizeof(CK_ATTRIBUTE));
612 crv = PK11_GetAttributes(tmp_arena,slot,id,template,templateCount);
613 if (crv != CKR_OK) break;
614
615 if ((keyClass != CKO_PUBLIC_KEY) || (pk11KeyType != CKK_RSA)) {
616 crv = CKR_OBJECT_HANDLE_INVALID;
617 break;
618 }
619 crv = pk11_Attr2SecItem(arena,modulus,&pubKey->u.rsa.modulus);
620 if (crv != CKR_OK) break;
621 crv = pk11_Attr2SecItem(arena,exponent,&pubKey->u.rsa.publicExponent);
622 if (crv != CKR_OK) break;
623 break;
624 case dsaKey:
625 prime = attrs;
626 PK11_SETATTRS(attrs, CKA_PRIME, NULL, 0); attrs++;
627 subprime = attrs;
628 PK11_SETATTRS(attrs, CKA_SUBPRIME, NULL, 0); attrs++;
629 base = attrs;
630 PK11_SETATTRS(attrs, CKA_BASE, NULL, 0); attrs++;
631 value = attrs;
632 PK11_SETATTRS(attrs, CKA_VALUE, NULL, 0); attrs++;
633 templateCount = attrs - template;
634 PR_ASSERT(templateCount <= sizeof(template)/sizeof(CK_ATTRIBUTE));
635 crv = PK11_GetAttributes(tmp_arena,slot,id,template,templateCount);
636 if (crv != CKR_OK) break;
637
638 if ((keyClass != CKO_PUBLIC_KEY) || (pk11KeyType != CKK_DSA)) {
639 crv = CKR_OBJECT_HANDLE_INVALID;
640 break;
641 }
642 crv = pk11_Attr2SecItem(arena,prime,&pubKey->u.dsa.params.prime);
643 if (crv != CKR_OK) break;
644 crv = pk11_Attr2SecItem(arena,subprime,&pubKey->u.dsa.params.subPrime);
645 if (crv != CKR_OK) break;
646 crv = pk11_Attr2SecItem(arena,base,&pubKey->u.dsa.params.base);
647 if (crv != CKR_OK) break;
648 crv = pk11_Attr2SecItem(arena,value,&pubKey->u.dsa.publicValue);
649 if (crv != CKR_OK) break;
650 break;
651 case dhKey:
652 prime = attrs;
653 PK11_SETATTRS(attrs, CKA_PRIME, NULL, 0); attrs++;
654 base = attrs;
655 PK11_SETATTRS(attrs, CKA_BASE, NULL, 0); attrs++;
656 value =attrs;
657 PK11_SETATTRS(attrs, CKA_VALUE, NULL, 0); attrs++;
658 templateCount = attrs - template;
659 PR_ASSERT(templateCount <= sizeof(template)/sizeof(CK_ATTRIBUTE));
660 crv = PK11_GetAttributes(tmp_arena,slot,id,template,templateCount);
661 if (crv != CKR_OK) break;
662
663 if ((keyClass != CKO_PUBLIC_KEY) || (pk11KeyType != CKK_DH)) {
664 crv = CKR_OBJECT_HANDLE_INVALID;
665 break;
666 }
667 crv = pk11_Attr2SecItem(arena,prime,&pubKey->u.dh.prime);
668 if (crv != CKR_OK) break;
669 crv = pk11_Attr2SecItem(arena,base,&pubKey->u.dh.base);
670 if (crv != CKR_OK) break;
671 crv = pk11_Attr2SecItem(arena,value,&pubKey->u.dh.publicValue);
672 if (crv != CKR_OK) break;
673 break;
674 case ecKey:
675 pubKey->u.ec.size = 0;
676 ecparams = attrs;
677 PK11_SETATTRS(attrs, CKA_EC_PARAMS, NULL, 0); attrs++;
678 value =attrs;
679 PK11_SETATTRS(attrs, CKA_EC_POINT, NULL, 0); attrs++;
680 templateCount = attrs - template;
681 PR_ASSERT(templateCount <= sizeof(template)/sizeof(CK_ATTRIBUTE));
682 crv = PK11_GetAttributes(arena,slot,id,template,templateCount);
683 if (crv != CKR_OK) break;
684
685 if ((keyClass != CKO_PUBLIC_KEY) || (pk11KeyType != CKK_EC)) {
686 crv = CKR_OBJECT_HANDLE_INVALID;
687 break;
688 }
689
690 crv = pk11_Attr2SecItem(arena,ecparams,
691 &pubKey->u.ec.DEREncodedParams);
692 if (crv != CKR_OK) break;
693 crv = pk11_get_Decoded_ECPoint(arena,
694 &pubKey->u.ec.DEREncodedParams, value,
695 &pubKey->u.ec.publicValue);
696 break;
697 case fortezzaKey:
698 case nullKey:
699 default:
700 crv = CKR_OBJECT_HANDLE_INVALID;
701 break;
702 }
703
704 PORT_FreeArena(tmp_arena,PR_FALSE);
705
706 if (crv != CKR_OK) {
707 PORT_FreeArena(arena,PR_FALSE);
708 PK11_FreeSlot(slot);
709 PORT_SetError( PK11_MapError(crv) );
710 return NULL;
711 }
712
713 return pubKey;
714 }
715
716 /*
717 * Build a Private Key structure from raw PKCS #11 information.
718 */
719 SECKEYPrivateKey *
720 PK11_MakePrivKey(PK11SlotInfo *slot, KeyType keyType,
721 PRBool isTemp, CK_OBJECT_HANDLE privID, void *wincx)
722 {
723 PLArenaPool *arena;
724 SECKEYPrivateKey *privKey;
725 PRBool isPrivate;
726 SECStatus rv;
727
728 /* don't know? look it up */
729 if (keyType == nullKey) {
730 CK_KEY_TYPE pk11Type = CKK_RSA;
731
732 pk11Type = PK11_ReadULongAttribute(slot,privID,CKA_KEY_TYPE);
733 isTemp = (PRBool)!PK11_HasAttributeSet(slot,privID,CKA_TOKEN,PR_FALSE);
734 switch (pk11Type) {
735 case CKK_RSA: keyType = rsaKey; break;
736 case CKK_DSA: keyType = dsaKey; break;
737 case CKK_DH: keyType = dhKey; break;
738 case CKK_KEA: keyType = fortezzaKey; break;
739 case CKK_EC: keyType = ecKey; break;
740 default:
741 break;
742 }
743 }
744
745 /* if the key is private, make sure we are authenticated to the
746 * token before we try to use it */
747 isPrivate = (PRBool)PK11_HasAttributeSet(slot,privID,CKA_PRIVATE,PR_FALSE);
748 if (isPrivate) {
749 rv = PK11_Authenticate(slot, PR_TRUE, wincx);
750 if (rv != SECSuccess) {
751 return NULL;
752 }
753 }
754
755 /* now we need to create space for the private key */
756 arena = PORT_NewArena( DER_DEFAULT_CHUNKSIZE);
757 if (arena == NULL) return NULL;
758
759 privKey = (SECKEYPrivateKey *)
760 PORT_ArenaZAlloc(arena, sizeof(SECKEYPrivateKey));
761 if (privKey == NULL) {
762 PORT_FreeArena(arena, PR_FALSE);
763 return NULL;
764 }
765
766 privKey->arena = arena;
767 privKey->keyType = keyType;
768 privKey->pkcs11Slot = PK11_ReferenceSlot(slot);
769 privKey->pkcs11ID = privID;
770 privKey->pkcs11IsTemp = isTemp;
771 privKey->wincx = wincx;
772
773 return privKey;
774 }
775
776
777 PK11SlotInfo *
778 PK11_GetSlotFromPrivateKey(SECKEYPrivateKey *key)
779 {
780 PK11SlotInfo *slot = key->pkcs11Slot;
781 slot = PK11_ReferenceSlot(slot);
782 return slot;
783 }
784
785 /*
786 * Get the modulus length for raw parsing
787 */
788 int
789 PK11_GetPrivateModulusLen(SECKEYPrivateKey *key)
790 {
791 CK_ATTRIBUTE theTemplate = { CKA_MODULUS, NULL, 0 };
792 PK11SlotInfo *slot = key->pkcs11Slot;
793 CK_RV crv;
794 int length;
795
796 switch (key->keyType) {
797 case rsaKey:
798 crv = PK11_GetAttributes(NULL, slot, key->pkcs11ID, &theTemplate, 1);
799 if (crv != CKR_OK) {
800 PORT_SetError( PK11_MapError(crv) );
801 return -1;
802 }
803 length = theTemplate.ulValueLen;
804 if ( *(unsigned char *)theTemplate.pValue == 0) {
805 length--;
806 }
807 if (theTemplate.pValue != NULL)
808 PORT_Free(theTemplate.pValue);
809 return (int) length;
810
811 case fortezzaKey:
812 case dsaKey:
813 case dhKey:
814 default:
815 break;
816 }
817 if (theTemplate.pValue != NULL)
818 PORT_Free(theTemplate.pValue);
819 PORT_SetError( SEC_ERROR_INVALID_KEY );
820 return -1;
821 }
822
823
824
825 /*
826 * take a private key in one pkcs11 module and load it into another:
827 * NOTE: the source private key is a rare animal... it can't be sensitive.
828 * This is used to do a key gen using one pkcs11 module and storing the
829 * result into another.
830 */
831 static SECKEYPrivateKey *
832 pk11_loadPrivKeyWithFlags(PK11SlotInfo *slot,SECKEYPrivateKey *privKey,
833 SECKEYPublicKey *pubKey, PK11AttrFlags attrFlags)
834 {
835 CK_ATTRIBUTE privTemplate[] = {
836 /* class must be first */
837 { CKA_CLASS, NULL, 0 },
838 { CKA_KEY_TYPE, NULL, 0 },
839 { CKA_ID, NULL, 0 },
840 /* RSA - the attributes below will be replaced for other
841 * key types.
842 */
843 { CKA_MODULUS, NULL, 0 },
844 { CKA_PRIVATE_EXPONENT, NULL, 0 },
845 { CKA_PUBLIC_EXPONENT, NULL, 0 },
846 { CKA_PRIME_1, NULL, 0 },
847 { CKA_PRIME_2, NULL, 0 },
848 { CKA_EXPONENT_1, NULL, 0 },
849 { CKA_EXPONENT_2, NULL, 0 },
850 { CKA_COEFFICIENT, NULL, 0 },
851 { CKA_DECRYPT, NULL, 0 },
852 { CKA_DERIVE, NULL, 0 },
853 { CKA_SIGN, NULL, 0 },
854 { CKA_SIGN_RECOVER, NULL, 0 },
855 { CKA_UNWRAP, NULL, 0 },
856 /* reserve space for the attributes that may be
857 * specified in attrFlags */
858 { CKA_TOKEN, NULL, 0 },
859 { CKA_PRIVATE, NULL, 0 },
860 { CKA_MODIFIABLE, NULL, 0 },
861 { CKA_SENSITIVE, NULL, 0 },
862 { CKA_EXTRACTABLE, NULL, 0 },
863 #define NUM_RESERVED_ATTRS 5 /* number of reserved attributes above */
864 };
865 CK_BBOOL cktrue = CK_TRUE;
866 CK_BBOOL ckfalse = CK_FALSE;
867 CK_ATTRIBUTE *attrs = NULL, *ap;
868 const int templateSize = sizeof(privTemplate)/sizeof(privTemplate[0]);
869 PLArenaPool *arena;
870 CK_OBJECT_HANDLE objectID;
871 int i, count = 0;
872 int extra_count = 0;
873 CK_RV crv;
874 SECStatus rv;
875 PRBool token = ((attrFlags & PK11_ATTR_TOKEN) != 0);
876
877 if (pk11_BadAttrFlags(attrFlags)) {
878 PORT_SetError(SEC_ERROR_INVALID_ARGS);
879 return NULL;
880 }
881
882 for (i=0; i < templateSize; i++) {
883 if (privTemplate[i].type == CKA_MODULUS) {
884 attrs= &privTemplate[i];
885 count = i;
886 break;
887 }
888 }
889 PORT_Assert(attrs != NULL);
890 if (attrs == NULL) {
891 PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
892 return NULL;
893 }
894
895 ap = attrs;
896
897 switch (privKey->keyType) {
898 case rsaKey:
899 count = templateSize - NUM_RESERVED_ATTRS;
900 extra_count = count - (attrs - privTemplate);
901 break;
902 case dsaKey:
903 ap->type = CKA_PRIME; ap++; count++; extra_count++;
904 ap->type = CKA_SUBPRIME; ap++; count++; extra_count++;
905 ap->type = CKA_BASE; ap++; count++; extra_count++;
906 ap->type = CKA_VALUE; ap++; count++; extra_count++;
907 ap->type = CKA_SIGN; ap++; count++; extra_count++;
908 break;
909 case dhKey:
910 ap->type = CKA_PRIME; ap++; count++; extra_count++;
911 ap->type = CKA_BASE; ap++; count++; extra_count++;
912 ap->type = CKA_VALUE; ap++; count++; extra_count++;
913 ap->type = CKA_DERIVE; ap++; count++; extra_count++;
914 break;
915 case ecKey:
916 ap->type = CKA_EC_PARAMS; ap++; count++; extra_count++;
917 ap->type = CKA_VALUE; ap++; count++; extra_count++;
918 ap->type = CKA_DERIVE; ap++; count++; extra_count++;
919 ap->type = CKA_SIGN; ap++; count++; extra_count++;
920 break;
921 default:
922 count = 0;
923 extra_count = 0;
924 break;
925 }
926
927 if (count == 0) {
928 PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
929 return NULL;
930 }
931
932 arena = PORT_NewArena( DER_DEFAULT_CHUNKSIZE);
933 if (arena == NULL) return NULL;
934 /*
935 * read out the old attributes.
936 */
937 crv = PK11_GetAttributes(arena, privKey->pkcs11Slot, privKey->pkcs11ID,
938 privTemplate,count);
939 if (crv != CKR_OK) {
940 PORT_SetError( PK11_MapError(crv) );
941 PORT_FreeArena(arena, PR_TRUE);
942 return NULL;
943 }
944
945 /* Set token, private, modifiable, sensitive, and extractable */
946 count += pk11_AttrFlagsToAttributes(attrFlags, &privTemplate[count],
947 &cktrue, &ckfalse);
948
949 /* Not everyone can handle zero padded key values, give
950 * them the raw data as unsigned */
951 for (ap=attrs; extra_count; ap++, extra_count--) {
952 pk11_SignedToUnsigned(ap);
953 }
954
955 /* now Store the puppies */
956 rv = PK11_CreateNewObject(slot, CK_INVALID_SESSION, privTemplate,
957 count, token, &objectID);
958 PORT_FreeArena(arena, PR_TRUE);
959 if (rv != SECSuccess) {
960 return NULL;
961 }
962
963 /* try loading the public key */
964 if (pubKey) {
965 PK11_ImportPublicKey(slot, pubKey, token);
966 if (pubKey->pkcs11Slot) {
967 PK11_FreeSlot(pubKey->pkcs11Slot);
968 pubKey->pkcs11Slot = NULL;
969 pubKey->pkcs11ID = CK_INVALID_HANDLE;
970 }
971 }
972
973 /* build new key structure */
974 return PK11_MakePrivKey(slot, privKey->keyType, !token,
975 objectID, privKey->wincx);
976 }
977
978 static SECKEYPrivateKey *
979 pk11_loadPrivKey(PK11SlotInfo *slot,SECKEYPrivateKey *privKey,
980 SECKEYPublicKey *pubKey, PRBool token, PRBool sensitive)
981 {
982 PK11AttrFlags attrFlags = 0;
983 if (token) {
984 attrFlags |= (PK11_ATTR_TOKEN | PK11_ATTR_PRIVATE);
985 } else {
986 attrFlags |= (PK11_ATTR_SESSION | PK11_ATTR_PUBLIC);
987 }
988 if (sensitive) {
989 attrFlags |= PK11_ATTR_SENSITIVE;
990 } else {
991 attrFlags |= PK11_ATTR_INSENSITIVE;
992 }
993 return pk11_loadPrivKeyWithFlags(slot, privKey, pubKey, attrFlags);
994 }
995
996 /*
997 * export this for PSM
998 */
999 SECKEYPrivateKey *
1000 PK11_LoadPrivKey(PK11SlotInfo *slot,SECKEYPrivateKey *privKey,
1001 SECKEYPublicKey *pubKey, PRBool token, PRBool sensitive)
1002 {
1003 return pk11_loadPrivKey(slot,privKey,pubKey,token,sensitive);
1004 }
1005
1006
1007 /*
1008 * Use the token to generate a key pair.
1009 */
1010 SECKEYPrivateKey *
1011 PK11_GenerateKeyPairWithOpFlags(PK11SlotInfo *slot,CK_MECHANISM_TYPE type,
1012 void *param, SECKEYPublicKey **pubKey, PK11AttrFlags attrFlags,
1013 CK_FLAGS opFlags, CK_FLAGS opFlagsMask, void *wincx)
1014 {
1015 /* we have to use these native types because when we call PKCS 11 modules
1016 * we have to make sure that we are using the correct sizes for all the
1017 * parameters. */
1018 CK_BBOOL ckfalse = CK_FALSE;
1019 CK_BBOOL cktrue = CK_TRUE;
1020 CK_ULONG modulusBits;
1021 CK_BYTE publicExponent[4];
1022 CK_ATTRIBUTE privTemplate[] = {
1023 { CKA_SENSITIVE, NULL, 0},
1024 { CKA_TOKEN, NULL, 0},
1025 { CKA_PRIVATE, NULL, 0},
1026 { CKA_DERIVE, NULL, 0},
1027 { CKA_UNWRAP, NULL, 0},
1028 { CKA_SIGN, NULL, 0},
1029 { CKA_DECRYPT, NULL, 0},
1030 { CKA_EXTRACTABLE, NULL, 0},
1031 { CKA_MODIFIABLE, NULL, 0},
1032 };
1033 CK_ATTRIBUTE rsaPubTemplate[] = {
1034 { CKA_MODULUS_BITS, NULL, 0},
1035 { CKA_PUBLIC_EXPONENT, NULL, 0},
1036 { CKA_TOKEN, NULL, 0},
1037 { CKA_DERIVE, NULL, 0},
1038 { CKA_WRAP, NULL, 0},
1039 { CKA_VERIFY, NULL, 0},
1040 { CKA_VERIFY_RECOVER, NULL, 0},
1041 { CKA_ENCRYPT, NULL, 0},
1042 { CKA_MODIFIABLE, NULL, 0},
1043 };
1044 CK_ATTRIBUTE dsaPubTemplate[] = {
1045 { CKA_PRIME, NULL, 0 },
1046 { CKA_SUBPRIME, NULL, 0 },
1047 { CKA_BASE, NULL, 0 },
1048 { CKA_TOKEN, NULL, 0},
1049 { CKA_DERIVE, NULL, 0},
1050 { CKA_WRAP, NULL, 0},
1051 { CKA_VERIFY, NULL, 0},
1052 { CKA_VERIFY_RECOVER, NULL, 0},
1053 { CKA_ENCRYPT, NULL, 0},
1054 { CKA_MODIFIABLE, NULL, 0},
1055 };
1056 CK_ATTRIBUTE dhPubTemplate[] = {
1057 { CKA_PRIME, NULL, 0 },
1058 { CKA_BASE, NULL, 0 },
1059 { CKA_TOKEN, NULL, 0},
1060 { CKA_DERIVE, NULL, 0},
1061 { CKA_WRAP, NULL, 0},
1062 { CKA_VERIFY, NULL, 0},
1063 { CKA_VERIFY_RECOVER, NULL, 0},
1064 { CKA_ENCRYPT, NULL, 0},
1065 { CKA_MODIFIABLE, NULL, 0},
1066 };
1067 CK_ATTRIBUTE ecPubTemplate[] = {
1068 { CKA_EC_PARAMS, NULL, 0 },
1069 { CKA_TOKEN, NULL, 0},
1070 { CKA_DERIVE, NULL, 0},
1071 { CKA_WRAP, NULL, 0},
1072 { CKA_VERIFY, NULL, 0},
1073 { CKA_VERIFY_RECOVER, NULL, 0},
1074 { CKA_ENCRYPT, NULL, 0},
1075 { CKA_MODIFIABLE, NULL, 0},
1076 };
1077 SECKEYECParams * ecParams;
1078
1079 /*CK_ULONG key_size = 0;*/
1080 CK_ATTRIBUTE *pubTemplate;
1081 int privCount = 0;
1082 int pubCount = 0;
1083 PK11RSAGenParams *rsaParams;
1084 SECKEYPQGParams *dsaParams;
1085 SECKEYDHParams * dhParams;
1086 CK_MECHANISM mechanism;
1087 CK_MECHANISM test_mech;
1088 CK_MECHANISM test_mech2;
1089 CK_SESSION_HANDLE session_handle;
1090 CK_RV crv;
1091 CK_OBJECT_HANDLE privID,pubID;
1092 SECKEYPrivateKey *privKey;
1093 KeyType keyType;
1094 PRBool restore;
1095 int peCount,i;
1096 CK_ATTRIBUTE *attrs;
1097 CK_ATTRIBUTE *privattrs;
1098 CK_ATTRIBUTE setTemplate;
1099 CK_MECHANISM_INFO mechanism_info;
1100 CK_OBJECT_CLASS keyClass;
1101 SECItem *cka_id;
1102 PRBool haslock = PR_FALSE;
1103 PRBool pubIsToken = PR_FALSE;
1104 PRBool token = ((attrFlags & PK11_ATTR_TOKEN) != 0);
1105 /* subset of attrFlags applicable to the public key */
1106 PK11AttrFlags pubKeyAttrFlags = attrFlags &
1107 (PK11_ATTR_TOKEN | PK11_ATTR_SESSION
1108 | PK11_ATTR_MODIFIABLE | PK11_ATTR_UNMODIFIABLE);
1109
1110 if (pk11_BadAttrFlags(attrFlags)) {
1111 PORT_SetError( SEC_ERROR_INVALID_ARGS );
1112 return NULL;
1113 }
1114
1115 if (!param) {
1116 PORT_SetError( SEC_ERROR_INVALID_ARGS );
1117 return NULL;
1118 }
1119
1120 /*
1121 * The opFlags and opFlagMask parameters allow us to control the
1122 * settings of the key usage attributes (CKA_ENCRYPT and friends).
1123 * opFlagMask is set to one if the flag is specified in opFlags and
1124 * zero if it is to take on a default value calculated by
1125 * PK11_GenerateKeyPairWithOpFlags.
1126 * opFlags specifies the actual value of the flag 1 or 0.
1127 * Bits not corresponding to one bits in opFlagMask should be zero.
1128 */
1129
1130 /* if we are trying to turn on a flag, it better be in the mask */
1131 PORT_Assert ((opFlags & ~opFlagsMask) == 0);
1132 opFlags &= opFlagsMask;
1133
1134 PORT_Assert(slot != NULL);
1135 if (slot == NULL) {
1136 PORT_SetError( SEC_ERROR_NO_MODULE);
1137 return NULL;
1138 }
1139
1140 /* if our slot really doesn't do this mechanism, Generate the key
1141 * in our internal token and write it out */
1142 if (!PK11_DoesMechanism(slot,type)) {
1143 PK11SlotInfo *int_slot = PK11_GetInternalSlot();
1144
1145 /* don't loop forever looking for a slot */
1146 if (slot == int_slot) {
1147 PK11_FreeSlot(int_slot);
1148 PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
1149 return NULL;
1150 }
1151
1152 /* if there isn't a suitable slot, then we can't do the keygen */
1153 if (int_slot == NULL) {
1154 PORT_SetError( SEC_ERROR_NO_MODULE );
1155 return NULL;
1156 }
1157
1158 /* generate the temporary key to load */
1159 privKey = PK11_GenerateKeyPair(int_slot,type, param, pubKey, PR_FALSE,
1160 PR_FALSE, wincx);
1161 PK11_FreeSlot(int_slot);
1162
1163 /* if successful, load the temp key into the new token */
1164 if (privKey != NULL) {
1165 SECKEYPrivateKey *newPrivKey = pk11_loadPrivKeyWithFlags(slot,
1166 privKey,*pubKey,attrFlags);
1167 SECKEY_DestroyPrivateKey(privKey);
1168 if (newPrivKey == NULL) {
1169 SECKEY_DestroyPublicKey(*pubKey);
1170 *pubKey = NULL;
1171 }
1172 return newPrivKey;
1173 }
1174 return NULL;
1175 }
1176
1177
1178 mechanism.mechanism = type;
1179 mechanism.pParameter = NULL;
1180 mechanism.ulParameterLen = 0;
1181 test_mech.pParameter = NULL;
1182 test_mech.ulParameterLen = 0;
1183 test_mech2.mechanism = CKM_INVALID_MECHANISM;
1184 test_mech2.pParameter = NULL;
1185 test_mech2.ulParameterLen = 0;
1186
1187 /* set up the private key template */
1188 privattrs = privTemplate;
1189 privattrs += pk11_AttrFlagsToAttributes(attrFlags, privattrs,
1190 &cktrue, &ckfalse);
1191
1192 /* set up the mechanism specific info */
1193 switch (type) {
1194 case CKM_RSA_PKCS_KEY_PAIR_GEN:
1195 case CKM_RSA_X9_31_KEY_PAIR_GEN:
1196 rsaParams = (PK11RSAGenParams *)param;
1197 if (rsaParams->pe == 0) {
1198 PORT_SetError(SEC_ERROR_INVALID_ARGS);
1199 return NULL;
1200 }
1201 modulusBits = rsaParams->keySizeInBits;
1202 peCount = 0;
1203
1204 /* convert pe to a PKCS #11 string */
1205 for (i=0; i < 4; i++) {
1206 if (peCount || (rsaParams->pe &
1207 ((unsigned long)0xff000000L >> (i*8)))) {
1208 publicExponent[peCount] =
1209 (CK_BYTE)((rsaParams->pe >> (3-i)*8) & 0xff);
1210 peCount++;
1211 }
1212 }
1213 PORT_Assert(peCount != 0);
1214 attrs = rsaPubTemplate;
1215 PK11_SETATTRS(attrs, CKA_MODULUS_BITS,
1216 &modulusBits, sizeof(modulusBits)); attrs++;
1217 PK11_SETATTRS(attrs, CKA_PUBLIC_EXPONENT,
1218 publicExponent, peCount);attrs++;
1219 pubTemplate = rsaPubTemplate;
1220 keyType = rsaKey;
1221 test_mech.mechanism = CKM_RSA_PKCS;
1222 break;
1223 case CKM_DSA_KEY_PAIR_GEN:
1224 dsaParams = (SECKEYPQGParams *)param;
1225 attrs = dsaPubTemplate;
1226 PK11_SETATTRS(attrs, CKA_PRIME, dsaParams->prime.data,
1227 dsaParams->prime.len); attrs++;
1228 PK11_SETATTRS(attrs, CKA_SUBPRIME, dsaParams->subPrime.data,
1229 dsaParams->subPrime.len); attrs++;
1230 PK11_SETATTRS(attrs, CKA_BASE, dsaParams->base.data,
1231 dsaParams->base.len); attrs++;
1232 pubTemplate = dsaPubTemplate;
1233 keyType = dsaKey;
1234 test_mech.mechanism = CKM_DSA;
1235 break;
1236 case CKM_DH_PKCS_KEY_PAIR_GEN:
1237 dhParams = (SECKEYDHParams *)param;
1238 attrs = dhPubTemplate;
1239 PK11_SETATTRS(attrs, CKA_PRIME, dhParams->prime.data,
1240 dhParams->prime.len); attrs++;
1241 PK11_SETATTRS(attrs, CKA_BASE, dhParams->base.data,
1242 dhParams->base.len); attrs++;
1243 pubTemplate = dhPubTemplate;
1244 keyType = dhKey;
1245 test_mech.mechanism = CKM_DH_PKCS_DERIVE;
1246 break;
1247 case CKM_EC_KEY_PAIR_GEN:
1248 ecParams = (SECKEYECParams *)param;
1249 attrs = ecPubTemplate;
1250 PK11_SETATTRS(attrs, CKA_EC_PARAMS, ecParams->data,
1251 ecParams->len); attrs++;
1252 pubTemplate = ecPubTemplate;
1253 keyType = ecKey;
1254 /*
1255 * ECC supports 2 different mechanism types (unlike RSA, which
1256 * supports different usages with the same mechanism).
1257 * We may need to query both mechanism types and or the results
1258 * together -- but we only do that if either the user has
1259 * requested both usages, or not specified any usages.
1260 */
1261 if ((opFlags & (CKF_SIGN|CKF_DERIVE)) == (CKF_SIGN|CKF_DERIVE)) {
1262 /* We've explicitly turned on both flags, use both mechanism */
1263 test_mech.mechanism = CKM_ECDH1_DERIVE;
1264 test_mech2.mechanism = CKM_ECDSA;
1265 } else if (opFlags & CKF_SIGN) {
1266 /* just do signing */
1267 test_mech.mechanism = CKM_ECDSA;
1268 } else if (opFlags & CKF_DERIVE) {
1269 /* just do ECDH */
1270 test_mech.mechanism = CKM_ECDH1_DERIVE;
1271 } else {
1272 /* neither was specified default to both */
1273 test_mech.mechanism = CKM_ECDH1_DERIVE;
1274 test_mech2.mechanism = CKM_ECDSA;
1275 }
1276 break;
1277 default:
1278 PORT_SetError( SEC_ERROR_BAD_KEY );
1279 return NULL;
1280 }
1281
1282 /* now query the slot to find out how "good" a key we can generate */
1283 if (!slot->isThreadSafe) PK11_EnterSlotMonitor(slot);
1284 crv = PK11_GETTAB(slot)->C_GetMechanismInfo(slot->slotID,
1285 test_mech.mechanism,&mechanism_info);
1286 /*
1287 * EC keys are used in multiple different types of mechanism, if we
1288 * are using dual use keys, we need to query the second mechanism
1289 * as well.
1290 */
1291 if (test_mech2.mechanism != CKM_INVALID_MECHANISM) {
1292 CK_MECHANISM_INFO mechanism_info2;
1293 CK_RV crv2;
1294
1295 if (crv != CKR_OK) {
1296 /* the first failed, make sure there is no trash in the
1297 * mechanism flags when we or it below */
1298 mechanism_info.flags = 0;
1299 }
1300 crv2 = PK11_GETTAB(slot)->C_GetMechanismInfo(slot->slotID,
1301 test_mech2.mechanism, &mechanism_info2);
1302 if (crv2 == CKR_OK) {
1303 crv = CKR_OK; /* succeed if either mechnaism info succeeds */
1304 /* combine the 2 sets of mechnanism flags */
1305 mechanism_info.flags |= mechanism_info2.flags;
1306 }
1307 }
1308 if (!slot->isThreadSafe) PK11_ExitSlotMonitor(slot);
1309 if ((crv != CKR_OK) || (mechanism_info.flags == 0)) {
1310 /* must be old module... guess what it should be... */
1311 switch (test_mech.mechanism) {
1312 case CKM_RSA_PKCS:
1313 mechanism_info.flags = (CKF_SIGN | CKF_DECRYPT |
1314 CKF_WRAP | CKF_VERIFY_RECOVER | CKF_ENCRYPT | CKF_WRAP);
1315 break;
1316 case CKM_DSA:
1317 mechanism_info.flags = CKF_SIGN | CKF_VERIFY;
1318 break;
1319 case CKM_DH_PKCS_DERIVE:
1320 mechanism_info.flags = CKF_DERIVE;
1321 break;
1322 case CKM_ECDH1_DERIVE:
1323 mechanism_info.flags = CKF_DERIVE;
1324 if (test_mech2.mechanism == CKM_ECDSA) {
1325 mechanism_info.flags |= CKF_SIGN | CKF_VERIFY;
1326 }
1327 break;
1328 case CKM_ECDSA:
1329 mechanism_info.flags = CKF_SIGN | CKF_VERIFY;
1330 break;
1331 default:
1332 break;
1333 }
1334 }
1335 /* now adjust our flags according to the user's key usage passed to us */
1336 mechanism_info.flags = (mechanism_info.flags & (~opFlagsMask)) | opFlags;
1337 /* set the public key attributes */
1338 attrs += pk11_AttrFlagsToAttributes(pubKeyAttrFlags, attrs,
1339 &cktrue, &ckfalse);
1340 PK11_SETATTRS(attrs, CKA_DERIVE,
1341 mechanism_info.flags & CKF_DERIVE ? &cktrue : &ckfalse,
1342 sizeof(CK_BBOOL)); attrs++;
1343 PK11_SETATTRS(attrs, CKA_WRAP,
1344 mechanism_info.flags & CKF_WRAP ? &cktrue : &ckfalse,
1345 sizeof(CK_BBOOL)); attrs++;
1346 PK11_SETATTRS(attrs, CKA_VERIFY,
1347 mechanism_info.flags & CKF_VERIFY ? &cktrue : &ckfalse,
1348 sizeof(CK_BBOOL)); attrs++;
1349 PK11_SETATTRS(attrs, CKA_VERIFY_RECOVER,
1350 mechanism_info.flags & CKF_VERIFY_RECOVER ? &cktrue : &ckfalse,
1351 sizeof(CK_BBOOL)); attrs++;
1352 PK11_SETATTRS(attrs, CKA_ENCRYPT,
1353 mechanism_info.flags & CKF_ENCRYPT? &cktrue : &ckfalse,
1354 sizeof(CK_BBOOL)); attrs++;
1355 /* set the private key attributes */
1356 PK11_SETATTRS(privattrs, CKA_DERIVE,
1357 mechanism_info.flags & CKF_DERIVE ? &cktrue : &ckfalse,
1358 sizeof(CK_BBOOL)); privattrs++;
1359 PK11_SETATTRS(privattrs, CKA_UNWRAP,
1360 mechanism_info.flags & CKF_UNWRAP ? &cktrue : &ckfalse,
1361 sizeof(CK_BBOOL)); privattrs++;
1362 PK11_SETATTRS(privattrs, CKA_SIGN,
1363 mechanism_info.flags & CKF_SIGN ? &cktrue : &ckfalse,
1364 sizeof(CK_BBOOL)); privattrs++;
1365 PK11_SETATTRS(privattrs, CKA_DECRYPT,
1366 mechanism_info.flags & CKF_DECRYPT ? &cktrue : &ckfalse,
1367 sizeof(CK_BBOOL)); privattrs++;
1368
1369 if (token) {
1370 session_handle = PK11_GetRWSession(slot);
1371 haslock = PK11_RWSessionHasLock(slot,session_handle);
1372 restore = PR_TRUE;
1373 } else {
1374 session_handle = slot->session;
1375 if (session_handle != CK_INVALID_SESSION)
1376 PK11_EnterSlotMonitor(slot);
1377 restore = PR_FALSE;
1378 haslock = PR_TRUE;
1379 }
1380
1381 if (session_handle == CK_INVALID_SESSION) {
1382 PORT_SetError(SEC_ERROR_BAD_DATA);
1383 return NULL;
1384 }
1385 privCount = privattrs - privTemplate;
1386 pubCount = attrs - pubTemplate;
1387 crv = PK11_GETTAB(slot)->C_GenerateKeyPair(session_handle, &mechanism,
1388 pubTemplate,pubCount,privTemplate,privCount,&pubID,&privID);
1389
1390 if (crv != CKR_OK) {
1391 if (restore) {
1392 PK11_RestoreROSession(slot,session_handle);
1393 } else PK11_ExitSlotMonitor(slot);
1394 PORT_SetError( PK11_MapError(crv) );
1395 return NULL;
1396 }
1397 /* This locking code is dangerous and needs to be more thought
1398 * out... the real problem is that we're holding the mutex open this long
1399 */
1400 if (haslock) { PK11_ExitSlotMonitor(slot); }
1401
1402 /* swap around the ID's for older PKCS #11 modules */
1403 keyClass = PK11_ReadULongAttribute(slot,pubID,CKA_CLASS);
1404 if (keyClass != CKO_PUBLIC_KEY) {
1405 CK_OBJECT_HANDLE tmp = pubID;
1406 pubID = privID;
1407 privID = tmp;
1408 }
1409
1410 *pubKey = PK11_ExtractPublicKey(slot, keyType, pubID);
1411 if (*pubKey == NULL) {
1412 if (restore) {
1413 /* we may have to restore the mutex so it get's exited properly
1414 * in RestoreROSession */
1415 if (haslock) PK11_EnterSlotMonitor(slot);
1416 PK11_RestoreROSession(slot,session_handle);
1417 }
1418 PK11_DestroyObject(slot,pubID);
1419 PK11_DestroyObject(slot,privID);
1420 return NULL;
1421 }
1422
1423 /* set the ID to the public key so we can find it again */
1424 cka_id = pk11_MakeIDFromPublicKey(*pubKey);
1425 pubIsToken = (PRBool)PK11_HasAttributeSet(slot,pubID, CKA_TOKEN,PR_FALSE);
1426
1427 PK11_SETATTRS(&setTemplate, CKA_ID, cka_id->data, cka_id->len);
1428
1429 if (haslock) { PK11_EnterSlotMonitor(slot); }
1430 crv = PK11_GETTAB(slot)->C_SetAttributeValue(session_handle, privID,
1431 &setTemplate, 1);
1432
1433 if (crv == CKR_OK && pubIsToken) {
1434 crv = PK11_GETTAB(slot)->C_SetAttributeValue(session_handle, pubID,
1435 &setTemplate, 1);
1436 }
1437
1438
1439 if (restore) {
1440 PK11_RestoreROSession(slot,session_handle);
1441 } else {
1442 PK11_ExitSlotMonitor(slot);
1443 }
1444 SECITEM_FreeItem(cka_id,PR_TRUE);
1445
1446
1447 if (crv != CKR_OK) {
1448 PK11_DestroyObject(slot,pubID);
1449 PK11_DestroyObject(slot,privID);
1450 PORT_SetError( PK11_MapError(crv) );
1451 *pubKey = NULL;
1452 return NULL;
1453 }
1454
1455 privKey = PK11_MakePrivKey(slot,keyType,!token,privID,wincx);
1456 if (privKey == NULL) {
1457 SECKEY_DestroyPublicKey(*pubKey);
1458 PK11_DestroyObject(slot,privID);
1459 *pubKey = NULL;
1460 return NULL;
1461 }
1462
1463 return privKey;
1464 }
1465
1466 SECKEYPrivateKey *
1467 PK11_GenerateKeyPairWithFlags(PK11SlotInfo *slot,CK_MECHANISM_TYPE type,
1468 void *param, SECKEYPublicKey **pubKey, PK11AttrFlags attrFlags, void *wincx)
1469 {
1470 return PK11_GenerateKeyPairWithOpFlags(slot,type,param,pubKey,attrFlags,
1471 0, 0, wincx);
1472 }
1473
1474 /*
1475 * Use the token to generate a key pair.
1476 */
1477 SECKEYPrivateKey *
1478 PK11_GenerateKeyPair(PK11SlotInfo *slot,CK_MECHANISM_TYPE type,
1479 void *param, SECKEYPublicKey **pubKey, PRBool token,
1480 PRBool sensitive, void *wincx)
1481 {
1482 PK11AttrFlags attrFlags = 0;
1483
1484 if (token) {
1485 attrFlags |= PK11_ATTR_TOKEN;
1486 } else {
1487 attrFlags |= PK11_ATTR_SESSION;
1488 }
1489 if (sensitive) {
1490 attrFlags |= (PK11_ATTR_SENSITIVE | PK11_ATTR_PRIVATE);
1491 } else {
1492 attrFlags |= (PK11_ATTR_INSENSITIVE | PK11_ATTR_PUBLIC);
1493 }
1494 return PK11_GenerateKeyPairWithFlags(slot, type, param, pubKey,
1495 attrFlags, wincx);
1496 }
1497
1498 /* build a public KEA key from the public value */
1499 SECKEYPublicKey *
1500 PK11_MakeKEAPubKey(unsigned char *keyData,int length)
1501 {
1502 SECKEYPublicKey *pubk;
1503 SECItem pkData;
1504 SECStatus rv;
1505 PLArenaPool *arena;
1506
1507 pkData.data = keyData;
1508 pkData.len = length;
1509
1510 arena = PORT_NewArena (DER_DEFAULT_CHUNKSIZE);
1511 if (arena == NULL)
1512 return NULL;
1513
1514 pubk = (SECKEYPublicKey *) PORT_ArenaZAlloc(arena, sizeof(SECKEYPublicKey));
1515 if (pubk == NULL) {
1516 PORT_FreeArena (arena, PR_FALSE);
1517 return NULL;
1518 }
1519
1520 pubk->arena = arena;
1521 pubk->pkcs11Slot = 0;
1522 pubk->pkcs11ID = CK_INVALID_HANDLE;
1523 pubk->keyType = fortezzaKey;
1524 rv = SECITEM_CopyItem(arena, &pubk->u.fortezza.KEAKey, &pkData);
1525 if (rv != SECSuccess) {
1526 PORT_FreeArena (arena, PR_FALSE);
1527 return NULL;
1528 }
1529 return pubk;
1530 }
1531
1532 /*
1533 * NOTE: This function doesn't return a SECKEYPrivateKey struct to represent
1534 * the new private key object. If it were to create a session object that
1535 * could later be looked up by its nickname, it would leak a SECKEYPrivateKey.
1536 * So isPerm must be true.
1537 */
1538 SECStatus
1539 PK11_ImportEncryptedPrivateKeyInfo(PK11SlotInfo *slot,
1540 SECKEYEncryptedPrivateKeyInfo *epki, SECItem *pwitem,
1541 SECItem *nickname, SECItem *publicValue, PRBool isPerm,
1542 PRBool isPrivate, KeyType keyType,
1543 unsigned int keyUsage, void *wincx)
1544 {
1545 if (!isPerm) {
1546 PORT_SetError(SEC_ERROR_INVALID_ARGS);
1547 return SECFailure;
1548 }
1549 return PK11_ImportEncryptedPrivateKeyInfoAndReturnKey(slot, epki,
1550 pwitem, nickname, publicValue, isPerm, isPrivate, keyType,
1551 keyUsage, NULL, wincx);
1552 }
1553
1554 SECStatus
1555 PK11_ImportEncryptedPrivateKeyInfoAndReturnKey(PK11SlotInfo *slot,
1556 SECKEYEncryptedPrivateKeyInfo *epki, SECItem *pwitem,
1557 SECItem *nickname, SECItem *publicValue, PRBool isPerm,
1558 PRBool isPrivate, KeyType keyType,
1559 unsigned int keyUsage, SECKEYPrivateKey **privk,
1560 void *wincx)
1561 {
1562 CK_MECHANISM_TYPE pbeMechType;
1563 SECItem *crypto_param = NULL;
1564 PK11SymKey *key = NULL;
1565 SECStatus rv = SECSuccess;
1566 CK_MECHANISM_TYPE cryptoMechType;
1567 SECKEYPrivateKey *privKey = NULL;
1568 PRBool faulty3DES = PR_FALSE;
1569 int usageCount = 0;
1570 CK_KEY_TYPE key_type;
1571 CK_ATTRIBUTE_TYPE *usage = NULL;
1572 CK_ATTRIBUTE_TYPE rsaUsage[] = {
1573 CKA_UNWRAP, CKA_DECRYPT, CKA_SIGN, CKA_SIGN_RECOVER };
1574 CK_ATTRIBUTE_TYPE dsaUsage[] = { CKA_SIGN };
1575 CK_ATTRIBUTE_TYPE dhUsage[] = { CKA_DERIVE };
1576 CK_ATTRIBUTE_TYPE ecUsage[] = { CKA_SIGN, CKA_DERIVE };
1577 if((epki == NULL) || (pwitem == NULL))
1578 return SECFailure;
1579
1580 pbeMechType = PK11_AlgtagToMechanism(SECOID_FindOIDTag(
1581 &epki->algorithm.algorithm));
1582
1583 switch (keyType) {
1584 default:
1585 case rsaKey:
1586 key_type = CKK_RSA;
1587 switch (keyUsage & (KU_KEY_ENCIPHERMENT|KU_DIGITAL_SIGNATURE)) {
1588 case KU_KEY_ENCIPHERMENT:
1589 usage = rsaUsage;
1590 usageCount = 2;
1591 break;
1592 case KU_DIGITAL_SIGNATURE:
1593 usage = &rsaUsage[2];
1594 usageCount = 2;
1595 break;
1596 case KU_KEY_ENCIPHERMENT|KU_DIGITAL_SIGNATURE:
1597 case 0: /* default to everything */
1598 usage = rsaUsage;
1599 usageCount = 4;
1600 break;
1601 }
1602 break;
1603 case dhKey:
1604 key_type = CKK_DH;
1605 usage = dhUsage;
1606 usageCount = sizeof(dhUsage)/sizeof(dhUsage[0]);
1607 break;
1608 case dsaKey:
1609 key_type = CKK_DSA;
1610 usage = dsaUsage;
1611 usageCount = sizeof(dsaUsage)/sizeof(dsaUsage[0]);
1612 break;
1613 case ecKey:
1614 key_type = CKK_EC;
1615 switch (keyUsage & (KU_DIGITAL_SIGNATURE|KU_KEY_AGREEMENT)) {
1616 case KU_DIGITAL_SIGNATURE:
1617 usage = ecUsage;
1618 usageCount = 1;
1619 break;
1620 case KU_KEY_AGREEMENT:
1621 usage = &ecUsage[1];
1622 usageCount = 1;
1623 break;
1624 case KU_DIGITAL_SIGNATURE|KU_KEY_AGREEMENT:
1625 default: /* default to everything */
1626 usage = ecUsage;
1627 usageCount = 2;
1628 break;
1629 }
1630 break;
1631 }
1632
1633 try_faulty_3des:
1634
1635 key = PK11_PBEKeyGen(slot, &epki->algorithm, pwitem, faulty3DES, wincx);
1636 if (key == NULL) {
1637 rv = SECFailure;
1638 goto done;
1639 }
1640 cryptoMechType = pk11_GetPBECryptoMechanism(&epki->algorithm,
1641 &crypto_param, pwitem, faulty3DES);
1642 if (cryptoMechType == CKM_INVALID_MECHANISM) {
1643 rv = SECFailure;
1644 goto done;
1645 }
1646
1647
1648 cryptoMechType = PK11_GetPadMechanism(cryptoMechType);
1649
1650 PORT_Assert(usage != NULL);
1651 PORT_Assert(usageCount != 0);
1652 privKey = PK11_UnwrapPrivKey(slot, key, cryptoMechType,
1653 crypto_param, &epki->encryptedData,
1654 nickname, publicValue, isPerm, isPrivate,
1655 key_type, usage, usageCount, wincx);
1656 if(privKey) {
1657 if (privk) {
1658 *privk = privKey;
1659 } else {
1660 SECKEY_DestroyPrivateKey(privKey);
1661 }
1662 privKey = NULL;
1663 rv = SECSuccess;
1664 goto done;
1665 }
1666
1667 /* if we are unable to import the key and the pbeMechType is
1668 * CKM_NETSCAPE_PBE_SHA1_TRIPLE_DES_CBC, then it is possible that
1669 * the encrypted blob was created with a buggy key generation method
1670 * which is described in the PKCS 12 implementation notes. So we
1671 * need to try importing via that method.
1672 */
1673 if((pbeMechType == CKM_NETSCAPE_PBE_SHA1_TRIPLE_DES_CBC) && (!faulty3DES)) {
1674 /* clean up after ourselves before redoing the key generation. */
1675
1676 PK11_FreeSymKey(key);
1677 key = NULL;
1678
1679 if(crypto_param) {
1680 SECITEM_ZfreeItem(crypto_param, PR_TRUE);
1681 crypto_param = NULL;
1682 }
1683
1684 faulty3DES = PR_TRUE;
1685 goto try_faulty_3des;
1686 }
1687
1688 /* key import really did fail */
1689 rv = SECFailure;
1690
1691 done:
1692 if(crypto_param != NULL) {
1693 SECITEM_ZfreeItem(crypto_param, PR_TRUE);
1694 }
1695
1696 if(key != NULL) {
1697 PK11_FreeSymKey(key);
1698 }
1699
1700 return rv;
1701 }
1702
1703 SECKEYPrivateKeyInfo *
1704 PK11_ExportPrivateKeyInfo(CERTCertificate *cert, void *wincx)
1705 {
1706 SECKEYPrivateKeyInfo *pki = NULL;
1707 SECKEYPrivateKey *pk = PK11_FindKeyByAnyCert(cert, wincx);
1708 if (pk != NULL) {
1709 pki = PK11_ExportPrivKeyInfo(pk, wincx);
1710 SECKEY_DestroyPrivateKey(pk);
1711 }
1712 return pki;
1713 }
1714
1715 SECKEYEncryptedPrivateKeyInfo *
1716 PK11_ExportEncryptedPrivKeyInfo(
1717 PK11SlotInfo *slot, /* optional, encrypt key in this slot */
1718 SECOidTag algTag, /* encrypt key with this algorithm */
1719 SECItem *pwitem, /* password for PBE encryption */
1720 SECKEYPrivateKey *pk, /* encrypt this private key */
1721 int iteration, /* interations for PBE alg */
1722 void *wincx) /* context for password callback ? */
1723 {
1724 SECKEYEncryptedPrivateKeyInfo *epki = NULL;
1725 PLArenaPool *arena = NULL;
1726 SECAlgorithmID *algid;
1727 SECOidTag pbeAlgTag = SEC_OID_UNKNOWN;
1728 SECItem *crypto_param = NULL;
1729 PK11SymKey *key = NULL;
1730 SECKEYPrivateKey *tmpPK = NULL;
1731 SECStatus rv = SECSuccess;
1732 CK_RV crv;
1733 CK_ULONG encBufLen;
1734 CK_MECHANISM_TYPE pbeMechType;
1735 CK_MECHANISM_TYPE cryptoMechType;
1736 CK_MECHANISM cryptoMech;
1737
1738 if (!pwitem || !pk) {
1739 PORT_SetError(SEC_ERROR_INVALID_ARGS);
1740 return NULL;
1741 }
1742
1743 algid = sec_pkcs5CreateAlgorithmID(algTag, SEC_OID_UNKNOWN, SEC_OID_UNKNOWN,
1744 &pbeAlgTag, 0, NULL, iteration);
1745 if (algid == NULL) {
1746 return NULL;
1747 }
1748
1749 arena = PORT_NewArena(2048);
1750 if (arena)
1751 epki = PORT_ArenaZNew(arena, SECKEYEncryptedPrivateKeyInfo);
1752 if(epki == NULL) {
1753 rv = SECFailure;
1754 goto loser;
1755 }
1756 epki->arena = arena;
1757
1758
1759 /* if we didn't specify a slot, use the slot the private key was in */
1760 if (!slot) {
1761 slot = pk->pkcs11Slot;
1762 }
1763
1764 /* if we specified a different slot, and the private key slot can do the
1765 * pbe key gen, generate the key in the private key slot so we don't have
1766 * to move it later */
1767 pbeMechType = PK11_AlgtagToMechanism(pbeAlgTag);
1768 if (slot != pk->pkcs11Slot) {
1769 if (PK11_DoesMechanism(pk->pkcs11Slot,pbeMechType)) {
1770 slot = pk->pkcs11Slot;
1771 }
1772 }
1773 key = PK11_PBEKeyGen(slot, algid, pwitem, PR_FALSE, wincx);
1774 if (key == NULL) {
1775 rv = SECFailure;
1776 goto loser;
1777 }
1778
1779 cryptoMechType = PK11_GetPBECryptoMechanism(algid, &crypto_param, pwitem);
1780 if (cryptoMechType == CKM_INVALID_MECHANISM) {
1781 rv = SECFailure;
1782 goto loser;
1783 }
1784
1785 cryptoMech.mechanism = PK11_GetPadMechanism(cryptoMechType);
1786 cryptoMech.pParameter = crypto_param ? crypto_param->data : NULL;
1787 cryptoMech.ulParameterLen = crypto_param ? crypto_param->len : 0;
1788
1789 /* If the key isn't in the private key slot, move it */
1790 if (key->slot != pk->pkcs11Slot) {
1791 PK11SymKey *newkey = pk11_CopyToSlot(pk->pkcs11Slot,
1792 key->type, CKA_WRAP, key);
1793 if (newkey == NULL) {
1794 /* couldn't import the wrapping key, try exporting the
1795 * private key */
1796 tmpPK = pk11_loadPrivKey(key->slot, pk, NULL, PR_FALSE, PR_TRUE);
1797 if (tmpPK == NULL) {
1798 rv = SECFailure;
1799 goto loser;
1800 }
1801 pk = tmpPK;
1802 } else {
1803 /* free the old key and use the new key */
1804 PK11_FreeSymKey(key);
1805 key = newkey;
1806 }
1807 }
1808
1809 /* we are extracting an encrypted privateKey structure.
1810 * which needs to be freed along with the buffer into which it is
1811 * returned. eventually, we should retrieve an encrypted key using
1812 * pkcs8/pkcs5.
1813 */
1814 encBufLen = 0;
1815 PK11_EnterSlotMonitor(pk->pkcs11Slot);
1816 crv = PK11_GETTAB(pk->pkcs11Slot)->C_WrapKey(pk->pkcs11Slot->session,
1817 &cryptoMech, key->objectID, pk->pkcs11ID, NULL,
1818 &encBufLen);
1819 PK11_ExitSlotMonitor(pk->pkcs11Slot);
1820 if (crv != CKR_OK) {
1821 rv = SECFailure;
1822 goto loser;
1823 }
1824 epki->encryptedData.data = PORT_ArenaAlloc(arena, encBufLen);
1825 if (!epki->encryptedData.data) {
1826 rv = SECFailure;
1827 goto loser;
1828 }
1829 PK11_EnterSlotMonitor(pk->pkcs11Slot);
1830 crv = PK11_GETTAB(pk->pkcs11Slot)->C_WrapKey(pk->pkcs11Slot->session,
1831 &cryptoMech, key->objectID, pk->pkcs11ID,
1832 epki->encryptedData.data, &encBufLen);
1833 PK11_ExitSlotMonitor(pk->pkcs11Slot);
1834 epki->encryptedData.len = (unsigned int) encBufLen;
1835 if(crv != CKR_OK) {
1836 rv = SECFailure;
1837 goto loser;
1838 }
1839
1840 if(!epki->encryptedData.len) {
1841 rv = SECFailure;
1842 goto loser;
1843 }
1844
1845 rv = SECOID_CopyAlgorithmID(arena, &epki->algorithm, algid);
1846
1847 loser:
1848 if(crypto_param != NULL) {
1849 SECITEM_ZfreeItem(crypto_param, PR_TRUE);
1850 crypto_param = NULL;
1851 }
1852
1853 if(key != NULL) {
1854 PK11_FreeSymKey(key);
1855 }
1856 if (tmpPK != NULL) {
1857 SECKEY_DestroyPrivateKey(tmpPK);
1858 }
1859 SECOID_DestroyAlgorithmID(algid, PR_TRUE);
1860
1861 if(rv == SECFailure) {
1862 if(arena != NULL) {
1863 PORT_FreeArena(arena, PR_TRUE);
1864 }
1865 epki = NULL;
1866 }
1867
1868 return epki;
1869 }
1870
1871 SECKEYEncryptedPrivateKeyInfo *
1872 PK11_ExportEncryptedPrivateKeyInfo(
1873 PK11SlotInfo *slot, /* optional, encrypt key in this slot */
1874 SECOidTag algTag, /* encrypt key with this algorithm */
1875 SECItem *pwitem, /* password for PBE encryption */
1876 CERTCertificate *cert, /* wrap priv key for this user cert */
1877 int iteration, /* interations for PBE alg */
1878 void *wincx) /* context for password callback ? */
1879 {
1880 SECKEYEncryptedPrivateKeyInfo *epki = NULL;
1881 SECKEYPrivateKey *pk = PK11_FindKeyByAnyCert(cert, wincx);
1882 if (pk != NULL) {
1883 epki = PK11_ExportEncryptedPrivKeyInfo(slot, algTag, pwitem, pk,
1884 iteration, wincx);
1885 SECKEY_DestroyPrivateKey(pk);
1886 }
1887 return epki;
1888 }
1889
1890 SECItem*
1891 PK11_DEREncodePublicKey(const SECKEYPublicKey *pubk)
1892 {
1893 return SECKEY_EncodeDERSubjectPublicKeyInfo(pubk);
1894 }
1895
1896 char *
1897 PK11_GetPrivateKeyNickname(SECKEYPrivateKey *privKey)
1898 {
1899 return PK11_GetObjectNickname(privKey->pkcs11Slot,privKey->pkcs11ID);
1900 }
1901
1902 char *
1903 PK11_GetPublicKeyNickname(SECKEYPublicKey *pubKey)
1904 {
1905 return PK11_GetObjectNickname(pubKey->pkcs11Slot,pubKey->pkcs11ID);
1906 }
1907
1908 SECStatus
1909 PK11_SetPrivateKeyNickname(SECKEYPrivateKey *privKey, const char *nickname)
1910 {
1911 return PK11_SetObjectNickname(privKey->pkcs11Slot,
1912 privKey->pkcs11ID,nickname);
1913 }
1914
1915 SECStatus
1916 PK11_SetPublicKeyNickname(SECKEYPublicKey *pubKey, const char *nickname)
1917 {
1918 return PK11_SetObjectNickname(pubKey->pkcs11Slot,
1919 pubKey->pkcs11ID,nickname);
1920 }
1921
1922 SECKEYPQGParams *
1923 PK11_GetPQGParamsFromPrivateKey(SECKEYPrivateKey *privKey)
1924 {
1925 CK_ATTRIBUTE pTemplate[] = {
1926 { CKA_PRIME, NULL, 0 },
1927 { CKA_SUBPRIME, NULL, 0 },
1928 { CKA_BASE, NULL, 0 },
1929 };
1930 int pTemplateLen = sizeof(pTemplate)/sizeof(pTemplate[0]);
1931 PLArenaPool *arena = NULL;
1932 SECKEYPQGParams *params;
1933 CK_RV crv;
1934
1935
1936 arena = PORT_NewArena(2048);
1937 if (arena == NULL) {
1938 goto loser;
1939 }
1940 params=(SECKEYPQGParams *)PORT_ArenaZAlloc(arena,sizeof(SECKEYPQGParams));
1941 if (params == NULL) {
1942 goto loser;
1943 }
1944
1945 crv = PK11_GetAttributes(arena, privKey->pkcs11Slot, privKey->pkcs11ID,
1946 pTemplate, pTemplateLen);
1947 if (crv != CKR_OK) {
1948 PORT_SetError( PK11_MapError(crv) );
1949 goto loser;
1950 }
1951
1952 params->arena = arena;
1953 params->prime.data = pTemplate[0].pValue;
1954 params->prime.len = pTemplate[0].ulValueLen;
1955 params->subPrime.data = pTemplate[1].pValue;
1956 params->subPrime.len = pTemplate[1].ulValueLen;
1957 params->base.data = pTemplate[2].pValue;
1958 params->base.len = pTemplate[2].ulValueLen;
1959
1960 return params;
1961
1962 loser:
1963 if (arena != NULL) {
1964 PORT_FreeArena(arena,PR_FALSE);
1965 }
1966 return NULL;
1967 }
1968
1969 SECKEYPrivateKey*
1970 PK11_CopyTokenPrivKeyToSessionPrivKey(PK11SlotInfo *destSlot,
1971 SECKEYPrivateKey *privKey)
1972 {
1973 CK_RV crv;
1974 CK_OBJECT_HANDLE newKeyID;
1975
1976 static const CK_BBOOL ckfalse = CK_FALSE;
1977 static const CK_ATTRIBUTE template[1] = {
1978 { CKA_TOKEN, (CK_BBOOL *)&ckfalse, sizeof ckfalse }
1979 };
1980
1981 if (destSlot && destSlot != privKey->pkcs11Slot) {
1982 SECKEYPrivateKey *newKey =
1983 pk11_loadPrivKey(destSlot,
1984 privKey,
1985 NULL, /* pubKey */
1986 PR_FALSE, /* token */
1987 PR_FALSE);/* sensitive */
1988 if (newKey)
1989 return newKey;
1990 }
1991 destSlot = privKey->pkcs11Slot;
1992 PK11_Authenticate(destSlot, PR_TRUE, privKey->wincx);
1993 PK11_EnterSlotMonitor(destSlot);
1994 crv = PK11_GETTAB(destSlot)->C_CopyObject( destSlot->session,
1995 privKey->pkcs11ID,
1996 (CK_ATTRIBUTE *)template,
1997 1, &newKeyID);
1998 PK11_ExitSlotMonitor(destSlot);
1999
2000 if (crv != CKR_OK) {
2001 PORT_SetError( PK11_MapError(crv) );
2002 return NULL;
2003 }
2004
2005 return PK11_MakePrivKey(destSlot, privKey->keyType, PR_TRUE /*isTemp*/,
2006 newKeyID, privKey->wincx);
2007 }
2008
2009 SECKEYPrivateKey*
2010 PK11_ConvertSessionPrivKeyToTokenPrivKey(SECKEYPrivateKey *privk, void* wincx)
2011 {
2012 PK11SlotInfo* slot = privk->pkcs11Slot;
2013 CK_ATTRIBUTE template[1];
2014 CK_ATTRIBUTE *attrs = template;
2015 CK_BBOOL cktrue = CK_TRUE;
2016 CK_RV crv;
2017 CK_OBJECT_HANDLE newKeyID;
2018 CK_SESSION_HANDLE rwsession;
2019
2020 PK11_SETATTRS(attrs, CKA_TOKEN, &cktrue, sizeof(cktrue)); attrs++;
2021
2022 PK11_Authenticate(slot, PR_TRUE, wincx);
2023 rwsession = PK11_GetRWSession(slot);
2024 if (rwsession == CK_INVALID_SESSION) {
2025 PORT_SetError(SEC_ERROR_BAD_DATA);
2026 return NULL;
2027 }
2028 crv = PK11_GETTAB(slot)->C_CopyObject(rwsession, privk->pkcs11ID,
2029 template, 1, &newKeyID);
2030 PK11_RestoreROSession(slot, rwsession);
2031
2032 if (crv != CKR_OK) {
2033 PORT_SetError( PK11_MapError(crv) );
2034 return NULL;
2035 }
2036
2037 return PK11_MakePrivKey(slot, nullKey /*KeyType*/, PR_FALSE /*isTemp*/,
2038 newKeyID, NULL /*wincx*/);
2039 }
2040
2041 /*
2042 * destroy a private key if there are no matching certs.
2043 * this function also frees the privKey structure.
2044 */
2045 SECStatus
2046 PK11_DeleteTokenPrivateKey(SECKEYPrivateKey *privKey, PRBool force)
2047 {
2048 CERTCertificate *cert=PK11_GetCertFromPrivateKey(privKey);
2049 SECStatus rv = SECWouldBlock;
2050
2051 if (!cert || force) {
2052 /* now, then it's safe for the key to go away */
2053 rv = PK11_DestroyTokenObject(privKey->pkcs11Slot,privKey->pkcs11ID);
2054 }
2055 if (cert) {
2056 CERT_DestroyCertificate(cert);
2057 }
2058 SECKEY_DestroyPrivateKey(privKey);
2059 return rv;
2060 }
2061
2062 /*
2063 * destroy a private key if there are no matching certs.
2064 * this function also frees the privKey structure.
2065 */
2066 SECStatus
2067 PK11_DeleteTokenPublicKey(SECKEYPublicKey *pubKey)
2068 {
2069 /* now, then it's safe for the key to go away */
2070 if (pubKey->pkcs11Slot == NULL) {
2071 return SECFailure;
2072 }
2073 PK11_DestroyTokenObject(pubKey->pkcs11Slot,pubKey->pkcs11ID);
2074 SECKEY_DestroyPublicKey(pubKey);
2075 return SECSuccess;
2076 }
2077
2078 /*
2079 * key call back structure.
2080 */
2081 typedef struct pk11KeyCallbackStr {
2082 SECStatus (* callback)(SECKEYPrivateKey *,void *);
2083 void *callbackArg;
2084 void *wincx;
2085 } pk11KeyCallback;
2086
2087 /*
2088 * callback to map Object Handles to Private Keys;
2089 */
2090 SECStatus
2091 pk11_DoKeys(PK11SlotInfo *slot, CK_OBJECT_HANDLE keyHandle, void *arg)
2092 {
2093 SECStatus rv = SECSuccess;
2094 SECKEYPrivateKey *privKey;
2095 pk11KeyCallback *keycb = (pk11KeyCallback *) arg;
2096 if (!arg) {
2097 return SECFailure;
2098 }
2099
2100 privKey = PK11_MakePrivKey(slot,nullKey,PR_TRUE,keyHandle,keycb->wincx);
2101
2102 if (privKey == NULL) {
2103 return SECFailure;
2104 }
2105
2106 if (keycb->callback) {
2107 rv = (*keycb->callback)(privKey,keycb->callbackArg);
2108 }
2109
2110 SECKEY_DestroyPrivateKey(privKey);
2111 return rv;
2112 }
2113
2114 /***********************************************************************
2115 * PK11_TraversePrivateKeysInSlot
2116 *
2117 * Traverses all the private keys on a slot.
2118 *
2119 * INPUTS
2120 * slot
2121 * The PKCS #11 slot whose private keys you want to traverse.
2122 * callback
2123 * A callback function that will be called for each key.
2124 * arg
2125 * An argument that will be passed to the callback function.
2126 */
2127 SECStatus
2128 PK11_TraversePrivateKeysInSlot( PK11SlotInfo *slot,
2129 SECStatus(* callback)(SECKEYPrivateKey*, void*), void *arg)
2130 {
2131 pk11KeyCallback perKeyCB;
2132 pk11TraverseSlot perObjectCB;
2133 CK_OBJECT_CLASS privkClass = CKO_PRIVATE_KEY;
2134 CK_BBOOL ckTrue = CK_TRUE;
2135 CK_ATTRIBUTE theTemplate[2];
2136 int templateSize = 2;
2137
2138 theTemplate[0].type = CKA_CLASS;
2139 theTemplate[0].pValue = &privkClass;
2140 theTemplate[0].ulValueLen = sizeof(privkClass);
2141 theTemplate[1].type = CKA_TOKEN;
2142 theTemplate[1].pValue = &ckTrue;
2143 theTemplate[1].ulValueLen = sizeof(ckTrue);
2144
2145 if(slot==NULL) {
2146 return SECSuccess;
2147 }
2148
2149 perObjectCB.callback = pk11_DoKeys;
2150 perObjectCB.callbackArg = &perKeyCB;
2151 perObjectCB.findTemplate = theTemplate;
2152 perObjectCB.templateCount = templateSize;
2153 perKeyCB.callback = callback;
2154 perKeyCB.callbackArg = arg;
2155 perKeyCB.wincx = NULL;
2156
2157 return PK11_TraverseSlot(slot, &perObjectCB);
2158 }
2159
2160 /*
2161 * return the private key with the given ID
2162 */
2163 CK_OBJECT_HANDLE
2164 pk11_FindPrivateKeyFromCertID(PK11SlotInfo *slot, SECItem *keyID)
2165 {
2166 CK_OBJECT_CLASS privKey = CKO_PRIVATE_KEY;
2167 CK_ATTRIBUTE theTemplate[] = {
2168 { CKA_ID, NULL, 0 },
2169 { CKA_CLASS, NULL, 0 },
2170 };
2171 /* if you change the array, change the variable below as well */
2172 int tsize = sizeof(theTemplate)/sizeof(theTemplate[0]);
2173 CK_ATTRIBUTE *attrs = theTemplate;
2174
2175 PK11_SETATTRS(attrs, CKA_ID, keyID->data, keyID->len ); attrs++;
2176 PK11_SETATTRS(attrs, CKA_CLASS, &privKey, sizeof(privKey));
2177
2178 return pk11_FindObjectByTemplate(slot,theTemplate,tsize);
2179 }
2180
2181
2182 SECKEYPrivateKey *
2183 PK11_FindKeyByKeyID(PK11SlotInfo *slot, SECItem *keyID, void *wincx)
2184 {
2185 CK_OBJECT_HANDLE keyHandle;
2186 SECKEYPrivateKey *privKey;
2187
2188 keyHandle = pk11_FindPrivateKeyFromCertID(slot, keyID);
2189 if (keyHandle == CK_INVALID_HANDLE) {
2190 return NULL;
2191 }
2192 privKey = PK11_MakePrivKey(slot, nullKey, PR_TRUE, keyHandle, wincx);
2193 return privKey;
2194 }
2195
2196 /*
2197 * Generate a CKA_ID from the relevant public key data. The CKA_ID is generated
2198 * from the pubKeyData by SHA1_Hashing it to produce a smaller CKA_ID (to make
2199 * smart cards happy.
2200 */
2201 SECItem *
2202 PK11_MakeIDFromPubKey(SECItem *pubKeyData)
2203 {
2204 PK11Context *context;
2205 SECItem *certCKA_ID;
2206 SECStatus rv;
2207
2208 if (pubKeyData->len <= SHA1_LENGTH) {
2209 /* probably an already hashed value. The strongest known public
2210 * key values <= 160 bits would be less than 40 bit symetric in
2211 * strength. Don't hash them, just return the value. There are
2212 * none at the time of this writing supported by previous versions
2213 * of NSS, so change is binary compatible safe */
2214 return SECITEM_DupItem(pubKeyData);
2215 }
2216
2217 context = PK11_CreateDigestContext(SEC_OID_SHA1);
2218 if (context == NULL) {
2219 return NULL;
2220 }
2221
2222 rv = PK11_DigestBegin(context);
2223 if (rv == SECSuccess) {
2224 rv = PK11_DigestOp(context,pubKeyData->data,pubKeyData->len);
2225 }
2226 if (rv != SECSuccess) {
2227 PK11_DestroyContext(context,PR_TRUE);
2228 return NULL;
2229 }
2230
2231 certCKA_ID = (SECItem *)PORT_Alloc(sizeof(SECItem));
2232 if (certCKA_ID == NULL) {
2233 PK11_DestroyContext(context,PR_TRUE);
2234 return NULL;
2235 }
2236
2237 certCKA_ID->len = SHA1_LENGTH;
2238 certCKA_ID->data = (unsigned char*)PORT_Alloc(certCKA_ID->len);
2239 if (certCKA_ID->data == NULL) {
2240 PORT_Free(certCKA_ID);
2241 PK11_DestroyContext(context,PR_TRUE);
2242 return NULL;
2243 }
2244
2245 rv = PK11_DigestFinal(context,certCKA_ID->data,&certCKA_ID->len,
2246 SHA1_LENGTH);
2247 PK11_DestroyContext(context,PR_TRUE);
2248 if (rv != SECSuccess) {
2249 SECITEM_FreeItem(certCKA_ID,PR_TRUE);
2250 return NULL;
2251 }
2252
2253 return certCKA_ID;
2254 }
2255
2256 /* Looking for PK11_GetKeyIDFromPrivateKey?
2257 * Call PK11_GetLowLevelKeyIDForPrivateKey instead.
2258 */
2259
2260
2261 SECItem *
2262 PK11_GetLowLevelKeyIDForPrivateKey(SECKEYPrivateKey *privKey)
2263 {
2264 return pk11_GetLowLevelKeyFromHandle(privKey->pkcs11Slot,privKey->pkcs11ID);
2265 }
2266
2267 static SECStatus
2268 privateKeyListCallback(SECKEYPrivateKey *key, void *arg)
2269 {
2270 SECKEYPrivateKeyList *list = (SECKEYPrivateKeyList*)arg;
2271 return SECKEY_AddPrivateKeyToListTail(list, SECKEY_CopyPrivateKey(key));
2272 }
2273
2274 SECKEYPrivateKeyList*
2275 PK11_ListPrivateKeysInSlot(PK11SlotInfo *slot)
2276 {
2277 SECStatus status;
2278 SECKEYPrivateKeyList *keys;
2279
2280 keys = SECKEY_NewPrivateKeyList();
2281 if(keys == NULL) return NULL;
2282
2283 status = PK11_TraversePrivateKeysInSlot(slot, privateKeyListCallback,
2284 (void*)keys);
2285
2286 if( status != SECSuccess ) {
2287 SECKEY_DestroyPrivateKeyList(keys);
2288 keys = NULL;
2289 }
2290
2291 return keys;
2292 }
2293
2294 SECKEYPublicKeyList*
2295 PK11_ListPublicKeysInSlot(PK11SlotInfo *slot, char *nickname)
2296 {
2297 CK_ATTRIBUTE findTemp[4];
2298 CK_ATTRIBUTE *attrs;
2299 CK_BBOOL ckTrue = CK_TRUE;
2300 CK_OBJECT_CLASS keyclass = CKO_PUBLIC_KEY;
2301 int tsize = 0;
2302 int objCount = 0;
2303 CK_OBJECT_HANDLE *key_ids;
2304 SECKEYPublicKeyList *keys;
2305 int i,len;
2306
2307
2308 attrs = findTemp;
2309 PK11_SETATTRS(attrs, CKA_CLASS, &keyclass, sizeof(keyclass)); attrs++;
2310 PK11_SETATTRS(attrs, CKA_TOKEN, &ckTrue, sizeof(ckTrue)); attrs++;
2311 if (nickname) {
2312 len = PORT_Strlen(nickname);
2313 PK11_SETATTRS(attrs, CKA_LABEL, nickname, len); attrs++;
2314 }
2315 tsize = attrs - findTemp;
2316 PORT_Assert(tsize <= sizeof(findTemp)/sizeof(CK_ATTRIBUTE));
2317
2318 key_ids = pk11_FindObjectsByTemplate(slot,findTemp,tsize,&objCount);
2319 if (key_ids == NULL) {
2320 return NULL;
2321 }
2322 keys = SECKEY_NewPublicKeyList();
2323 if (keys == NULL) {
2324 PORT_Free(key_ids);
2325 return NULL;
2326 }
2327
2328 for (i=0; i < objCount ; i++) {
2329 SECKEYPublicKey *pubKey =
2330 PK11_ExtractPublicKey(slot,nullKey,key_ids[i]);
2331 if (pubKey) {
2332 SECKEY_AddPublicKeyToListTail(keys, pubKey);
2333 }
2334 }
2335
2336 PORT_Free(key_ids);
2337 return keys;
2338 }
2339
2340 SECKEYPrivateKeyList*
2341 PK11_ListPrivKeysInSlot(PK11SlotInfo *slot, char *nickname, void *wincx)
2342 {
2343 CK_ATTRIBUTE findTemp[4];
2344 CK_ATTRIBUTE *attrs;
2345 CK_BBOOL ckTrue = CK_TRUE;
2346 CK_OBJECT_CLASS keyclass = CKO_PRIVATE_KEY;
2347 int tsize = 0;
2348 int objCount = 0;
2349 CK_OBJECT_HANDLE *key_ids;
2350 SECKEYPrivateKeyList *keys;
2351 int i,len;
2352
2353
2354 attrs = findTemp;
2355 PK11_SETATTRS(attrs, CKA_CLASS, &keyclass, sizeof(keyclass)); attrs++;
2356 PK11_SETATTRS(attrs, CKA_TOKEN, &ckTrue, sizeof(ckTrue)); attrs++;
2357 if (nickname) {
2358 len = PORT_Strlen(nickname);
2359 PK11_SETATTRS(attrs, CKA_LABEL, nickname, len); attrs++;
2360 }
2361 tsize = attrs - findTemp;
2362 PORT_Assert(tsize <= sizeof(findTemp)/sizeof(CK_ATTRIBUTE));
2363
2364 key_ids = pk11_FindObjectsByTemplate(slot,findTemp,tsize,&objCount);
2365 if (key_ids == NULL) {
2366 return NULL;
2367 }
2368 keys = SECKEY_NewPrivateKeyList();
2369 if (keys == NULL) {
2370 PORT_Free(key_ids);
2371 return NULL;
2372 }
2373
2374 for (i=0; i < objCount ; i++) {
2375 SECKEYPrivateKey *privKey =
2376 PK11_MakePrivKey(slot,nullKey,PR_TRUE,key_ids[i],wincx);
2377 SECKEY_AddPrivateKeyToListTail(keys, privKey);
2378 }
2379
2380 PORT_Free(key_ids);
2381 return keys;
2382 }
2383
This site is hosted by Intevation GmbH (Datenschutzerklärung und Impressum | Privacy Policy and Imprint)