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
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.
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.
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
{
68 SECItem publicExponent
;
69 SECItem privateExponent
;
76 typedef struct SECKEYRSAPrivateKeyStr SECKEYRSAPrivateKey
;
80 ** DSA Raw Private Key structures
83 struct SECKEYDSAPrivateKeyStr
{
84 SECKEYPQGParams params
;
87 typedef struct SECKEYDSAPrivateKeyStr SECKEYDSAPrivateKey
;
90 ** Diffie-Hellman Raw Private Key structures
91 ** Structure member names suggested by PKCS#3.
93 struct SECKEYDHPrivateKeyStr
{
99 typedef struct SECKEYDHPrivateKeyStr SECKEYDHPrivateKey
;
102 ** raw private key object
104 struct SECKEYRawPrivateKeyStr
{
108 SECKEYRSAPrivateKey rsa
;
109 SECKEYDSAPrivateKey dsa
;
110 SECKEYDHPrivateKey dh
;
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
[] = {
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
) },
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
},
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
) },
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
[] = {
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
) },
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
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
;
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
;
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
;
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
);
246 PK11_ImportDERPrivateKeyInfoAndReturnKey(PK11SlotInfo
*slot
, SECItem
*derPKI
,
247 SECItem
*nickname
, SECItem
*publicValue
, PRBool isPerm
,
248 PRBool isPrivate
, unsigned int keyUsage
, SECKEYPrivateKey
** privk
,
251 SECKEYPrivateKeyInfo
*pki
= NULL
;
252 PRArenaPool
*temparena
= NULL
;
253 SECStatus rv
= SECFailure
;
255 temparena
= PORT_NewArena(DER_DEFAULT_CHUNKSIZE
);
258 pki
= PORT_ArenaZNew(temparena
, SECKEYPrivateKeyInfo
);
260 PORT_FreeArena(temparena
, PR_FALSE
);
263 pki
->arena
= temparena
;
265 rv
= SEC_ASN1DecodeItem(pki
->arena
, pki
, SECKEY_PrivateKeyInfoTemplate
,
267 if( rv
!= SECSuccess
) {
271 rv
= PK11_ImportPrivateKeyInfoAndReturnKey(slot
, pki
, nickname
,
272 publicValue
, isPerm
, isPrivate
, keyUsage
, privk
, wincx
);
275 /* this zeroes the key and frees the arena */
276 SECKEY_DestroyPrivateKeyInfo(pki
, PR_TRUE
/*freeit*/);
281 PK11_ImportAndReturnPrivateKey(PK11SlotInfo
*slot
, SECKEYRawPrivateKey
*lpk
,
282 SECItem
*nickname
, SECItem
*publicValue
, PRBool isPerm
,
283 PRBool isPrivate
, unsigned int keyUsage
, SECKEYPrivateKey
**privk
,
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
;
296 CK_ATTRIBUTE
*signedattr
= NULL
;
299 SECItem
*ck_id
= NULL
;
301 arena
= PORT_NewArena(2048);
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
) {
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
);
334 PK11_SETATTRS(attrs
, CKA_ID
, ck_id
->data
,ck_id
->len
); attrs
++;
336 PK11_SETATTRS(attrs
, CKA_LABEL
, nickname
->data
, nickname
->len
); 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
++;
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
) {
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
++;
379 PK11_SETATTRS(attrs
, CKA_LABEL
, nickname
->data
, nickname
->len
);
382 ck_id
= PK11_MakeIDFromPubKey(publicValue
);
386 PK11_SETATTRS(attrs
, CKA_ID
, ck_id
->data
,ck_id
->len
); 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
++;
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
++;
409 PK11_SETATTRS(attrs
, CKA_LABEL
, nickname
->data
, nickname
->len
);
412 ck_id
= PK11_MakeIDFromPubKey(publicValue
);
416 PK11_SETATTRS(attrs
, CKA_ID
, ck_id
->data
,ck_id
->len
); 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
++;
425 /* what about fortezza??? */
427 PORT_SetError(SEC_ERROR_BAD_KEY
);
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
) {
451 SECITEM_ZfreeItem(ck_id
, PR_TRUE
);
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
);
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
;
478 arena
= PORT_NewArena(2048);
483 /* need to change this to use RSA/DSA keys */
484 lpk
= (SECKEYRawPrivateKey
*)PORT_ArenaZAlloc(arena
,
485 sizeof(SECKEYRawPrivateKey
));
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
;
497 lpk
->keyType
= rsaKey
;
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
;
508 case SEC_OID_X942_DIFFIE_HELMAN_KEY
:
512 prepare_dh_priv_key_export_for_asn1(lpk
);
513 keyTemplate
= SECKEY_DHPrivateKeyExportTemplate
;
514 paramTemplate
= NULL
;
516 lpk
->keyType
= dhKey
;
522 paramTemplate
= NULL
;
531 /* decode the private key and any algorithm parameters */
532 rv
= SEC_ASN1DecodeItem(arena
, lpk
, keyTemplate
, &pki
->privateKey
);
533 if(rv
!= SECSuccess
) {
536 if(paramDest
&& paramTemplate
) {
537 rv
= SEC_ASN1DecodeItem(arena
, paramDest
, paramTemplate
,
538 &(pki
->algorithm
.parameters
));
539 if(rv
!= SECSuccess
) {
544 rv
= PK11_ImportAndReturnPrivateKey(slot
,lpk
,nickname
,publicValue
, isPerm
,
545 isPrivate
, keyUsage
, privk
, wincx
);
550 PORT_FreeArena(arena
, PR_TRUE
);
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
);