Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(581)

Side by Side Diff: nss/lib/pk11wrap/pk11akey.c

Issue 2078763002: Delete bundled copy of NSS and replace with README. (Closed) Base URL: https://chromium.googlesource.com/chromium/deps/nss@master
Patch Set: Delete bundled copy of NSS and replace with README. Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « nss/lib/pk11wrap/dev3hack.c ('k') | nss/lib/pk11wrap/pk11auth.c » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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 "sechash.h"
22
23 #include "secpkcs5.h"
24 #include "blapit.h"
25
26 static SECItem *
27 pk11_MakeIDFromPublicKey(SECKEYPublicKey *pubKey)
28 {
29 /* set the ID to the public key so we can find it again */
30 SECItem *pubKeyIndex = NULL;
31 switch (pubKey->keyType) {
32 case rsaKey:
33 pubKeyIndex = &pubKey->u.rsa.modulus;
34 break;
35 case dsaKey:
36 pubKeyIndex = &pubKey->u.dsa.publicValue;
37 break;
38 case dhKey:
39 pubKeyIndex = &pubKey->u.dh.publicValue;
40 break;
41 case ecKey:
42 pubKeyIndex = &pubKey->u.ec.publicValue;
43 break;
44 default:
45 return NULL;
46 }
47 PORT_Assert(pubKeyIndex != NULL);
48
49 return PK11_MakeIDFromPubKey(pubKeyIndex);
50 }
51
52 /*
53 * import a public key into the desired slot
54 *
55 * This function takes a public key structure and creates a public key in a
56 * given slot. If isToken is set, then a persistant public key is created.
57 *
58 * Note: it is possible for this function to return a handle for a key which
59 * is persistant, even if isToken is not set.
60 */
61 CK_OBJECT_HANDLE
62 PK11_ImportPublicKey(PK11SlotInfo *slot, SECKEYPublicKey *pubKey,
63 PRBool isToken)
64 {
65 CK_BBOOL cktrue = CK_TRUE;
66 CK_BBOOL ckfalse = CK_FALSE;
67 CK_OBJECT_CLASS keyClass = CKO_PUBLIC_KEY;
68 CK_KEY_TYPE keyType = CKK_GENERIC_SECRET;
69 CK_OBJECT_HANDLE objectID;
70 CK_ATTRIBUTE theTemplate[11];
71 CK_ATTRIBUTE *signedattr = NULL;
72 CK_ATTRIBUTE *attrs = theTemplate;
73 SECItem *ckaId = NULL;
74 SECItem *pubValue = NULL;
75 int signedcount = 0;
76 unsigned int templateCount = 0;
77 SECStatus rv;
78
79 /* if we already have an object in the desired slot, use it */
80 if (!isToken && pubKey->pkcs11Slot == slot) {
81 return pubKey->pkcs11ID;
82 }
83
84 /* free the existing key */
85 if (pubKey->pkcs11Slot != NULL) {
86 PK11SlotInfo *oSlot = pubKey->pkcs11Slot;
87 if (!PK11_IsPermObject(pubKey->pkcs11Slot,pubKey->pkcs11ID)) {
88 PK11_EnterSlotMonitor(oSlot);
89 (void) PK11_GETTAB(oSlot)->C_DestroyObject(oSlot->session,
90 pubKey->pkcs11ID);
91 PK11_ExitSlotMonitor(oSlot);
92 }
93 PK11_FreeSlot(oSlot);
94 pubKey->pkcs11Slot = NULL;
95 }
96 PK11_SETATTRS(attrs, CKA_CLASS, &keyClass, sizeof(keyClass) ); attrs++;
97 PK11_SETATTRS(attrs, CKA_KEY_TYPE, &keyType, sizeof(keyType) ); attrs++;
98 PK11_SETATTRS(attrs, CKA_TOKEN, isToken ? &cktrue : &ckfalse,
99 sizeof(CK_BBOOL) ); attrs++;
100 if (isToken) {
101 ckaId = pk11_MakeIDFromPublicKey(pubKey);
102 if (ckaId == NULL) {
103 PORT_SetError( SEC_ERROR_BAD_KEY );
104 return CK_INVALID_HANDLE;
105 }
106 PK11_SETATTRS(attrs, CKA_ID, ckaId->data, ckaId->len); attrs++;
107 }
108
109 /* now import the key */
110 {
111 switch (pubKey->keyType) {
112 case rsaKey:
113 keyType = CKK_RSA;
114 PK11_SETATTRS(attrs, CKA_WRAP, &cktrue, sizeof(CK_BBOOL) ); attrs++;
115 PK11_SETATTRS(attrs, CKA_ENCRYPT, &cktrue,
116 sizeof(CK_BBOOL) ); attrs++;
117 PK11_SETATTRS(attrs, CKA_VERIFY, &cktrue, sizeof(CK_BBOOL)); attrs++ ;
118 signedattr = attrs;
119 PK11_SETATTRS(attrs, CKA_MODULUS, pubKey->u.rsa.modulus.data,
120 pubKey->u.rsa.modulus.len); attrs++;
121 PK11_SETATTRS(attrs, CKA_PUBLIC_EXPONENT,
122 pubKey->u.rsa.publicExponent.data,
123 pubKey->u.rsa.publicExponent.len); attrs++;
124 break;
125 case dsaKey:
126 keyType = CKK_DSA;
127 PK11_SETATTRS(attrs, CKA_VERIFY, &cktrue, sizeof(CK_BBOOL));attrs++;
128 signedattr = attrs;
129 PK11_SETATTRS(attrs, CKA_PRIME, pubKey->u.dsa.params.prime.data,
130 pubKey->u.dsa.params.prime.len); attrs++;
131 PK11_SETATTRS(attrs,CKA_SUBPRIME,pubKey->u.dsa.params.subPrime.data,
132 pubKey->u.dsa.params.subPrime.len); attrs++;
133 PK11_SETATTRS(attrs, CKA_BASE, pubKey->u.dsa.params.base.data,
134 pubKey->u.dsa.params.base.len); attrs++;
135 PK11_SETATTRS(attrs, CKA_VALUE, pubKey->u.dsa.publicValue.data,
136 pubKey->u.dsa.publicValue.len); attrs++;
137 break;
138 case dhKey:
139 keyType = CKK_DH;
140 PK11_SETATTRS(attrs, CKA_DERIVE, &cktrue, sizeof(CK_BBOOL));attrs++;
141 signedattr = attrs;
142 PK11_SETATTRS(attrs, CKA_PRIME, pubKey->u.dh.prime.data,
143 pubKey->u.dh.prime.len); attrs++;
144 PK11_SETATTRS(attrs, CKA_BASE, pubKey->u.dh.base.data,
145 pubKey->u.dh.base.len); attrs++;
146 PK11_SETATTRS(attrs, CKA_VALUE, pubKey->u.dh.publicValue.data,
147 pubKey->u.dh.publicValue.len); attrs++;
148 break;
149 case ecKey:
150 keyType = CKK_EC;
151 PK11_SETATTRS(attrs, CKA_VERIFY, &cktrue, sizeof(CK_BBOOL));attrs++;
152 PK11_SETATTRS(attrs, CKA_DERIVE, &cktrue, sizeof(CK_BBOOL));attrs++;
153 signedattr = attrs;
154 PK11_SETATTRS(attrs, CKA_EC_PARAMS,
155 pubKey->u.ec.DEREncodedParams.data,
156 pubKey->u.ec.DEREncodedParams.len); attrs++;
157 if (PR_GetEnvSecure("NSS_USE_DECODED_CKA_EC_POINT")) {
158 PK11_SETATTRS(attrs, CKA_EC_POINT,
159 pubKey->u.ec.publicValue.data,
160 pubKey->u.ec.publicValue.len); attrs++;
161 } else {
162 pubValue = SEC_ASN1EncodeItem(NULL, NULL,
163 &pubKey->u.ec.publicValue,
164 SEC_ASN1_GET(SEC_OctetStringTemplate));
165 if (pubValue == NULL) {
166 if (ckaId) {
167 SECITEM_FreeItem(ckaId,PR_TRUE);
168 }
169 return CK_INVALID_HANDLE;
170 }
171 PK11_SETATTRS(attrs, CKA_EC_POINT,
172 pubValue->data, pubValue->len); attrs++;
173 }
174 break;
175 default:
176 if (ckaId) {
177 SECITEM_FreeItem(ckaId,PR_TRUE);
178 }
179 PORT_SetError( SEC_ERROR_BAD_KEY );
180 return CK_INVALID_HANDLE;
181 }
182
183 templateCount = attrs - theTemplate;
184 signedcount = attrs - signedattr;
185 PORT_Assert(templateCount <= (sizeof(theTemplate)/sizeof(CK_ATTRIBUTE))) ;
186 for (attrs=signedattr; signedcount; attrs++, signedcount--) {
187 pk11_SignedToUnsigned(attrs);
188 }
189 rv = PK11_CreateNewObject(slot, CK_INVALID_SESSION, theTemplate,
190 templateCount, isToken, &objectID);
191 if (ckaId) {
192 SECITEM_FreeItem(ckaId,PR_TRUE);
193 }
194 if (pubValue) {
195 SECITEM_FreeItem(pubValue,PR_TRUE);
196 }
197 if ( rv != SECSuccess) {
198 /* CKR_ATTRIBUTE_VALUE_INVALID is mapped to SEC_ERROR_BAD_DATA */
199 if (PORT_GetError() == SEC_ERROR_BAD_DATA) {
200 PORT_SetError( SEC_ERROR_BAD_KEY );
201 }
202 return CK_INVALID_HANDLE;
203 }
204 }
205
206 pubKey->pkcs11ID = objectID;
207 pubKey->pkcs11Slot = PK11_ReferenceSlot(slot);
208
209 return objectID;
210 }
211
212 /*
213 * take an attribute and copy it into a secitem
214 */
215 static CK_RV
216 pk11_Attr2SecItem(PLArenaPool *arena, const CK_ATTRIBUTE *attr, SECItem *item)
217 {
218 item->data = NULL;
219
220 (void)SECITEM_AllocItem(arena, item, attr->ulValueLen);
221 if (item->data == NULL) {
222 return CKR_HOST_MEMORY;
223 }
224 PORT_Memcpy(item->data, attr->pValue, item->len);
225 return CKR_OK;
226 }
227
228
229 /*
230 * get a curve length from a set of ecParams.
231 *
232 * We need this so we can reliably determine if the ecPoint passed to us
233 * was encoded or not. With out this, for many curves, we would incorrectly
234 * identify an unencoded curve as an encoded curve 1 in 65536 times, and for
235 * a few we would make that same mistake 1 in 32768 times. These are bad
236 * numbers since they are rare enough to pass tests, but common enough to
237 * be tripped over in the field.
238 *
239 * This function will only work for curves we recognized as of March 2009.
240 * The assumption is curves in use after March of 2009 would be supplied by
241 * PKCS #11 modules that already pass the correct encoding to us.
242 *
243 * Point length = (Roundup(curveLenInBits/8)*2+1)
244 */
245 static int
246 pk11_get_EC_PointLenInBytes(PLArenaPool *arena, const SECItem *ecParams)
247 {
248 SECItem oid;
249 SECOidTag tag;
250 SECStatus rv;
251
252 /* decode the OID tag */
253 rv = SEC_QuickDERDecodeItem(arena, &oid,
254 SEC_ASN1_GET(SEC_ObjectIDTemplate), ecParams);
255 if (rv != SECSuccess) {
256 /* could be explict curves, allow them to work if the
257 * PKCS #11 module support them. If we try to parse the
258 * explicit curve value in the future, we may return -1 here
259 * to indicate an invalid parameter if the explicit curve
260 * decode fails. */
261 return 0;
262 }
263
264 tag = SECOID_FindOIDTag(&oid);
265 switch (tag) {
266 case SEC_OID_SECG_EC_SECP112R1:
267 case SEC_OID_SECG_EC_SECP112R2:
268 return 29; /* curve len in bytes = 14 bytes */
269 case SEC_OID_SECG_EC_SECT113R1:
270 case SEC_OID_SECG_EC_SECT113R2:
271 return 31; /* curve len in bytes = 15 bytes */
272 case SEC_OID_SECG_EC_SECP128R1:
273 case SEC_OID_SECG_EC_SECP128R2:
274 return 33; /* curve len in bytes = 16 bytes */
275 case SEC_OID_SECG_EC_SECT131R1:
276 case SEC_OID_SECG_EC_SECT131R2:
277 return 35; /* curve len in bytes = 17 bytes */
278 case SEC_OID_SECG_EC_SECP160K1:
279 case SEC_OID_SECG_EC_SECP160R1:
280 case SEC_OID_SECG_EC_SECP160R2:
281 return 41; /* curve len in bytes = 20 bytes */
282 case SEC_OID_SECG_EC_SECT163K1:
283 case SEC_OID_SECG_EC_SECT163R1:
284 case SEC_OID_SECG_EC_SECT163R2:
285 case SEC_OID_ANSIX962_EC_C2PNB163V1:
286 case SEC_OID_ANSIX962_EC_C2PNB163V2:
287 case SEC_OID_ANSIX962_EC_C2PNB163V3:
288 return 43; /* curve len in bytes = 21 bytes */
289 case SEC_OID_ANSIX962_EC_C2PNB176V1:
290 return 45; /* curve len in bytes = 22 bytes */
291 case SEC_OID_ANSIX962_EC_C2TNB191V1:
292 case SEC_OID_ANSIX962_EC_C2TNB191V2:
293 case SEC_OID_ANSIX962_EC_C2TNB191V3:
294 case SEC_OID_SECG_EC_SECP192K1:
295 case SEC_OID_ANSIX962_EC_PRIME192V1:
296 case SEC_OID_ANSIX962_EC_PRIME192V2:
297 case SEC_OID_ANSIX962_EC_PRIME192V3:
298 return 49; /*curve len in bytes = 24 bytes */
299 case SEC_OID_SECG_EC_SECT193R1:
300 case SEC_OID_SECG_EC_SECT193R2:
301 return 51; /*curve len in bytes = 25 bytes */
302 case SEC_OID_ANSIX962_EC_C2PNB208W1:
303 return 53; /*curve len in bytes = 26 bytes */
304 case SEC_OID_SECG_EC_SECP224K1:
305 case SEC_OID_SECG_EC_SECP224R1:
306 return 57; /*curve len in bytes = 28 bytes */
307 case SEC_OID_SECG_EC_SECT233K1:
308 case SEC_OID_SECG_EC_SECT233R1:
309 case SEC_OID_SECG_EC_SECT239K1:
310 case SEC_OID_ANSIX962_EC_PRIME239V1:
311 case SEC_OID_ANSIX962_EC_PRIME239V2:
312 case SEC_OID_ANSIX962_EC_PRIME239V3:
313 case SEC_OID_ANSIX962_EC_C2TNB239V1:
314 case SEC_OID_ANSIX962_EC_C2TNB239V2:
315 case SEC_OID_ANSIX962_EC_C2TNB239V3:
316 return 61; /*curve len in bytes = 30 bytes */
317 case SEC_OID_ANSIX962_EC_PRIME256V1:
318 case SEC_OID_SECG_EC_SECP256K1:
319 return 65; /*curve len in bytes = 32 bytes */
320 case SEC_OID_ANSIX962_EC_C2PNB272W1:
321 return 69; /*curve len in bytes = 34 bytes */
322 case SEC_OID_SECG_EC_SECT283K1:
323 case SEC_OID_SECG_EC_SECT283R1:
324 return 73; /*curve len in bytes = 36 bytes */
325 case SEC_OID_ANSIX962_EC_C2PNB304W1:
326 return 77; /*curve len in bytes = 38 bytes */
327 case SEC_OID_ANSIX962_EC_C2TNB359V1:
328 return 91; /*curve len in bytes = 45 bytes */
329 case SEC_OID_ANSIX962_EC_C2PNB368W1:
330 return 93; /*curve len in bytes = 46 bytes */
331 case SEC_OID_SECG_EC_SECP384R1:
332 return 97; /*curve len in bytes = 48 bytes */
333 case SEC_OID_SECG_EC_SECT409K1:
334 case SEC_OID_SECG_EC_SECT409R1:
335 return 105; /*curve len in bytes = 52 bytes */
336 case SEC_OID_ANSIX962_EC_C2TNB431R1:
337 return 109; /*curve len in bytes = 54 bytes */
338 case SEC_OID_SECG_EC_SECP521R1:
339 return 133; /*curve len in bytes = 66 bytes */
340 case SEC_OID_SECG_EC_SECT571K1:
341 case SEC_OID_SECG_EC_SECT571R1:
342 return 145; /*curve len in bytes = 72 bytes */
343 /* unknown or unrecognized OIDs. return unknown length */
344 default:
345 break;
346 }
347 return 0;
348 }
349
350 /*
351 * returns the decoded point. In some cases the point may already be decoded.
352 * this function tries to detect those cases and return the point in
353 * publicKeyValue. In other cases it's DER encoded. In those cases the point
354 * is first decoded and returned. Space for the point is allocated out of
355 * the passed in arena.
356 */
357 static CK_RV
358 pk11_get_Decoded_ECPoint(PLArenaPool *arena, const SECItem *ecParams,
359 const CK_ATTRIBUTE *ecPoint, SECItem *publicKeyValue)
360 {
361 SECItem encodedPublicValue;
362 SECStatus rv;
363 int keyLen;
364
365 if (ecPoint->ulValueLen == 0) {
366 return CKR_ATTRIBUTE_VALUE_INVALID;
367 }
368
369 /*
370 * The PKCS #11 spec requires ecPoints to be encoded as a DER OCTET String.
371 * NSS has mistakenly passed unencoded values, and some PKCS #11 vendors
372 * followed that mistake. Now we need to detect which encoding we were
373 * passed in. The task is made more complicated by the fact the the
374 * DER encoding byte (SEC_ASN_OCTET_STRING) is the same as the
375 * EC_POINT_FORM_UNCOMPRESSED byte (0x04), so we can't use that to
376 * determine which curve we are using.
377 */
378
379 /* get the expected key length for the passed in curve.
380 * pk11_get_EC_PointLenInBytes only returns valid values for curves
381 * NSS has traditionally recognized. If the curve is not recognized,
382 * it will return '0', and we have to figure out if the key was
383 * encoded or not heuristically. If the ecParams are invalid, it
384 * will return -1 for the keyLen.
385 */
386 keyLen = pk11_get_EC_PointLenInBytes(arena, ecParams);
387 if (keyLen < 0) {
388 return CKR_ATTRIBUTE_VALUE_INVALID;
389 }
390
391
392 /* If the point is uncompressed and the lengths match, it
393 * must be an unencoded point */
394 if ((*((char *)ecPoint->pValue) == EC_POINT_FORM_UNCOMPRESSED)
395 && (ecPoint->ulValueLen == (unsigned int)keyLen)) {
396 return pk11_Attr2SecItem(arena, ecPoint, publicKeyValue);
397 }
398
399 /* now assume the key passed to us was encoded and decode it */
400 if (*((char *)ecPoint->pValue) == SEC_ASN1_OCTET_STRING) {
401 /* OK, now let's try to decode it and see if it's valid */
402 encodedPublicValue.data = ecPoint->pValue;
403 encodedPublicValue.len = ecPoint->ulValueLen;
404 rv = SEC_QuickDERDecodeItem(arena, publicKeyValue,
405 SEC_ASN1_GET(SEC_OctetStringTemplate), &encodedPublicValue);
406
407 /* it coded correctly & we know the key length (and they match)
408 * then we are done, return the results. */
409 if (keyLen && rv == SECSuccess && publicKeyValue->len == (unsigned int)k eyLen) {
410 return CKR_OK;
411 }
412
413 /* if we know the key length, one of the above tests should have
414 * succeded. If it doesn't the module gave us bad data */
415 if (keyLen) {
416 return CKR_ATTRIBUTE_VALUE_INVALID;
417 }
418
419
420 /* We don't know the key length, so we don't know deterministically
421 * which encoding was used. We now will try to pick the most likely
422 * form that's correct, with a preference for the encoded form if we
423 * can't determine for sure. We do this by checking the key we got
424 * back from SEC_QuickDERDecodeItem for defects. If no defects are
425 * found, we assume the encoded parameter was was passed to us.
426 * our defect tests include:
427 * 1) it didn't decode.
428 * 2) The decode key had an invalid length (must be odd).
429 * 3) The decoded key wasn't an UNCOMPRESSED key.
430 * 4) The decoded key didn't include the entire encoded block
431 * except the DER encoding values. (fixing DER length to one
432 * particular value).
433 */
434 if ((rv != SECSuccess)
435 || ((publicKeyValue->len & 1) != 1)
436 || (publicKeyValue->data[0] != EC_POINT_FORM_UNCOMPRESSED)
437 || (PORT_Memcmp(&encodedPublicValue.data[encodedPublicValue.len -
438 publicKeyValue->len], publicKeyValue->data,
439 publicKeyValue->len) != 0)) {
440 /* The decoded public key was flawed, the original key must have
441 * already been in decoded form. Do a quick sanity check then
442 * return the original key value.
443 */
444 if ((encodedPublicValue.len & 1) == 0) {
445 return CKR_ATTRIBUTE_VALUE_INVALID;
446 }
447 return pk11_Attr2SecItem(arena, ecPoint, publicKeyValue);
448 }
449
450 /* as best we can figure, the passed in key was encoded, and we've
451 * now decoded it. Note: there is a chance this could be wrong if the
452 * following conditions hold:
453 * 1) The first byte or bytes of the X point looks like a valid length
454 * of precisely the right size (2*curveSize -1). this means for curves
455 * less than 512 bits (64 bytes), this will happen 1 in 256 times*.
456 * for curves between 512 and 1024, this will happen 1 in 65,536 times*
457 * for curves between 1024 and 256K this will happen 1 in 16 million*
458 * 2) The length of the 'DER length field' is odd
459 * (making both the encoded and decode
460 * values an odd length. this is true of all curves less than 512,
461 * as well as curves between 1024 and 256K).
462 * 3) The X[length of the 'DER length field'] == 0x04, 1 in 256.
463 *
464 * (* assuming all values are equally likely in the first byte,
465 * This isn't true if the curve length is not a multiple of 8. In these
466 * cases, if the DER length is possible, it's more likely,
467 * if it's not possible, then we have no false decodes).
468 *
469 * For reference here are the odds for the various curves we currently
470 * have support for (and the only curves SSL will negotiate at this
471 * time). NOTE: None of the supported curves will show up here
472 * because we return a valid length for all of these curves.
473 * The only way to get here is to have some application (not SSL)
474 * which supports some unknown curve and have some vendor supplied
475 * PKCS #11 module support that curve. NOTE: in this case, one
476 * presumes that that pkcs #11 module is likely to be using the
477 * correct encodings.
478 *
479 * Prime Curves (GFp):
480 * Bit False Odds of
481 * Size DER Len False Decode Positive
482 * 112 27 1 in 65536
483 * 128 31 1 in 65536
484 * 160 39 1 in 65536
485 * 192 47 1 in 65536
486 * 224 55 1 in 65536
487 * 239 59 1 in 32768 (top byte can only be 0-127)
488 * 256 63 1 in 65536
489 * 521 129,131 0 (decoded value would be even)
490 *
491 * Binary curves (GF2m).
492 * Bit False Odds of
493 * Size DER Len False Decode Positive
494 * 131 33 0 (top byte can only be 0-7)
495 * 163 41 0 (top byte can only be 0-7)
496 * 176 43 1 in 65536
497 * 191 47 1 in 32768 (top byte can only be 0-127)
498 * 193 49 0 (top byte can only be 0-1)
499 * 208 51 1 in 65536
500 * 233 59 0 (top byte can only be 0-1)
501 * 239 59 1 in 32768 (top byte can only be 0-127)
502 * 272 67 1 in 65536
503 * 283 71 0 (top byte can only be 0-7)
504 * 304 75 1 in 65536
505 * 359 89 1 in 32768 (top byte can only be 0-127)
506 * 368 91 1 in 65536
507 * 409 103 0 (top byte can only be 0-1)
508 * 431 107 1 in 32768 (top byte can only be 0-127)
509 * 571 129,143 0 (decoded value would be even)
510 *
511 */
512
513 return CKR_OK;
514 }
515
516 /* In theory, we should handle the case where the curve == 0 and
517 * the first byte is EC_POINT_FORM_UNCOMPRESSED, (which would be
518 * handled by doing a santity check on the key length and returning
519 * pk11_Attr2SecItem() to copy the ecPoint to the publicKeyValue).
520 *
521 * This test is unnecessary, however, due to the fact that
522 * EC_POINT_FORM_UNCOMPRESSED == SEC_ASIN1_OCTET_STRING, that case is
523 * handled in the above if. That means if we get here, the initial
524 * byte of our ecPoint value was invalid, so we can safely return.
525 * invalid attribute.
526 */
527
528 return CKR_ATTRIBUTE_VALUE_INVALID;
529 }
530
531 /*
532 * extract a public key from a slot and id
533 */
534 SECKEYPublicKey *
535 PK11_ExtractPublicKey(PK11SlotInfo *slot,KeyType keyType,CK_OBJECT_HANDLE id)
536 {
537 CK_OBJECT_CLASS keyClass = CKO_PUBLIC_KEY;
538 PLArenaPool *arena;
539 PLArenaPool *tmp_arena;
540 SECKEYPublicKey *pubKey;
541 unsigned int templateCount = 0;
542 CK_KEY_TYPE pk11KeyType;
543 CK_RV crv;
544 CK_ATTRIBUTE template[8];
545 CK_ATTRIBUTE *attrs= template;
546 CK_ATTRIBUTE *modulus,*exponent,*base,*prime,*subprime,*value;
547 CK_ATTRIBUTE *ecparams;
548
549 /* if we didn't know the key type, get it */
550 if (keyType== nullKey) {
551
552 pk11KeyType = PK11_ReadULongAttribute(slot,id,CKA_KEY_TYPE);
553 if (pk11KeyType == CK_UNAVAILABLE_INFORMATION) {
554 return NULL;
555 }
556 switch (pk11KeyType) {
557 case CKK_RSA:
558 keyType = rsaKey;
559 break;
560 case CKK_DSA:
561 keyType = dsaKey;
562 break;
563 case CKK_DH:
564 keyType = dhKey;
565 break;
566 case CKK_EC:
567 keyType = ecKey;
568 break;
569 default:
570 PORT_SetError( SEC_ERROR_BAD_KEY );
571 return NULL;
572 }
573 }
574
575
576 /* now we need to create space for the public key */
577 arena = PORT_NewArena( DER_DEFAULT_CHUNKSIZE);
578 if (arena == NULL) return NULL;
579 tmp_arena = PORT_NewArena( DER_DEFAULT_CHUNKSIZE);
580 if (tmp_arena == NULL) {
581 PORT_FreeArena (arena, PR_FALSE);
582 return NULL;
583 }
584
585
586 pubKey = (SECKEYPublicKey *)
587 PORT_ArenaZAlloc(arena, sizeof(SECKEYPublicKey));
588 if (pubKey == NULL) {
589 PORT_FreeArena (arena, PR_FALSE);
590 PORT_FreeArena (tmp_arena, PR_FALSE);
591 return NULL;
592 }
593
594 pubKey->arena = arena;
595 pubKey->keyType = keyType;
596 pubKey->pkcs11Slot = PK11_ReferenceSlot(slot);
597 pubKey->pkcs11ID = id;
598 PK11_SETATTRS(attrs, CKA_CLASS, &keyClass,
599 sizeof(keyClass)); attrs++;
600 PK11_SETATTRS(attrs, CKA_KEY_TYPE, &pk11KeyType,
601 sizeof(pk11KeyType) ); attrs++;
602 switch (pubKey->keyType) {
603 case rsaKey:
604 modulus = attrs;
605 PK11_SETATTRS(attrs, CKA_MODULUS, NULL, 0); attrs++;
606 exponent = attrs;
607 PK11_SETATTRS(attrs, CKA_PUBLIC_EXPONENT, NULL, 0); attrs++;
608
609 templateCount = attrs - template;
610 PR_ASSERT(templateCount <= sizeof(template)/sizeof(CK_ATTRIBUTE));
611 crv = PK11_GetAttributes(tmp_arena,slot,id,template,templateCount);
612 if (crv != CKR_OK) break;
613
614 if ((keyClass != CKO_PUBLIC_KEY) || (pk11KeyType != CKK_RSA)) {
615 crv = CKR_OBJECT_HANDLE_INVALID;
616 break;
617 }
618 crv = pk11_Attr2SecItem(arena,modulus,&pubKey->u.rsa.modulus);
619 if (crv != CKR_OK) break;
620 crv = pk11_Attr2SecItem(arena,exponent,&pubKey->u.rsa.publicExponent);
621 if (crv != CKR_OK) break;
622 break;
623 case dsaKey:
624 prime = attrs;
625 PK11_SETATTRS(attrs, CKA_PRIME, NULL, 0); attrs++;
626 subprime = attrs;
627 PK11_SETATTRS(attrs, CKA_SUBPRIME, NULL, 0); attrs++;
628 base = attrs;
629 PK11_SETATTRS(attrs, CKA_BASE, NULL, 0); attrs++;
630 value = attrs;
631 PK11_SETATTRS(attrs, CKA_VALUE, NULL, 0); attrs++;
632 templateCount = attrs - template;
633 PR_ASSERT(templateCount <= sizeof(template)/sizeof(CK_ATTRIBUTE));
634 crv = PK11_GetAttributes(tmp_arena,slot,id,template,templateCount);
635 if (crv != CKR_OK) break;
636
637 if ((keyClass != CKO_PUBLIC_KEY) || (pk11KeyType != CKK_DSA)) {
638 crv = CKR_OBJECT_HANDLE_INVALID;
639 break;
640 }
641 crv = pk11_Attr2SecItem(arena,prime,&pubKey->u.dsa.params.prime);
642 if (crv != CKR_OK) break;
643 crv = pk11_Attr2SecItem(arena,subprime,&pubKey->u.dsa.params.subPrime);
644 if (crv != CKR_OK) break;
645 crv = pk11_Attr2SecItem(arena,base,&pubKey->u.dsa.params.base);
646 if (crv != CKR_OK) break;
647 crv = pk11_Attr2SecItem(arena,value,&pubKey->u.dsa.publicValue);
648 if (crv != CKR_OK) break;
649 break;
650 case dhKey:
651 prime = attrs;
652 PK11_SETATTRS(attrs, CKA_PRIME, NULL, 0); attrs++;
653 base = attrs;
654 PK11_SETATTRS(attrs, CKA_BASE, NULL, 0); attrs++;
655 value =attrs;
656 PK11_SETATTRS(attrs, CKA_VALUE, NULL, 0); attrs++;
657 templateCount = attrs - template;
658 PR_ASSERT(templateCount <= sizeof(template)/sizeof(CK_ATTRIBUTE));
659 crv = PK11_GetAttributes(tmp_arena,slot,id,template,templateCount);
660 if (crv != CKR_OK) break;
661
662 if ((keyClass != CKO_PUBLIC_KEY) || (pk11KeyType != CKK_DH)) {
663 crv = CKR_OBJECT_HANDLE_INVALID;
664 break;
665 }
666 crv = pk11_Attr2SecItem(arena,prime,&pubKey->u.dh.prime);
667 if (crv != CKR_OK) break;
668 crv = pk11_Attr2SecItem(arena,base,&pubKey->u.dh.base);
669 if (crv != CKR_OK) break;
670 crv = pk11_Attr2SecItem(arena,value,&pubKey->u.dh.publicValue);
671 if (crv != CKR_OK) break;
672 break;
673 case ecKey:
674 pubKey->u.ec.size = 0;
675 ecparams = attrs;
676 PK11_SETATTRS(attrs, CKA_EC_PARAMS, NULL, 0); attrs++;
677 value =attrs;
678 PK11_SETATTRS(attrs, CKA_EC_POINT, NULL, 0); attrs++;
679 templateCount = attrs - template;
680 PR_ASSERT(templateCount <= sizeof(template)/sizeof(CK_ATTRIBUTE));
681 crv = PK11_GetAttributes(arena,slot,id,template,templateCount);
682 if (crv != CKR_OK) break;
683
684 if ((keyClass != CKO_PUBLIC_KEY) || (pk11KeyType != CKK_EC)) {
685 crv = CKR_OBJECT_HANDLE_INVALID;
686 break;
687 }
688
689 crv = pk11_Attr2SecItem(arena,ecparams,
690 &pubKey->u.ec.DEREncodedParams);
691 if (crv != CKR_OK) break;
692 crv = pk11_get_Decoded_ECPoint(arena,
693 &pubKey->u.ec.DEREncodedParams, value,
694 &pubKey->u.ec.publicValue);
695 break;
696 case fortezzaKey:
697 case nullKey:
698 default:
699 crv = CKR_OBJECT_HANDLE_INVALID;
700 break;
701 }
702
703 PORT_FreeArena(tmp_arena,PR_FALSE);
704
705 if (crv != CKR_OK) {
706 PORT_FreeArena(arena,PR_FALSE);
707 PK11_FreeSlot(slot);
708 PORT_SetError( PK11_MapError(crv) );
709 return NULL;
710 }
711
712 return pubKey;
713 }
714
715 /*
716 * Build a Private Key structure from raw PKCS #11 information.
717 */
718 SECKEYPrivateKey *
719 PK11_MakePrivKey(PK11SlotInfo *slot, KeyType keyType,
720 PRBool isTemp, CK_OBJECT_HANDLE privID, void *wincx)
721 {
722 PLArenaPool *arena;
723 SECKEYPrivateKey *privKey;
724 PRBool isPrivate;
725 SECStatus rv;
726
727 /* don't know? look it up */
728 if (keyType == nullKey) {
729 CK_KEY_TYPE pk11Type = CKK_RSA;
730
731 pk11Type = PK11_ReadULongAttribute(slot,privID,CKA_KEY_TYPE);
732 isTemp = (PRBool)!PK11_HasAttributeSet(slot,privID,CKA_TOKEN,PR_FALSE);
733 switch (pk11Type) {
734 case CKK_RSA: keyType = rsaKey; break;
735 case CKK_DSA: keyType = dsaKey; break;
736 case CKK_DH: keyType = dhKey; break;
737 case CKK_KEA: keyType = fortezzaKey; break;
738 case CKK_EC: keyType = ecKey; break;
739 default:
740 break;
741 }
742 }
743
744 /* if the key is private, make sure we are authenticated to the
745 * token before we try to use it */
746 isPrivate = (PRBool)PK11_HasAttributeSet(slot,privID,CKA_PRIVATE,PR_FALSE);
747 if (isPrivate) {
748 rv = PK11_Authenticate(slot, PR_TRUE, wincx);
749 if (rv != SECSuccess) {
750 return NULL;
751 }
752 }
753
754 /* now we need to create space for the private key */
755 arena = PORT_NewArena( DER_DEFAULT_CHUNKSIZE);
756 if (arena == NULL) return NULL;
757
758 privKey = (SECKEYPrivateKey *)
759 PORT_ArenaZAlloc(arena, sizeof(SECKEYPrivateKey));
760 if (privKey == NULL) {
761 PORT_FreeArena(arena, PR_FALSE);
762 return NULL;
763 }
764
765 privKey->arena = arena;
766 privKey->keyType = keyType;
767 privKey->pkcs11Slot = PK11_ReferenceSlot(slot);
768 privKey->pkcs11ID = privID;
769 privKey->pkcs11IsTemp = isTemp;
770 privKey->wincx = wincx;
771
772 return privKey;
773 }
774
775
776 PK11SlotInfo *
777 PK11_GetSlotFromPrivateKey(SECKEYPrivateKey *key)
778 {
779 PK11SlotInfo *slot = key->pkcs11Slot;
780 slot = PK11_ReferenceSlot(slot);
781 return slot;
782 }
783
784 /*
785 * Get the modulus length for raw parsing
786 */
787 int
788 PK11_GetPrivateModulusLen(SECKEYPrivateKey *key)
789 {
790 CK_ATTRIBUTE theTemplate = { CKA_MODULUS, NULL, 0 };
791 PK11SlotInfo *slot = key->pkcs11Slot;
792 CK_RV crv;
793 int length;
794
795 switch (key->keyType) {
796 case rsaKey:
797 crv = PK11_GetAttributes(NULL, slot, key->pkcs11ID, &theTemplate, 1);
798 if (crv != CKR_OK) {
799 PORT_SetError( PK11_MapError(crv) );
800 return -1;
801 }
802 length = theTemplate.ulValueLen;
803 if ( *(unsigned char *)theTemplate.pValue == 0) {
804 length--;
805 }
806 if (theTemplate.pValue != NULL)
807 PORT_Free(theTemplate.pValue);
808 return (int) length;
809
810 case fortezzaKey:
811 case dsaKey:
812 case dhKey:
813 default:
814 break;
815 }
816 if (theTemplate.pValue != NULL)
817 PORT_Free(theTemplate.pValue);
818 PORT_SetError( SEC_ERROR_INVALID_KEY );
819 return -1;
820 }
821
822
823
824 /*
825 * take a private key in one pkcs11 module and load it into another:
826 * NOTE: the source private key is a rare animal... it can't be sensitive.
827 * This is used to do a key gen using one pkcs11 module and storing the
828 * result into another.
829 */
830 static SECKEYPrivateKey *
831 pk11_loadPrivKeyWithFlags(PK11SlotInfo *slot,SECKEYPrivateKey *privKey,
832 SECKEYPublicKey *pubKey, PK11AttrFlags attrFlags)
833 {
834 CK_ATTRIBUTE privTemplate[] = {
835 /* class must be first */
836 { CKA_CLASS, NULL, 0 },
837 { CKA_KEY_TYPE, NULL, 0 },
838 { CKA_ID, NULL, 0 },
839 /* RSA - the attributes below will be replaced for other
840 * key types.
841 */
842 { CKA_MODULUS, NULL, 0 },
843 { CKA_PRIVATE_EXPONENT, NULL, 0 },
844 { CKA_PUBLIC_EXPONENT, NULL, 0 },
845 { CKA_PRIME_1, NULL, 0 },
846 { CKA_PRIME_2, NULL, 0 },
847 { CKA_EXPONENT_1, NULL, 0 },
848 { CKA_EXPONENT_2, NULL, 0 },
849 { CKA_COEFFICIENT, NULL, 0 },
850 { CKA_DECRYPT, NULL, 0 },
851 { CKA_DERIVE, NULL, 0 },
852 { CKA_SIGN, NULL, 0 },
853 { CKA_SIGN_RECOVER, NULL, 0 },
854 { CKA_UNWRAP, NULL, 0 },
855 /* reserve space for the attributes that may be
856 * specified in attrFlags */
857 { CKA_TOKEN, NULL, 0 },
858 { CKA_PRIVATE, NULL, 0 },
859 { CKA_MODIFIABLE, NULL, 0 },
860 { CKA_SENSITIVE, NULL, 0 },
861 { CKA_EXTRACTABLE, NULL, 0 },
862 #define NUM_RESERVED_ATTRS 5 /* number of reserved attributes above */
863 };
864 CK_BBOOL cktrue = CK_TRUE;
865 CK_BBOOL ckfalse = CK_FALSE;
866 CK_ATTRIBUTE *attrs = NULL, *ap;
867 const int templateSize = sizeof(privTemplate)/sizeof(privTemplate[0]);
868 PLArenaPool *arena;
869 CK_OBJECT_HANDLE objectID;
870 int i, count = 0;
871 int extra_count = 0;
872 CK_RV crv;
873 SECStatus rv;
874 PRBool token = ((attrFlags & PK11_ATTR_TOKEN) != 0);
875
876 if (pk11_BadAttrFlags(attrFlags)) {
877 PORT_SetError(SEC_ERROR_INVALID_ARGS);
878 return NULL;
879 }
880
881 for (i=0; i < templateSize; i++) {
882 if (privTemplate[i].type == CKA_MODULUS) {
883 attrs= &privTemplate[i];
884 count = i;
885 break;
886 }
887 }
888 PORT_Assert(attrs != NULL);
889 if (attrs == NULL) {
890 PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
891 return NULL;
892 }
893
894 ap = attrs;
895
896 switch (privKey->keyType) {
897 case rsaKey:
898 count = templateSize - NUM_RESERVED_ATTRS;
899 extra_count = count - (attrs - privTemplate);
900 break;
901 case dsaKey:
902 ap->type = CKA_PRIME; ap++; count++; extra_count++;
903 ap->type = CKA_SUBPRIME; ap++; count++; extra_count++;
904 ap->type = CKA_BASE; ap++; count++; extra_count++;
905 ap->type = CKA_VALUE; ap++; count++; extra_count++;
906 ap->type = CKA_SIGN; ap++; count++; extra_count++;
907 break;
908 case dhKey:
909 ap->type = CKA_PRIME; ap++; count++; extra_count++;
910 ap->type = CKA_BASE; ap++; count++; extra_count++;
911 ap->type = CKA_VALUE; ap++; count++; extra_count++;
912 ap->type = CKA_DERIVE; ap++; count++; extra_count++;
913 break;
914 case ecKey:
915 ap->type = CKA_EC_PARAMS; ap++; count++; extra_count++;
916 ap->type = CKA_VALUE; ap++; count++; extra_count++;
917 ap->type = CKA_DERIVE; ap++; count++; extra_count++;
918 ap->type = CKA_SIGN; ap++; count++; extra_count++;
919 break;
920 default:
921 count = 0;
922 extra_count = 0;
923 break;
924 }
925
926 if (count == 0) {
927 PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
928 return NULL;
929 }
930
931 arena = PORT_NewArena( DER_DEFAULT_CHUNKSIZE);
932 if (arena == NULL) return NULL;
933 /*
934 * read out the old attributes.
935 */
936 crv = PK11_GetAttributes(arena, privKey->pkcs11Slot, privKey->pkcs11ID,
937 privTemplate,count);
938 if (crv != CKR_OK) {
939 PORT_SetError( PK11_MapError(crv) );
940 PORT_FreeArena(arena, PR_TRUE);
941 return NULL;
942 }
943
944 /* Set token, private, modifiable, sensitive, and extractable */
945 count += pk11_AttrFlagsToAttributes(attrFlags, &privTemplate[count],
946 &cktrue, &ckfalse);
947
948 /* Not everyone can handle zero padded key values, give
949 * them the raw data as unsigned */
950 for (ap=attrs; extra_count; ap++, extra_count--) {
951 pk11_SignedToUnsigned(ap);
952 }
953
954 /* now Store the puppies */
955 rv = PK11_CreateNewObject(slot, CK_INVALID_SESSION, privTemplate,
956 count, token, &objectID);
957 PORT_FreeArena(arena, PR_TRUE);
958 if (rv != SECSuccess) {
959 return NULL;
960 }
961
962 /* try loading the public key */
963 if (pubKey) {
964 PK11_ImportPublicKey(slot, pubKey, token);
965 if (pubKey->pkcs11Slot) {
966 PK11_FreeSlot(pubKey->pkcs11Slot);
967 pubKey->pkcs11Slot = NULL;
968 pubKey->pkcs11ID = CK_INVALID_HANDLE;
969 }
970 }
971
972 /* build new key structure */
973 return PK11_MakePrivKey(slot, privKey->keyType, !token,
974 objectID, privKey->wincx);
975 }
976
977 static SECKEYPrivateKey *
978 pk11_loadPrivKey(PK11SlotInfo *slot,SECKEYPrivateKey *privKey,
979 SECKEYPublicKey *pubKey, PRBool token, PRBool sensitive)
980 {
981 PK11AttrFlags attrFlags = 0;
982 if (token) {
983 attrFlags |= (PK11_ATTR_TOKEN | PK11_ATTR_PRIVATE);
984 } else {
985 attrFlags |= (PK11_ATTR_SESSION | PK11_ATTR_PUBLIC);
986 }
987 if (sensitive) {
988 attrFlags |= PK11_ATTR_SENSITIVE;
989 } else {
990 attrFlags |= PK11_ATTR_INSENSITIVE;
991 }
992 return pk11_loadPrivKeyWithFlags(slot, privKey, pubKey, attrFlags);
993 }
994
995 /*
996 * export this for PSM
997 */
998 SECKEYPrivateKey *
999 PK11_LoadPrivKey(PK11SlotInfo *slot,SECKEYPrivateKey *privKey,
1000 SECKEYPublicKey *pubKey, PRBool token, PRBool sensitive)
1001 {
1002 return pk11_loadPrivKey(slot,privKey,pubKey,token,sensitive);
1003 }
1004
1005
1006 /*
1007 * Use the token to generate a key pair.
1008 */
1009 SECKEYPrivateKey *
1010 PK11_GenerateKeyPairWithOpFlags(PK11SlotInfo *slot,CK_MECHANISM_TYPE type,
1011 void *param, SECKEYPublicKey **pubKey, PK11AttrFlags attrFlags,
1012 CK_FLAGS opFlags, CK_FLAGS opFlagsMask, void *wincx)
1013 {
1014 /* we have to use these native types because when we call PKCS 11 modules
1015 * we have to make sure that we are using the correct sizes for all the
1016 * parameters. */
1017 CK_BBOOL ckfalse = CK_FALSE;
1018 CK_BBOOL cktrue = CK_TRUE;
1019 CK_ULONG modulusBits;
1020 CK_BYTE publicExponent[4];
1021 CK_ATTRIBUTE privTemplate[] = {
1022 { CKA_SENSITIVE, NULL, 0},
1023 { CKA_TOKEN, NULL, 0},
1024 { CKA_PRIVATE, NULL, 0},
1025 { CKA_DERIVE, NULL, 0},
1026 { CKA_UNWRAP, NULL, 0},
1027 { CKA_SIGN, NULL, 0},
1028 { CKA_DECRYPT, NULL, 0},
1029 { CKA_EXTRACTABLE, NULL, 0},
1030 { CKA_MODIFIABLE, NULL, 0},
1031 };
1032 CK_ATTRIBUTE rsaPubTemplate[] = {
1033 { CKA_MODULUS_BITS, NULL, 0},
1034 { CKA_PUBLIC_EXPONENT, NULL, 0},
1035 { CKA_TOKEN, NULL, 0},
1036 { CKA_DERIVE, NULL, 0},
1037 { CKA_WRAP, NULL, 0},
1038 { CKA_VERIFY, NULL, 0},
1039 { CKA_VERIFY_RECOVER, NULL, 0},
1040 { CKA_ENCRYPT, NULL, 0},
1041 { CKA_MODIFIABLE, NULL, 0},
1042 };
1043 CK_ATTRIBUTE dsaPubTemplate[] = {
1044 { CKA_PRIME, NULL, 0 },
1045 { CKA_SUBPRIME, NULL, 0 },
1046 { CKA_BASE, NULL, 0 },
1047 { CKA_TOKEN, NULL, 0},
1048 { CKA_DERIVE, NULL, 0},
1049 { CKA_WRAP, NULL, 0},
1050 { CKA_VERIFY, NULL, 0},
1051 { CKA_VERIFY_RECOVER, NULL, 0},
1052 { CKA_ENCRYPT, NULL, 0},
1053 { CKA_MODIFIABLE, NULL, 0},
1054 };
1055 CK_ATTRIBUTE dhPubTemplate[] = {
1056 { CKA_PRIME, NULL, 0 },
1057 { CKA_BASE, NULL, 0 },
1058 { CKA_TOKEN, NULL, 0},
1059 { CKA_DERIVE, NULL, 0},
1060 { CKA_WRAP, NULL, 0},
1061 { CKA_VERIFY, NULL, 0},
1062 { CKA_VERIFY_RECOVER, NULL, 0},
1063 { CKA_ENCRYPT, NULL, 0},
1064 { CKA_MODIFIABLE, NULL, 0},
1065 };
1066 CK_ATTRIBUTE ecPubTemplate[] = {
1067 { CKA_EC_PARAMS, NULL, 0 },
1068 { CKA_TOKEN, NULL, 0},
1069 { CKA_DERIVE, NULL, 0},
1070 { CKA_WRAP, NULL, 0},
1071 { CKA_VERIFY, NULL, 0},
1072 { CKA_VERIFY_RECOVER, NULL, 0},
1073 { CKA_ENCRYPT, NULL, 0},
1074 { CKA_MODIFIABLE, NULL, 0},
1075 };
1076 SECKEYECParams * ecParams;
1077
1078 /*CK_ULONG key_size = 0;*/
1079 CK_ATTRIBUTE *pubTemplate;
1080 int privCount = 0;
1081 int pubCount = 0;
1082 PK11RSAGenParams *rsaParams;
1083 SECKEYPQGParams *dsaParams;
1084 SECKEYDHParams * dhParams;
1085 CK_MECHANISM mechanism;
1086 CK_MECHANISM test_mech;
1087 CK_MECHANISM test_mech2;
1088 CK_SESSION_HANDLE session_handle;
1089 CK_RV crv;
1090 CK_OBJECT_HANDLE privID,pubID;
1091 SECKEYPrivateKey *privKey;
1092 KeyType keyType;
1093 PRBool restore;
1094 int peCount,i;
1095 CK_ATTRIBUTE *attrs;
1096 CK_ATTRIBUTE *privattrs;
1097 CK_ATTRIBUTE setTemplate;
1098 CK_MECHANISM_INFO mechanism_info;
1099 CK_OBJECT_CLASS keyClass;
1100 SECItem *cka_id;
1101 PRBool haslock = PR_FALSE;
1102 PRBool pubIsToken = PR_FALSE;
1103 PRBool token = ((attrFlags & PK11_ATTR_TOKEN) != 0);
1104 /* subset of attrFlags applicable to the public key */
1105 PK11AttrFlags pubKeyAttrFlags = attrFlags &
1106 (PK11_ATTR_TOKEN | PK11_ATTR_SESSION
1107 | PK11_ATTR_MODIFIABLE | PK11_ATTR_UNMODIFIABLE);
1108
1109 if (pk11_BadAttrFlags(attrFlags)) {
1110 PORT_SetError( SEC_ERROR_INVALID_ARGS );
1111 return NULL;
1112 }
1113
1114 if (!param) {
1115 PORT_SetError( SEC_ERROR_INVALID_ARGS );
1116 return NULL;
1117 }
1118
1119 /*
1120 * The opFlags and opFlagMask parameters allow us to control the
1121 * settings of the key usage attributes (CKA_ENCRYPT and friends).
1122 * opFlagMask is set to one if the flag is specified in opFlags and
1123 * zero if it is to take on a default value calculated by
1124 * PK11_GenerateKeyPairWithOpFlags.
1125 * opFlags specifies the actual value of the flag 1 or 0.
1126 * Bits not corresponding to one bits in opFlagMask should be zero.
1127 */
1128
1129 /* if we are trying to turn on a flag, it better be in the mask */
1130 PORT_Assert ((opFlags & ~opFlagsMask) == 0);
1131 opFlags &= opFlagsMask;
1132
1133 PORT_Assert(slot != NULL);
1134 if (slot == NULL) {
1135 PORT_SetError( SEC_ERROR_NO_MODULE);
1136 return NULL;
1137 }
1138
1139 /* if our slot really doesn't do this mechanism, Generate the key
1140 * in our internal token and write it out */
1141 if (!PK11_DoesMechanism(slot,type)) {
1142 PK11SlotInfo *int_slot = PK11_GetInternalSlot();
1143
1144 /* don't loop forever looking for a slot */
1145 if (slot == int_slot) {
1146 PK11_FreeSlot(int_slot);
1147 PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
1148 return NULL;
1149 }
1150
1151 /* if there isn't a suitable slot, then we can't do the keygen */
1152 if (int_slot == NULL) {
1153 PORT_SetError( SEC_ERROR_NO_MODULE );
1154 return NULL;
1155 }
1156
1157 /* generate the temporary key to load */
1158 privKey = PK11_GenerateKeyPair(int_slot,type, param, pubKey, PR_FALSE,
1159 PR_FALSE, wincx);
1160 PK11_FreeSlot(int_slot);
1161
1162 /* if successful, load the temp key into the new token */
1163 if (privKey != NULL) {
1164 SECKEYPrivateKey *newPrivKey = pk11_loadPrivKeyWithFlags(slot,
1165 privKey,*pubKey,attrFlags);
1166 SECKEY_DestroyPrivateKey(privKey);
1167 if (newPrivKey == NULL) {
1168 SECKEY_DestroyPublicKey(*pubKey);
1169 *pubKey = NULL;
1170 }
1171 return newPrivKey;
1172 }
1173 return NULL;
1174 }
1175
1176
1177 mechanism.mechanism = type;
1178 mechanism.pParameter = NULL;
1179 mechanism.ulParameterLen = 0;
1180 test_mech.pParameter = NULL;
1181 test_mech.ulParameterLen = 0;
1182 test_mech2.mechanism = CKM_INVALID_MECHANISM;
1183 test_mech2.pParameter = NULL;
1184 test_mech2.ulParameterLen = 0;
1185
1186 /* set up the private key template */
1187 privattrs = privTemplate;
1188 privattrs += pk11_AttrFlagsToAttributes(attrFlags, privattrs,
1189 &cktrue, &ckfalse);
1190
1191 /* set up the mechanism specific info */
1192 switch (type) {
1193 case CKM_RSA_PKCS_KEY_PAIR_GEN:
1194 case CKM_RSA_X9_31_KEY_PAIR_GEN:
1195 rsaParams = (PK11RSAGenParams *)param;
1196 if (rsaParams->pe == 0) {
1197 PORT_SetError(SEC_ERROR_INVALID_ARGS);
1198 return NULL;
1199 }
1200 modulusBits = rsaParams->keySizeInBits;
1201 peCount = 0;
1202
1203 /* convert pe to a PKCS #11 string */
1204 for (i=0; i < 4; i++) {
1205 if (peCount || (rsaParams->pe &
1206 ((unsigned long)0xff000000L >> (i*8)))) {
1207 publicExponent[peCount] =
1208 (CK_BYTE)((rsaParams->pe >> (3-i)*8) & 0xff);
1209 peCount++;
1210 }
1211 }
1212 PORT_Assert(peCount != 0);
1213 attrs = rsaPubTemplate;
1214 PK11_SETATTRS(attrs, CKA_MODULUS_BITS,
1215 &modulusBits, sizeof(modulusBits)); attrs++;
1216 PK11_SETATTRS(attrs, CKA_PUBLIC_EXPONENT,
1217 publicExponent, peCount);attrs++;
1218 pubTemplate = rsaPubTemplate;
1219 keyType = rsaKey;
1220 test_mech.mechanism = CKM_RSA_PKCS;
1221 break;
1222 case CKM_DSA_KEY_PAIR_GEN:
1223 dsaParams = (SECKEYPQGParams *)param;
1224 attrs = dsaPubTemplate;
1225 PK11_SETATTRS(attrs, CKA_PRIME, dsaParams->prime.data,
1226 dsaParams->prime.len); attrs++;
1227 PK11_SETATTRS(attrs, CKA_SUBPRIME, dsaParams->subPrime.data,
1228 dsaParams->subPrime.len); attrs++;
1229 PK11_SETATTRS(attrs, CKA_BASE, dsaParams->base.data,
1230 dsaParams->base.len); attrs++;
1231 pubTemplate = dsaPubTemplate;
1232 keyType = dsaKey;
1233 test_mech.mechanism = CKM_DSA;
1234 break;
1235 case CKM_DH_PKCS_KEY_PAIR_GEN:
1236 dhParams = (SECKEYDHParams *)param;
1237 attrs = dhPubTemplate;
1238 PK11_SETATTRS(attrs, CKA_PRIME, dhParams->prime.data,
1239 dhParams->prime.len); attrs++;
1240 PK11_SETATTRS(attrs, CKA_BASE, dhParams->base.data,
1241 dhParams->base.len); attrs++;
1242 pubTemplate = dhPubTemplate;
1243 keyType = dhKey;
1244 test_mech.mechanism = CKM_DH_PKCS_DERIVE;
1245 break;
1246 case CKM_EC_KEY_PAIR_GEN:
1247 ecParams = (SECKEYECParams *)param;
1248 attrs = ecPubTemplate;
1249 PK11_SETATTRS(attrs, CKA_EC_PARAMS, ecParams->data,
1250 ecParams->len); attrs++;
1251 pubTemplate = ecPubTemplate;
1252 keyType = ecKey;
1253 /*
1254 * ECC supports 2 different mechanism types (unlike RSA, which
1255 * supports different usages with the same mechanism).
1256 * We may need to query both mechanism types and or the results
1257 * together -- but we only do that if either the user has
1258 * requested both usages, or not specified any usages.
1259 */
1260 if ((opFlags & (CKF_SIGN|CKF_DERIVE)) == (CKF_SIGN|CKF_DERIVE)) {
1261 /* We've explicitly turned on both flags, use both mechanism */
1262 test_mech.mechanism = CKM_ECDH1_DERIVE;
1263 test_mech2.mechanism = CKM_ECDSA;
1264 } else if (opFlags & CKF_SIGN) {
1265 /* just do signing */
1266 test_mech.mechanism = CKM_ECDSA;
1267 } else if (opFlags & CKF_DERIVE) {
1268 /* just do ECDH */
1269 test_mech.mechanism = CKM_ECDH1_DERIVE;
1270 } else {
1271 /* neither was specified default to both */
1272 test_mech.mechanism = CKM_ECDH1_DERIVE;
1273 test_mech2.mechanism = CKM_ECDSA;
1274 }
1275 break;
1276 default:
1277 PORT_SetError( SEC_ERROR_BAD_KEY );
1278 return NULL;
1279 }
1280
1281 /* now query the slot to find out how "good" a key we can generate */
1282 if (!slot->isThreadSafe) PK11_EnterSlotMonitor(slot);
1283 crv = PK11_GETTAB(slot)->C_GetMechanismInfo(slot->slotID,
1284 test_mech.mechanism,&mechanism_info);
1285 /*
1286 * EC keys are used in multiple different types of mechanism, if we
1287 * are using dual use keys, we need to query the second mechanism
1288 * as well.
1289 */
1290 if (test_mech2.mechanism != CKM_INVALID_MECHANISM) {
1291 CK_MECHANISM_INFO mechanism_info2;
1292 CK_RV crv2;
1293
1294 if (crv != CKR_OK) {
1295 /* the first failed, make sure there is no trash in the
1296 * mechanism flags when we or it below */
1297 mechanism_info.flags = 0;
1298 }
1299 crv2 = PK11_GETTAB(slot)->C_GetMechanismInfo(slot->slotID,
1300 test_mech2.mechanism, &mechanism_info2);
1301 if (crv2 == CKR_OK) {
1302 crv = CKR_OK; /* succeed if either mechnaism info succeeds */
1303 /* combine the 2 sets of mechnanism flags */
1304 mechanism_info.flags |= mechanism_info2.flags;
1305 }
1306 }
1307 if (!slot->isThreadSafe) PK11_ExitSlotMonitor(slot);
1308 if ((crv != CKR_OK) || (mechanism_info.flags == 0)) {
1309 /* must be old module... guess what it should be... */
1310 switch (test_mech.mechanism) {
1311 case CKM_RSA_PKCS:
1312 mechanism_info.flags = (CKF_SIGN | CKF_DECRYPT |
1313 CKF_WRAP | CKF_VERIFY_RECOVER | CKF_ENCRYPT | CKF_WRAP);
1314 break;
1315 case CKM_DSA:
1316 mechanism_info.flags = CKF_SIGN | CKF_VERIFY;
1317 break;
1318 case CKM_DH_PKCS_DERIVE:
1319 mechanism_info.flags = CKF_DERIVE;
1320 break;
1321 case CKM_ECDH1_DERIVE:
1322 mechanism_info.flags = CKF_DERIVE;
1323 if (test_mech2.mechanism == CKM_ECDSA) {
1324 mechanism_info.flags |= CKF_SIGN | CKF_VERIFY;
1325 }
1326 break;
1327 case CKM_ECDSA:
1328 mechanism_info.flags = CKF_SIGN | CKF_VERIFY;
1329 break;
1330 default:
1331 break;
1332 }
1333 }
1334 /* now adjust our flags according to the user's key usage passed to us */
1335 mechanism_info.flags = (mechanism_info.flags & (~opFlagsMask)) | opFlags;
1336 /* set the public key attributes */
1337 attrs += pk11_AttrFlagsToAttributes(pubKeyAttrFlags, attrs,
1338 &cktrue, &ckfalse);
1339 PK11_SETATTRS(attrs, CKA_DERIVE,
1340 mechanism_info.flags & CKF_DERIVE ? &cktrue : &ckfalse,
1341 sizeof(CK_BBOOL)); attrs++;
1342 PK11_SETATTRS(attrs, CKA_WRAP,
1343 mechanism_info.flags & CKF_WRAP ? &cktrue : &ckfalse,
1344 sizeof(CK_BBOOL)); attrs++;
1345 PK11_SETATTRS(attrs, CKA_VERIFY,
1346 mechanism_info.flags & CKF_VERIFY ? &cktrue : &ckfalse,
1347 sizeof(CK_BBOOL)); attrs++;
1348 PK11_SETATTRS(attrs, CKA_VERIFY_RECOVER,
1349 mechanism_info.flags & CKF_VERIFY_RECOVER ? &cktrue : &ckfalse,
1350 sizeof(CK_BBOOL)); attrs++;
1351 PK11_SETATTRS(attrs, CKA_ENCRYPT,
1352 mechanism_info.flags & CKF_ENCRYPT? &cktrue : &ckfalse,
1353 sizeof(CK_BBOOL)); attrs++;
1354 /* set the private key attributes */
1355 PK11_SETATTRS(privattrs, CKA_DERIVE,
1356 mechanism_info.flags & CKF_DERIVE ? &cktrue : &ckfalse,
1357 sizeof(CK_BBOOL)); privattrs++;
1358 PK11_SETATTRS(privattrs, CKA_UNWRAP,
1359 mechanism_info.flags & CKF_UNWRAP ? &cktrue : &ckfalse,
1360 sizeof(CK_BBOOL)); privattrs++;
1361 PK11_SETATTRS(privattrs, CKA_SIGN,
1362 mechanism_info.flags & CKF_SIGN ? &cktrue : &ckfalse,
1363 sizeof(CK_BBOOL)); privattrs++;
1364 PK11_SETATTRS(privattrs, CKA_DECRYPT,
1365 mechanism_info.flags & CKF_DECRYPT ? &cktrue : &ckfalse,
1366 sizeof(CK_BBOOL)); privattrs++;
1367
1368 if (token) {
1369 session_handle = PK11_GetRWSession(slot);
1370 haslock = PK11_RWSessionHasLock(slot,session_handle);
1371 restore = PR_TRUE;
1372 } else {
1373 session_handle = slot->session;
1374 if (session_handle != CK_INVALID_SESSION)
1375 PK11_EnterSlotMonitor(slot);
1376 restore = PR_FALSE;
1377 haslock = PR_TRUE;
1378 }
1379
1380 if (session_handle == CK_INVALID_SESSION) {
1381 PORT_SetError(SEC_ERROR_BAD_DATA);
1382 return NULL;
1383 }
1384 privCount = privattrs - privTemplate;
1385 pubCount = attrs - pubTemplate;
1386 crv = PK11_GETTAB(slot)->C_GenerateKeyPair(session_handle, &mechanism,
1387 pubTemplate,pubCount,privTemplate,privCount,&pubID,&privID);
1388
1389 if (crv != CKR_OK) {
1390 if (restore) {
1391 PK11_RestoreROSession(slot,session_handle);
1392 } else PK11_ExitSlotMonitor(slot);
1393 PORT_SetError( PK11_MapError(crv) );
1394 return NULL;
1395 }
1396 /* This locking code is dangerous and needs to be more thought
1397 * out... the real problem is that we're holding the mutex open this long
1398 */
1399 if (haslock) { PK11_ExitSlotMonitor(slot); }
1400
1401 /* swap around the ID's for older PKCS #11 modules */
1402 keyClass = PK11_ReadULongAttribute(slot,pubID,CKA_CLASS);
1403 if (keyClass != CKO_PUBLIC_KEY) {
1404 CK_OBJECT_HANDLE tmp = pubID;
1405 pubID = privID;
1406 privID = tmp;
1407 }
1408
1409 *pubKey = PK11_ExtractPublicKey(slot, keyType, pubID);
1410 if (*pubKey == NULL) {
1411 if (restore) {
1412 /* we may have to restore the mutex so it get's exited properly
1413 * in RestoreROSession */
1414 if (haslock) PK11_EnterSlotMonitor(slot);
1415 PK11_RestoreROSession(slot,session_handle);
1416 }
1417 PK11_DestroyObject(slot,pubID);
1418 PK11_DestroyObject(slot,privID);
1419 return NULL;
1420 }
1421
1422 /* set the ID to the public key so we can find it again */
1423 cka_id = pk11_MakeIDFromPublicKey(*pubKey);
1424 pubIsToken = (PRBool)PK11_HasAttributeSet(slot,pubID, CKA_TOKEN,PR_FALSE);
1425
1426 PK11_SETATTRS(&setTemplate, CKA_ID, cka_id->data, cka_id->len);
1427
1428 if (haslock) { PK11_EnterSlotMonitor(slot); }
1429 crv = PK11_GETTAB(slot)->C_SetAttributeValue(session_handle, privID,
1430 &setTemplate, 1);
1431
1432 if (crv == CKR_OK && pubIsToken) {
1433 crv = PK11_GETTAB(slot)->C_SetAttributeValue(session_handle, pubID,
1434 &setTemplate, 1);
1435 }
1436
1437
1438 if (restore) {
1439 PK11_RestoreROSession(slot,session_handle);
1440 } else {
1441 PK11_ExitSlotMonitor(slot);
1442 }
1443 SECITEM_FreeItem(cka_id,PR_TRUE);
1444
1445
1446 if (crv != CKR_OK) {
1447 PK11_DestroyObject(slot,pubID);
1448 PK11_DestroyObject(slot,privID);
1449 PORT_SetError( PK11_MapError(crv) );
1450 *pubKey = NULL;
1451 return NULL;
1452 }
1453
1454 privKey = PK11_MakePrivKey(slot,keyType,!token,privID,wincx);
1455 if (privKey == NULL) {
1456 SECKEY_DestroyPublicKey(*pubKey);
1457 PK11_DestroyObject(slot,privID);
1458 *pubKey = NULL;
1459 return NULL;
1460 }
1461
1462 return privKey;
1463 }
1464
1465 SECKEYPrivateKey *
1466 PK11_GenerateKeyPairWithFlags(PK11SlotInfo *slot,CK_MECHANISM_TYPE type,
1467 void *param, SECKEYPublicKey **pubKey, PK11AttrFlags attrFlags, void *wincx)
1468 {
1469 return PK11_GenerateKeyPairWithOpFlags(slot,type,param,pubKey,attrFlags,
1470 0, 0, wincx);
1471 }
1472
1473 /*
1474 * Use the token to generate a key pair.
1475 */
1476 SECKEYPrivateKey *
1477 PK11_GenerateKeyPair(PK11SlotInfo *slot,CK_MECHANISM_TYPE type,
1478 void *param, SECKEYPublicKey **pubKey, PRBool token,
1479 PRBool sensitive, void *wincx)
1480 {
1481 PK11AttrFlags attrFlags = 0;
1482
1483 if (token) {
1484 attrFlags |= PK11_ATTR_TOKEN;
1485 } else {
1486 attrFlags |= PK11_ATTR_SESSION;
1487 }
1488 if (sensitive) {
1489 attrFlags |= (PK11_ATTR_SENSITIVE | PK11_ATTR_PRIVATE);
1490 } else {
1491 attrFlags |= (PK11_ATTR_INSENSITIVE | PK11_ATTR_PUBLIC);
1492 }
1493 return PK11_GenerateKeyPairWithFlags(slot, type, param, pubKey,
1494 attrFlags, wincx);
1495 }
1496
1497 /* build a public KEA key from the public value */
1498 SECKEYPublicKey *
1499 PK11_MakeKEAPubKey(unsigned char *keyData,int length)
1500 {
1501 SECKEYPublicKey *pubk;
1502 SECItem pkData;
1503 SECStatus rv;
1504 PLArenaPool *arena;
1505
1506 pkData.data = keyData;
1507 pkData.len = length;
1508 pkData.type = siBuffer;
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 unsigned 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 unsigned 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
OLDNEW
« no previous file with comments | « nss/lib/pk11wrap/dev3hack.c ('k') | nss/lib/pk11wrap/pk11auth.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698