1
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 /*
6 * This file PKCS #12 fuctions that should really be moved to the
7 * PKCS #12 directory, however we can't do that in a point release
8 * because that will break binary compatibility, so we keep them here for now.
9 */
10
11 #include "seccomon.h"
12 #include "secmod.h"
13 #include "secmodi.h"
14 #include "secmodti.h"
15 #include "secmodt.h"
16 #include "pkcs11.h"
17 #include "pk11func.h"
18 #include "secitem.h"
19 #include "keyhi.h"
20 #include "secoid.h"
21 #include "secasn1.h"
22 #include "secerr.h"
23 #include "prerror.h"
24
25 /* These data structures should move to a common .h file shared between the
26 * wrappers and the pkcs 12 code. */
27
28 /*
29 ** RSA Raw Private Key structures
30 */
31
32 /* member names from PKCS#1, section 7.2 */
33 struct SECKEYRSAPrivateKeyStr {
34 PLArenaPool *arena;
35 SECItem version;
36 SECItem modulus;
37 SECItem publicExponent;
38 SECItem privateExponent;
39 SECItem prime1;
40 SECItem prime2;
41 SECItem exponent1;
42 SECItem exponent2;
43 SECItem coefficient;
44 };
45 typedef struct SECKEYRSAPrivateKeyStr SECKEYRSAPrivateKey;
46
47 /*
48 ** DSA Raw Private Key structures
49 */
50
51 struct SECKEYDSAPrivateKeyStr {
52 SECKEYPQGParams params;
53 SECItem privateValue;
54 };
55 typedef struct SECKEYDSAPrivateKeyStr SECKEYDSAPrivateKey;
56
57 /*
58 ** Diffie-Hellman Raw Private Key structures
59 ** Structure member names suggested by PKCS#3.
60 */
61 struct SECKEYDHPrivateKeyStr {
62 PLArenaPool *arena;
63 SECItem prime;
64 SECItem base;
65 SECItem privateValue;
66 };
67 typedef struct SECKEYDHPrivateKeyStr SECKEYDHPrivateKey;
68
69 /*
70 ** Elliptic Curve Private Key structures
71 ** <https://tools.ietf.org/html/rfc5915#section-3>
72 */
73 struct SECKEYECPrivateKeyStr {
74 PLArenaPool *arena;
75 SECItem version;
76 SECItem curveOID; /* optional/ignored */
77 SECItem publicValue; /* required (for now) */
78 SECItem privateValue;
79 };
80 typedef struct SECKEYECPrivateKeyStr SECKEYECPrivateKey;
81
82 /*
83 ** raw private key object
84 */
85 struct SECKEYRawPrivateKeyStr {
86 PLArenaPool *arena;
87 KeyType keyType;
88 union {
89 SECKEYRSAPrivateKey rsa;
90 SECKEYDSAPrivateKey dsa;
91 SECKEYDHPrivateKey dh;
92 SECKEYECPrivateKey ec;
93 } u;
94 };
95 typedef struct SECKEYRawPrivateKeyStr SECKEYRawPrivateKey;
96
97 SEC_ASN1_MKSUB(SEC_AnyTemplate)
98 SEC_ASN1_MKSUB(SECOID_AlgorithmIDTemplate)
99
100 /* ASN1 Templates for new decoder/encoder */
101 /*
102 * Attribute value for PKCS8 entries (static?)
103 */
104 const SEC_ASN1Template SECKEY_AttributeTemplate[] = {
105 { SEC_ASN1_SEQUENCE,
106 0, NULL, sizeof(SECKEYAttribute) },
107 { SEC_ASN1_OBJECT_ID, offsetof(SECKEYAttribute, attrType) },
108 { SEC_ASN1_SET_OF | SEC_ASN1_XTRN, offsetof(SECKEYAttribute, attrValue),
109 SEC_ASN1_SUB(SEC_AnyTemplate) },
110 { 0 }
111 };
112
113 const SEC_ASN1Template SECKEY_SetOfAttributeTemplate[] = {
114 { SEC_ASN1_SET_OF, 0, SECKEY_AttributeTemplate },
115 };
116
117 const SEC_ASN1Template SECKEY_PrivateKeyInfoTemplate[] = {
118 { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SECKEYPrivateKeyInfo) },
119 { SEC_ASN1_INTEGER, offsetof(SECKEYPrivateKeyInfo, version) },
120 { SEC_ASN1_INLINE | SEC_ASN1_XTRN,
121 offsetof(SECKEYPrivateKeyInfo, algorithm),
122 SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
123 { SEC_ASN1_OCTET_STRING, offsetof(SECKEYPrivateKeyInfo, privateKey) },
124 { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0,
125 offsetof(SECKEYPrivateKeyInfo, attributes),
126 SECKEY_SetOfAttributeTemplate },
127 { 0 }
128 };
129
130 const SEC_ASN1Template SECKEY_PointerToPrivateKeyInfoTemplate[] = {
131 { SEC_ASN1_POINTER, 0, SECKEY_PrivateKeyInfoTemplate }
132 };
133
134 const SEC_ASN1Template SECKEY_RSAPrivateKeyExportTemplate[] = {
135 { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SECKEYRawPrivateKey) },
136 { SEC_ASN1_INTEGER, offsetof(SECKEYRawPrivateKey, u.rsa.version) },
137 { SEC_ASN1_INTEGER, offsetof(SECKEYRawPrivateKey, u.rsa.modulus) },
138 { SEC_ASN1_INTEGER, offsetof(SECKEYRawPrivateKey, u.rsa.publicExponent) },
139 { SEC_ASN1_INTEGER, offsetof(SECKEYRawPrivateKey, u.rsa.privateExponent) },
140 { SEC_ASN1_INTEGER, offsetof(SECKEYRawPrivateKey, u.rsa.prime1) },
141 { SEC_ASN1_INTEGER, offsetof(SECKEYRawPrivateKey, u.rsa.prime2) },
142 { SEC_ASN1_INTEGER, offsetof(SECKEYRawPrivateKey, u.rsa.exponent1) },
143 { SEC_ASN1_INTEGER, offsetof(SECKEYRawPrivateKey, u.rsa.exponent2) },
144 { SEC_ASN1_INTEGER, offsetof(SECKEYRawPrivateKey, u.rsa.coefficient) },
145 { 0 }
146 };
147
148 const SEC_ASN1Template SECKEY_DSAPrivateKeyExportTemplate[] = {
149 { SEC_ASN1_INTEGER, offsetof(SECKEYRawPrivateKey, u.dsa.privateValue) },
150 };
151
152 const SEC_ASN1Template SECKEY_DHPrivateKeyExportTemplate[] = {
153 { SEC_ASN1_INTEGER, offsetof(SECKEYRawPrivateKey, u.dh.privateValue) },
154 { SEC_ASN1_INTEGER, offsetof(SECKEYRawPrivateKey, u.dh.base) },
155 { SEC_ASN1_INTEGER, offsetof(SECKEYRawPrivateKey, u.dh.prime) },
156 };
157
158 SEC_ASN1_MKSUB(SEC_BitStringTemplate)
159 SEC_ASN1_MKSUB(SEC_ObjectIDTemplate)
160
161 const SEC_ASN1Template SECKEY_ECPrivateKeyExportTemplate[] = {
162 { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SECKEYRawPrivateKey) },
163 { SEC_ASN1_INTEGER, offsetof(SECKEYRawPrivateKey, u.ec.version) },
164 { SEC_ASN1_OCTET_STRING,
165 offsetof(SECKEYRawPrivateKey, u.ec.privateValue) },
166 /* This value will always be ignored. u.ec.curveOID will always be
167 * overriden with the outer AlgorithmID.parameters. */
168 { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED |
169 SEC_ASN1_EXPLICIT | SEC_ASN1_CONTEXT_SPECIFIC |
170 SEC_ASN1_XTRN | 0,
171 offsetof(SECKEYRawPrivateKey, u.ec.curveOID),
172 SEC_ASN1_SUB(SEC_ObjectIDTemplate) },
173 /* The public value is optional per RFC, but required in NSS. We
174 * can't do scalar mult on ECs to get a raw point with PK11 APIs. */
175 { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED |
176 SEC_ASN1_EXPLICIT | SEC_ASN1_CONTEXT_SPECIFIC |
177 SEC_ASN1_XTRN | 1,
178 offsetof(SECKEYRawPrivateKey, u.ec.publicValue),
179 SEC_ASN1_SUB(SEC_BitStringTemplate) },
180 { 0 }
181 };
182
183 const SEC_ASN1Template SECKEY_EncryptedPrivateKeyInfoTemplate[] = {
184 { SEC_ASN1_SEQUENCE,
185 0, NULL, sizeof(SECKEYEncryptedPrivateKeyInfo) },
186 { SEC_ASN1_INLINE | SEC_ASN1_XTRN,
187 offsetof(SECKEYEncryptedPrivateKeyInfo, algorithm),
188 SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
189 { SEC_ASN1_OCTET_STRING,
190 offsetof(SECKEYEncryptedPrivateKeyInfo, encryptedData) },
191 { 0 }
192 };
193
194 const SEC_ASN1Template SECKEY_PointerToEncryptedPrivateKeyInfoTemplate[] = {
195 { SEC_ASN1_POINTER, 0, SECKEY_EncryptedPrivateKeyInfoTemplate }
196 };
197
198 SEC_ASN1_CHOOSER_IMPLEMENT(SECKEY_EncryptedPrivateKeyInfoTemplate)
SEC_ASN1_CHOOSER_IMPLEMENT(SECKEY_PointerToEncryptedPrivateKeyInfoTemplate)199 SEC_ASN1_CHOOSER_IMPLEMENT(SECKEY_PointerToEncryptedPrivateKeyInfoTemplate)
200 SEC_ASN1_CHOOSER_IMPLEMENT(SECKEY_PrivateKeyInfoTemplate)
201 SEC_ASN1_CHOOSER_IMPLEMENT(SECKEY_PointerToPrivateKeyInfoTemplate)
202
203 /*
204 * See bugzilla bug 125359
205 * Since NSS (via PKCS#11) wants to handle big integers as unsigned ints,
206 * all of the templates above that en/decode into integers must be converted
207 * from ASN.1's signed integer type. This is done by marking either the
208 * source or destination (encoding or decoding, respectively) type as
209 * siUnsignedInteger.
210 */
211
212 static void
213 prepare_rsa_priv_key_export_for_asn1(SECKEYRawPrivateKey *key)
214 {
215 key->u.rsa.modulus.type = siUnsignedInteger;
216 key->u.rsa.publicExponent.type = siUnsignedInteger;
217 key->u.rsa.privateExponent.type = siUnsignedInteger;
218 key->u.rsa.prime1.type = siUnsignedInteger;
219 key->u.rsa.prime2.type = siUnsignedInteger;
220 key->u.rsa.exponent1.type = siUnsignedInteger;
221 key->u.rsa.exponent2.type = siUnsignedInteger;
222 key->u.rsa.coefficient.type = siUnsignedInteger;
223 }
224
225 static void
prepare_dsa_priv_key_export_for_asn1(SECKEYRawPrivateKey * key)226 prepare_dsa_priv_key_export_for_asn1(SECKEYRawPrivateKey *key)
227 {
228 key->u.dsa.privateValue.type = siUnsignedInteger;
229 key->u.dsa.params.prime.type = siUnsignedInteger;
230 key->u.dsa.params.subPrime.type = siUnsignedInteger;
231 key->u.dsa.params.base.type = siUnsignedInteger;
232 }
233
234 static void
prepare_dh_priv_key_export_for_asn1(SECKEYRawPrivateKey * key)235 prepare_dh_priv_key_export_for_asn1(SECKEYRawPrivateKey *key)
236 {
237 key->u.dh.privateValue.type = siUnsignedInteger;
238 key->u.dh.prime.type = siUnsignedInteger;
239 key->u.dh.base.type = siUnsignedInteger;
240 }
241
242 static void
prepare_ec_priv_key_export_for_asn1(SECKEYRawPrivateKey * key)243 prepare_ec_priv_key_export_for_asn1(SECKEYRawPrivateKey *key)
244 {
245 key->u.ec.version.type = siUnsignedInteger;
246 key->u.ec.curveOID.type = siUnsignedInteger;
247 key->u.ec.privateValue.type = siUnsignedInteger;
248 key->u.ec.publicValue.type = siUnsignedInteger;
249 }
250
251 SECStatus
PK11_ImportDERPrivateKeyInfo(PK11SlotInfo * slot,SECItem * derPKI,SECItem * nickname,SECItem * publicValue,PRBool isPerm,PRBool isPrivate,unsigned int keyUsage,void * wincx)252 PK11_ImportDERPrivateKeyInfo(PK11SlotInfo *slot, SECItem *derPKI,
253 SECItem *nickname, SECItem *publicValue, PRBool isPerm,
254 PRBool isPrivate, unsigned int keyUsage, void *wincx)
255 {
256 return PK11_ImportDERPrivateKeyInfoAndReturnKey(slot, derPKI,
257 nickname, publicValue,
258 isPerm, isPrivate, keyUsage,
259 NULL, wincx);
260 }
261
262 SECStatus
PK11_ImportDERPrivateKeyInfoAndReturnKey(PK11SlotInfo * slot,SECItem * derPKI,SECItem * nickname,SECItem * publicValue,PRBool isPerm,PRBool isPrivate,unsigned int keyUsage,SECKEYPrivateKey ** privk,void * wincx)263 PK11_ImportDERPrivateKeyInfoAndReturnKey(PK11SlotInfo *slot, SECItem *derPKI,
264 SECItem *nickname, SECItem *publicValue,
265 PRBool isPerm, PRBool isPrivate, unsigned int keyUsage,
266 SECKEYPrivateKey **privk, void *wincx)
267 {
268 SECKEYPrivateKeyInfo *pki = NULL;
269 PLArenaPool *temparena = NULL;
270 SECStatus rv = SECFailure;
271
272 temparena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
273 if (!temparena)
274 return rv;
275 pki = PORT_ArenaZNew(temparena, SECKEYPrivateKeyInfo);
276 if (!pki) {
277 PORT_FreeArena(temparena, PR_FALSE);
278 return rv;
279 }
280 pki->arena = temparena;
281
282 rv = SEC_ASN1DecodeItem(pki->arena, pki, SECKEY_PrivateKeyInfoTemplate,
283 derPKI);
284 if (rv != SECSuccess) {
285 /* If SEC_ASN1DecodeItem fails, we cannot assume anything about the
286 * validity of the data in pki. The best we can do is free the arena
287 * and return. */
288 PORT_FreeArena(temparena, PR_TRUE);
289 return rv;
290 }
291 if (pki->privateKey.data == NULL) {
292 /* If SEC_ASN1DecodeItems succeeds but SECKEYPrivateKeyInfo.privateKey
293 * is a zero-length octet string, free the arena and return a failure
294 * to avoid trying to zero the corresponding SECItem in
295 * SECKEY_DestroyPrivateKeyInfo(). */
296 PORT_FreeArena(temparena, PR_TRUE);
297 PORT_SetError(SEC_ERROR_BAD_KEY);
298 return SECFailure;
299 }
300
301 rv = PK11_ImportPrivateKeyInfoAndReturnKey(slot, pki, nickname,
302 publicValue, isPerm, isPrivate,
303 keyUsage, privk, wincx);
304
305 /* this zeroes the key and frees the arena */
306 SECKEY_DestroyPrivateKeyInfo(pki, PR_TRUE /*freeit*/);
307 return rv;
308 }
309
310 SECStatus
PK11_ImportAndReturnPrivateKey(PK11SlotInfo * slot,SECKEYRawPrivateKey * lpk,SECItem * nickname,SECItem * publicValue,PRBool isPerm,PRBool isPrivate,unsigned int keyUsage,SECKEYPrivateKey ** privk,void * wincx)311 PK11_ImportAndReturnPrivateKey(PK11SlotInfo *slot, SECKEYRawPrivateKey *lpk,
312 SECItem *nickname, SECItem *publicValue, PRBool isPerm,
313 PRBool isPrivate, unsigned int keyUsage, SECKEYPrivateKey **privk,
314 void *wincx)
315 {
316 CK_BBOOL cktrue = CK_TRUE;
317 CK_BBOOL ckfalse = CK_FALSE;
318 CK_OBJECT_CLASS keyClass = CKO_PRIVATE_KEY;
319 CK_KEY_TYPE keyType = CKK_RSA;
320 CK_OBJECT_HANDLE objectID;
321 CK_ATTRIBUTE theTemplate[20];
322 int templateCount = 0;
323 SECStatus rv = SECFailure;
324 CK_ATTRIBUTE *attrs;
325 CK_ATTRIBUTE *signedattr = NULL;
326 int signedcount = 0;
327 CK_ATTRIBUTE *ap;
328 SECItem *ck_id = NULL;
329
330 attrs = theTemplate;
331
332 PK11_SETATTRS(attrs, CKA_CLASS, &keyClass, sizeof(keyClass));
333 attrs++;
334 PK11_SETATTRS(attrs, CKA_KEY_TYPE, &keyType, sizeof(keyType));
335 attrs++;
336 PK11_SETATTRS(attrs, CKA_TOKEN, isPerm ? &cktrue : &ckfalse,
337 sizeof(CK_BBOOL));
338 attrs++;
339 PK11_SETATTRS(attrs, CKA_SENSITIVE, isPrivate ? &cktrue : &ckfalse,
340 sizeof(CK_BBOOL));
341 attrs++;
342 PK11_SETATTRS(attrs, CKA_PRIVATE, isPrivate ? &cktrue : &ckfalse,
343 sizeof(CK_BBOOL));
344 attrs++;
345
346 switch (lpk->keyType) {
347 case rsaKey:
348 keyType = CKK_RSA;
349 PK11_SETATTRS(attrs, CKA_UNWRAP, (keyUsage & KU_KEY_ENCIPHERMENT) ? &cktrue : &ckfalse,
350 sizeof(CK_BBOOL));
351 attrs++;
352 PK11_SETATTRS(attrs, CKA_DECRYPT, (keyUsage & KU_DATA_ENCIPHERMENT) ? &cktrue : &ckfalse,
353 sizeof(CK_BBOOL));
354 attrs++;
355 PK11_SETATTRS(attrs, CKA_SIGN, (keyUsage & KU_DIGITAL_SIGNATURE) ? &cktrue : &ckfalse,
356 sizeof(CK_BBOOL));
357 attrs++;
358 PK11_SETATTRS(attrs, CKA_SIGN_RECOVER,
359 (keyUsage & KU_DIGITAL_SIGNATURE) ? &cktrue
360 : &ckfalse,
361 sizeof(CK_BBOOL));
362 attrs++;
363 ck_id = PK11_MakeIDFromPubKey(&lpk->u.rsa.modulus);
364 if (ck_id == NULL) {
365 goto loser;
366 }
367 PK11_SETATTRS(attrs, CKA_ID, ck_id->data, ck_id->len);
368 attrs++;
369 if (nickname) {
370 PK11_SETATTRS(attrs, CKA_LABEL, nickname->data, nickname->len);
371 attrs++;
372 }
373 signedattr = attrs;
374 PK11_SETATTRS(attrs, CKA_MODULUS, lpk->u.rsa.modulus.data,
375 lpk->u.rsa.modulus.len);
376 attrs++;
377 PK11_SETATTRS(attrs, CKA_PUBLIC_EXPONENT,
378 lpk->u.rsa.publicExponent.data,
379 lpk->u.rsa.publicExponent.len);
380 attrs++;
381 PK11_SETATTRS(attrs, CKA_PRIVATE_EXPONENT,
382 lpk->u.rsa.privateExponent.data,
383 lpk->u.rsa.privateExponent.len);
384 attrs++;
385 PK11_SETATTRS(attrs, CKA_PRIME_1,
386 lpk->u.rsa.prime1.data,
387 lpk->u.rsa.prime1.len);
388 attrs++;
389 PK11_SETATTRS(attrs, CKA_PRIME_2,
390 lpk->u.rsa.prime2.data,
391 lpk->u.rsa.prime2.len);
392 attrs++;
393 PK11_SETATTRS(attrs, CKA_EXPONENT_1,
394 lpk->u.rsa.exponent1.data,
395 lpk->u.rsa.exponent1.len);
396 attrs++;
397 PK11_SETATTRS(attrs, CKA_EXPONENT_2,
398 lpk->u.rsa.exponent2.data,
399 lpk->u.rsa.exponent2.len);
400 attrs++;
401 PK11_SETATTRS(attrs, CKA_COEFFICIENT,
402 lpk->u.rsa.coefficient.data,
403 lpk->u.rsa.coefficient.len);
404 attrs++;
405 break;
406 case dsaKey:
407 keyType = CKK_DSA;
408 /* To make our intenal PKCS #11 module work correctly with
409 * our database, we need to pass in the public key value for
410 * this dsa key. We have a netscape only CKA_ value to do this.
411 * Only send it to internal slots */
412 if (publicValue == NULL) {
413 goto loser;
414 }
415 if (PK11_IsInternal(slot)) {
416 PK11_SETATTRS(attrs, CKA_NSS_DB,
417 publicValue->data, publicValue->len);
418 attrs++;
419 }
420 PK11_SETATTRS(attrs, CKA_SIGN, &cktrue, sizeof(CK_BBOOL));
421 attrs++;
422 PK11_SETATTRS(attrs, CKA_SIGN_RECOVER, &cktrue, sizeof(CK_BBOOL));
423 attrs++;
424 if (nickname) {
425 PK11_SETATTRS(attrs, CKA_LABEL, nickname->data, nickname->len);
426 attrs++;
427 }
428 ck_id = PK11_MakeIDFromPubKey(publicValue);
429 if (ck_id == NULL) {
430 goto loser;
431 }
432 PK11_SETATTRS(attrs, CKA_ID, ck_id->data, ck_id->len);
433 attrs++;
434 signedattr = attrs;
435 PK11_SETATTRS(attrs, CKA_PRIME, lpk->u.dsa.params.prime.data,
436 lpk->u.dsa.params.prime.len);
437 attrs++;
438 PK11_SETATTRS(attrs, CKA_SUBPRIME, lpk->u.dsa.params.subPrime.data,
439 lpk->u.dsa.params.subPrime.len);
440 attrs++;
441 PK11_SETATTRS(attrs, CKA_BASE, lpk->u.dsa.params.base.data,
442 lpk->u.dsa.params.base.len);
443 attrs++;
444 PK11_SETATTRS(attrs, CKA_VALUE, lpk->u.dsa.privateValue.data,
445 lpk->u.dsa.privateValue.len);
446 attrs++;
447 break;
448 case dhKey:
449 keyType = CKK_DH;
450 /* To make our intenal PKCS #11 module work correctly with
451 * our database, we need to pass in the public key value for
452 * this dh key. We have a netscape only CKA_ value to do this.
453 * Only send it to internal slots */
454 if (PK11_IsInternal(slot)) {
455 PK11_SETATTRS(attrs, CKA_NSS_DB,
456 publicValue->data, publicValue->len);
457 attrs++;
458 }
459 PK11_SETATTRS(attrs, CKA_DERIVE, &cktrue, sizeof(CK_BBOOL));
460 attrs++;
461 if (nickname) {
462 PK11_SETATTRS(attrs, CKA_LABEL, nickname->data, nickname->len);
463 attrs++;
464 }
465 ck_id = PK11_MakeIDFromPubKey(publicValue);
466 if (ck_id == NULL) {
467 goto loser;
468 }
469 PK11_SETATTRS(attrs, CKA_ID, ck_id->data, ck_id->len);
470 attrs++;
471 signedattr = attrs;
472 PK11_SETATTRS(attrs, CKA_PRIME, lpk->u.dh.prime.data,
473 lpk->u.dh.prime.len);
474 attrs++;
475 PK11_SETATTRS(attrs, CKA_BASE, lpk->u.dh.base.data,
476 lpk->u.dh.base.len);
477 attrs++;
478 PK11_SETATTRS(attrs, CKA_VALUE, lpk->u.dh.privateValue.data,
479 lpk->u.dh.privateValue.len);
480 attrs++;
481 break;
482 case ecKey:
483 keyType = CKK_EC;
484 if (lpk->u.ec.publicValue.len == 0) {
485 goto loser;
486 }
487 if (PK11_IsInternal(slot)) {
488 PK11_SETATTRS(attrs, CKA_NSS_DB,
489 lpk->u.ec.publicValue.data,
490 lpk->u.ec.publicValue.len);
491 attrs++;
492 }
493 PK11_SETATTRS(attrs, CKA_SIGN, (keyUsage & KU_DIGITAL_SIGNATURE) ? &cktrue : &ckfalse,
494 sizeof(CK_BBOOL));
495 attrs++;
496 PK11_SETATTRS(attrs, CKA_SIGN_RECOVER,
497 (keyUsage & KU_DIGITAL_SIGNATURE) ? &cktrue
498 : &ckfalse,
499 sizeof(CK_BBOOL));
500 attrs++;
501 PK11_SETATTRS(attrs, CKA_DERIVE, (keyUsage & KU_KEY_AGREEMENT) ? &cktrue : &ckfalse,
502 sizeof(CK_BBOOL));
503 attrs++;
504 if (nickname) {
505 PK11_SETATTRS(attrs, CKA_LABEL, nickname->data, nickname->len);
506 attrs++;
507 }
508 ck_id = PK11_MakeIDFromPubKey(&lpk->u.ec.publicValue);
509 if (ck_id == NULL) {
510 goto loser;
511 }
512 PK11_SETATTRS(attrs, CKA_ID, ck_id->data, ck_id->len);
513 attrs++;
514 /* No signed attrs for EC */
515 /* curveOID always is a copy of AlgorithmID.parameters. */
516 PK11_SETATTRS(attrs, CKA_EC_PARAMS, lpk->u.ec.curveOID.data,
517 lpk->u.ec.curveOID.len);
518 attrs++;
519 PK11_SETATTRS(attrs, CKA_VALUE, lpk->u.ec.privateValue.data,
520 lpk->u.ec.privateValue.len);
521 attrs++;
522 PK11_SETATTRS(attrs, CKA_EC_POINT, lpk->u.ec.publicValue.data,
523 lpk->u.ec.publicValue.len);
524 attrs++;
525 break;
526 default:
527 PORT_SetError(SEC_ERROR_BAD_KEY);
528 goto loser;
529 }
530 templateCount = attrs - theTemplate;
531 PORT_Assert(templateCount <= sizeof(theTemplate) / sizeof(CK_ATTRIBUTE));
532 if (lpk->keyType != ecKey) {
533 PORT_Assert(signedattr);
534 signedcount = attrs - signedattr;
535 for (ap = signedattr; signedcount; ap++, signedcount--) {
536 pk11_SignedToUnsigned(ap);
537 }
538 }
539
540 rv = PK11_CreateNewObject(slot, CK_INVALID_HANDLE,
541 theTemplate, templateCount, isPerm, &objectID);
542
543 /* create and return a SECKEYPrivateKey */
544 if (rv == SECSuccess && privk != NULL) {
545 *privk = PK11_MakePrivKey(slot, lpk->keyType, !isPerm, objectID, wincx);
546 if (*privk == NULL) {
547 rv = SECFailure;
548 }
549 }
550 loser:
551 if (ck_id) {
552 SECITEM_ZfreeItem(ck_id, PR_TRUE);
553 }
554 return rv;
555 }
556
557 SECStatus
PK11_ImportPrivateKeyInfoAndReturnKey(PK11SlotInfo * slot,SECKEYPrivateKeyInfo * pki,SECItem * nickname,SECItem * publicValue,PRBool isPerm,PRBool isPrivate,unsigned int keyUsage,SECKEYPrivateKey ** privk,void * wincx)558 PK11_ImportPrivateKeyInfoAndReturnKey(PK11SlotInfo *slot,
559 SECKEYPrivateKeyInfo *pki, SECItem *nickname, SECItem *publicValue,
560 PRBool isPerm, PRBool isPrivate, unsigned int keyUsage,
561 SECKEYPrivateKey **privk, void *wincx)
562 {
563 SECStatus rv = SECFailure;
564 SECKEYRawPrivateKey *lpk = NULL;
565 const SEC_ASN1Template *keyTemplate, *paramTemplate;
566 void *paramDest = NULL;
567 PLArenaPool *arena = NULL;
568
569 arena = PORT_NewArena(2048);
570 if (!arena) {
571 return SECFailure;
572 }
573
574 /* need to change this to use RSA/DSA keys */
575 lpk = (SECKEYRawPrivateKey *)PORT_ArenaZAlloc(arena,
576 sizeof(SECKEYRawPrivateKey));
577 if (lpk == NULL) {
578 goto loser;
579 }
580 lpk->arena = arena;
581
582 switch (SECOID_GetAlgorithmTag(&pki->algorithm)) {
583 case SEC_OID_PKCS1_RSA_ENCRYPTION:
584 prepare_rsa_priv_key_export_for_asn1(lpk);
585 keyTemplate = SECKEY_RSAPrivateKeyExportTemplate;
586 paramTemplate = NULL;
587 paramDest = NULL;
588 lpk->keyType = rsaKey;
589 break;
590 case SEC_OID_ANSIX9_DSA_SIGNATURE:
591 prepare_dsa_priv_key_export_for_asn1(lpk);
592 keyTemplate = SECKEY_DSAPrivateKeyExportTemplate;
593 paramTemplate = SECKEY_PQGParamsTemplate;
594 paramDest = &(lpk->u.dsa.params);
595 lpk->keyType = dsaKey;
596 break;
597 case SEC_OID_X942_DIFFIE_HELMAN_KEY:
598 if (!publicValue) {
599 goto loser;
600 }
601 prepare_dh_priv_key_export_for_asn1(lpk);
602 keyTemplate = SECKEY_DHPrivateKeyExportTemplate;
603 paramTemplate = NULL;
604 paramDest = NULL;
605 lpk->keyType = dhKey;
606 break;
607 case SEC_OID_ANSIX962_EC_PUBLIC_KEY:
608 prepare_ec_priv_key_export_for_asn1(lpk);
609 keyTemplate = SECKEY_ECPrivateKeyExportTemplate;
610 paramTemplate = NULL;
611 paramDest = NULL;
612 lpk->keyType = ecKey;
613 break;
614
615 default:
616 keyTemplate = NULL;
617 paramTemplate = NULL;
618 paramDest = NULL;
619 break;
620 }
621
622 if (!keyTemplate) {
623 goto loser;
624 }
625
626 /* decode the private key and any algorithm parameters */
627 rv = SEC_QuickDERDecodeItem(arena, lpk, keyTemplate, &pki->privateKey);
628 if (rv != SECSuccess) {
629 goto loser;
630 }
631
632 if (lpk->keyType == ecKey) {
633 /* Convert length in bits to length in bytes. */
634 lpk->u.ec.publicValue.len >>= 3;
635
636 /* Always override curveOID, we're ignoring any given value. */
637 rv = SECITEM_CopyItem(arena, &lpk->u.ec.curveOID,
638 &pki->algorithm.parameters);
639 if (rv != SECSuccess) {
640 goto loser;
641 }
642 }
643
644 if (paramDest && paramTemplate) {
645 rv = SEC_ASN1DecodeItem(arena, paramDest, paramTemplate,
646 &(pki->algorithm.parameters));
647 if (rv != SECSuccess) {
648 goto loser;
649 }
650 }
651
652 rv = PK11_ImportAndReturnPrivateKey(slot, lpk, nickname, publicValue, isPerm,
653 isPrivate, keyUsage, privk, wincx);
654
655 loser:
656 if (arena != NULL) {
657 PORT_FreeArena(arena, PR_TRUE);
658 }
659
660 return rv;
661 }
662
663 SECStatus
PK11_ImportPrivateKeyInfo(PK11SlotInfo * slot,SECKEYPrivateKeyInfo * pki,SECItem * nickname,SECItem * publicValue,PRBool isPerm,PRBool isPrivate,unsigned int keyUsage,void * wincx)664 PK11_ImportPrivateKeyInfo(PK11SlotInfo *slot, SECKEYPrivateKeyInfo *pki,
665 SECItem *nickname, SECItem *publicValue, PRBool isPerm,
666 PRBool isPrivate, unsigned int keyUsage, void *wincx)
667 {
668 return PK11_ImportPrivateKeyInfoAndReturnKey(slot, pki, nickname,
669 publicValue, isPerm, isPrivate, keyUsage, NULL, wincx);
670 }
671
672 SECItem *
PK11_ExportDERPrivateKeyInfo(SECKEYPrivateKey * pk,void * wincx)673 PK11_ExportDERPrivateKeyInfo(SECKEYPrivateKey *pk, void *wincx)
674 {
675 SECKEYPrivateKeyInfo *pki = PK11_ExportPrivKeyInfo(pk, wincx);
676 SECItem *derPKI;
677
678 if (!pki) {
679 return NULL;
680 }
681 derPKI = SEC_ASN1EncodeItem(NULL, NULL, pki,
682 SECKEY_PrivateKeyInfoTemplate);
683 SECKEY_DestroyPrivateKeyInfo(pki, PR_TRUE);
684 return derPKI;
685 }
686
687 static PRBool
ReadAttribute(SECKEYPrivateKey * key,CK_ATTRIBUTE_TYPE type,PLArenaPool * arena,SECItem * output)688 ReadAttribute(SECKEYPrivateKey *key, CK_ATTRIBUTE_TYPE type,
689 PLArenaPool *arena, SECItem *output)
690 {
691 SECStatus rv = PK11_ReadAttribute(key->pkcs11Slot, key->pkcs11ID, type,
692 arena, output);
693 return rv == SECSuccess;
694 }
695
696 /*
697 * The caller is responsible for freeing the return value by passing it to
698 * SECKEY_DestroyPrivateKeyInfo(..., PR_TRUE).
699 */
700 SECKEYPrivateKeyInfo *
PK11_ExportPrivKeyInfo(SECKEYPrivateKey * pk,void * wincx)701 PK11_ExportPrivKeyInfo(SECKEYPrivateKey *pk, void *wincx)
702 {
703 /* PrivateKeyInfo version (always zero) */
704 const unsigned char pkiVersion = 0;
705 /* RSAPrivateKey version (always zero) */
706 const unsigned char rsaVersion = 0;
707 /* ECPrivateKey version (always one) */
708 const unsigned char ecVersion = 1;
709 PLArenaPool *arena = NULL;
710 SECKEYRawPrivateKey rawKey;
711 SECKEYPrivateKeyInfo *pki;
712 SECItem *encoded;
713 const SEC_ASN1Template *keyTemplate;
714 SECStatus rv;
715
716 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
717 if (!arena) {
718 goto loser;
719 }
720 memset(&rawKey, 0, sizeof(rawKey));
721 rawKey.keyType = pk->keyType;
722 pki = PORT_ArenaZNew(arena, SECKEYPrivateKeyInfo);
723 if (!pki) {
724 goto loser;
725 }
726
727 switch (pk->keyType) {
728 case rsaKey: {
729 rawKey.u.rsa.version.type = siUnsignedInteger;
730 rawKey.u.rsa.version.data = (unsigned char *)PORT_ArenaAlloc(arena, 1);
731 if (!rawKey.u.rsa.version.data) {
732 goto loser;
733 }
734
735 rawKey.u.rsa.version.data[0] = rsaVersion;
736 rawKey.u.rsa.version.len = 1;
737
738 /* Read the component attributes of the private key */
739 prepare_rsa_priv_key_export_for_asn1(&rawKey);
740 if (!ReadAttribute(pk, CKA_MODULUS, arena, &rawKey.u.rsa.modulus) ||
741 !ReadAttribute(pk, CKA_PUBLIC_EXPONENT, arena,
742 &rawKey.u.rsa.publicExponent) ||
743 !ReadAttribute(pk, CKA_PRIVATE_EXPONENT, arena,
744 &rawKey.u.rsa.privateExponent) ||
745 !ReadAttribute(pk, CKA_PRIME_1, arena, &rawKey.u.rsa.prime1) ||
746 !ReadAttribute(pk, CKA_PRIME_2, arena, &rawKey.u.rsa.prime2) ||
747 !ReadAttribute(pk, CKA_EXPONENT_1, arena,
748 &rawKey.u.rsa.exponent1) ||
749 !ReadAttribute(pk, CKA_EXPONENT_2, arena,
750 &rawKey.u.rsa.exponent2) ||
751 !ReadAttribute(pk, CKA_COEFFICIENT, arena,
752 &rawKey.u.rsa.coefficient)) {
753 goto loser;
754 }
755
756 keyTemplate = SECKEY_RSAPrivateKeyExportTemplate;
757
758 rv = SECOID_SetAlgorithmID(arena, &pki->algorithm, SEC_OID_PKCS1_RSA_ENCRYPTION, NULL);
759 if (rv != SECSuccess) {
760 goto loser;
761 }
762
763 } break;
764 case ecKey: {
765 rawKey.u.ec.version.type = siUnsignedInteger;
766 rawKey.u.ec.version.data = (unsigned char *)PORT_ArenaAlloc(arena, 1);
767 if (!rawKey.u.ec.version.data) {
768 goto loser;
769 }
770 rawKey.u.ec.version.data[0] = ecVersion;
771 rawKey.u.ec.version.len = 1;
772
773 SECItem curveOID;
774 /* Read the component attributes of the private key */
775 prepare_ec_priv_key_export_for_asn1(&rawKey);
776 if (!ReadAttribute(pk, CKA_VALUE, arena,
777 &rawKey.u.ec.privateValue) ||
778 !ReadAttribute(pk, CKA_EC_PARAMS, arena, &curveOID)) {
779 goto loser;
780 }
781 if (!ReadAttribute(pk, CKA_EC_POINT, arena,
782 &rawKey.u.ec.publicValue)) {
783 SECKEYPublicKey *pubk = SECKEY_ConvertToPublicKey(pk);
784 if (pubk == NULL)
785 goto loser;
786 rv = SECITEM_CopyItem(arena, &rawKey.u.ec.publicValue, &pubk->u.ec.publicValue);
787 SECKEY_DestroyPublicKey(pubk);
788 if (rv != SECSuccess) {
789 goto loser;
790 }
791 }
792
793 keyTemplate = SECKEY_ECPrivateKeyExportTemplate;
794 /* Convert length in bytes to length in bits. */
795 rawKey.u.ec.publicValue.len <<= 3;
796
797 rv = SECOID_SetAlgorithmID(arena, &pki->algorithm, SEC_OID_ANSIX962_EC_PUBLIC_KEY, &curveOID);
798 if (rv != SECSuccess) {
799 goto loser;
800 }
801
802 } break;
803 default: {
804 PORT_SetError(PR_NOT_IMPLEMENTED_ERROR);
805 goto loser;
806 }
807 }
808
809 encoded = SEC_ASN1EncodeItem(arena, &pki->privateKey, &rawKey, keyTemplate);
810 if (!encoded) {
811 goto loser;
812 }
813 pki->version.type = siUnsignedInteger;
814 pki->version.data = (unsigned char *)PORT_ArenaAlloc(arena, 1);
815 if (!pki->version.data) {
816 goto loser;
817 }
818 pki->version.data[0] = pkiVersion;
819 pki->version.len = 1;
820 pki->arena = arena;
821
822 return pki;
823
824 loser:
825 if (arena) {
826 PORT_FreeArena(arena, PR_TRUE);
827 }
828 return NULL;
829 }
830