OLD | NEW |
| (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 | |
22 | |
23 | |
24 /* These data structures should move to a common .h file shared between the | |
25 * wrappers and the pkcs 12 code. */ | |
26 | |
27 /* | |
28 ** RSA Raw Private Key structures | |
29 */ | |
30 | |
31 /* member names from PKCS#1, section 7.2 */ | |
32 struct SECKEYRSAPrivateKeyStr { | |
33 PRArenaPool * arena; | |
34 SECItem version; | |
35 SECItem modulus; | |
36 SECItem publicExponent; | |
37 SECItem privateExponent; | |
38 SECItem prime1; | |
39 SECItem prime2; | |
40 SECItem exponent1; | |
41 SECItem exponent2; | |
42 SECItem coefficient; | |
43 }; | |
44 typedef struct SECKEYRSAPrivateKeyStr SECKEYRSAPrivateKey; | |
45 | |
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 PRArenaPool * arena; | |
63 SECItem prime; | |
64 SECItem base; | |
65 SECItem privateValue; | |
66 }; | |
67 typedef struct SECKEYDHPrivateKeyStr SECKEYDHPrivateKey; | |
68 | |
69 /* | |
70 ** raw private key object | |
71 */ | |
72 struct SECKEYRawPrivateKeyStr { | |
73 PLArenaPool *arena; | |
74 KeyType keyType; | |
75 union { | |
76 SECKEYRSAPrivateKey rsa; | |
77 SECKEYDSAPrivateKey dsa; | |
78 SECKEYDHPrivateKey dh; | |
79 } u; | |
80 }; | |
81 typedef struct SECKEYRawPrivateKeyStr SECKEYRawPrivateKey; | |
82 | |
83 SEC_ASN1_MKSUB(SEC_AnyTemplate) | |
84 SEC_ASN1_MKSUB(SECOID_AlgorithmIDTemplate) | |
85 | |
86 /* ASN1 Templates for new decoder/encoder */ | |
87 /* | |
88 * Attribute value for PKCS8 entries (static?) | |
89 */ | |
90 const SEC_ASN1Template SECKEY_AttributeTemplate[] = { | |
91 { SEC_ASN1_SEQUENCE, | |
92 0, NULL, sizeof(SECKEYAttribute) }, | |
93 { SEC_ASN1_OBJECT_ID, offsetof(SECKEYAttribute, attrType) }, | |
94 { SEC_ASN1_SET_OF | SEC_ASN1_XTRN, offsetof(SECKEYAttribute, attrValue), | |
95 SEC_ASN1_SUB(SEC_AnyTemplate) }, | |
96 { 0 } | |
97 }; | |
98 | |
99 const SEC_ASN1Template SECKEY_SetOfAttributeTemplate[] = { | |
100 { SEC_ASN1_SET_OF, 0, SECKEY_AttributeTemplate }, | |
101 }; | |
102 | |
103 const SEC_ASN1Template SECKEY_PrivateKeyInfoTemplate[] = { | |
104 { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SECKEYPrivateKeyInfo) }, | |
105 { SEC_ASN1_INTEGER, offsetof(SECKEYPrivateKeyInfo,version) }, | |
106 { SEC_ASN1_INLINE | SEC_ASN1_XTRN, | |
107 offsetof(SECKEYPrivateKeyInfo,algorithm), | |
108 SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) }, | |
109 { SEC_ASN1_OCTET_STRING, offsetof(SECKEYPrivateKeyInfo,privateKey) }, | |
110 { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0, | |
111 offsetof(SECKEYPrivateKeyInfo,attributes), | |
112 SECKEY_SetOfAttributeTemplate }, | |
113 { 0 } | |
114 }; | |
115 | |
116 const SEC_ASN1Template SECKEY_PointerToPrivateKeyInfoTemplate[] = { | |
117 { SEC_ASN1_POINTER, 0, SECKEY_PrivateKeyInfoTemplate } | |
118 }; | |
119 | |
120 const SEC_ASN1Template SECKEY_RSAPrivateKeyExportTemplate[] = { | |
121 { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SECKEYRawPrivateKey) }, | |
122 { SEC_ASN1_INTEGER, offsetof(SECKEYRawPrivateKey,u.rsa.version) }, | |
123 { SEC_ASN1_INTEGER, offsetof(SECKEYRawPrivateKey,u.rsa.modulus) }, | |
124 { SEC_ASN1_INTEGER, offsetof(SECKEYRawPrivateKey,u.rsa.publicExponent) }, | |
125 { SEC_ASN1_INTEGER, offsetof(SECKEYRawPrivateKey,u.rsa.privateExponent) }, | |
126 { SEC_ASN1_INTEGER, offsetof(SECKEYRawPrivateKey,u.rsa.prime1) }, | |
127 { SEC_ASN1_INTEGER, offsetof(SECKEYRawPrivateKey,u.rsa.prime2) }, | |
128 { SEC_ASN1_INTEGER, offsetof(SECKEYRawPrivateKey,u.rsa.exponent1) }, | |
129 { SEC_ASN1_INTEGER, offsetof(SECKEYRawPrivateKey,u.rsa.exponent2) }, | |
130 { SEC_ASN1_INTEGER, offsetof(SECKEYRawPrivateKey,u.rsa.coefficient) }, | |
131 { 0 } | |
132 }; | |
133 | |
134 const SEC_ASN1Template SECKEY_DSAPrivateKeyExportTemplate[] = { | |
135 { SEC_ASN1_INTEGER, offsetof(SECKEYRawPrivateKey,u.dsa.privateValue) }, | |
136 }; | |
137 | |
138 const SEC_ASN1Template SECKEY_DHPrivateKeyExportTemplate[] = { | |
139 { SEC_ASN1_INTEGER, offsetof(SECKEYRawPrivateKey,u.dh.privateValue) }, | |
140 { SEC_ASN1_INTEGER, offsetof(SECKEYRawPrivateKey,u.dh.base) }, | |
141 { SEC_ASN1_INTEGER, offsetof(SECKEYRawPrivateKey,u.dh.prime) }, | |
142 }; | |
143 | |
144 const SEC_ASN1Template SECKEY_EncryptedPrivateKeyInfoTemplate[] = { | |
145 { SEC_ASN1_SEQUENCE, | |
146 0, NULL, sizeof(SECKEYEncryptedPrivateKeyInfo) }, | |
147 { SEC_ASN1_INLINE | SEC_ASN1_XTRN, | |
148 offsetof(SECKEYEncryptedPrivateKeyInfo,algorithm), | |
149 SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) }, | |
150 { SEC_ASN1_OCTET_STRING, | |
151 offsetof(SECKEYEncryptedPrivateKeyInfo,encryptedData) }, | |
152 { 0 } | |
153 }; | |
154 | |
155 const SEC_ASN1Template SECKEY_PointerToEncryptedPrivateKeyInfoTemplate[] = { | |
156 { SEC_ASN1_POINTER, 0, SECKEY_EncryptedPrivateKeyInfoTemplate } | |
157 }; | |
158 | |
159 SEC_ASN1_CHOOSER_IMPLEMENT(SECKEY_EncryptedPrivateKeyInfoTemplate) | |
160 SEC_ASN1_CHOOSER_IMPLEMENT(SECKEY_PointerToEncryptedPrivateKeyInfoTemplate) | |
161 SEC_ASN1_CHOOSER_IMPLEMENT(SECKEY_PrivateKeyInfoTemplate) | |
162 SEC_ASN1_CHOOSER_IMPLEMENT(SECKEY_PointerToPrivateKeyInfoTemplate) | |
163 | |
164 /* | |
165 * See bugzilla bug 125359 | |
166 * Since NSS (via PKCS#11) wants to handle big integers as unsigned ints, | |
167 * all of the templates above that en/decode into integers must be converted | |
168 * from ASN.1's signed integer type. This is done by marking either the | |
169 * source or destination (encoding or decoding, respectively) type as | |
170 * siUnsignedInteger. | |
171 */ | |
172 | |
173 static void | |
174 prepare_rsa_priv_key_export_for_asn1(SECKEYRawPrivateKey *key) | |
175 { | |
176 key->u.rsa.modulus.type = siUnsignedInteger; | |
177 key->u.rsa.publicExponent.type = siUnsignedInteger; | |
178 key->u.rsa.privateExponent.type = siUnsignedInteger; | |
179 key->u.rsa.prime1.type = siUnsignedInteger; | |
180 key->u.rsa.prime2.type = siUnsignedInteger; | |
181 key->u.rsa.exponent1.type = siUnsignedInteger; | |
182 key->u.rsa.exponent2.type = siUnsignedInteger; | |
183 key->u.rsa.coefficient.type = siUnsignedInteger; | |
184 } | |
185 | |
186 static void | |
187 prepare_dsa_priv_key_export_for_asn1(SECKEYRawPrivateKey *key) | |
188 { | |
189 key->u.dsa.privateValue.type = siUnsignedInteger; | |
190 key->u.dsa.params.prime.type = siUnsignedInteger; | |
191 key->u.dsa.params.subPrime.type = siUnsignedInteger; | |
192 key->u.dsa.params.base.type = siUnsignedInteger; | |
193 } | |
194 | |
195 static void | |
196 prepare_dh_priv_key_export_for_asn1(SECKEYRawPrivateKey *key) | |
197 { | |
198 key->u.dh.privateValue.type = siUnsignedInteger; | |
199 key->u.dh.prime.type = siUnsignedInteger; | |
200 key->u.dh.base.type = siUnsignedInteger; | |
201 } | |
202 | |
203 | |
204 SECStatus | |
205 PK11_ImportDERPrivateKeyInfo(PK11SlotInfo *slot, SECItem *derPKI, | |
206 SECItem *nickname, SECItem *publicValue, PRBool isPerm, | |
207 PRBool isPrivate, unsigned int keyUsage, void *wincx) | |
208 { | |
209 return PK11_ImportDERPrivateKeyInfoAndReturnKey(slot, derPKI, | |
210 nickname, publicValue, isPerm, isPrivate, keyUsage, NULL, wincx); | |
211 } | |
212 | |
213 SECStatus | |
214 PK11_ImportDERPrivateKeyInfoAndReturnKey(PK11SlotInfo *slot, SECItem *derPKI, | |
215 SECItem *nickname, SECItem *publicValue, PRBool isPerm, | |
216 PRBool isPrivate, unsigned int keyUsage, SECKEYPrivateKey** privk, | |
217 void *wincx) | |
218 { | |
219 SECKEYPrivateKeyInfo *pki = NULL; | |
220 PRArenaPool *temparena = NULL; | |
221 SECStatus rv = SECFailure; | |
222 | |
223 temparena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); | |
224 if (!temparena) | |
225 return rv; | |
226 pki = PORT_ArenaZNew(temparena, SECKEYPrivateKeyInfo); | |
227 if (!pki) { | |
228 PORT_FreeArena(temparena, PR_FALSE); | |
229 return rv; | |
230 } | |
231 pki->arena = temparena; | |
232 | |
233 rv = SEC_ASN1DecodeItem(pki->arena, pki, SECKEY_PrivateKeyInfoTemplate, | |
234 derPKI); | |
235 if( rv != SECSuccess ) { | |
236 goto finish; | |
237 } | |
238 | |
239 rv = PK11_ImportPrivateKeyInfoAndReturnKey(slot, pki, nickname, | |
240 publicValue, isPerm, isPrivate, keyUsage, privk, wincx); | |
241 | |
242 finish: | |
243 /* this zeroes the key and frees the arena */ | |
244 SECKEY_DestroyPrivateKeyInfo(pki, PR_TRUE /*freeit*/); | |
245 return rv; | |
246 } | |
247 | |
248 SECStatus | |
249 PK11_ImportAndReturnPrivateKey(PK11SlotInfo *slot, SECKEYRawPrivateKey *lpk, | |
250 SECItem *nickname, SECItem *publicValue, PRBool isPerm, | |
251 PRBool isPrivate, unsigned int keyUsage, SECKEYPrivateKey **privk, | |
252 void *wincx) | |
253 { | |
254 CK_BBOOL cktrue = CK_TRUE; | |
255 CK_BBOOL ckfalse = CK_FALSE; | |
256 CK_OBJECT_CLASS keyClass = CKO_PRIVATE_KEY; | |
257 CK_KEY_TYPE keyType = CKK_RSA; | |
258 CK_OBJECT_HANDLE objectID; | |
259 CK_ATTRIBUTE theTemplate[20]; | |
260 int templateCount = 0; | |
261 SECStatus rv = SECFailure; | |
262 CK_ATTRIBUTE *attrs; | |
263 CK_ATTRIBUTE *signedattr = NULL; | |
264 int signedcount = 0; | |
265 CK_ATTRIBUTE *ap; | |
266 SECItem *ck_id = NULL; | |
267 | |
268 attrs = theTemplate; | |
269 | |
270 | |
271 PK11_SETATTRS(attrs, CKA_CLASS, &keyClass, sizeof(keyClass) ); attrs++; | |
272 PK11_SETATTRS(attrs, CKA_KEY_TYPE, &keyType, sizeof(keyType) ); attrs++; | |
273 PK11_SETATTRS(attrs, CKA_TOKEN, isPerm ? &cktrue : &ckfalse, | |
274 sizeof(CK_BBOOL) ); attrs++; | |
275 PK11_SETATTRS(attrs, CKA_SENSITIVE, isPrivate ? &cktrue : &ckfalse, | |
276 sizeof(CK_BBOOL) ); attrs++; | |
277 PK11_SETATTRS(attrs, CKA_PRIVATE, isPrivate ? &cktrue : &ckfalse, | |
278 sizeof(CK_BBOOL) ); attrs++; | |
279 | |
280 switch (lpk->keyType) { | |
281 case rsaKey: | |
282 keyType = CKK_RSA; | |
283 PK11_SETATTRS(attrs, CKA_UNWRAP, (keyUsage & KU_KEY_ENCIPHERMENT) ? | |
284 &cktrue : &ckfalse, sizeof(CK_BBOOL) ); attrs++; | |
285 PK11_SETATTRS(attrs, CKA_DECRYPT, (keyUsage & KU_DATA_ENCIPHERMENT)
? | |
286 &cktrue : &ckfalse, sizeof(CK_BBOOL) ); attrs++; | |
287 PK11_SETATTRS(attrs, CKA_SIGN, (keyUsage & KU_DIGITAL_SIGNATURE) ? | |
288 &cktrue : &ckfalse, sizeof(CK_BBOOL) ); attrs++; | |
289 PK11_SETATTRS(attrs, CKA_SIGN_RECOVER, | |
290 (keyUsage & KU_DIGITAL_SIGNATURE) ? | |
291 &cktrue : &ckfalse, sizeof(CK_BBOOL) ); attrs++; | |
292 ck_id = PK11_MakeIDFromPubKey(&lpk->u.rsa.modulus); | |
293 if (ck_id == NULL) { | |
294 goto loser; | |
295 } | |
296 PK11_SETATTRS(attrs, CKA_ID, ck_id->data,ck_id->len); attrs++; | |
297 if (nickname) { | |
298 PK11_SETATTRS(attrs, CKA_LABEL, nickname->data, nickname->len);
attrs++; | |
299 } | |
300 signedattr = attrs; | |
301 PK11_SETATTRS(attrs, CKA_MODULUS, lpk->u.rsa.modulus.data, | |
302 lpk->u.rsa.modulus.len); attrs++
; | |
303 PK11_SETATTRS(attrs, CKA_PUBLIC_EXPONENT, | |
304 lpk->u.rsa.publicExponent.data, | |
305 lpk->u.rsa.publicExponent.len); attrs++; | |
306 PK11_SETATTRS(attrs, CKA_PRIVATE_EXPONENT, | |
307 lpk->u.rsa.privateExponent.data, | |
308 lpk->u.rsa.privateExponent.len); attrs++; | |
309 PK11_SETATTRS(attrs, CKA_PRIME_1, | |
310 lpk->u.rsa.prime1.data, | |
311 lpk->u.rsa.prime1.len); attrs++; | |
312 PK11_SETATTRS(attrs, CKA_PRIME_2, | |
313 lpk->u.rsa.prime2.data, | |
314 lpk->u.rsa.prime2.len); attrs++; | |
315 PK11_SETATTRS(attrs, CKA_EXPONENT_1, | |
316 lpk->u.rsa.exponent1.data, | |
317 lpk->u.rsa.exponent1.len); attrs++; | |
318 PK11_SETATTRS(attrs, CKA_EXPONENT_2, | |
319 lpk->u.rsa.exponent2.data, | |
320 lpk->u.rsa.exponent2.len); attrs++; | |
321 PK11_SETATTRS(attrs, CKA_COEFFICIENT, | |
322 lpk->u.rsa.coefficient.data, | |
323 lpk->u.rsa.coefficient.len); attrs++; | |
324 break; | |
325 case dsaKey: | |
326 keyType = CKK_DSA; | |
327 /* To make our intenal PKCS #11 module work correctly with | |
328 * our database, we need to pass in the public key value for | |
329 * this dsa key. We have a netscape only CKA_ value to do this. | |
330 * Only send it to internal slots */ | |
331 if( publicValue == NULL ) { | |
332 goto loser; | |
333 } | |
334 if (PK11_IsInternal(slot)) { | |
335 PK11_SETATTRS(attrs, CKA_NETSCAPE_DB, | |
336 publicValue->data, publicValue->len); attrs++; | |
337 } | |
338 PK11_SETATTRS(attrs, CKA_SIGN, &cktrue, sizeof(CK_BBOOL)); attrs++; | |
339 PK11_SETATTRS(attrs, CKA_SIGN_RECOVER, &cktrue, sizeof(CK_BBOOL)); a
ttrs++; | |
340 if(nickname) { | |
341 PK11_SETATTRS(attrs, CKA_LABEL, nickname->data, nickname->len); | |
342 attrs++; | |
343 } | |
344 ck_id = PK11_MakeIDFromPubKey(publicValue); | |
345 if (ck_id == NULL) { | |
346 goto loser; | |
347 } | |
348 PK11_SETATTRS(attrs, CKA_ID, ck_id->data,ck_id->len); attrs++; | |
349 signedattr = attrs; | |
350 PK11_SETATTRS(attrs, CKA_PRIME, lpk->u.dsa.params.prime.data, | |
351 lpk->u.dsa.params.prime.len); attrs++; | |
352 PK11_SETATTRS(attrs,CKA_SUBPRIME,lpk->u.dsa.params.subPrime.data, | |
353 lpk->u.dsa.params.subPrime.len); attrs++; | |
354 PK11_SETATTRS(attrs, CKA_BASE, lpk->u.dsa.params.base.data, | |
355 lpk->u.dsa.params.base.len); attrs++; | |
356 PK11_SETATTRS(attrs, CKA_VALUE, lpk->u.dsa.privateValue.data, | |
357 lpk->u.dsa.privateValue.len); attrs++; | |
358 break; | |
359 case dhKey: | |
360 keyType = CKK_DH; | |
361 /* To make our intenal PKCS #11 module work correctly with | |
362 * our database, we need to pass in the public key value for | |
363 * this dh key. We have a netscape only CKA_ value to do this. | |
364 * Only send it to internal slots */ | |
365 if (PK11_IsInternal(slot)) { | |
366 PK11_SETATTRS(attrs, CKA_NETSCAPE_DB, | |
367 publicValue->data, publicValue->len); attrs++; | |
368 } | |
369 PK11_SETATTRS(attrs, CKA_DERIVE, &cktrue, sizeof(CK_BBOOL)); attrs++
; | |
370 if(nickname) { | |
371 PK11_SETATTRS(attrs, CKA_LABEL, nickname->data, nickname->len); | |
372 attrs++; | |
373 } | |
374 ck_id = PK11_MakeIDFromPubKey(publicValue); | |
375 if (ck_id == NULL) { | |
376 goto loser; | |
377 } | |
378 PK11_SETATTRS(attrs, CKA_ID, ck_id->data,ck_id->len); attrs++; | |
379 signedattr = attrs; | |
380 PK11_SETATTRS(attrs, CKA_PRIME, lpk->u.dh.prime.data, | |
381 lpk->u.dh.prime.len); attrs++; | |
382 PK11_SETATTRS(attrs, CKA_BASE, lpk->u.dh.base.data, | |
383 lpk->u.dh.base.len); attrs++; | |
384 PK11_SETATTRS(attrs, CKA_VALUE, lpk->u.dh.privateValue.data, | |
385 lpk->u.dh.privateValue.len); attrs++; | |
386 break; | |
387 /* what about fortezza??? */ | |
388 default: | |
389 PORT_SetError(SEC_ERROR_BAD_KEY); | |
390 goto loser; | |
391 } | |
392 templateCount = attrs - theTemplate; | |
393 PORT_Assert(templateCount <= sizeof(theTemplate)/sizeof(CK_ATTRIBUTE)); | |
394 PORT_Assert(signedattr != NULL); | |
395 signedcount = attrs - signedattr; | |
396 | |
397 for (ap=signedattr; signedcount; ap++, signedcount--) { | |
398 pk11_SignedToUnsigned(ap); | |
399 } | |
400 | |
401 rv = PK11_CreateNewObject(slot, CK_INVALID_SESSION, | |
402 theTemplate, templateCount, isPerm, &objectID); | |
403 | |
404 /* create and return a SECKEYPrivateKey */ | |
405 if( rv == SECSuccess && privk != NULL) { | |
406 *privk = PK11_MakePrivKey(slot, lpk->keyType, !isPerm, objectID, wincx); | |
407 if( *privk == NULL ) { | |
408 rv = SECFailure; | |
409 } | |
410 } | |
411 loser: | |
412 if (ck_id) { | |
413 SECITEM_ZfreeItem(ck_id, PR_TRUE); | |
414 } | |
415 return rv; | |
416 } | |
417 | |
418 SECStatus | |
419 PK11_ImportPrivateKeyInfoAndReturnKey(PK11SlotInfo *slot, | |
420 SECKEYPrivateKeyInfo *pki, SECItem *nickname, SECItem *publicValue, | |
421 PRBool isPerm, PRBool isPrivate, unsigned int keyUsage, | |
422 SECKEYPrivateKey **privk, void *wincx) | |
423 { | |
424 CK_KEY_TYPE keyType = CKK_RSA; | |
425 SECStatus rv = SECFailure; | |
426 SECKEYRawPrivateKey *lpk = NULL; | |
427 const SEC_ASN1Template *keyTemplate, *paramTemplate; | |
428 void *paramDest = NULL; | |
429 PRArenaPool *arena = NULL; | |
430 | |
431 arena = PORT_NewArena(2048); | |
432 if(!arena) { | |
433 return SECFailure; | |
434 } | |
435 | |
436 /* need to change this to use RSA/DSA keys */ | |
437 lpk = (SECKEYRawPrivateKey *)PORT_ArenaZAlloc(arena, | |
438 sizeof(SECKEYRawPrivateKey)); | |
439 if(lpk == NULL) { | |
440 goto loser; | |
441 } | |
442 lpk->arena = arena; | |
443 | |
444 switch(SECOID_GetAlgorithmTag(&pki->algorithm)) { | |
445 case SEC_OID_PKCS1_RSA_ENCRYPTION: | |
446 prepare_rsa_priv_key_export_for_asn1(lpk); | |
447 keyTemplate = SECKEY_RSAPrivateKeyExportTemplate; | |
448 paramTemplate = NULL; | |
449 paramDest = NULL; | |
450 lpk->keyType = rsaKey; | |
451 keyType = CKK_RSA; | |
452 break; | |
453 case SEC_OID_ANSIX9_DSA_SIGNATURE: | |
454 prepare_dsa_priv_key_export_for_asn1(lpk); | |
455 keyTemplate = SECKEY_DSAPrivateKeyExportTemplate; | |
456 paramTemplate = SECKEY_PQGParamsTemplate; | |
457 paramDest = &(lpk->u.dsa.params); | |
458 lpk->keyType = dsaKey; | |
459 keyType = CKK_DSA; | |
460 break; | |
461 case SEC_OID_X942_DIFFIE_HELMAN_KEY: | |
462 if(!publicValue) { | |
463 goto loser; | |
464 } | |
465 prepare_dh_priv_key_export_for_asn1(lpk); | |
466 keyTemplate = SECKEY_DHPrivateKeyExportTemplate; | |
467 paramTemplate = NULL; | |
468 paramDest = NULL; | |
469 lpk->keyType = dhKey; | |
470 keyType = CKK_DH; | |
471 break; | |
472 | |
473 default: | |
474 keyTemplate = NULL; | |
475 paramTemplate = NULL; | |
476 paramDest = NULL; | |
477 break; | |
478 } | |
479 | |
480 if(!keyTemplate) { | |
481 goto loser; | |
482 } | |
483 | |
484 /* decode the private key and any algorithm parameters */ | |
485 rv = SEC_ASN1DecodeItem(arena, lpk, keyTemplate, &pki->privateKey); | |
486 if(rv != SECSuccess) { | |
487 goto loser; | |
488 } | |
489 if(paramDest && paramTemplate) { | |
490 rv = SEC_ASN1DecodeItem(arena, paramDest, paramTemplate, | |
491 &(pki->algorithm.parameters)); | |
492 if(rv != SECSuccess) { | |
493 goto loser; | |
494 } | |
495 } | |
496 | |
497 rv = PK11_ImportAndReturnPrivateKey(slot,lpk,nickname,publicValue, isPerm, | |
498 isPrivate, keyUsage, privk, wincx); | |
499 | |
500 | |
501 loser: | |
502 if (arena != NULL) { | |
503 PORT_FreeArena(arena, PR_TRUE); | |
504 } | |
505 | |
506 return rv; | |
507 } | |
508 | |
509 SECStatus | |
510 PK11_ImportPrivateKeyInfo(PK11SlotInfo *slot, SECKEYPrivateKeyInfo *pki, | |
511 SECItem *nickname, SECItem *publicValue, PRBool isPerm, | |
512 PRBool isPrivate, unsigned int keyUsage, void *wincx) | |
513 { | |
514 return PK11_ImportPrivateKeyInfoAndReturnKey(slot, pki, nickname, | |
515 publicValue, isPerm, isPrivate, keyUsage, NULL, wincx); | |
516 | |
517 } | |
518 | |
OLD | NEW |