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