1 /* ***** BEGIN LICENSE BLOCK *****
2 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 * The contents of this file are subject to the Mozilla Public License Version
5 * 1.1 (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 * http://www.mozilla.org/MPL/
9 * Software distributed under the License is distributed on an "AS IS" basis,
10 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
11 * for the specific language governing rights and limitations under the
14 * The Original Code is the Netscape security libraries.
16 * The Initial Developer of the Original Code is
17 * Netscape Communications Corporation.
18 * Portions created by the Initial Developer are Copyright (C) 1994-2000
19 * the Initial Developer. All Rights Reserved.
22 * Dr Stephen Henson <stephen.henson@gemplus.com>
23 * Dr Vipul Gupta <vipul.gupta@sun.com>, and
24 * Douglas Stebila <douglas@stebila.ca>, Sun Microsystems Laboratories
26 * Alternatively, the contents of this file may be used under the terms of
27 * either the GNU General Public License Version 2 or later (the "GPL"), or
28 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
29 * in which case the provisions of the GPL or the LGPL are applicable instead
30 * of those above. If you wish to allow use of your version of this file only
31 * under the terms of either the GPL or the LGPL, and not to allow others to
32 * use your version of this file under the terms of the MPL, indicate your
33 * decision by deleting the provisions above and replace them with the notice
34 * and other provisions required by the GPL or the LGPL. If you do not delete
35 * the provisions above, a recipient may use your version of this file under
36 * the terms of any one of the MPL, the GPL or the LGPL.
38 * ***** END LICENSE BLOCK ***** */
40 * This file contains functions to manage asymetric keys, (public and
63 * import a public key into the desired slot
66 PK11_ImportPublicKey(PK11SlotInfo
*slot
, SECKEYPublicKey
*pubKey
,
69 CK_BBOOL cktrue
= CK_TRUE
;
70 CK_BBOOL ckfalse
= CK_FALSE
;
71 CK_OBJECT_CLASS keyClass
= CKO_PUBLIC_KEY
;
72 CK_KEY_TYPE keyType
= CKK_GENERIC_SECRET
;
73 CK_OBJECT_HANDLE objectID
;
74 CK_ATTRIBUTE theTemplate
[10];
75 CK_ATTRIBUTE
*signedattr
= NULL
;
76 CK_ATTRIBUTE
*attrs
= theTemplate
;
78 int templateCount
= 0;
81 /* if we already have an object in the desired slot, use it */
82 if (!isToken
&& pubKey
->pkcs11Slot
== slot
) {
83 return pubKey
->pkcs11ID
;
86 /* free the existing key */
87 if (pubKey
->pkcs11Slot
!= NULL
) {
88 PK11SlotInfo
*oSlot
= pubKey
->pkcs11Slot
;
89 PK11_EnterSlotMonitor(oSlot
);
90 (void) PK11_GETTAB(oSlot
)->C_DestroyObject(oSlot
->session
,
92 PK11_ExitSlotMonitor(oSlot
);
94 pubKey
->pkcs11Slot
= NULL
;
96 PK11_SETATTRS(attrs
, CKA_CLASS
, &keyClass
, sizeof(keyClass
) ); attrs
++;
97 PK11_SETATTRS(attrs
, CKA_KEY_TYPE
, &keyType
, sizeof(keyType
) ); attrs
++;
98 PK11_SETATTRS(attrs
, CKA_TOKEN
, isToken
? &cktrue
: &ckfalse
,
99 sizeof(CK_BBOOL
) ); attrs
++;
101 /* now import the key */
103 switch (pubKey
->keyType
) {
106 PK11_SETATTRS(attrs
, CKA_WRAP
, &cktrue
, sizeof(CK_BBOOL
) ); attrs
++;
107 PK11_SETATTRS(attrs
, CKA_ENCRYPT
, &cktrue
,
108 sizeof(CK_BBOOL
) ); attrs
++;
109 PK11_SETATTRS(attrs
, CKA_VERIFY
, &cktrue
, sizeof(CK_BBOOL
)); attrs
++;
111 PK11_SETATTRS(attrs
, CKA_MODULUS
, pubKey
->u
.rsa
.modulus
.data
,
112 pubKey
->u
.rsa
.modulus
.len
); attrs
++;
113 PK11_SETATTRS(attrs
, CKA_PUBLIC_EXPONENT
,
114 pubKey
->u
.rsa
.publicExponent
.data
,
115 pubKey
->u
.rsa
.publicExponent
.len
); attrs
++;
119 PK11_SETATTRS(attrs
, CKA_VERIFY
, &cktrue
, sizeof(CK_BBOOL
));attrs
++;
121 PK11_SETATTRS(attrs
, CKA_PRIME
, pubKey
->u
.dsa
.params
.prime
.data
,
122 pubKey
->u
.dsa
.params
.prime
.len
); attrs
++;
123 PK11_SETATTRS(attrs
,CKA_SUBPRIME
,pubKey
->u
.dsa
.params
.subPrime
.data
,
124 pubKey
->u
.dsa
.params
.subPrime
.len
); attrs
++;
125 PK11_SETATTRS(attrs
, CKA_BASE
, pubKey
->u
.dsa
.params
.base
.data
,
126 pubKey
->u
.dsa
.params
.base
.len
); attrs
++;
127 PK11_SETATTRS(attrs
, CKA_VALUE
, pubKey
->u
.dsa
.publicValue
.data
,
128 pubKey
->u
.dsa
.publicValue
.len
); attrs
++;
132 PK11_SETATTRS(attrs
, CKA_VERIFY
, &cktrue
, sizeof(CK_BBOOL
));attrs
++;
134 PK11_SETATTRS(attrs
, CKA_PRIME
,pubKey
->u
.fortezza
.params
.prime
.data
,
135 pubKey
->u
.fortezza
.params
.prime
.len
); attrs
++;
136 PK11_SETATTRS(attrs
,CKA_SUBPRIME
,
137 pubKey
->u
.fortezza
.params
.subPrime
.data
,
138 pubKey
->u
.fortezza
.params
.subPrime
.len
);attrs
++;
139 PK11_SETATTRS(attrs
, CKA_BASE
, pubKey
->u
.fortezza
.params
.base
.data
,
140 pubKey
->u
.fortezza
.params
.base
.len
); attrs
++;
141 PK11_SETATTRS(attrs
, CKA_VALUE
, pubKey
->u
.fortezza
.DSSKey
.data
,
142 pubKey
->u
.fortezza
.DSSKey
.len
); attrs
++;
146 PK11_SETATTRS(attrs
, CKA_DERIVE
, &cktrue
, sizeof(CK_BBOOL
));attrs
++;
148 PK11_SETATTRS(attrs
, CKA_PRIME
, pubKey
->u
.dh
.prime
.data
,
149 pubKey
->u
.dh
.prime
.len
); attrs
++;
150 PK11_SETATTRS(attrs
, CKA_BASE
, pubKey
->u
.dh
.base
.data
,
151 pubKey
->u
.dh
.base
.len
); attrs
++;
152 PK11_SETATTRS(attrs
, CKA_VALUE
, pubKey
->u
.dh
.publicValue
.data
,
153 pubKey
->u
.dh
.publicValue
.len
); attrs
++;
157 PK11_SETATTRS(attrs
, CKA_VERIFY
, &cktrue
, sizeof(CK_BBOOL
));attrs
++;
158 PK11_SETATTRS(attrs
, CKA_DERIVE
, &cktrue
, sizeof(CK_BBOOL
));attrs
++;
160 PK11_SETATTRS(attrs
, CKA_EC_PARAMS
,
161 pubKey
->u
.ec
.DEREncodedParams
.data
,
162 pubKey
->u
.ec
.DEREncodedParams
.len
); attrs
++;
163 PK11_SETATTRS(attrs
, CKA_EC_POINT
, pubKey
->u
.ec
.publicValue
.data
,
164 pubKey
->u
.ec
.publicValue
.len
); attrs
++;
167 PORT_SetError( SEC_ERROR_BAD_KEY
);
168 return CK_INVALID_HANDLE
;
171 templateCount
= attrs
- theTemplate
;
172 signedcount
= attrs
- signedattr
;
173 PORT_Assert(templateCount
<= (sizeof(theTemplate
)/sizeof(CK_ATTRIBUTE
)));
174 for (attrs
=signedattr
; signedcount
; attrs
++, signedcount
--) {
175 pk11_SignedToUnsigned(attrs
);
177 rv
= PK11_CreateNewObject(slot
, CK_INVALID_SESSION
, theTemplate
,
178 templateCount
, isToken
, &objectID
);
179 if ( rv
!= SECSuccess
) {
180 return CK_INVALID_HANDLE
;
184 pubKey
->pkcs11ID
= objectID
;
185 pubKey
->pkcs11Slot
= PK11_ReferenceSlot(slot
);
191 * take an attribute and copy it into a secitem
194 pk11_Attr2SecItem(PRArenaPool
*arena
, CK_ATTRIBUTE
*attr
, SECItem
*item
)
198 (void)SECITEM_AllocItem(arena
, item
, attr
->ulValueLen
);
199 if (item
->data
== NULL
) {
200 return CKR_HOST_MEMORY
;
202 PORT_Memcpy(item
->data
, attr
->pValue
, item
->len
);
207 * extract a public key from a slot and id
210 PK11_ExtractPublicKey(PK11SlotInfo
*slot
,KeyType keyType
,CK_OBJECT_HANDLE id
)
212 CK_OBJECT_CLASS keyClass
= CKO_PUBLIC_KEY
;
214 PRArenaPool
*tmp_arena
;
215 SECKEYPublicKey
*pubKey
;
216 int templateCount
= 0;
217 CK_KEY_TYPE pk11KeyType
;
219 CK_ATTRIBUTE
template[8];
220 CK_ATTRIBUTE
*attrs
= template;
221 CK_ATTRIBUTE
*modulus
,*exponent
,*base
,*prime
,*subprime
,*value
;
222 CK_ATTRIBUTE
*ecparams
;
224 /* if we didn't know the key type, get it */
225 if (keyType
== nullKey
) {
227 pk11KeyType
= PK11_ReadULongAttribute(slot
,id
,CKA_KEY_TYPE
);
228 if (pk11KeyType
== CK_UNAVAILABLE_INFORMATION
) {
231 switch (pk11KeyType
) {
245 PORT_SetError( SEC_ERROR_BAD_KEY
);
251 /* now we need to create space for the public key */
252 arena
= PORT_NewArena( DER_DEFAULT_CHUNKSIZE
);
253 if (arena
== NULL
) return NULL
;
254 tmp_arena
= PORT_NewArena( DER_DEFAULT_CHUNKSIZE
);
255 if (tmp_arena
== NULL
) {
256 PORT_FreeArena (arena
, PR_FALSE
);
261 pubKey
= (SECKEYPublicKey
*)
262 PORT_ArenaZAlloc(arena
, sizeof(SECKEYPublicKey
));
263 if (pubKey
== NULL
) {
264 PORT_FreeArena (arena
, PR_FALSE
);
265 PORT_FreeArena (tmp_arena
, PR_FALSE
);
269 pubKey
->arena
= arena
;
270 pubKey
->keyType
= keyType
;
271 pubKey
->pkcs11Slot
= PK11_ReferenceSlot(slot
);
272 pubKey
->pkcs11ID
= id
;
273 PK11_SETATTRS(attrs
, CKA_CLASS
, &keyClass
,
274 sizeof(keyClass
)); attrs
++;
275 PK11_SETATTRS(attrs
, CKA_KEY_TYPE
, &pk11KeyType
,
276 sizeof(pk11KeyType
) ); attrs
++;
277 switch (pubKey
->keyType
) {
280 PK11_SETATTRS(attrs
, CKA_MODULUS
, NULL
, 0); attrs
++;
282 PK11_SETATTRS(attrs
, CKA_PUBLIC_EXPONENT
, NULL
, 0); attrs
++;
284 templateCount
= attrs
- template;
285 PR_ASSERT(templateCount
<= sizeof(template)/sizeof(CK_ATTRIBUTE
));
286 crv
= PK11_GetAttributes(tmp_arena
,slot
,id
,template,templateCount
);
287 if (crv
!= CKR_OK
) break;
289 if ((keyClass
!= CKO_PUBLIC_KEY
) || (pk11KeyType
!= CKK_RSA
)) {
290 crv
= CKR_OBJECT_HANDLE_INVALID
;
293 crv
= pk11_Attr2SecItem(arena
,modulus
,&pubKey
->u
.rsa
.modulus
);
294 if (crv
!= CKR_OK
) break;
295 crv
= pk11_Attr2SecItem(arena
,exponent
,&pubKey
->u
.rsa
.publicExponent
);
296 if (crv
!= CKR_OK
) break;
300 PK11_SETATTRS(attrs
, CKA_PRIME
, NULL
, 0); attrs
++;
302 PK11_SETATTRS(attrs
, CKA_SUBPRIME
, NULL
, 0); attrs
++;
304 PK11_SETATTRS(attrs
, CKA_BASE
, NULL
, 0); attrs
++;
306 PK11_SETATTRS(attrs
, CKA_VALUE
, NULL
, 0); attrs
++;
307 templateCount
= attrs
- template;
308 PR_ASSERT(templateCount
<= sizeof(template)/sizeof(CK_ATTRIBUTE
));
309 crv
= PK11_GetAttributes(tmp_arena
,slot
,id
,template,templateCount
);
310 if (crv
!= CKR_OK
) break;
312 if ((keyClass
!= CKO_PUBLIC_KEY
) || (pk11KeyType
!= CKK_DSA
)) {
313 crv
= CKR_OBJECT_HANDLE_INVALID
;
316 crv
= pk11_Attr2SecItem(arena
,prime
,&pubKey
->u
.dsa
.params
.prime
);
317 if (crv
!= CKR_OK
) break;
318 crv
= pk11_Attr2SecItem(arena
,subprime
,&pubKey
->u
.dsa
.params
.subPrime
);
319 if (crv
!= CKR_OK
) break;
320 crv
= pk11_Attr2SecItem(arena
,base
,&pubKey
->u
.dsa
.params
.base
);
321 if (crv
!= CKR_OK
) break;
322 crv
= pk11_Attr2SecItem(arena
,value
,&pubKey
->u
.dsa
.publicValue
);
323 if (crv
!= CKR_OK
) break;
327 PK11_SETATTRS(attrs
, CKA_PRIME
, NULL
, 0); attrs
++;
329 PK11_SETATTRS(attrs
, CKA_BASE
, NULL
, 0); attrs
++;
331 PK11_SETATTRS(attrs
, CKA_VALUE
, NULL
, 0); attrs
++;
332 templateCount
= attrs
- template;
333 PR_ASSERT(templateCount
<= sizeof(template)/sizeof(CK_ATTRIBUTE
));
334 crv
= PK11_GetAttributes(tmp_arena
,slot
,id
,template,templateCount
);
335 if (crv
!= CKR_OK
) break;
337 if ((keyClass
!= CKO_PUBLIC_KEY
) || (pk11KeyType
!= CKK_DH
)) {
338 crv
= CKR_OBJECT_HANDLE_INVALID
;
341 crv
= pk11_Attr2SecItem(arena
,prime
,&pubKey
->u
.dh
.prime
);
342 if (crv
!= CKR_OK
) break;
343 crv
= pk11_Attr2SecItem(arena
,base
,&pubKey
->u
.dh
.base
);
344 if (crv
!= CKR_OK
) break;
345 crv
= pk11_Attr2SecItem(arena
,value
,&pubKey
->u
.dh
.publicValue
);
346 if (crv
!= CKR_OK
) break;
349 pubKey
->u
.ec
.size
= 0;
351 PK11_SETATTRS(attrs
, CKA_EC_PARAMS
, NULL
, 0); attrs
++;
353 PK11_SETATTRS(attrs
, CKA_EC_POINT
, NULL
, 0); attrs
++;
354 templateCount
= attrs
- template;
355 PR_ASSERT(templateCount
<= sizeof(template)/sizeof(CK_ATTRIBUTE
));
356 crv
= PK11_GetAttributes(tmp_arena
,slot
,id
,template,templateCount
);
357 if (crv
!= CKR_OK
) break;
359 if ((keyClass
!= CKO_PUBLIC_KEY
) || (pk11KeyType
!= CKK_EC
)) {
360 crv
= CKR_OBJECT_HANDLE_INVALID
;
364 crv
= pk11_Attr2SecItem(arena
,ecparams
,
365 &pubKey
->u
.ec
.DEREncodedParams
);
366 if (crv
!= CKR_OK
) break;
367 crv
= pk11_Attr2SecItem(arena
,value
,&pubKey
->u
.ec
.publicValue
);
368 if (crv
!= CKR_OK
) break;
373 crv
= CKR_OBJECT_HANDLE_INVALID
;
377 PORT_FreeArena(tmp_arena
,PR_FALSE
);
380 PORT_FreeArena(arena
,PR_FALSE
);
382 PORT_SetError( PK11_MapError(crv
) );
390 * Build a Private Key structure from raw PKCS #11 information.
393 PK11_MakePrivKey(PK11SlotInfo
*slot
, KeyType keyType
,
394 PRBool isTemp
, CK_OBJECT_HANDLE privID
, void *wincx
)
397 SECKEYPrivateKey
*privKey
;
401 /* don't know? look it up */
402 if (keyType
== nullKey
) {
403 CK_KEY_TYPE pk11Type
= CKK_RSA
;
405 pk11Type
= PK11_ReadULongAttribute(slot
,privID
,CKA_KEY_TYPE
);
406 isTemp
= (PRBool
)!PK11_HasAttributeSet(slot
,privID
,CKA_TOKEN
);
408 case CKK_RSA
: keyType
= rsaKey
; break;
409 case CKK_DSA
: keyType
= dsaKey
; break;
410 case CKK_DH
: keyType
= dhKey
; break;
411 case CKK_KEA
: keyType
= fortezzaKey
; break;
412 case CKK_EC
: keyType
= ecKey
; break;
418 /* if the key is private, make sure we are authenticated to the
419 * token before we try to use it */
420 isPrivate
= (PRBool
)PK11_HasAttributeSet(slot
,privID
,CKA_PRIVATE
);
422 rv
= PK11_Authenticate(slot
, PR_TRUE
, wincx
);
423 if (rv
!= SECSuccess
) {
428 /* now we need to create space for the private key */
429 arena
= PORT_NewArena( DER_DEFAULT_CHUNKSIZE
);
430 if (arena
== NULL
) return NULL
;
432 privKey
= (SECKEYPrivateKey
*)
433 PORT_ArenaZAlloc(arena
, sizeof(SECKEYPrivateKey
));
434 if (privKey
== NULL
) {
435 PORT_FreeArena(arena
, PR_FALSE
);
439 privKey
->arena
= arena
;
440 privKey
->keyType
= keyType
;
441 privKey
->pkcs11Slot
= PK11_ReferenceSlot(slot
);
442 privKey
->pkcs11ID
= privID
;
443 privKey
->pkcs11IsTemp
= isTemp
;
444 privKey
->wincx
= wincx
;
451 PK11_GetSlotFromPrivateKey(SECKEYPrivateKey
*key
)
453 PK11SlotInfo
*slot
= key
->pkcs11Slot
;
454 slot
= PK11_ReferenceSlot(slot
);
459 * Get the modulus length for raw parsing
462 PK11_GetPrivateModulusLen(SECKEYPrivateKey
*key
)
464 CK_ATTRIBUTE theTemplate
= { CKA_MODULUS
, NULL
, 0 };
465 PK11SlotInfo
*slot
= key
->pkcs11Slot
;
469 switch (key
->keyType
) {
471 crv
= PK11_GetAttributes(NULL
, slot
, key
->pkcs11ID
, &theTemplate
, 1);
473 PORT_SetError( PK11_MapError(crv
) );
476 length
= theTemplate
.ulValueLen
;
477 if ( *(unsigned char *)theTemplate
.pValue
== 0) {
480 if (theTemplate
.pValue
!= NULL
)
481 PORT_Free(theTemplate
.pValue
);
490 if (theTemplate
.pValue
!= NULL
)
491 PORT_Free(theTemplate
.pValue
);
492 PORT_SetError( SEC_ERROR_INVALID_KEY
);
499 * take a private key in one pkcs11 module and load it into another:
500 * NOTE: the source private key is a rare animal... it can't be sensitive.
501 * This is used to do a key gen using one pkcs11 module and storing the
502 * result into another.
504 static SECKEYPrivateKey
*
505 pk11_loadPrivKeyWithFlags(PK11SlotInfo
*slot
,SECKEYPrivateKey
*privKey
,
506 SECKEYPublicKey
*pubKey
, PK11AttrFlags attrFlags
)
508 CK_ATTRIBUTE privTemplate
[] = {
509 /* class must be first */
510 { CKA_CLASS
, NULL
, 0 },
511 { CKA_KEY_TYPE
, NULL
, 0 },
514 { CKA_LABEL
, NULL
, 0 },
515 { CKA_SUBJECT
, NULL
, 0 },
518 { CKA_MODULUS
, NULL
, 0 },
519 { CKA_PRIVATE_EXPONENT
, NULL
, 0 },
520 { CKA_PUBLIC_EXPONENT
, NULL
, 0 },
521 { CKA_PRIME_1
, NULL
, 0 },
522 { CKA_PRIME_2
, NULL
, 0 },
523 { CKA_EXPONENT_1
, NULL
, 0 },
524 { CKA_EXPONENT_2
, NULL
, 0 },
525 { CKA_COEFFICIENT
, NULL
, 0 },
526 /* reserve space for the attributes that may be
527 * specified in attrFlags */
528 { CKA_TOKEN
, NULL
, 0 },
529 { CKA_PRIVATE
, NULL
, 0 },
530 { CKA_MODIFIABLE
, NULL
, 0 },
531 { CKA_SENSITIVE
, NULL
, 0 },
532 { CKA_EXTRACTABLE
, NULL
, 0 },
533 #define NUM_RESERVED_ATTRS 5 /* number of reserved attributes above */
535 CK_BBOOL cktrue
= CK_TRUE
;
536 CK_BBOOL ckfalse
= CK_FALSE
;
537 CK_ATTRIBUTE
*attrs
= NULL
, *ap
;
538 const int templateSize
= sizeof(privTemplate
)/sizeof(privTemplate
[0]);
540 CK_OBJECT_HANDLE objectID
;
545 PRBool token
= ((attrFlags
& PK11_ATTR_TOKEN
) != 0);
547 if (pk11_BadAttrFlags(attrFlags
)) {
548 PORT_SetError(SEC_ERROR_INVALID_ARGS
);
552 for (i
=0; i
< templateSize
; i
++) {
553 if (privTemplate
[i
].type
== CKA_MODULUS
) {
554 attrs
= &privTemplate
[i
];
559 PORT_Assert(attrs
!= NULL
);
561 PORT_SetError(SEC_ERROR_LIBRARY_FAILURE
);
567 switch (privKey
->keyType
) {
569 count
= templateSize
- NUM_RESERVED_ATTRS
;
570 extra_count
= count
- (attrs
- privTemplate
);
573 ap
->type
= CKA_PRIME
; ap
++; count
++; extra_count
++;
574 ap
->type
= CKA_SUBPRIME
; ap
++; count
++; extra_count
++;
575 ap
->type
= CKA_BASE
; ap
++; count
++; extra_count
++;
576 ap
->type
= CKA_VALUE
; ap
++; count
++; extra_count
++;
579 ap
->type
= CKA_PRIME
; ap
++; count
++; extra_count
++;
580 ap
->type
= CKA_BASE
; ap
++; count
++; extra_count
++;
581 ap
->type
= CKA_VALUE
; ap
++; count
++; extra_count
++;
584 ap
->type
= CKA_EC_PARAMS
; ap
++; count
++; extra_count
++;
585 ap
->type
= CKA_VALUE
; ap
++; count
++; extra_count
++;
594 PORT_SetError(SEC_ERROR_LIBRARY_FAILURE
);
598 arena
= PORT_NewArena( DER_DEFAULT_CHUNKSIZE
);
599 if (arena
== NULL
) return NULL
;
601 * read out the old attributes.
603 crv
= PK11_GetAttributes(arena
, privKey
->pkcs11Slot
, privKey
->pkcs11ID
,
606 PORT_SetError( PK11_MapError(crv
) );
607 PORT_FreeArena(arena
, PR_TRUE
);
611 /* Set token, private, modifiable, sensitive, and extractable */
612 count
+= pk11_AttrFlagsToAttributes(attrFlags
, &privTemplate
[count
],
615 /* Not everyone can handle zero padded key values, give
616 * them the raw data as unsigned */
617 for (ap
=attrs
; extra_count
; ap
++, extra_count
--) {
618 pk11_SignedToUnsigned(ap
);
621 /* now Store the puppies */
622 rv
= PK11_CreateNewObject(slot
, CK_INVALID_SESSION
, privTemplate
,
623 count
, token
, &objectID
);
624 PORT_FreeArena(arena
, PR_TRUE
);
625 if (rv
!= SECSuccess
) {
629 /* try loading the public key */
631 PK11_ImportPublicKey(slot
, pubKey
, token
);
632 if (pubKey
->pkcs11Slot
) {
633 PK11_FreeSlot(pubKey
->pkcs11Slot
);
634 pubKey
->pkcs11Slot
= NULL
;
635 pubKey
->pkcs11ID
= CK_INVALID_HANDLE
;
639 /* build new key structure */
640 return PK11_MakePrivKey(slot
, privKey
->keyType
, !token
,
641 objectID
, privKey
->wincx
);
644 static SECKEYPrivateKey
*
645 pk11_loadPrivKey(PK11SlotInfo
*slot
,SECKEYPrivateKey
*privKey
,
646 SECKEYPublicKey
*pubKey
, PRBool token
, PRBool sensitive
)
648 PK11AttrFlags attrFlags
= 0;
650 attrFlags
|= (PK11_ATTR_TOKEN
| PK11_ATTR_PRIVATE
);
652 attrFlags
|= (PK11_ATTR_SESSION
| PK11_ATTR_PUBLIC
);
655 attrFlags
|= PK11_ATTR_SENSITIVE
;
657 attrFlags
|= PK11_ATTR_INSENSITIVE
;
659 return pk11_loadPrivKeyWithFlags(slot
, privKey
, pubKey
, attrFlags
);
663 * export this for PSM
666 PK11_LoadPrivKey(PK11SlotInfo
*slot
,SECKEYPrivateKey
*privKey
,
667 SECKEYPublicKey
*pubKey
, PRBool token
, PRBool sensitive
)
669 return pk11_loadPrivKey(slot
,privKey
,pubKey
,token
,sensitive
);
674 * Use the token to generate a key pair.
677 PK11_GenerateKeyPairWithOpFlags(PK11SlotInfo
*slot
,CK_MECHANISM_TYPE type
,
678 void *param
, SECKEYPublicKey
**pubKey
, PK11AttrFlags attrFlags
,
679 CK_FLAGS opFlags
, CK_FLAGS opFlagsMask
, void *wincx
)
681 /* we have to use these native types because when we call PKCS 11 modules
682 * we have to make sure that we are using the correct sizes for all the
684 CK_BBOOL ckfalse
= CK_FALSE
;
685 CK_BBOOL cktrue
= CK_TRUE
;
686 CK_ULONG modulusBits
;
687 CK_BYTE publicExponent
[4];
688 CK_ATTRIBUTE privTemplate
[] = {
689 { CKA_SENSITIVE
, NULL
, 0},
690 { CKA_TOKEN
, NULL
, 0},
691 { CKA_PRIVATE
, NULL
, 0},
692 { CKA_DERIVE
, NULL
, 0},
693 { CKA_UNWRAP
, NULL
, 0},
694 { CKA_SIGN
, NULL
, 0},
695 { CKA_DECRYPT
, NULL
, 0},
696 { CKA_EXTRACTABLE
, NULL
, 0},
697 { CKA_MODIFIABLE
, NULL
, 0},
699 CK_ATTRIBUTE rsaPubTemplate
[] = {
700 { CKA_MODULUS_BITS
, NULL
, 0},
701 { CKA_PUBLIC_EXPONENT
, NULL
, 0},
702 { CKA_TOKEN
, NULL
, 0},
703 { CKA_DERIVE
, NULL
, 0},
704 { CKA_WRAP
, NULL
, 0},
705 { CKA_VERIFY
, NULL
, 0},
706 { CKA_VERIFY_RECOVER
, NULL
, 0},
707 { CKA_ENCRYPT
, NULL
, 0},
708 { CKA_MODIFIABLE
, NULL
, 0},
710 CK_ATTRIBUTE dsaPubTemplate
[] = {
711 { CKA_PRIME
, NULL
, 0 },
712 { CKA_SUBPRIME
, NULL
, 0 },
713 { CKA_BASE
, NULL
, 0 },
714 { CKA_TOKEN
, NULL
, 0},
715 { CKA_DERIVE
, NULL
, 0},
716 { CKA_WRAP
, NULL
, 0},
717 { CKA_VERIFY
, NULL
, 0},
718 { CKA_VERIFY_RECOVER
, NULL
, 0},
719 { CKA_ENCRYPT
, NULL
, 0},
720 { CKA_MODIFIABLE
, NULL
, 0},
722 CK_ATTRIBUTE dhPubTemplate
[] = {
723 { CKA_PRIME
, NULL
, 0 },
724 { CKA_BASE
, NULL
, 0 },
725 { CKA_TOKEN
, NULL
, 0},
726 { CKA_DERIVE
, NULL
, 0},
727 { CKA_WRAP
, NULL
, 0},
728 { CKA_VERIFY
, NULL
, 0},
729 { CKA_VERIFY_RECOVER
, NULL
, 0},
730 { CKA_ENCRYPT
, NULL
, 0},
731 { CKA_MODIFIABLE
, NULL
, 0},
733 CK_ATTRIBUTE ecPubTemplate
[] = {
734 { CKA_EC_PARAMS
, NULL
, 0 },
735 { CKA_TOKEN
, NULL
, 0},
736 { CKA_DERIVE
, NULL
, 0},
737 { CKA_WRAP
, NULL
, 0},
738 { CKA_VERIFY
, NULL
, 0},
739 { CKA_VERIFY_RECOVER
, NULL
, 0},
740 { CKA_ENCRYPT
, NULL
, 0},
741 { CKA_MODIFIABLE
, NULL
, 0},
743 SECKEYECParams
* ecParams
;
745 /*CK_ULONG key_size = 0;*/
746 CK_ATTRIBUTE
*pubTemplate
;
749 PK11RSAGenParams
*rsaParams
;
750 SECKEYPQGParams
*dsaParams
;
751 SECKEYDHParams
* dhParams
;
752 CK_MECHANISM mechanism
;
753 CK_MECHANISM test_mech
;
754 CK_MECHANISM test_mech2
;
755 CK_SESSION_HANDLE session_handle
;
757 CK_OBJECT_HANDLE privID
,pubID
;
758 SECKEYPrivateKey
*privKey
;
763 CK_ATTRIBUTE
*privattrs
;
764 SECItem
*pubKeyIndex
;
765 CK_ATTRIBUTE setTemplate
;
766 CK_MECHANISM_INFO mechanism_info
;
767 CK_OBJECT_CLASS keyClass
;
769 PRBool haslock
= PR_FALSE
;
770 PRBool pubIsToken
= PR_FALSE
;
771 PRBool token
= ((attrFlags
& PK11_ATTR_TOKEN
) != 0);
772 /* subset of attrFlags applicable to the public key */
773 PK11AttrFlags pubKeyAttrFlags
= attrFlags
&
774 (PK11_ATTR_TOKEN
| PK11_ATTR_SESSION
775 | PK11_ATTR_MODIFIABLE
| PK11_ATTR_UNMODIFIABLE
);
777 if (pk11_BadAttrFlags(attrFlags
)) {
778 PORT_SetError( SEC_ERROR_INVALID_ARGS
);
783 * The opFlags and opFlagMask parameters allow us to control the
784 * settings of the key usage attributes (CKA_ENCRYPT and friends).
785 * opFlagMask is set to one if the flag is specified in opFlags and
786 * zero if it is to take on a default value calculated by
787 * PK11_GenerateKeyPairWithOpFlags.
788 * opFlags specifies the actual value of the flag 1 or 0.
789 * Bits not corresponding to one bits in opFlagMask should be zero.
792 /* if we are trying to turn on a flag, it better be in the mask */
793 PORT_Assert ((opFlags
& ~opFlagsMask
) == 0);
794 opFlags
&= opFlagsMask
;
796 PORT_Assert(slot
!= NULL
);
798 PORT_SetError( SEC_ERROR_NO_MODULE
);
802 /* if our slot really doesn't do this mechanism, Generate the key
803 * in our internal token and write it out */
804 if (!PK11_DoesMechanism(slot
,type
)) {
805 PK11SlotInfo
*int_slot
= PK11_GetInternalSlot();
807 /* don't loop forever looking for a slot */
808 if (slot
== int_slot
) {
809 PK11_FreeSlot(int_slot
);
810 PORT_SetError(SEC_ERROR_LIBRARY_FAILURE
);
814 /* if there isn't a suitable slot, then we can't do the keygen */
815 if (int_slot
== NULL
) {
816 PORT_SetError( SEC_ERROR_NO_MODULE
);
820 /* generate the temporary key to load */
821 privKey
= PK11_GenerateKeyPair(int_slot
,type
, param
, pubKey
, PR_FALSE
,
823 PK11_FreeSlot(int_slot
);
825 /* if successful, load the temp key into the new token */
826 if (privKey
!= NULL
) {
827 SECKEYPrivateKey
*newPrivKey
= pk11_loadPrivKeyWithFlags(slot
,
828 privKey
,*pubKey
,attrFlags
);
829 SECKEY_DestroyPrivateKey(privKey
);
830 if (newPrivKey
== NULL
) {
831 SECKEY_DestroyPublicKey(*pubKey
);
840 mechanism
.mechanism
= type
;
841 mechanism
.pParameter
= NULL
;
842 mechanism
.ulParameterLen
= 0;
843 test_mech
.pParameter
= NULL
;
844 test_mech
.ulParameterLen
= 0;
845 test_mech2
.mechanism
= CKM_INVALID_MECHANISM
;
846 test_mech2
.pParameter
= NULL
;
847 test_mech2
.ulParameterLen
= 0;
849 /* set up the private key template */
850 privattrs
= privTemplate
;
851 privattrs
+= pk11_AttrFlagsToAttributes(attrFlags
, privattrs
,
854 /* set up the mechanism specific info */
856 case CKM_RSA_PKCS_KEY_PAIR_GEN
:
857 case CKM_RSA_X9_31_KEY_PAIR_GEN
:
858 rsaParams
= (PK11RSAGenParams
*)param
;
859 if (rsaParams
->pe
== 0) {
860 PORT_SetError(SEC_ERROR_INVALID_ARGS
);
863 modulusBits
= rsaParams
->keySizeInBits
;
866 /* convert pe to a PKCS #11 string */
867 for (i
=0; i
< 4; i
++) {
868 if (peCount
|| (rsaParams
->pe
&
869 ((unsigned long)0xff000000L
>> (i
*8)))) {
870 publicExponent
[peCount
] =
871 (CK_BYTE
)((rsaParams
->pe
>> (3-i
)*8) & 0xff);
875 PORT_Assert(peCount
!= 0);
876 attrs
= rsaPubTemplate
;
877 PK11_SETATTRS(attrs
, CKA_MODULUS_BITS
,
878 &modulusBits
, sizeof(modulusBits
)); attrs
++;
879 PK11_SETATTRS(attrs
, CKA_PUBLIC_EXPONENT
,
880 publicExponent
, peCount
);attrs
++;
881 pubTemplate
= rsaPubTemplate
;
883 test_mech
.mechanism
= CKM_RSA_PKCS
;
885 case CKM_DSA_KEY_PAIR_GEN
:
886 dsaParams
= (SECKEYPQGParams
*)param
;
887 attrs
= dsaPubTemplate
;
888 PK11_SETATTRS(attrs
, CKA_PRIME
, dsaParams
->prime
.data
,
889 dsaParams
->prime
.len
); attrs
++;
890 PK11_SETATTRS(attrs
, CKA_SUBPRIME
, dsaParams
->subPrime
.data
,
891 dsaParams
->subPrime
.len
); attrs
++;
892 PK11_SETATTRS(attrs
, CKA_BASE
, dsaParams
->base
.data
,
893 dsaParams
->base
.len
); attrs
++;
894 pubTemplate
= dsaPubTemplate
;
896 test_mech
.mechanism
= CKM_DSA
;
898 case CKM_DH_PKCS_KEY_PAIR_GEN
:
899 dhParams
= (SECKEYDHParams
*)param
;
900 attrs
= dhPubTemplate
;
901 PK11_SETATTRS(attrs
, CKA_PRIME
, dhParams
->prime
.data
,
902 dhParams
->prime
.len
); attrs
++;
903 PK11_SETATTRS(attrs
, CKA_BASE
, dhParams
->base
.data
,
904 dhParams
->base
.len
); attrs
++;
905 pubTemplate
= dhPubTemplate
;
907 test_mech
.mechanism
= CKM_DH_PKCS_DERIVE
;
909 case CKM_EC_KEY_PAIR_GEN
:
910 ecParams
= (SECKEYECParams
*)param
;
911 attrs
= ecPubTemplate
;
912 PK11_SETATTRS(attrs
, CKA_EC_PARAMS
, ecParams
->data
,
913 ecParams
->len
); attrs
++;
914 pubTemplate
= ecPubTemplate
;
917 * ECC supports 2 different mechanism types (unlike RSA, which
918 * supports different usages with the same mechanism).
919 * We may need to query both mechanism types and or the results
920 * together -- but we only do that if either the user has
921 * requested both usages, or not specified any usages.
923 if ((opFlags
& (CKF_SIGN
|CKF_DERIVE
)) == (CKF_SIGN
|CKF_DERIVE
)) {
924 /* We've explicitly turned on both flags, use both mechanism */
925 test_mech
.mechanism
= CKM_ECDH1_DERIVE
;
926 test_mech2
.mechanism
= CKM_ECDSA
;
927 } else if (opFlags
& CKF_SIGN
) {
928 /* just do signing */
929 test_mech
.mechanism
= CKM_ECDSA
;
930 } else if (opFlags
& CKF_DERIVE
) {
932 test_mech
.mechanism
= CKM_ECDH1_DERIVE
;
934 /* neither was specified default to both */
935 test_mech
.mechanism
= CKM_ECDH1_DERIVE
;
936 test_mech2
.mechanism
= CKM_ECDSA
;
940 PORT_SetError( SEC_ERROR_BAD_KEY
);
944 /* now query the slot to find out how "good" a key we can generate */
945 if (!slot
->isThreadSafe
) PK11_EnterSlotMonitor(slot
);
946 crv
= PK11_GETTAB(slot
)->C_GetMechanismInfo(slot
->slotID
,
947 test_mech
.mechanism
,&mechanism_info
);
949 * EC keys are used in multiple different types of mechanism, if we
950 * are using dual use keys, we need to query the second mechanism
953 if (test_mech2
.mechanism
!= CKM_INVALID_MECHANISM
) {
954 CK_MECHANISM_INFO mechanism_info2
;
958 /* the first failed, make sure there is no trash in the
959 * mechanism flags when we or it below */
960 mechanism_info
.flags
= 0;
962 crv2
= PK11_GETTAB(slot
)->C_GetMechanismInfo(slot
->slotID
,
963 test_mech2
.mechanism
, &mechanism_info2
);
964 if (crv2
== CKR_OK
) {
965 crv
= CKR_OK
; /* succeed if either mechnaism info succeeds */
966 /* combine the 2 sets of mechnanism flags */
967 mechanism_info
.flags
|= mechanism_info2
.flags
;
970 if (!slot
->isThreadSafe
) PK11_ExitSlotMonitor(slot
);
971 if ((crv
!= CKR_OK
) || (mechanism_info
.flags
== 0)) {
972 /* must be old module... guess what it should be... */
973 switch (test_mech
.mechanism
) {
975 mechanism_info
.flags
= (CKF_SIGN
| CKF_DECRYPT
|
976 CKF_WRAP
| CKF_VERIFY_RECOVER
| CKF_ENCRYPT
| CKF_WRAP
);
979 mechanism_info
.flags
= CKF_SIGN
| CKF_VERIFY
;
981 case CKM_DH_PKCS_DERIVE
:
982 mechanism_info
.flags
= CKF_DERIVE
;
984 case CKM_ECDH1_DERIVE
:
985 mechanism_info
.flags
= CKF_DERIVE
;
986 if (test_mech2
.mechanism
== CKM_ECDSA
) {
987 mechanism_info
.flags
|= CKF_SIGN
| CKF_VERIFY
;
991 mechanism_info
.flags
= CKF_SIGN
| CKF_VERIFY
;
997 /* now adjust our flags according to the user's key usage passed to us */
998 mechanism_info
.flags
= (mechanism_info
.flags
& (~opFlagsMask
)) | opFlags
;
999 /* set the public key attributes */
1000 attrs
+= pk11_AttrFlagsToAttributes(pubKeyAttrFlags
, attrs
,
1002 PK11_SETATTRS(attrs
, CKA_DERIVE
,
1003 mechanism_info
.flags
& CKF_DERIVE
? &cktrue
: &ckfalse
,
1004 sizeof(CK_BBOOL
)); attrs
++;
1005 PK11_SETATTRS(attrs
, CKA_WRAP
,
1006 mechanism_info
.flags
& CKF_WRAP
? &cktrue
: &ckfalse
,
1007 sizeof(CK_BBOOL
)); attrs
++;
1008 PK11_SETATTRS(attrs
, CKA_VERIFY
,
1009 mechanism_info
.flags
& CKF_VERIFY
? &cktrue
: &ckfalse
,
1010 sizeof(CK_BBOOL
)); attrs
++;
1011 PK11_SETATTRS(attrs
, CKA_VERIFY_RECOVER
,
1012 mechanism_info
.flags
& CKF_VERIFY_RECOVER
? &cktrue
: &ckfalse
,
1013 sizeof(CK_BBOOL
)); attrs
++;
1014 PK11_SETATTRS(attrs
, CKA_ENCRYPT
,
1015 mechanism_info
.flags
& CKF_ENCRYPT
? &cktrue
: &ckfalse
,
1016 sizeof(CK_BBOOL
)); attrs
++;
1017 /* set the private key attributes */
1018 PK11_SETATTRS(privattrs
, CKA_DERIVE
,
1019 mechanism_info
.flags
& CKF_DERIVE
? &cktrue
: &ckfalse
,
1020 sizeof(CK_BBOOL
)); privattrs
++;
1021 PK11_SETATTRS(privattrs
, CKA_UNWRAP
,
1022 mechanism_info
.flags
& CKF_UNWRAP
? &cktrue
: &ckfalse
,
1023 sizeof(CK_BBOOL
)); privattrs
++;
1024 PK11_SETATTRS(privattrs
, CKA_SIGN
,
1025 mechanism_info
.flags
& CKF_SIGN
? &cktrue
: &ckfalse
,
1026 sizeof(CK_BBOOL
)); privattrs
++;
1027 PK11_SETATTRS(privattrs
, CKA_DECRYPT
,
1028 mechanism_info
.flags
& CKF_DECRYPT
? &cktrue
: &ckfalse
,
1029 sizeof(CK_BBOOL
)); privattrs
++;
1032 session_handle
= PK11_GetRWSession(slot
);
1033 haslock
= PK11_RWSessionHasLock(slot
,session_handle
);
1036 session_handle
= slot
->session
;
1037 if (session_handle
!= CK_INVALID_SESSION
)
1038 PK11_EnterSlotMonitor(slot
);
1043 if (session_handle
== CK_INVALID_SESSION
) {
1044 PORT_SetError(SEC_ERROR_BAD_DATA
);
1047 privCount
= privattrs
- privTemplate
;
1048 pubCount
= attrs
- pubTemplate
;
1049 crv
= PK11_GETTAB(slot
)->C_GenerateKeyPair(session_handle
, &mechanism
,
1050 pubTemplate
,pubCount
,privTemplate
,privCount
,&pubID
,&privID
);
1052 if (crv
!= CKR_OK
) {
1054 PK11_RestoreROSession(slot
,session_handle
);
1055 } else PK11_ExitSlotMonitor(slot
);
1056 PORT_SetError( PK11_MapError(crv
) );
1059 /* This locking code is dangerous and needs to be more thought
1060 * out... the real problem is that we're holding the mutex open this long
1062 if (haslock
) { PK11_ExitSlotMonitor(slot
); }
1064 /* swap around the ID's for older PKCS #11 modules */
1065 keyClass
= PK11_ReadULongAttribute(slot
,pubID
,CKA_CLASS
);
1066 if (keyClass
!= CKO_PUBLIC_KEY
) {
1067 CK_OBJECT_HANDLE tmp
= pubID
;
1072 *pubKey
= PK11_ExtractPublicKey(slot
, keyType
, pubID
);
1073 if (*pubKey
== NULL
) {
1075 /* we may have to restore the mutex so it get's exited properly
1076 * in RestoreROSession */
1077 if (haslock
) PK11_EnterSlotMonitor(slot
);
1078 PK11_RestoreROSession(slot
,session_handle
);
1080 PK11_DestroyObject(slot
,pubID
);
1081 PK11_DestroyObject(slot
,privID
);
1085 /* set the ID to the public key so we can find it again */
1088 case CKM_RSA_PKCS_KEY_PAIR_GEN
:
1089 case CKM_RSA_X9_31_KEY_PAIR_GEN
:
1090 pubKeyIndex
= &(*pubKey
)->u
.rsa
.modulus
;
1092 case CKM_DSA_KEY_PAIR_GEN
:
1093 pubKeyIndex
= &(*pubKey
)->u
.dsa
.publicValue
;
1095 case CKM_DH_PKCS_KEY_PAIR_GEN
:
1096 pubKeyIndex
= &(*pubKey
)->u
.dh
.publicValue
;
1098 case CKM_EC_KEY_PAIR_GEN
:
1099 pubKeyIndex
= &(*pubKey
)->u
.ec
.publicValue
;
1102 PORT_Assert(pubKeyIndex
!= NULL
);
1104 cka_id
= PK11_MakeIDFromPubKey(pubKeyIndex
);
1105 pubIsToken
= (PRBool
)PK11_HasAttributeSet(slot
,pubID
, CKA_TOKEN
);
1107 PK11_SETATTRS(&setTemplate
, CKA_ID
, cka_id
->data
, cka_id
->len
);
1109 if (haslock
) { PK11_EnterSlotMonitor(slot
); }
1110 crv
= PK11_GETTAB(slot
)->C_SetAttributeValue(session_handle
, privID
,
1113 if (crv
== CKR_OK
&& pubIsToken
) {
1114 crv
= PK11_GETTAB(slot
)->C_SetAttributeValue(session_handle
, pubID
,
1120 PK11_RestoreROSession(slot
,session_handle
);
1122 PK11_ExitSlotMonitor(slot
);
1124 SECITEM_FreeItem(cka_id
,PR_TRUE
);
1127 if (crv
!= CKR_OK
) {
1128 PK11_DestroyObject(slot
,pubID
);
1129 PK11_DestroyObject(slot
,privID
);
1130 PORT_SetError( PK11_MapError(crv
) );
1135 privKey
= PK11_MakePrivKey(slot
,keyType
,!token
,privID
,wincx
);
1136 if (privKey
== NULL
) {
1137 SECKEY_DestroyPublicKey(*pubKey
);
1138 PK11_DestroyObject(slot
,privID
);
1147 PK11_GenerateKeyPairWithFlags(PK11SlotInfo
*slot
,CK_MECHANISM_TYPE type
,
1148 void *param
, SECKEYPublicKey
**pubKey
, PK11AttrFlags attrFlags
, void *wincx
)
1150 return PK11_GenerateKeyPairWithOpFlags(slot
,type
,param
,pubKey
,attrFlags
,
1155 * Use the token to generate a key pair.
1158 PK11_GenerateKeyPair(PK11SlotInfo
*slot
,CK_MECHANISM_TYPE type
,
1159 void *param
, SECKEYPublicKey
**pubKey
, PRBool token
,
1160 PRBool sensitive
, void *wincx
)
1162 PK11AttrFlags attrFlags
= 0;
1165 attrFlags
|= PK11_ATTR_TOKEN
;
1167 attrFlags
|= PK11_ATTR_SESSION
;
1170 attrFlags
|= (PK11_ATTR_SENSITIVE
| PK11_ATTR_PRIVATE
);
1172 attrFlags
|= (PK11_ATTR_INSENSITIVE
| PK11_ATTR_PUBLIC
);
1174 return PK11_GenerateKeyPairWithFlags(slot
, type
, param
, pubKey
,
1178 /* build a public KEA key from the public value */
1180 PK11_MakeKEAPubKey(unsigned char *keyData
,int length
)
1182 SECKEYPublicKey
*pubk
;
1187 pkData
.data
= keyData
;
1188 pkData
.len
= length
;
1190 arena
= PORT_NewArena (DER_DEFAULT_CHUNKSIZE
);
1194 pubk
= (SECKEYPublicKey
*) PORT_ArenaZAlloc(arena
, sizeof(SECKEYPublicKey
));
1196 PORT_FreeArena (arena
, PR_FALSE
);
1200 pubk
->arena
= arena
;
1201 pubk
->pkcs11Slot
= 0;
1202 pubk
->pkcs11ID
= CK_INVALID_HANDLE
;
1203 pubk
->keyType
= fortezzaKey
;
1204 rv
= SECITEM_CopyItem(arena
, &pubk
->u
.fortezza
.KEAKey
, &pkData
);
1205 if (rv
!= SECSuccess
) {
1206 PORT_FreeArena (arena
, PR_FALSE
);
1213 PK11_ImportEncryptedPrivateKeyInfo(PK11SlotInfo
*slot
,
1214 SECKEYEncryptedPrivateKeyInfo
*epki
, SECItem
*pwitem
,
1215 SECItem
*nickname
, SECItem
*publicValue
, PRBool isPerm
,
1216 PRBool isPrivate
, KeyType keyType
,
1217 unsigned int keyUsage
, void *wincx
)
1219 CK_MECHANISM_TYPE mechanism
;
1220 SECItem
*pbe_param
, crypto_param
;
1221 PK11SymKey
*key
= NULL
;
1222 SECStatus rv
= SECSuccess
;
1223 CK_MECHANISM cryptoMech
, pbeMech
;
1225 SECKEYPrivateKey
*privKey
= NULL
;
1226 PRBool faulty3DES
= PR_FALSE
;
1228 CK_KEY_TYPE key_type
;
1229 CK_ATTRIBUTE_TYPE
*usage
= NULL
;
1230 CK_ATTRIBUTE_TYPE rsaUsage
[] = {
1231 CKA_UNWRAP
, CKA_DECRYPT
, CKA_SIGN
, CKA_SIGN_RECOVER
};
1232 CK_ATTRIBUTE_TYPE dsaUsage
[] = { CKA_SIGN
};
1233 CK_ATTRIBUTE_TYPE dhUsage
[] = { CKA_DERIVE
};
1234 CK_ATTRIBUTE_TYPE ecUsage
[] = { CKA_SIGN
, CKA_DERIVE
};
1235 if((epki
== NULL
) || (pwitem
== NULL
))
1238 crypto_param
.data
= NULL
;
1240 mechanism
= PK11_AlgtagToMechanism(SECOID_FindOIDTag(
1241 &epki
->algorithm
.algorithm
));
1247 switch (keyUsage
& (KU_KEY_ENCIPHERMENT
|KU_DIGITAL_SIGNATURE
)) {
1248 case KU_KEY_ENCIPHERMENT
:
1252 case KU_DIGITAL_SIGNATURE
:
1253 usage
= &rsaUsage
[2];
1256 case KU_KEY_ENCIPHERMENT
|KU_DIGITAL_SIGNATURE
:
1257 case 0: /* default to everything */
1266 usageCount
= sizeof(dhUsage
)/sizeof(dhUsage
[0]);
1271 usageCount
= sizeof(dsaUsage
)/sizeof(dsaUsage
[0]);
1275 switch (keyUsage
& (KU_DIGITAL_SIGNATURE
|KU_KEY_AGREEMENT
)) {
1276 case KU_DIGITAL_SIGNATURE
:
1280 case KU_KEY_AGREEMENT
:
1281 usage
= &ecUsage
[1];
1284 case KU_DIGITAL_SIGNATURE
|KU_KEY_AGREEMENT
:
1285 default: /* default to everything */
1294 pbe_param
= PK11_ParamFromAlgid(&epki
->algorithm
);
1296 key
= PK11_RawPBEKeyGen(slot
, mechanism
, pbe_param
, pwitem
,
1298 if((key
== NULL
) || (pbe_param
== NULL
)) {
1303 pbeMech
.mechanism
= mechanism
;
1304 pbeMech
.pParameter
= pbe_param
->data
;
1305 pbeMech
.ulParameterLen
= pbe_param
->len
;
1307 crv
= PK11_MapPBEMechanismToCryptoMechanism(&pbeMech
, &cryptoMech
,
1308 pwitem
, faulty3DES
);
1314 cryptoMech
.mechanism
= PK11_GetPadMechanism(cryptoMech
.mechanism
);
1315 crypto_param
.data
= (unsigned char*)cryptoMech
.pParameter
;
1316 crypto_param
.len
= cryptoMech
.ulParameterLen
;
1318 PORT_Assert(usage
!= NULL
);
1319 PORT_Assert(usageCount
!= 0);
1320 privKey
= PK11_UnwrapPrivKey(slot
, key
, cryptoMech
.mechanism
,
1321 &crypto_param
, &epki
->encryptedData
,
1322 nickname
, publicValue
, isPerm
, isPrivate
,
1323 key_type
, usage
, usageCount
, wincx
);
1325 SECKEY_DestroyPrivateKey(privKey
);
1331 /* if we are unable to import the key and the mechanism is
1332 * CKM_NETSCAPE_PBE_SHA1_TRIPLE_DES_CBC, then it is possible that
1333 * the encrypted blob was created with a buggy key generation method
1334 * which is described in the PKCS 12 implementation notes. So we
1335 * need to try importing via that method.
1337 if((mechanism
== CKM_NETSCAPE_PBE_SHA1_TRIPLE_DES_CBC
) && (!faulty3DES
)) {
1338 /* clean up after ourselves before redoing the key generation. */
1340 PK11_FreeSymKey(key
);
1344 SECITEM_ZfreeItem(pbe_param
, PR_TRUE
);
1348 if(crypto_param
.data
) {
1349 SECITEM_ZfreeItem(&crypto_param
, PR_FALSE
);
1350 crypto_param
.data
= NULL
;
1351 cryptoMech
.pParameter
= NULL
;
1352 crypto_param
.len
= cryptoMech
.ulParameterLen
= 0;
1355 faulty3DES
= PR_TRUE
;
1356 goto try_faulty_3des
;
1359 /* key import really did fail */
1363 if(pbe_param
!= NULL
) {
1364 SECITEM_ZfreeItem(pbe_param
, PR_TRUE
);
1368 if(crypto_param
.data
!= NULL
) {
1369 SECITEM_ZfreeItem(&crypto_param
, PR_FALSE
);
1373 PK11_FreeSymKey(key
);
1379 SECKEYPrivateKeyInfo
*
1380 PK11_ExportPrivateKeyInfo(CERTCertificate
*cert
, void *wincx
)
1385 SECKEYEncryptedPrivateKeyInfo
*
1386 PK11_ExportEncryptedPrivKeyInfo(
1387 PK11SlotInfo
*slot
, /* optional, encrypt key in this slot */
1388 SECOidTag algTag
, /* encrypt key with this algorithm */
1389 SECItem
*pwitem
, /* password for PBE encryption */
1390 SECKEYPrivateKey
*pk
, /* encrypt this private key */
1391 int iteration
, /* interations for PBE alg */
1392 void *wincx
) /* context for password callback ? */
1394 SECKEYEncryptedPrivateKeyInfo
*epki
= NULL
;
1395 PRArenaPool
*arena
= NULL
;
1396 SECAlgorithmID
*algid
;
1397 SECItem
*pbe_param
= NULL
;
1398 PK11SymKey
*key
= NULL
;
1399 SECKEYPrivateKey
*tmpPK
= NULL
;
1400 SECStatus rv
= SECSuccess
;
1403 CK_MECHANISM_TYPE mechanism
;
1404 CK_MECHANISM pbeMech
;
1405 CK_MECHANISM cryptoMech
;
1406 SECItem crypto_param
;
1408 if (!pwitem
|| !pk
) {
1409 PORT_SetError(SEC_ERROR_INVALID_ARGS
);
1413 algid
= SEC_PKCS5CreateAlgorithmID(algTag
, NULL
, iteration
);
1414 if (algid
== NULL
) {
1418 crypto_param
.data
= NULL
;
1420 arena
= PORT_NewArena(2048);
1422 epki
= PORT_ArenaZNew(arena
, SECKEYEncryptedPrivateKeyInfo
);
1427 epki
->arena
= arena
;
1429 mechanism
= PK11_AlgtagToMechanism(algTag
);
1430 pbe_param
= PK11_ParamFromAlgid(algid
);
1431 if (!pbe_param
|| mechanism
== CKM_INVALID_MECHANISM
) {
1435 pbeMech
.mechanism
= mechanism
;
1436 pbeMech
.pParameter
= pbe_param
->data
;
1437 pbeMech
.ulParameterLen
= pbe_param
->len
;
1439 /* if we didn't specify a slot, use the slot the private key was in */
1441 slot
= pk
->pkcs11Slot
;
1444 /* if we specified a different slot, and the private key slot can do the
1445 * pbe key gen, generate the key in the private key slot so we don't have
1446 * to move it later */
1447 if (slot
!= pk
->pkcs11Slot
) {
1448 if (PK11_DoesMechanism(pk
->pkcs11Slot
,mechanism
)) {
1449 slot
= pk
->pkcs11Slot
;
1452 key
= PK11_RawPBEKeyGen(slot
, mechanism
, pbe_param
, pwitem
,
1455 if((key
== NULL
) || (pbe_param
== NULL
)) {
1460 crv
= PK11_MapPBEMechanismToCryptoMechanism(&pbeMech
, &cryptoMech
,
1466 cryptoMech
.mechanism
= PK11_GetPadMechanism(cryptoMech
.mechanism
);
1467 crypto_param
.data
= (unsigned char *)cryptoMech
.pParameter
;
1468 crypto_param
.len
= cryptoMech
.ulParameterLen
;
1470 /* If the key isn't in the private key slot, move it */
1471 if (key
->slot
!= pk
->pkcs11Slot
) {
1472 PK11SymKey
*newkey
= pk11_CopyToSlot(pk
->pkcs11Slot
,
1473 key
->type
, CKA_WRAP
, key
);
1474 if (newkey
== NULL
) {
1475 /* couldn't import the wrapping key, try exporting the
1477 tmpPK
= pk11_loadPrivKey(key
->slot
, pk
, NULL
, PR_FALSE
, PR_TRUE
);
1478 if (tmpPK
== NULL
) {
1484 /* free the old key and use the new key */
1485 PK11_FreeSymKey(key
);
1490 /* we are extracting an encrypted privateKey structure.
1491 * which needs to be freed along with the buffer into which it is
1492 * returned. eventually, we should retrieve an encrypted key using
1496 PK11_EnterSlotMonitor(pk
->pkcs11Slot
);
1497 crv
= PK11_GETTAB(pk
->pkcs11Slot
)->C_WrapKey(pk
->pkcs11Slot
->session
,
1498 &cryptoMech
, key
->objectID
, pk
->pkcs11ID
, NULL
,
1500 PK11_ExitSlotMonitor(pk
->pkcs11Slot
);
1501 if (crv
!= CKR_OK
) {
1505 epki
->encryptedData
.data
= PORT_ArenaAlloc(arena
, encBufLen
);
1506 if (!epki
->encryptedData
.data
) {
1510 PK11_EnterSlotMonitor(pk
->pkcs11Slot
);
1511 crv
= PK11_GETTAB(pk
->pkcs11Slot
)->C_WrapKey(pk
->pkcs11Slot
->session
,
1512 &cryptoMech
, key
->objectID
, pk
->pkcs11ID
,
1513 epki
->encryptedData
.data
, &encBufLen
);
1514 PK11_ExitSlotMonitor(pk
->pkcs11Slot
);
1515 epki
->encryptedData
.len
= (unsigned int) encBufLen
;
1521 if(!epki
->encryptedData
.len
) {
1526 rv
= SECOID_CopyAlgorithmID(arena
, &epki
->algorithm
, algid
);
1529 if(pbe_param
!= NULL
) {
1530 SECITEM_ZfreeItem(pbe_param
, PR_TRUE
);
1534 if(crypto_param
.data
!= NULL
) {
1535 SECITEM_ZfreeItem(&crypto_param
, PR_FALSE
);
1536 crypto_param
.data
= NULL
;
1540 PK11_FreeSymKey(key
);
1542 if (tmpPK
!= NULL
) {
1543 SECKEY_DestroyPrivateKey(tmpPK
);
1545 SECOID_DestroyAlgorithmID(algid
, PR_TRUE
);
1547 if(rv
== SECFailure
) {
1549 PORT_FreeArena(arena
, PR_TRUE
);
1557 SECKEYEncryptedPrivateKeyInfo
*
1558 PK11_ExportEncryptedPrivateKeyInfo(
1559 PK11SlotInfo
*slot
, /* optional, encrypt key in this slot */
1560 SECOidTag algTag
, /* encrypt key with this algorithm */
1561 SECItem
*pwitem
, /* password for PBE encryption */
1562 CERTCertificate
*cert
, /* wrap priv key for this user cert */
1563 int iteration
, /* interations for PBE alg */
1564 void *wincx
) /* context for password callback ? */
1566 SECKEYEncryptedPrivateKeyInfo
*epki
= NULL
;
1567 SECKEYPrivateKey
*pk
= PK11_FindKeyByAnyCert(cert
, wincx
);
1569 epki
= PK11_ExportEncryptedPrivKeyInfo(slot
, algTag
, pwitem
, pk
,
1571 SECKEY_DestroyPrivateKey(pk
);
1577 PK11_DEREncodePublicKey(SECKEYPublicKey
*pubk
)
1579 CERTSubjectPublicKeyInfo
*spki
=NULL
;
1580 SECItem
*spkiDER
= NULL
;
1582 if( pubk
== NULL
) {
1586 /* get the subjectpublickeyinfo */
1587 spki
= SECKEY_CreateSubjectPublicKeyInfo(pubk
);
1588 if( spki
== NULL
) {
1592 /* DER-encode the subjectpublickeyinfo */
1593 spkiDER
= SEC_ASN1EncodeItem(NULL
/*arena*/, NULL
/*dest*/, spki
,
1594 CERT_SubjectPublicKeyInfoTemplate
);
1601 PK11_GetPrivateKeyNickname(SECKEYPrivateKey
*privKey
)
1603 return PK11_GetObjectNickname(privKey
->pkcs11Slot
,privKey
->pkcs11ID
);
1607 PK11_GetPublicKeyNickname(SECKEYPublicKey
*pubKey
)
1609 return PK11_GetObjectNickname(pubKey
->pkcs11Slot
,pubKey
->pkcs11ID
);
1613 PK11_SetPrivateKeyNickname(SECKEYPrivateKey
*privKey
, const char *nickname
)
1615 return PK11_SetObjectNickname(privKey
->pkcs11Slot
,
1616 privKey
->pkcs11ID
,nickname
);
1620 PK11_SetPublicKeyNickname(SECKEYPublicKey
*pubKey
, const char *nickname
)
1622 return PK11_SetObjectNickname(pubKey
->pkcs11Slot
,
1623 pubKey
->pkcs11ID
,nickname
);
1627 PK11_GetPQGParamsFromPrivateKey(SECKEYPrivateKey
*privKey
)
1629 CK_ATTRIBUTE pTemplate
[] = {
1630 { CKA_PRIME
, NULL
, 0 },
1631 { CKA_SUBPRIME
, NULL
, 0 },
1632 { CKA_BASE
, NULL
, 0 },
1634 int pTemplateLen
= sizeof(pTemplate
)/sizeof(pTemplate
[0]);
1635 PRArenaPool
*arena
= NULL
;
1636 SECKEYPQGParams
*params
;
1640 arena
= PORT_NewArena(2048);
1641 if (arena
== NULL
) {
1644 params
=(SECKEYPQGParams
*)PORT_ArenaZAlloc(arena
,sizeof(SECKEYPQGParams
));
1645 if (params
== NULL
) {
1649 crv
= PK11_GetAttributes(arena
, privKey
->pkcs11Slot
, privKey
->pkcs11ID
,
1650 pTemplate
, pTemplateLen
);
1651 if (crv
!= CKR_OK
) {
1652 PORT_SetError( PK11_MapError(crv
) );
1656 params
->arena
= arena
;
1657 params
->prime
.data
= pTemplate
[0].pValue
;
1658 params
->prime
.len
= pTemplate
[0].ulValueLen
;
1659 params
->subPrime
.data
= pTemplate
[1].pValue
;
1660 params
->subPrime
.len
= pTemplate
[1].ulValueLen
;
1661 params
->base
.data
= pTemplate
[2].pValue
;
1662 params
->base
.len
= pTemplate
[2].ulValueLen
;
1667 if (arena
!= NULL
) {
1668 PORT_FreeArena(arena
,PR_FALSE
);
1674 PK11_CopyTokenPrivKeyToSessionPrivKey(PK11SlotInfo
*destSlot
,
1675 SECKEYPrivateKey
*privKey
)
1678 CK_OBJECT_HANDLE newKeyID
;
1680 static const CK_BBOOL ckfalse
= CK_FALSE
;
1681 static const CK_ATTRIBUTE
template[1] = {
1682 { CKA_TOKEN
, (CK_BBOOL
*)&ckfalse
, sizeof ckfalse
}
1685 if (destSlot
&& destSlot
!= privKey
->pkcs11Slot
) {
1686 SECKEYPrivateKey
*newKey
=
1687 pk11_loadPrivKey(destSlot
,
1690 PR_FALSE
, /* token */
1691 PR_FALSE
);/* sensitive */
1695 destSlot
= privKey
->pkcs11Slot
;
1696 PK11_Authenticate(destSlot
, PR_TRUE
, privKey
->wincx
);
1697 PK11_EnterSlotMonitor(destSlot
);
1698 crv
= PK11_GETTAB(destSlot
)->C_CopyObject( destSlot
->session
,
1700 (CK_ATTRIBUTE
*)template,
1702 PK11_ExitSlotMonitor(destSlot
);
1704 if (crv
!= CKR_OK
) {
1705 PORT_SetError( PK11_MapError(crv
) );
1709 return PK11_MakePrivKey(destSlot
, privKey
->keyType
, PR_TRUE
/*isTemp*/,
1710 newKeyID
, privKey
->wincx
);
1714 PK11_ConvertSessionPrivKeyToTokenPrivKey(SECKEYPrivateKey
*privk
, void* wincx
)
1716 PK11SlotInfo
* slot
= privk
->pkcs11Slot
;
1717 CK_ATTRIBUTE
template[1];
1718 CK_ATTRIBUTE
*attrs
= template;
1719 CK_BBOOL cktrue
= CK_TRUE
;
1721 CK_OBJECT_HANDLE newKeyID
;
1722 CK_SESSION_HANDLE rwsession
;
1724 PK11_SETATTRS(attrs
, CKA_TOKEN
, &cktrue
, sizeof(cktrue
)); attrs
++;
1726 PK11_Authenticate(slot
, PR_TRUE
, wincx
);
1727 rwsession
= PK11_GetRWSession(slot
);
1728 if (rwsession
== CK_INVALID_SESSION
) {
1729 PORT_SetError(SEC_ERROR_BAD_DATA
);
1732 crv
= PK11_GETTAB(slot
)->C_CopyObject(rwsession
, privk
->pkcs11ID
,
1733 template, 1, &newKeyID
);
1734 PK11_RestoreROSession(slot
, rwsession
);
1736 if (crv
!= CKR_OK
) {
1737 PORT_SetError( PK11_MapError(crv
) );
1741 return PK11_MakePrivKey(slot
, nullKey
/*KeyType*/, PR_FALSE
/*isTemp*/,
1742 newKeyID
, NULL
/*wincx*/);
1746 * destroy a private key if there are no matching certs.
1747 * this function also frees the privKey structure.
1750 PK11_DeleteTokenPrivateKey(SECKEYPrivateKey
*privKey
, PRBool force
)
1752 CERTCertificate
*cert
=PK11_GetCertFromPrivateKey(privKey
);
1753 SECStatus rv
= SECWouldBlock
;
1755 if (!cert
|| force
) {
1756 /* now, then it's safe for the key to go away */
1757 rv
= PK11_DestroyTokenObject(privKey
->pkcs11Slot
,privKey
->pkcs11ID
);
1760 CERT_DestroyCertificate(cert
);
1762 SECKEY_DestroyPrivateKey(privKey
);
1767 * destroy a private key if there are no matching certs.
1768 * this function also frees the privKey structure.
1771 PK11_DeleteTokenPublicKey(SECKEYPublicKey
*pubKey
)
1773 /* now, then it's safe for the key to go away */
1774 if (pubKey
->pkcs11Slot
== NULL
) {
1777 PK11_DestroyTokenObject(pubKey
->pkcs11Slot
,pubKey
->pkcs11ID
);
1778 SECKEY_DestroyPublicKey(pubKey
);
1783 * key call back structure.
1785 typedef struct pk11KeyCallbackStr
{
1786 SECStatus (* callback
)(SECKEYPrivateKey
*,void *);
1792 * callback to map Object Handles to Private Keys;
1795 pk11_DoKeys(PK11SlotInfo
*slot
, CK_OBJECT_HANDLE keyHandle
, void *arg
)
1797 SECStatus rv
= SECSuccess
;
1798 SECKEYPrivateKey
*privKey
;
1799 pk11KeyCallback
*keycb
= (pk11KeyCallback
*) arg
;
1804 privKey
= PK11_MakePrivKey(slot
,nullKey
,PR_TRUE
,keyHandle
,keycb
->wincx
);
1806 if (privKey
== NULL
) {
1810 if (keycb
->callback
) {
1811 rv
= (*keycb
->callback
)(privKey
,keycb
->callbackArg
);
1814 SECKEY_DestroyPrivateKey(privKey
);
1818 /***********************************************************************
1819 * PK11_TraversePrivateKeysInSlot
1821 * Traverses all the private keys on a slot.
1825 * The PKCS #11 slot whose private keys you want to traverse.
1827 * A callback function that will be called for each key.
1829 * An argument that will be passed to the callback function.
1832 PK11_TraversePrivateKeysInSlot( PK11SlotInfo
*slot
,
1833 SECStatus(* callback
)(SECKEYPrivateKey
*, void*), void *arg
)
1835 pk11KeyCallback perKeyCB
;
1836 pk11TraverseSlot perObjectCB
;
1837 CK_OBJECT_CLASS privkClass
= CKO_PRIVATE_KEY
;
1838 CK_BBOOL ckTrue
= CK_TRUE
;
1839 CK_ATTRIBUTE theTemplate
[2];
1840 int templateSize
= 2;
1842 theTemplate
[0].type
= CKA_CLASS
;
1843 theTemplate
[0].pValue
= &privkClass
;
1844 theTemplate
[0].ulValueLen
= sizeof(privkClass
);
1845 theTemplate
[1].type
= CKA_TOKEN
;
1846 theTemplate
[1].pValue
= &ckTrue
;
1847 theTemplate
[1].ulValueLen
= sizeof(ckTrue
);
1853 perObjectCB
.callback
= pk11_DoKeys
;
1854 perObjectCB
.callbackArg
= &perKeyCB
;
1855 perObjectCB
.findTemplate
= theTemplate
;
1856 perObjectCB
.templateCount
= templateSize
;
1857 perKeyCB
.callback
= callback
;
1858 perKeyCB
.callbackArg
= arg
;
1859 perKeyCB
.wincx
= NULL
;
1861 return PK11_TraverseSlot(slot
, &perObjectCB
);
1865 * return the private key with the given ID
1868 pk11_FindPrivateKeyFromCertID(PK11SlotInfo
*slot
, SECItem
*keyID
)
1870 CK_OBJECT_CLASS privKey
= CKO_PRIVATE_KEY
;
1871 CK_ATTRIBUTE theTemplate
[] = {
1872 { CKA_ID
, NULL
, 0 },
1873 { CKA_CLASS
, NULL
, 0 },
1875 /* if you change the array, change the variable below as well */
1876 int tsize
= sizeof(theTemplate
)/sizeof(theTemplate
[0]);
1877 CK_ATTRIBUTE
*attrs
= theTemplate
;
1879 PK11_SETATTRS(attrs
, CKA_ID
, keyID
->data
, keyID
->len
); attrs
++;
1880 PK11_SETATTRS(attrs
, CKA_CLASS
, &privKey
, sizeof(privKey
));
1882 return pk11_FindObjectByTemplate(slot
,theTemplate
,tsize
);
1887 PK11_FindKeyByKeyID(PK11SlotInfo
*slot
, SECItem
*keyID
, void *wincx
)
1889 CK_OBJECT_HANDLE keyHandle
;
1890 SECKEYPrivateKey
*privKey
;
1892 keyHandle
= pk11_FindPrivateKeyFromCertID(slot
, keyID
);
1893 if (keyHandle
== CK_INVALID_HANDLE
) {
1896 privKey
= PK11_MakePrivKey(slot
, nullKey
, PR_TRUE
, keyHandle
, wincx
);
1901 * Generate a CKA_ID from the relevant public key data. The CKA_ID is generated
1902 * from the pubKeyData by SHA1_Hashing it to produce a smaller CKA_ID (to make
1903 * smart cards happy.
1906 PK11_MakeIDFromPubKey(SECItem
*pubKeyData
)
1908 PK11Context
*context
;
1909 SECItem
*certCKA_ID
;
1912 context
= PK11_CreateDigestContext(SEC_OID_SHA1
);
1913 if (context
== NULL
) {
1917 rv
= PK11_DigestBegin(context
);
1918 if (rv
== SECSuccess
) {
1919 rv
= PK11_DigestOp(context
,pubKeyData
->data
,pubKeyData
->len
);
1921 if (rv
!= SECSuccess
) {
1922 PK11_DestroyContext(context
,PR_TRUE
);
1926 certCKA_ID
= (SECItem
*)PORT_Alloc(sizeof(SECItem
));
1927 if (certCKA_ID
== NULL
) {
1928 PK11_DestroyContext(context
,PR_TRUE
);
1932 certCKA_ID
->len
= SHA1_LENGTH
;
1933 certCKA_ID
->data
= (unsigned char*)PORT_Alloc(certCKA_ID
->len
);
1934 if (certCKA_ID
->data
== NULL
) {
1935 PORT_Free(certCKA_ID
);
1936 PK11_DestroyContext(context
,PR_TRUE
);
1940 rv
= PK11_DigestFinal(context
,certCKA_ID
->data
,&certCKA_ID
->len
,
1942 PK11_DestroyContext(context
,PR_TRUE
);
1943 if (rv
!= SECSuccess
) {
1944 SECITEM_FreeItem(certCKA_ID
,PR_TRUE
);
1952 PK11_GetKeyIDFromPrivateKey(SECKEYPrivateKey
*key
, void *wincx
)
1954 CK_ATTRIBUTE theTemplate
[] = {
1955 { CKA_ID
, NULL
, 0 },
1957 int tsize
= sizeof(theTemplate
)/sizeof(theTemplate
[0]);
1958 SECItem
*item
= NULL
;
1961 crv
= PK11_GetAttributes(NULL
,key
->pkcs11Slot
,key
->pkcs11ID
,
1963 if (crv
!= CKR_OK
) {
1964 PORT_SetError( PK11_MapError(crv
) );
1968 item
= PORT_ZNew(SECItem
);
1970 item
->data
= (unsigned char*) theTemplate
[0].pValue
;
1971 item
->len
= theTemplate
[0].ulValueLen
;
1979 PK11_GetLowLevelKeyIDForPrivateKey(SECKEYPrivateKey
*privKey
)
1981 return pk11_GetLowLevelKeyFromHandle(privKey
->pkcs11Slot
,privKey
->pkcs11ID
);
1985 privateKeyListCallback(SECKEYPrivateKey
*key
, void *arg
)
1987 SECKEYPrivateKeyList
*list
= (SECKEYPrivateKeyList
*)arg
;
1988 return SECKEY_AddPrivateKeyToListTail(list
, SECKEY_CopyPrivateKey(key
));
1991 SECKEYPrivateKeyList
*
1992 PK11_ListPrivateKeysInSlot(PK11SlotInfo
*slot
)
1995 SECKEYPrivateKeyList
*keys
;
1997 keys
= SECKEY_NewPrivateKeyList();
1998 if(keys
== NULL
) return NULL
;
2000 status
= PK11_TraversePrivateKeysInSlot(slot
, privateKeyListCallback
,
2003 if( status
!= SECSuccess
) {
2004 SECKEY_DestroyPrivateKeyList(keys
);
2011 SECKEYPublicKeyList
*
2012 PK11_ListPublicKeysInSlot(PK11SlotInfo
*slot
, char *nickname
)
2014 CK_ATTRIBUTE findTemp
[4];
2015 CK_ATTRIBUTE
*attrs
;
2016 CK_BBOOL ckTrue
= CK_TRUE
;
2017 CK_OBJECT_CLASS keyclass
= CKO_PUBLIC_KEY
;
2020 CK_OBJECT_HANDLE
*key_ids
;
2021 SECKEYPublicKeyList
*keys
;
2026 PK11_SETATTRS(attrs
, CKA_CLASS
, &keyclass
, sizeof(keyclass
)); attrs
++;
2027 PK11_SETATTRS(attrs
, CKA_TOKEN
, &ckTrue
, sizeof(ckTrue
)); attrs
++;
2029 len
= PORT_Strlen(nickname
);
2030 PK11_SETATTRS(attrs
, CKA_LABEL
, nickname
, len
); attrs
++;
2032 tsize
= attrs
- findTemp
;
2033 PORT_Assert(tsize
<= sizeof(findTemp
)/sizeof(CK_ATTRIBUTE
));
2035 key_ids
= pk11_FindObjectsByTemplate(slot
,findTemp
,tsize
,&objCount
);
2036 if (key_ids
== NULL
) {
2039 keys
= SECKEY_NewPublicKeyList();
2045 for (i
=0; i
< objCount
; i
++) {
2046 SECKEYPublicKey
*pubKey
=
2047 PK11_ExtractPublicKey(slot
,nullKey
,key_ids
[i
]);
2049 SECKEY_AddPublicKeyToListTail(keys
, pubKey
);
2057 SECKEYPrivateKeyList
*
2058 PK11_ListPrivKeysInSlot(PK11SlotInfo
*slot
, char *nickname
, void *wincx
)
2060 CK_ATTRIBUTE findTemp
[4];
2061 CK_ATTRIBUTE
*attrs
;
2062 CK_BBOOL ckTrue
= CK_TRUE
;
2063 CK_OBJECT_CLASS keyclass
= CKO_PRIVATE_KEY
;
2066 CK_OBJECT_HANDLE
*key_ids
;
2067 SECKEYPrivateKeyList
*keys
;
2072 PK11_SETATTRS(attrs
, CKA_CLASS
, &keyclass
, sizeof(keyclass
)); attrs
++;
2073 PK11_SETATTRS(attrs
, CKA_TOKEN
, &ckTrue
, sizeof(ckTrue
)); attrs
++;
2075 len
= PORT_Strlen(nickname
);
2076 PK11_SETATTRS(attrs
, CKA_LABEL
, nickname
, len
); attrs
++;
2078 tsize
= attrs
- findTemp
;
2079 PORT_Assert(tsize
<= sizeof(findTemp
)/sizeof(CK_ATTRIBUTE
));
2081 key_ids
= pk11_FindObjectsByTemplate(slot
,findTemp
,tsize
,&objCount
);
2082 if (key_ids
== NULL
) {
2085 keys
= SECKEY_NewPrivateKeyList();
2091 for (i
=0; i
< objCount
; i
++) {
2092 SECKEYPrivateKey
*privKey
=
2093 PK11_MakePrivKey(slot
,nullKey
,PR_TRUE
,key_ids
[i
],wincx
);
2094 SECKEY_AddPrivateKeyToListTail(keys
, privKey
);