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