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

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

Issue 2078763002: Delete bundled copy of NSS and replace with README. (Closed) Base URL: https://chromium.googlesource.com/chromium/deps/nss@master
Patch Set: Delete bundled copy of NSS and replace with README. Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « nss/lib/pk11wrap/pk11pbe.c ('k') | nss/lib/pk11wrap/pk11pqg.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1
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 "pkcs11.h"
15 #include "pk11func.h"
16 #include "secitem.h"
17 #include "key.h"
18 #include "secoid.h"
19 #include "secasn1.h"
20 #include "secerr.h"
21 #include "prerror.h"
22
23
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 /*
49 ** DSA Raw Private Key structures
50 */
51
52 struct SECKEYDSAPrivateKeyStr {
53 SECKEYPQGParams params;
54 SECItem privateValue;
55 };
56 typedef struct SECKEYDSAPrivateKeyStr SECKEYDSAPrivateKey;
57
58 /*
59 ** Diffie-Hellman Raw Private Key structures
60 ** Structure member names suggested by PKCS#3.
61 */
62 struct SECKEYDHPrivateKeyStr {
63 PLArenaPool * arena;
64 SECItem prime;
65 SECItem base;
66 SECItem privateValue;
67 };
68 typedef struct SECKEYDHPrivateKeyStr SECKEYDHPrivateKey;
69
70 /*
71 ** raw private key object
72 */
73 struct SECKEYRawPrivateKeyStr {
74 PLArenaPool *arena;
75 KeyType keyType;
76 union {
77 SECKEYRSAPrivateKey rsa;
78 SECKEYDSAPrivateKey dsa;
79 SECKEYDHPrivateKey dh;
80 } u;
81 };
82 typedef struct SECKEYRawPrivateKeyStr SECKEYRawPrivateKey;
83
84 SEC_ASN1_MKSUB(SEC_AnyTemplate)
85 SEC_ASN1_MKSUB(SECOID_AlgorithmIDTemplate)
86
87 /* ASN1 Templates for new decoder/encoder */
88 /*
89 * Attribute value for PKCS8 entries (static?)
90 */
91 const SEC_ASN1Template SECKEY_AttributeTemplate[] = {
92 { SEC_ASN1_SEQUENCE,
93 0, NULL, sizeof(SECKEYAttribute) },
94 { SEC_ASN1_OBJECT_ID, offsetof(SECKEYAttribute, attrType) },
95 { SEC_ASN1_SET_OF | SEC_ASN1_XTRN, offsetof(SECKEYAttribute, attrValue),
96 SEC_ASN1_SUB(SEC_AnyTemplate) },
97 { 0 }
98 };
99
100 const SEC_ASN1Template SECKEY_SetOfAttributeTemplate[] = {
101 { SEC_ASN1_SET_OF, 0, SECKEY_AttributeTemplate },
102 };
103
104 const SEC_ASN1Template SECKEY_PrivateKeyInfoTemplate[] = {
105 { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SECKEYPrivateKeyInfo) },
106 { SEC_ASN1_INTEGER, offsetof(SECKEYPrivateKeyInfo,version) },
107 { SEC_ASN1_INLINE | SEC_ASN1_XTRN,
108 offsetof(SECKEYPrivateKeyInfo,algorithm),
109 SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
110 { SEC_ASN1_OCTET_STRING, offsetof(SECKEYPrivateKeyInfo,privateKey) },
111 { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0,
112 offsetof(SECKEYPrivateKeyInfo,attributes),
113 SECKEY_SetOfAttributeTemplate },
114 { 0 }
115 };
116
117 const SEC_ASN1Template SECKEY_PointerToPrivateKeyInfoTemplate[] = {
118 { SEC_ASN1_POINTER, 0, SECKEY_PrivateKeyInfoTemplate }
119 };
120
121 const SEC_ASN1Template SECKEY_RSAPrivateKeyExportTemplate[] = {
122 { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SECKEYRawPrivateKey) },
123 { SEC_ASN1_INTEGER, offsetof(SECKEYRawPrivateKey,u.rsa.version) },
124 { SEC_ASN1_INTEGER, offsetof(SECKEYRawPrivateKey,u.rsa.modulus) },
125 { SEC_ASN1_INTEGER, offsetof(SECKEYRawPrivateKey,u.rsa.publicExponent) },
126 { SEC_ASN1_INTEGER, offsetof(SECKEYRawPrivateKey,u.rsa.privateExponent) },
127 { SEC_ASN1_INTEGER, offsetof(SECKEYRawPrivateKey,u.rsa.prime1) },
128 { SEC_ASN1_INTEGER, offsetof(SECKEYRawPrivateKey,u.rsa.prime2) },
129 { SEC_ASN1_INTEGER, offsetof(SECKEYRawPrivateKey,u.rsa.exponent1) },
130 { SEC_ASN1_INTEGER, offsetof(SECKEYRawPrivateKey,u.rsa.exponent2) },
131 { SEC_ASN1_INTEGER, offsetof(SECKEYRawPrivateKey,u.rsa.coefficient) },
132 { 0 }
133 };
134
135 const SEC_ASN1Template SECKEY_DSAPrivateKeyExportTemplate[] = {
136 { SEC_ASN1_INTEGER, offsetof(SECKEYRawPrivateKey,u.dsa.privateValue) },
137 };
138
139 const SEC_ASN1Template SECKEY_DHPrivateKeyExportTemplate[] = {
140 { SEC_ASN1_INTEGER, offsetof(SECKEYRawPrivateKey,u.dh.privateValue) },
141 { SEC_ASN1_INTEGER, offsetof(SECKEYRawPrivateKey,u.dh.base) },
142 { SEC_ASN1_INTEGER, offsetof(SECKEYRawPrivateKey,u.dh.prime) },
143 };
144
145 const SEC_ASN1Template SECKEY_EncryptedPrivateKeyInfoTemplate[] = {
146 { SEC_ASN1_SEQUENCE,
147 0, NULL, sizeof(SECKEYEncryptedPrivateKeyInfo) },
148 { SEC_ASN1_INLINE | SEC_ASN1_XTRN,
149 offsetof(SECKEYEncryptedPrivateKeyInfo,algorithm),
150 SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
151 { SEC_ASN1_OCTET_STRING,
152 offsetof(SECKEYEncryptedPrivateKeyInfo,encryptedData) },
153 { 0 }
154 };
155
156 const SEC_ASN1Template SECKEY_PointerToEncryptedPrivateKeyInfoTemplate[] = {
157 { SEC_ASN1_POINTER, 0, SECKEY_EncryptedPrivateKeyInfoTemplate }
158 };
159
160 SEC_ASN1_CHOOSER_IMPLEMENT(SECKEY_EncryptedPrivateKeyInfoTemplate)
161 SEC_ASN1_CHOOSER_IMPLEMENT(SECKEY_PointerToEncryptedPrivateKeyInfoTemplate)
162 SEC_ASN1_CHOOSER_IMPLEMENT(SECKEY_PrivateKeyInfoTemplate)
163 SEC_ASN1_CHOOSER_IMPLEMENT(SECKEY_PointerToPrivateKeyInfoTemplate)
164
165 /*
166 * See bugzilla bug 125359
167 * Since NSS (via PKCS#11) wants to handle big integers as unsigned ints,
168 * all of the templates above that en/decode into integers must be converted
169 * from ASN.1's signed integer type. This is done by marking either the
170 * source or destination (encoding or decoding, respectively) type as
171 * siUnsignedInteger.
172 */
173
174 static void
175 prepare_rsa_priv_key_export_for_asn1(SECKEYRawPrivateKey *key)
176 {
177 key->u.rsa.modulus.type = siUnsignedInteger;
178 key->u.rsa.publicExponent.type = siUnsignedInteger;
179 key->u.rsa.privateExponent.type = siUnsignedInteger;
180 key->u.rsa.prime1.type = siUnsignedInteger;
181 key->u.rsa.prime2.type = siUnsignedInteger;
182 key->u.rsa.exponent1.type = siUnsignedInteger;
183 key->u.rsa.exponent2.type = siUnsignedInteger;
184 key->u.rsa.coefficient.type = siUnsignedInteger;
185 }
186
187 static void
188 prepare_dsa_priv_key_export_for_asn1(SECKEYRawPrivateKey *key)
189 {
190 key->u.dsa.privateValue.type = siUnsignedInteger;
191 key->u.dsa.params.prime.type = siUnsignedInteger;
192 key->u.dsa.params.subPrime.type = siUnsignedInteger;
193 key->u.dsa.params.base.type = siUnsignedInteger;
194 }
195
196 static void
197 prepare_dh_priv_key_export_for_asn1(SECKEYRawPrivateKey *key)
198 {
199 key->u.dh.privateValue.type = siUnsignedInteger;
200 key->u.dh.prime.type = siUnsignedInteger;
201 key->u.dh.base.type = siUnsignedInteger;
202 }
203
204
205 SECStatus
206 PK11_ImportDERPrivateKeyInfo(PK11SlotInfo *slot, SECItem *derPKI,
207 SECItem *nickname, SECItem *publicValue, PRBool isPerm,
208 PRBool isPrivate, unsigned int keyUsage, void *wincx)
209 {
210 return PK11_ImportDERPrivateKeyInfoAndReturnKey(slot, derPKI,
211 nickname, publicValue, isPerm, isPrivate, keyUsage, NULL, wincx);
212 }
213
214 SECStatus
215 PK11_ImportDERPrivateKeyInfoAndReturnKey(PK11SlotInfo *slot, SECItem *derPKI,
216 SECItem *nickname, SECItem *publicValue, PRBool isPerm,
217 PRBool isPrivate, unsigned int keyUsage, SECKEYPrivateKey** privk,
218 void *wincx)
219 {
220 SECKEYPrivateKeyInfo *pki = NULL;
221 PLArenaPool *temparena = NULL;
222 SECStatus rv = SECFailure;
223
224 temparena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
225 if (!temparena)
226 return rv;
227 pki = PORT_ArenaZNew(temparena, SECKEYPrivateKeyInfo);
228 if (!pki) {
229 PORT_FreeArena(temparena, PR_FALSE);
230 return rv;
231 }
232 pki->arena = temparena;
233
234 rv = SEC_ASN1DecodeItem(pki->arena, pki, SECKEY_PrivateKeyInfoTemplate,
235 derPKI);
236 if( rv != SECSuccess ) {
237 /* If SEC_ASN1DecodeItem fails, we cannot assume anything about the
238 * validity of the data in pki. The best we can do is free the arena
239 * and return.
240 */
241 PORT_FreeArena(temparena, PR_TRUE);
242 return rv;
243 }
244
245 rv = PK11_ImportPrivateKeyInfoAndReturnKey(slot, pki, nickname,
246 publicValue, isPerm, isPrivate, keyUsage, privk, wincx);
247
248 /* this zeroes the key and frees the arena */
249 SECKEY_DestroyPrivateKeyInfo(pki, PR_TRUE /*freeit*/);
250 return rv;
251 }
252
253 SECStatus
254 PK11_ImportAndReturnPrivateKey(PK11SlotInfo *slot, SECKEYRawPrivateKey *lpk,
255 SECItem *nickname, SECItem *publicValue, PRBool isPerm,
256 PRBool isPrivate, unsigned int keyUsage, SECKEYPrivateKey **privk,
257 void *wincx)
258 {
259 CK_BBOOL cktrue = CK_TRUE;
260 CK_BBOOL ckfalse = CK_FALSE;
261 CK_OBJECT_CLASS keyClass = CKO_PRIVATE_KEY;
262 CK_KEY_TYPE keyType = CKK_RSA;
263 CK_OBJECT_HANDLE objectID;
264 CK_ATTRIBUTE theTemplate[20];
265 int templateCount = 0;
266 SECStatus rv = SECFailure;
267 CK_ATTRIBUTE *attrs;
268 CK_ATTRIBUTE *signedattr = NULL;
269 int signedcount = 0;
270 CK_ATTRIBUTE *ap;
271 SECItem *ck_id = NULL;
272
273 attrs = theTemplate;
274
275
276 PK11_SETATTRS(attrs, CKA_CLASS, &keyClass, sizeof(keyClass) ); attrs++;
277 PK11_SETATTRS(attrs, CKA_KEY_TYPE, &keyType, sizeof(keyType) ); attrs++;
278 PK11_SETATTRS(attrs, CKA_TOKEN, isPerm ? &cktrue : &ckfalse,
279 sizeof(CK_BBOOL) ); attrs++;
280 PK11_SETATTRS(attrs, CKA_SENSITIVE, isPrivate ? &cktrue : &ckfalse,
281 sizeof(CK_BBOOL) ); attrs++;
282 PK11_SETATTRS(attrs, CKA_PRIVATE, isPrivate ? &cktrue : &ckfalse,
283 sizeof(CK_BBOOL) ); attrs++;
284
285 switch (lpk->keyType) {
286 case rsaKey:
287 keyType = CKK_RSA;
288 PK11_SETATTRS(attrs, CKA_UNWRAP, (keyUsage & KU_KEY_ENCIPHERMENT) ?
289 &cktrue : &ckfalse, sizeof(CK_BBOOL) ); attrs++;
290 PK11_SETATTRS(attrs, CKA_DECRYPT, (keyUsage & KU_DATA_ENCIPHERMENT) ?
291 &cktrue : &ckfalse, sizeof(CK_BBOOL) ); attrs++;
292 PK11_SETATTRS(attrs, CKA_SIGN, (keyUsage & KU_DIGITAL_SIGNATURE) ?
293 &cktrue : &ckfalse, sizeof(CK_BBOOL) ); attrs++;
294 PK11_SETATTRS(attrs, CKA_SIGN_RECOVER,
295 (keyUsage & KU_DIGITAL_SIGNATURE) ?
296 &cktrue : &ckfalse, sizeof(CK_BBOOL) ); attrs++;
297 ck_id = PK11_MakeIDFromPubKey(&lpk->u.rsa.modulus);
298 if (ck_id == NULL) {
299 goto loser;
300 }
301 PK11_SETATTRS(attrs, CKA_ID, ck_id->data,ck_id->len); attrs++;
302 if (nickname) {
303 PK11_SETATTRS(attrs, CKA_LABEL, nickname->data, nickname->len); attrs++;
304 }
305 signedattr = attrs;
306 PK11_SETATTRS(attrs, CKA_MODULUS, lpk->u.rsa.modulus.data,
307 lpk->u.rsa.modulus.len); attrs++ ;
308 PK11_SETATTRS(attrs, CKA_PUBLIC_EXPONENT,
309 lpk->u.rsa.publicExponent.data,
310 lpk->u.rsa.publicExponent.len); attrs++;
311 PK11_SETATTRS(attrs, CKA_PRIVATE_EXPONENT,
312 lpk->u.rsa.privateExponent.data,
313 lpk->u.rsa.privateExponent.len); attrs++;
314 PK11_SETATTRS(attrs, CKA_PRIME_1,
315 lpk->u.rsa.prime1.data,
316 lpk->u.rsa.prime1.len); attrs++;
317 PK11_SETATTRS(attrs, CKA_PRIME_2,
318 lpk->u.rsa.prime2.data,
319 lpk->u.rsa.prime2.len); attrs++;
320 PK11_SETATTRS(attrs, CKA_EXPONENT_1,
321 lpk->u.rsa.exponent1.data,
322 lpk->u.rsa.exponent1.len); attrs++;
323 PK11_SETATTRS(attrs, CKA_EXPONENT_2,
324 lpk->u.rsa.exponent2.data,
325 lpk->u.rsa.exponent2.len); attrs++;
326 PK11_SETATTRS(attrs, CKA_COEFFICIENT,
327 lpk->u.rsa.coefficient.data,
328 lpk->u.rsa.coefficient.len); attrs++;
329 break;
330 case dsaKey:
331 keyType = CKK_DSA;
332 /* To make our intenal PKCS #11 module work correctly with
333 * our database, we need to pass in the public key value for
334 * this dsa key. We have a netscape only CKA_ value to do this.
335 * Only send it to internal slots */
336 if( publicValue == NULL ) {
337 goto loser;
338 }
339 if (PK11_IsInternal(slot)) {
340 PK11_SETATTRS(attrs, CKA_NETSCAPE_DB,
341 publicValue->data, publicValue->len); attrs++;
342 }
343 PK11_SETATTRS(attrs, CKA_SIGN, &cktrue, sizeof(CK_BBOOL)); attrs++;
344 PK11_SETATTRS(attrs, CKA_SIGN_RECOVER, &cktrue, sizeof(CK_BBOOL)); a ttrs++;
345 if(nickname) {
346 PK11_SETATTRS(attrs, CKA_LABEL, nickname->data, nickname->len);
347 attrs++;
348 }
349 ck_id = PK11_MakeIDFromPubKey(publicValue);
350 if (ck_id == NULL) {
351 goto loser;
352 }
353 PK11_SETATTRS(attrs, CKA_ID, ck_id->data,ck_id->len); attrs++;
354 signedattr = attrs;
355 PK11_SETATTRS(attrs, CKA_PRIME, lpk->u.dsa.params.prime.data,
356 lpk->u.dsa.params.prime.len); attrs++;
357 PK11_SETATTRS(attrs,CKA_SUBPRIME,lpk->u.dsa.params.subPrime.data,
358 lpk->u.dsa.params.subPrime.len); attrs++;
359 PK11_SETATTRS(attrs, CKA_BASE, lpk->u.dsa.params.base.data,
360 lpk->u.dsa.params.base.len); attrs++;
361 PK11_SETATTRS(attrs, CKA_VALUE, lpk->u.dsa.privateValue.data,
362 lpk->u.dsa.privateValue.len); attrs++;
363 break;
364 case dhKey:
365 keyType = CKK_DH;
366 /* To make our intenal PKCS #11 module work correctly with
367 * our database, we need to pass in the public key value for
368 * this dh key. We have a netscape only CKA_ value to do this.
369 * Only send it to internal slots */
370 if (PK11_IsInternal(slot)) {
371 PK11_SETATTRS(attrs, CKA_NETSCAPE_DB,
372 publicValue->data, publicValue->len); attrs++;
373 }
374 PK11_SETATTRS(attrs, CKA_DERIVE, &cktrue, sizeof(CK_BBOOL)); attrs++ ;
375 if(nickname) {
376 PK11_SETATTRS(attrs, CKA_LABEL, nickname->data, nickname->len);
377 attrs++;
378 }
379 ck_id = PK11_MakeIDFromPubKey(publicValue);
380 if (ck_id == NULL) {
381 goto loser;
382 }
383 PK11_SETATTRS(attrs, CKA_ID, ck_id->data,ck_id->len); attrs++;
384 signedattr = attrs;
385 PK11_SETATTRS(attrs, CKA_PRIME, lpk->u.dh.prime.data,
386 lpk->u.dh.prime.len); attrs++;
387 PK11_SETATTRS(attrs, CKA_BASE, lpk->u.dh.base.data,
388 lpk->u.dh.base.len); attrs++;
389 PK11_SETATTRS(attrs, CKA_VALUE, lpk->u.dh.privateValue.data,
390 lpk->u.dh.privateValue.len); attrs++;
391 break;
392 /* what about fortezza??? */
393 default:
394 PORT_SetError(SEC_ERROR_BAD_KEY);
395 goto loser;
396 }
397 templateCount = attrs - theTemplate;
398 PORT_Assert(templateCount <= sizeof(theTemplate)/sizeof(CK_ATTRIBUTE));
399 PORT_Assert(signedattr != NULL);
400 signedcount = attrs - signedattr;
401
402 for (ap=signedattr; signedcount; ap++, signedcount--) {
403 pk11_SignedToUnsigned(ap);
404 }
405
406 rv = PK11_CreateNewObject(slot, CK_INVALID_SESSION,
407 theTemplate, templateCount, isPerm, &objectID);
408
409 /* create and return a SECKEYPrivateKey */
410 if( rv == SECSuccess && privk != NULL) {
411 *privk = PK11_MakePrivKey(slot, lpk->keyType, !isPerm, objectID, wincx);
412 if( *privk == NULL ) {
413 rv = SECFailure;
414 }
415 }
416 loser:
417 if (ck_id) {
418 SECITEM_ZfreeItem(ck_id, PR_TRUE);
419 }
420 return rv;
421 }
422
423 SECStatus
424 PK11_ImportPrivateKeyInfoAndReturnKey(PK11SlotInfo *slot,
425 SECKEYPrivateKeyInfo *pki, SECItem *nickname, SECItem *publicValue,
426 PRBool isPerm, PRBool isPrivate, unsigned int keyUsage,
427 SECKEYPrivateKey **privk, void *wincx)
428 {
429 SECStatus rv = SECFailure;
430 SECKEYRawPrivateKey *lpk = NULL;
431 const SEC_ASN1Template *keyTemplate, *paramTemplate;
432 void *paramDest = NULL;
433 PLArenaPool *arena = NULL;
434
435 arena = PORT_NewArena(2048);
436 if(!arena) {
437 return SECFailure;
438 }
439
440 /* need to change this to use RSA/DSA keys */
441 lpk = (SECKEYRawPrivateKey *)PORT_ArenaZAlloc(arena,
442 sizeof(SECKEYRawPrivateKey));
443 if(lpk == NULL) {
444 goto loser;
445 }
446 lpk->arena = arena;
447
448 switch(SECOID_GetAlgorithmTag(&pki->algorithm)) {
449 case SEC_OID_PKCS1_RSA_ENCRYPTION:
450 prepare_rsa_priv_key_export_for_asn1(lpk);
451 keyTemplate = SECKEY_RSAPrivateKeyExportTemplate;
452 paramTemplate = NULL;
453 paramDest = NULL;
454 lpk->keyType = rsaKey;
455 break;
456 case SEC_OID_ANSIX9_DSA_SIGNATURE:
457 prepare_dsa_priv_key_export_for_asn1(lpk);
458 keyTemplate = SECKEY_DSAPrivateKeyExportTemplate;
459 paramTemplate = SECKEY_PQGParamsTemplate;
460 paramDest = &(lpk->u.dsa.params);
461 lpk->keyType = dsaKey;
462 break;
463 case SEC_OID_X942_DIFFIE_HELMAN_KEY:
464 if(!publicValue) {
465 goto loser;
466 }
467 prepare_dh_priv_key_export_for_asn1(lpk);
468 keyTemplate = SECKEY_DHPrivateKeyExportTemplate;
469 paramTemplate = NULL;
470 paramDest = NULL;
471 lpk->keyType = dhKey;
472 break;
473
474 default:
475 keyTemplate = NULL;
476 paramTemplate = NULL;
477 paramDest = NULL;
478 break;
479 }
480
481 if(!keyTemplate) {
482 goto loser;
483 }
484
485 /* decode the private key and any algorithm parameters */
486 rv = SEC_ASN1DecodeItem(arena, lpk, keyTemplate, &pki->privateKey);
487 if(rv != SECSuccess) {
488 goto loser;
489 }
490 if(paramDest && paramTemplate) {
491 rv = SEC_ASN1DecodeItem(arena, paramDest, paramTemplate,
492 &(pki->algorithm.parameters));
493 if(rv != SECSuccess) {
494 goto loser;
495 }
496 }
497
498 rv = PK11_ImportAndReturnPrivateKey(slot,lpk,nickname,publicValue, isPerm,
499 isPrivate, keyUsage, privk, wincx);
500
501
502 loser:
503 if (arena != NULL) {
504 PORT_FreeArena(arena, PR_TRUE);
505 }
506
507 return rv;
508 }
509
510 SECStatus
511 PK11_ImportPrivateKeyInfo(PK11SlotInfo *slot, SECKEYPrivateKeyInfo *pki,
512 SECItem *nickname, SECItem *publicValue, PRBool isPerm,
513 PRBool isPrivate, unsigned int keyUsage, void *wincx)
514 {
515 return PK11_ImportPrivateKeyInfoAndReturnKey(slot, pki, nickname,
516 publicValue, isPerm, isPrivate, keyUsage, NULL, wincx);
517
518 }
519
520 SECItem *
521 PK11_ExportDERPrivateKeyInfo(SECKEYPrivateKey *pk, void *wincx)
522 {
523 SECKEYPrivateKeyInfo *pki = PK11_ExportPrivKeyInfo(pk, wincx);
524 SECItem *derPKI;
525
526 if (!pki) {
527 return NULL;
528 }
529 derPKI = SEC_ASN1EncodeItem(NULL, NULL, pki,
530 SECKEY_PrivateKeyInfoTemplate);
531 SECKEY_DestroyPrivateKeyInfo(pki, PR_TRUE);
532 return derPKI;
533 }
534
535 static PRBool
536 ReadAttribute(SECKEYPrivateKey *key, CK_ATTRIBUTE_TYPE type,
537 PLArenaPool *arena, SECItem *output)
538 {
539 SECStatus rv = PK11_ReadAttribute(key->pkcs11Slot, key->pkcs11ID, type,
540 arena, output);
541 return rv == SECSuccess;
542 }
543
544 /*
545 * The caller is responsible for freeing the return value by passing it to
546 * SECKEY_DestroyPrivateKeyInfo(..., PR_TRUE).
547 */
548 SECKEYPrivateKeyInfo *
549 PK11_ExportPrivKeyInfo(SECKEYPrivateKey *pk, void *wincx)
550 {
551 /* PrivateKeyInfo version (always zero) */
552 const unsigned char pkiVersion = 0;
553 /* RSAPrivateKey version (always zero) */
554 const unsigned char rsaVersion = 0;
555 PLArenaPool *arena = NULL;
556 SECKEYRawPrivateKey rawKey;
557 SECKEYPrivateKeyInfo *pki;
558 SECItem *encoded;
559 SECStatus rv;
560
561 if (pk->keyType != rsaKey) {
562 PORT_SetError(PR_NOT_IMPLEMENTED_ERROR);
563 goto loser;
564 }
565
566 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
567 if (!arena) {
568 goto loser;
569 }
570 memset(&rawKey, 0, sizeof(rawKey));
571 rawKey.keyType = pk->keyType;
572 rawKey.u.rsa.version.type = siUnsignedInteger;
573 rawKey.u.rsa.version.data = (unsigned char *)PORT_ArenaAlloc(arena, 1);
574 if (!rawKey.u.rsa.version.data) {
575 goto loser;
576 }
577 rawKey.u.rsa.version.data[0] = rsaVersion;
578 rawKey.u.rsa.version.len = 1;
579
580 /* Read the component attributes of the private key */
581 prepare_rsa_priv_key_export_for_asn1(&rawKey);
582 if (!ReadAttribute(pk, CKA_MODULUS, arena, &rawKey.u.rsa.modulus) ||
583 !ReadAttribute(pk, CKA_PUBLIC_EXPONENT, arena,
584 &rawKey.u.rsa.publicExponent) ||
585 !ReadAttribute(pk, CKA_PRIVATE_EXPONENT, arena,
586 &rawKey.u.rsa.privateExponent) ||
587 !ReadAttribute(pk, CKA_PRIME_1, arena, &rawKey.u.rsa.prime1) ||
588 !ReadAttribute(pk, CKA_PRIME_2, arena, &rawKey.u.rsa.prime2) ||
589 !ReadAttribute(pk, CKA_EXPONENT_1, arena,
590 &rawKey.u.rsa.exponent1) ||
591 !ReadAttribute(pk, CKA_EXPONENT_2, arena,
592 &rawKey.u.rsa.exponent2) ||
593 !ReadAttribute(pk, CKA_COEFFICIENT, arena,
594 &rawKey.u.rsa.coefficient)) {
595 goto loser;
596 }
597
598 pki = PORT_ArenaZNew(arena, SECKEYPrivateKeyInfo);
599 if (!pki) {
600 goto loser;
601 }
602 encoded = SEC_ASN1EncodeItem(arena, &pki->privateKey, &rawKey,
603 SECKEY_RSAPrivateKeyExportTemplate);
604 if (!encoded) {
605 goto loser;
606 }
607 rv = SECOID_SetAlgorithmID(arena, &pki->algorithm,
608 SEC_OID_PKCS1_RSA_ENCRYPTION, NULL);
609 if (rv != SECSuccess) {
610 goto loser;
611 }
612 pki->version.type = siUnsignedInteger;
613 pki->version.data = (unsigned char *)PORT_ArenaAlloc(arena, 1);
614 if (!pki->version.data) {
615 goto loser;
616 }
617 pki->version.data[0] = pkiVersion;
618 pki->version.len = 1;
619 pki->arena = arena;
620
621 return pki;
622
623 loser:
624 if (arena) {
625 PORT_FreeArena(arena, PR_TRUE);
626 }
627 return NULL;
628 }
OLDNEW
« no previous file with comments | « nss/lib/pk11wrap/pk11pbe.c ('k') | nss/lib/pk11wrap/pk11pqg.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698