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