Bug 460926 A11y hierachy is broken on Ubuntu 8.10 (GNOME 2.24), r=Evan.Yan sr=roc
[wine-gecko.git] / security / nss / lib / pk11wrap / pk11pk12.c
bloba90081e20f39af9b07c1c107a9daecb3149423ef
2 /* ***** BEGIN LICENSE BLOCK *****
3 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
5 * The contents of this file are subject to the Mozilla Public License Version
6 * 1.1 (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 * http://www.mozilla.org/MPL/
10 * Software distributed under the License is distributed on an "AS IS" basis,
11 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 * for the specific language governing rights and limitations under the
13 * License.
15 * The Original Code is the Netscape security libraries.
17 * The Initial Developer of the Original Code is
18 * Netscape Communications Corporation.
19 * Portions created by the Initial Developer are Copyright (C) 1994-2000
20 * the Initial Developer. All Rights Reserved.
22 * Contributor(s):
24 * Alternatively, the contents of this file may be used under the terms of
25 * either the GNU General Public License Version 2 or later (the "GPL"), or
26 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27 * in which case the provisions of the GPL or the LGPL are applicable instead
28 * of those above. If you wish to allow use of your version of this file only
29 * under the terms of either the GPL or the LGPL, and not to allow others to
30 * use your version of this file under the terms of the MPL, indicate your
31 * decision by deleting the provisions above and replace them with the notice
32 * and other provisions required by the GPL or the LGPL. If you do not delete
33 * the provisions above, a recipient may use your version of this file under
34 * the terms of any one of the MPL, the GPL or the LGPL.
36 * ***** END LICENSE BLOCK ***** */
38 * This file PKCS #12 fuctions that should really be moved to the
39 * PKCS #12 directory, however we can't do that in a point release
40 * because that will break binary compatibility, so we keep them here for now.
43 #include "seccomon.h"
44 #include "secmod.h"
45 #include "secmodi.h"
46 #include "pkcs11.h"
47 #include "pk11func.h"
48 #include "secitem.h"
49 #include "key.h"
50 #include "secoid.h"
51 #include "secasn1.h"
52 #include "secerr.h"
56 /* These data structures should move to a common .h file shared between the
57 * wrappers and the pkcs 12 code. */
60 ** RSA Raw Private Key structures
63 /* member names from PKCS#1, section 7.2 */
64 struct SECKEYRSAPrivateKeyStr {
65 PRArenaPool * arena;
66 SECItem version;
67 SECItem modulus;
68 SECItem publicExponent;
69 SECItem privateExponent;
70 SECItem prime1;
71 SECItem prime2;
72 SECItem exponent1;
73 SECItem exponent2;
74 SECItem coefficient;
76 typedef struct SECKEYRSAPrivateKeyStr SECKEYRSAPrivateKey;
80 ** DSA Raw Private Key structures
83 struct SECKEYDSAPrivateKeyStr {
84 SECKEYPQGParams params;
85 SECItem privateValue;
87 typedef struct SECKEYDSAPrivateKeyStr SECKEYDSAPrivateKey;
90 ** Diffie-Hellman Raw Private Key structures
91 ** Structure member names suggested by PKCS#3.
93 struct SECKEYDHPrivateKeyStr {
94 PRArenaPool * arena;
95 SECItem prime;
96 SECItem base;
97 SECItem privateValue;
99 typedef struct SECKEYDHPrivateKeyStr SECKEYDHPrivateKey;
102 ** raw private key object
104 struct SECKEYRawPrivateKeyStr {
105 PLArenaPool *arena;
106 KeyType keyType;
107 union {
108 SECKEYRSAPrivateKey rsa;
109 SECKEYDSAPrivateKey dsa;
110 SECKEYDHPrivateKey dh;
111 } u;
113 typedef struct SECKEYRawPrivateKeyStr SECKEYRawPrivateKey;
115 SEC_ASN1_MKSUB(SEC_AnyTemplate)
116 SEC_ASN1_MKSUB(SECOID_AlgorithmIDTemplate)
118 /* ASN1 Templates for new decoder/encoder */
120 * Attribute value for PKCS8 entries (static?)
122 const SEC_ASN1Template SECKEY_AttributeTemplate[] = {
123 { SEC_ASN1_SEQUENCE,
124 0, NULL, sizeof(SECKEYAttribute) },
125 { SEC_ASN1_OBJECT_ID, offsetof(SECKEYAttribute, attrType) },
126 { SEC_ASN1_SET_OF | SEC_ASN1_XTRN, offsetof(SECKEYAttribute, attrValue),
127 SEC_ASN1_SUB(SEC_AnyTemplate) },
128 { 0 }
131 const SEC_ASN1Template SECKEY_SetOfAttributeTemplate[] = {
132 { SEC_ASN1_SET_OF, 0, SECKEY_AttributeTemplate },
135 const SEC_ASN1Template SECKEY_PrivateKeyInfoTemplate[] = {
136 { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SECKEYPrivateKeyInfo) },
137 { SEC_ASN1_INTEGER, offsetof(SECKEYPrivateKeyInfo,version) },
138 { SEC_ASN1_INLINE | SEC_ASN1_XTRN,
139 offsetof(SECKEYPrivateKeyInfo,algorithm),
140 SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
141 { SEC_ASN1_OCTET_STRING, offsetof(SECKEYPrivateKeyInfo,privateKey) },
142 { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0,
143 offsetof(SECKEYPrivateKeyInfo,attributes),
144 SECKEY_SetOfAttributeTemplate },
145 { 0 }
148 const SEC_ASN1Template SECKEY_PointerToPrivateKeyInfoTemplate[] = {
149 { SEC_ASN1_POINTER, 0, SECKEY_PrivateKeyInfoTemplate }
152 const SEC_ASN1Template SECKEY_RSAPrivateKeyExportTemplate[] = {
153 { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SECKEYRawPrivateKey) },
154 { SEC_ASN1_INTEGER, offsetof(SECKEYRawPrivateKey,u.rsa.version) },
155 { SEC_ASN1_INTEGER, offsetof(SECKEYRawPrivateKey,u.rsa.modulus) },
156 { SEC_ASN1_INTEGER, offsetof(SECKEYRawPrivateKey,u.rsa.publicExponent) },
157 { SEC_ASN1_INTEGER, offsetof(SECKEYRawPrivateKey,u.rsa.privateExponent) },
158 { SEC_ASN1_INTEGER, offsetof(SECKEYRawPrivateKey,u.rsa.prime1) },
159 { SEC_ASN1_INTEGER, offsetof(SECKEYRawPrivateKey,u.rsa.prime2) },
160 { SEC_ASN1_INTEGER, offsetof(SECKEYRawPrivateKey,u.rsa.exponent1) },
161 { SEC_ASN1_INTEGER, offsetof(SECKEYRawPrivateKey,u.rsa.exponent2) },
162 { SEC_ASN1_INTEGER, offsetof(SECKEYRawPrivateKey,u.rsa.coefficient) },
163 { 0 }
166 const SEC_ASN1Template SECKEY_DSAPrivateKeyExportTemplate[] = {
167 { SEC_ASN1_INTEGER, offsetof(SECKEYRawPrivateKey,u.dsa.privateValue) },
170 const SEC_ASN1Template SECKEY_DHPrivateKeyExportTemplate[] = {
171 { SEC_ASN1_INTEGER, offsetof(SECKEYRawPrivateKey,u.dh.privateValue) },
172 { SEC_ASN1_INTEGER, offsetof(SECKEYRawPrivateKey,u.dh.base) },
173 { SEC_ASN1_INTEGER, offsetof(SECKEYRawPrivateKey,u.dh.prime) },
176 const SEC_ASN1Template SECKEY_EncryptedPrivateKeyInfoTemplate[] = {
177 { SEC_ASN1_SEQUENCE,
178 0, NULL, sizeof(SECKEYEncryptedPrivateKeyInfo) },
179 { SEC_ASN1_INLINE | SEC_ASN1_XTRN,
180 offsetof(SECKEYEncryptedPrivateKeyInfo,algorithm),
181 SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
182 { SEC_ASN1_OCTET_STRING,
183 offsetof(SECKEYEncryptedPrivateKeyInfo,encryptedData) },
184 { 0 }
187 const SEC_ASN1Template SECKEY_PointerToEncryptedPrivateKeyInfoTemplate[] = {
188 { SEC_ASN1_POINTER, 0, SECKEY_EncryptedPrivateKeyInfoTemplate }
191 SEC_ASN1_CHOOSER_IMPLEMENT(SECKEY_EncryptedPrivateKeyInfoTemplate)
192 SEC_ASN1_CHOOSER_IMPLEMENT(SECKEY_PointerToEncryptedPrivateKeyInfoTemplate)
193 SEC_ASN1_CHOOSER_IMPLEMENT(SECKEY_PrivateKeyInfoTemplate)
194 SEC_ASN1_CHOOSER_IMPLEMENT(SECKEY_PointerToPrivateKeyInfoTemplate)
197 * See bugzilla bug 125359
198 * Since NSS (via PKCS#11) wants to handle big integers as unsigned ints,
199 * all of the templates above that en/decode into integers must be converted
200 * from ASN.1's signed integer type. This is done by marking either the
201 * source or destination (encoding or decoding, respectively) type as
202 * siUnsignedInteger.
205 static void
206 prepare_rsa_priv_key_export_for_asn1(SECKEYRawPrivateKey *key)
208 key->u.rsa.modulus.type = siUnsignedInteger;
209 key->u.rsa.publicExponent.type = siUnsignedInteger;
210 key->u.rsa.privateExponent.type = siUnsignedInteger;
211 key->u.rsa.prime1.type = siUnsignedInteger;
212 key->u.rsa.prime2.type = siUnsignedInteger;
213 key->u.rsa.exponent1.type = siUnsignedInteger;
214 key->u.rsa.exponent2.type = siUnsignedInteger;
215 key->u.rsa.coefficient.type = siUnsignedInteger;
218 static void
219 prepare_dsa_priv_key_export_for_asn1(SECKEYRawPrivateKey *key)
221 key->u.dsa.privateValue.type = siUnsignedInteger;
222 key->u.dsa.params.prime.type = siUnsignedInteger;
223 key->u.dsa.params.subPrime.type = siUnsignedInteger;
224 key->u.dsa.params.base.type = siUnsignedInteger;
227 static void
228 prepare_dh_priv_key_export_for_asn1(SECKEYRawPrivateKey *key)
230 key->u.dh.privateValue.type = siUnsignedInteger;
231 key->u.dh.prime.type = siUnsignedInteger;
232 key->u.dh.base.type = siUnsignedInteger;
236 SECStatus
237 PK11_ImportDERPrivateKeyInfo(PK11SlotInfo *slot, SECItem *derPKI,
238 SECItem *nickname, SECItem *publicValue, PRBool isPerm,
239 PRBool isPrivate, unsigned int keyUsage, void *wincx)
241 return PK11_ImportDERPrivateKeyInfoAndReturnKey(slot, derPKI,
242 nickname, publicValue, isPerm, isPrivate, keyUsage, NULL, wincx);
245 SECStatus
246 PK11_ImportDERPrivateKeyInfoAndReturnKey(PK11SlotInfo *slot, SECItem *derPKI,
247 SECItem *nickname, SECItem *publicValue, PRBool isPerm,
248 PRBool isPrivate, unsigned int keyUsage, SECKEYPrivateKey** privk,
249 void *wincx)
251 SECKEYPrivateKeyInfo *pki = NULL;
252 PRArenaPool *temparena = NULL;
253 SECStatus rv = SECFailure;
255 temparena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
256 if (!temparena)
257 return rv;
258 pki = PORT_ArenaZNew(temparena, SECKEYPrivateKeyInfo);
259 if (!pki) {
260 PORT_FreeArena(temparena, PR_FALSE);
261 return rv;
263 pki->arena = temparena;
265 rv = SEC_ASN1DecodeItem(pki->arena, pki, SECKEY_PrivateKeyInfoTemplate,
266 derPKI);
267 if( rv != SECSuccess ) {
268 goto finish;
271 rv = PK11_ImportPrivateKeyInfoAndReturnKey(slot, pki, nickname,
272 publicValue, isPerm, isPrivate, keyUsage, privk, wincx);
274 finish:
275 /* this zeroes the key and frees the arena */
276 SECKEY_DestroyPrivateKeyInfo(pki, PR_TRUE /*freeit*/);
277 return rv;
280 SECStatus
281 PK11_ImportAndReturnPrivateKey(PK11SlotInfo *slot, SECKEYRawPrivateKey *lpk,
282 SECItem *nickname, SECItem *publicValue, PRBool isPerm,
283 PRBool isPrivate, unsigned int keyUsage, SECKEYPrivateKey **privk,
284 void *wincx)
286 CK_BBOOL cktrue = CK_TRUE;
287 CK_BBOOL ckfalse = CK_FALSE;
288 CK_OBJECT_CLASS keyClass = CKO_PRIVATE_KEY;
289 CK_KEY_TYPE keyType = CKK_RSA;
290 CK_OBJECT_HANDLE objectID;
291 CK_ATTRIBUTE theTemplate[20];
292 int templateCount = 0;
293 SECStatus rv = SECFailure;
294 PRArenaPool *arena;
295 CK_ATTRIBUTE *attrs;
296 CK_ATTRIBUTE *signedattr = NULL;
297 int signedcount = 0;
298 CK_ATTRIBUTE *ap;
299 SECItem *ck_id = NULL;
301 arena = PORT_NewArena(2048);
302 if(!arena) {
303 return SECFailure;
306 attrs = theTemplate;
309 PK11_SETATTRS(attrs, CKA_CLASS, &keyClass, sizeof(keyClass) ); attrs++;
310 PK11_SETATTRS(attrs, CKA_KEY_TYPE, &keyType, sizeof(keyType) ); attrs++;
311 PK11_SETATTRS(attrs, CKA_TOKEN, isPerm ? &cktrue : &ckfalse,
312 sizeof(CK_BBOOL) ); attrs++;
313 PK11_SETATTRS(attrs, CKA_SENSITIVE, isPrivate ? &cktrue : &ckfalse,
314 sizeof(CK_BBOOL) ); attrs++;
315 PK11_SETATTRS(attrs, CKA_PRIVATE, isPrivate ? &cktrue : &ckfalse,
316 sizeof(CK_BBOOL) ); attrs++;
318 switch (lpk->keyType) {
319 case rsaKey:
320 keyType = CKK_RSA;
321 PK11_SETATTRS(attrs, CKA_UNWRAP, (keyUsage & KU_KEY_ENCIPHERMENT) ?
322 &cktrue : &ckfalse, sizeof(CK_BBOOL) ); attrs++;
323 PK11_SETATTRS(attrs, CKA_DECRYPT, (keyUsage & KU_DATA_ENCIPHERMENT) ?
324 &cktrue : &ckfalse, sizeof(CK_BBOOL) ); attrs++;
325 PK11_SETATTRS(attrs, CKA_SIGN, (keyUsage & KU_DIGITAL_SIGNATURE) ?
326 &cktrue : &ckfalse, sizeof(CK_BBOOL) ); attrs++;
327 PK11_SETATTRS(attrs, CKA_SIGN_RECOVER,
328 (keyUsage & KU_DIGITAL_SIGNATURE) ?
329 &cktrue : &ckfalse, sizeof(CK_BBOOL) ); attrs++;
330 ck_id = PK11_MakeIDFromPubKey(&lpk->u.rsa.modulus);
331 if (ck_id == NULL) {
332 goto loser;
334 PK11_SETATTRS(attrs, CKA_ID, ck_id->data,ck_id->len); attrs++;
335 if (nickname) {
336 PK11_SETATTRS(attrs, CKA_LABEL, nickname->data, nickname->len); attrs++;
338 signedattr = attrs;
339 PK11_SETATTRS(attrs, CKA_MODULUS, lpk->u.rsa.modulus.data,
340 lpk->u.rsa.modulus.len); attrs++;
341 PK11_SETATTRS(attrs, CKA_PUBLIC_EXPONENT,
342 lpk->u.rsa.publicExponent.data,
343 lpk->u.rsa.publicExponent.len); attrs++;
344 PK11_SETATTRS(attrs, CKA_PRIVATE_EXPONENT,
345 lpk->u.rsa.privateExponent.data,
346 lpk->u.rsa.privateExponent.len); attrs++;
347 PK11_SETATTRS(attrs, CKA_PRIME_1,
348 lpk->u.rsa.prime1.data,
349 lpk->u.rsa.prime1.len); attrs++;
350 PK11_SETATTRS(attrs, CKA_PRIME_2,
351 lpk->u.rsa.prime2.data,
352 lpk->u.rsa.prime2.len); attrs++;
353 PK11_SETATTRS(attrs, CKA_EXPONENT_1,
354 lpk->u.rsa.exponent1.data,
355 lpk->u.rsa.exponent1.len); attrs++;
356 PK11_SETATTRS(attrs, CKA_EXPONENT_2,
357 lpk->u.rsa.exponent2.data,
358 lpk->u.rsa.exponent2.len); attrs++;
359 PK11_SETATTRS(attrs, CKA_COEFFICIENT,
360 lpk->u.rsa.coefficient.data,
361 lpk->u.rsa.coefficient.len); attrs++;
362 break;
363 case dsaKey:
364 keyType = CKK_DSA;
365 /* To make our intenal PKCS #11 module work correctly with
366 * our database, we need to pass in the public key value for
367 * this dsa key. We have a netscape only CKA_ value to do this.
368 * Only send it to internal slots */
369 if( publicValue == NULL ) {
370 goto loser;
372 if (PK11_IsInternal(slot)) {
373 PK11_SETATTRS(attrs, CKA_NETSCAPE_DB,
374 publicValue->data, publicValue->len); attrs++;
376 PK11_SETATTRS(attrs, CKA_SIGN, &cktrue, sizeof(CK_BBOOL)); attrs++;
377 PK11_SETATTRS(attrs, CKA_SIGN_RECOVER, &cktrue, sizeof(CK_BBOOL)); attrs++;
378 if(nickname) {
379 PK11_SETATTRS(attrs, CKA_LABEL, nickname->data, nickname->len);
380 attrs++;
382 ck_id = PK11_MakeIDFromPubKey(publicValue);
383 if (ck_id == NULL) {
384 goto loser;
386 PK11_SETATTRS(attrs, CKA_ID, ck_id->data,ck_id->len); attrs++;
387 signedattr = attrs;
388 PK11_SETATTRS(attrs, CKA_PRIME, lpk->u.dsa.params.prime.data,
389 lpk->u.dsa.params.prime.len); attrs++;
390 PK11_SETATTRS(attrs,CKA_SUBPRIME,lpk->u.dsa.params.subPrime.data,
391 lpk->u.dsa.params.subPrime.len); attrs++;
392 PK11_SETATTRS(attrs, CKA_BASE, lpk->u.dsa.params.base.data,
393 lpk->u.dsa.params.base.len); attrs++;
394 PK11_SETATTRS(attrs, CKA_VALUE, lpk->u.dsa.privateValue.data,
395 lpk->u.dsa.privateValue.len); attrs++;
396 break;
397 case dhKey:
398 keyType = CKK_DH;
399 /* To make our intenal PKCS #11 module work correctly with
400 * our database, we need to pass in the public key value for
401 * this dh key. We have a netscape only CKA_ value to do this.
402 * Only send it to internal slots */
403 if (PK11_IsInternal(slot)) {
404 PK11_SETATTRS(attrs, CKA_NETSCAPE_DB,
405 publicValue->data, publicValue->len); attrs++;
407 PK11_SETATTRS(attrs, CKA_DERIVE, &cktrue, sizeof(CK_BBOOL)); attrs++;
408 if(nickname) {
409 PK11_SETATTRS(attrs, CKA_LABEL, nickname->data, nickname->len);
410 attrs++;
412 ck_id = PK11_MakeIDFromPubKey(publicValue);
413 if (ck_id == NULL) {
414 goto loser;
416 PK11_SETATTRS(attrs, CKA_ID, ck_id->data,ck_id->len); attrs++;
417 signedattr = attrs;
418 PK11_SETATTRS(attrs, CKA_PRIME, lpk->u.dh.prime.data,
419 lpk->u.dh.prime.len); attrs++;
420 PK11_SETATTRS(attrs, CKA_BASE, lpk->u.dh.base.data,
421 lpk->u.dh.base.len); attrs++;
422 PK11_SETATTRS(attrs, CKA_VALUE, lpk->u.dh.privateValue.data,
423 lpk->u.dh.privateValue.len); attrs++;
424 break;
425 /* what about fortezza??? */
426 default:
427 PORT_SetError(SEC_ERROR_BAD_KEY);
428 goto loser;
430 templateCount = attrs - theTemplate;
431 PORT_Assert(templateCount <= sizeof(theTemplate)/sizeof(CK_ATTRIBUTE));
432 PORT_Assert(signedattr != NULL);
433 signedcount = attrs - signedattr;
435 for (ap=signedattr; signedcount; ap++, signedcount--) {
436 pk11_SignedToUnsigned(ap);
439 rv = PK11_CreateNewObject(slot, CK_INVALID_SESSION,
440 theTemplate, templateCount, isPerm, &objectID);
442 /* create and return a SECKEYPrivateKey */
443 if( rv == SECSuccess && privk != NULL) {
444 *privk = PK11_MakePrivKey(slot, lpk->keyType, !isPerm, objectID, wincx);
445 if( *privk == NULL ) {
446 rv = SECFailure;
449 loser:
450 if (ck_id) {
451 SECITEM_ZfreeItem(ck_id, PR_TRUE);
453 return rv;
456 SECStatus
457 PK11_ImportPrivateKey(PK11SlotInfo *slot, SECKEYRawPrivateKey *lpk,
458 SECItem *nickname, SECItem *publicValue, PRBool isPerm,
459 PRBool isPrivate, unsigned int keyUsage, void *wincx)
461 return PK11_ImportAndReturnPrivateKey(slot, lpk, nickname, publicValue,
462 isPerm, isPrivate, keyUsage, NULL, wincx);
465 SECStatus
466 PK11_ImportPrivateKeyInfoAndReturnKey(PK11SlotInfo *slot,
467 SECKEYPrivateKeyInfo *pki, SECItem *nickname, SECItem *publicValue,
468 PRBool isPerm, PRBool isPrivate, unsigned int keyUsage,
469 SECKEYPrivateKey **privk, void *wincx)
471 CK_KEY_TYPE keyType = CKK_RSA;
472 SECStatus rv = SECFailure;
473 SECKEYRawPrivateKey *lpk = NULL;
474 const SEC_ASN1Template *keyTemplate, *paramTemplate;
475 void *paramDest = NULL;
476 PRArenaPool *arena;
478 arena = PORT_NewArena(2048);
479 if(!arena) {
480 return SECFailure;
483 /* need to change this to use RSA/DSA keys */
484 lpk = (SECKEYRawPrivateKey *)PORT_ArenaZAlloc(arena,
485 sizeof(SECKEYRawPrivateKey));
486 if(lpk == NULL) {
487 goto loser;
489 lpk->arena = arena;
491 switch(SECOID_GetAlgorithmTag(&pki->algorithm)) {
492 case SEC_OID_PKCS1_RSA_ENCRYPTION:
493 prepare_rsa_priv_key_export_for_asn1(lpk);
494 keyTemplate = SECKEY_RSAPrivateKeyExportTemplate;
495 paramTemplate = NULL;
496 paramDest = NULL;
497 lpk->keyType = rsaKey;
498 keyType = CKK_RSA;
499 break;
500 case SEC_OID_ANSIX9_DSA_SIGNATURE:
501 prepare_dsa_priv_key_export_for_asn1(lpk);
502 keyTemplate = SECKEY_DSAPrivateKeyExportTemplate;
503 paramTemplate = SECKEY_PQGParamsTemplate;
504 paramDest = &(lpk->u.dsa.params);
505 lpk->keyType = dsaKey;
506 keyType = CKK_DSA;
507 break;
508 case SEC_OID_X942_DIFFIE_HELMAN_KEY:
509 if(!publicValue) {
510 goto loser;
512 prepare_dh_priv_key_export_for_asn1(lpk);
513 keyTemplate = SECKEY_DHPrivateKeyExportTemplate;
514 paramTemplate = NULL;
515 paramDest = NULL;
516 lpk->keyType = dhKey;
517 keyType = CKK_DH;
518 break;
520 default:
521 keyTemplate = NULL;
522 paramTemplate = NULL;
523 paramDest = NULL;
524 break;
527 if(!keyTemplate) {
528 goto loser;
531 /* decode the private key and any algorithm parameters */
532 rv = SEC_ASN1DecodeItem(arena, lpk, keyTemplate, &pki->privateKey);
533 if(rv != SECSuccess) {
534 goto loser;
536 if(paramDest && paramTemplate) {
537 rv = SEC_ASN1DecodeItem(arena, paramDest, paramTemplate,
538 &(pki->algorithm.parameters));
539 if(rv != SECSuccess) {
540 goto loser;
544 rv = PK11_ImportAndReturnPrivateKey(slot,lpk,nickname,publicValue, isPerm,
545 isPrivate, keyUsage, privk, wincx);
548 loser:
549 if (lpk!= NULL) {
550 PORT_FreeArena(arena, PR_TRUE);
553 return rv;
556 SECStatus
557 PK11_ImportPrivateKeyInfo(PK11SlotInfo *slot, SECKEYPrivateKeyInfo *pki,
558 SECItem *nickname, SECItem *publicValue, PRBool isPerm,
559 PRBool isPrivate, unsigned int keyUsage, void *wincx)
561 return PK11_ImportPrivateKeyInfoAndReturnKey(slot, pki, nickname,
562 publicValue, isPerm, isPrivate, keyUsage, NULL, wincx);