4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * NSS keystore wrapper
25 * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
26 * Use is subject to license terms.
29 #include <sys/types.h>
37 /* NSS related headers */
41 #include <mps/certdb.h>
42 #include <mps/secoid.h>
43 #include <mps/secder.h>
44 #include <mps/secerr.h>
45 #include <mps/cryptohi.h>
46 #include <mps/keyhi.h>
47 #include <mps/keythi.h>
48 #include <mps/pk11func.h>
49 #include <mps/pk11pqg.h>
50 #include <mps/pkcs12.h>
51 #include <mps/p12plcy.h>
52 #include <mps/prerror.h>
56 mutex_t init_lock
= DEFAULTMUTEX
;
57 static int nss_initialized
= 0;
60 NSS_ConfigureKeystore(KMF_HANDLE_T
, int, KMF_ATTRIBUTE
*);
63 NSS_FindCert(KMF_HANDLE_T
, int, KMF_ATTRIBUTE
*);
66 NSS_FreeKMFCert(KMF_HANDLE_T
, KMF_X509_DER_CERT
*);
69 NSS_StoreCert(KMF_HANDLE_T
, int, KMF_ATTRIBUTE
*);
72 NSS_ImportCert(KMF_HANDLE_T
, int, KMF_ATTRIBUTE
*);
75 NSS_DeleteCert(KMF_HANDLE_T
, int, KMF_ATTRIBUTE
*);
78 NSS_CreateKeypair(KMF_HANDLE_T
, int, KMF_ATTRIBUTE
*);
81 NSS_StoreKey(KMF_HANDLE_T
, int, KMF_ATTRIBUTE
*);
84 NSS_EncodePubKeyData(KMF_HANDLE_T
, KMF_KEY_HANDLE
*, KMF_DATA
*);
87 NSS_SignData(KMF_HANDLE_T
, KMF_KEY_HANDLE
*, KMF_OID
*,
88 KMF_DATA
*, KMF_DATA
*);
91 NSS_ImportCRL(KMF_HANDLE_T
, int, KMF_ATTRIBUTE
*);
94 NSS_DeleteCRL(KMF_HANDLE_T
, int, KMF_ATTRIBUTE
*);
97 NSS_FindCRL(KMF_HANDLE_T
, int, KMF_ATTRIBUTE
*);
100 NSS_FindKey(KMF_HANDLE_T
, int, KMF_ATTRIBUTE
*);
103 NSS_FindCertInCRL(KMF_HANDLE_T
, int, KMF_ATTRIBUTE
*);
106 NSS_GetErrorString(KMF_HANDLE_T
, char **);
109 NSS_DeleteKey(KMF_HANDLE_T
, int, KMF_ATTRIBUTE
*);
112 NSS_FindPrikeyByCert(KMF_HANDLE_T
, int, KMF_ATTRIBUTE
*);
115 NSS_DecryptData(KMF_HANDLE_T
, KMF_KEY_HANDLE
*, KMF_OID
*,
116 KMF_DATA
*, KMF_DATA
*);
119 NSS_ExportPK12(KMF_HANDLE_T
, int, KMF_ATTRIBUTE
*);
122 NSS_CreateSymKey(KMF_HANDLE_T
, int, KMF_ATTRIBUTE
*);
125 NSS_GetSymKeyValue(KMF_HANDLE_T
, KMF_KEY_HANDLE
*, KMF_RAW_SYM_KEY
*);
128 NSS_SetTokenPin(KMF_HANDLE_T
, int, KMF_ATTRIBUTE
*);
131 KMF_PLUGIN_FUNCLIST nss_plugin_table
=
134 NSS_ConfigureKeystore
,
144 NSS_EncodePubKeyData
,
151 NSS_FindPrikeyByCert
,
161 /* additions for importing and exporting PKCS 12 files */
162 typedef struct p12uContextStr
{
163 char *filename
; /* name of file */
164 PRFileDesc
*file
; /* pointer to file */
165 PRBool error
; /* error occurred? */
166 int errorValue
; /* which error occurred? */
169 #define SET_ERROR(h, c) h->lasterr.kstype = KMF_KEYSTORE_NSS; \
170 h->lasterr.errcode = c;
172 KMF_PLUGIN_FUNCLIST
*
173 KMF_Plugin_Initialize()
175 (void) SEC_PKCS12EnableCipher(PKCS12_RC4_40
, 1);
176 (void) SEC_PKCS12EnableCipher(PKCS12_RC4_128
, 1);
177 (void) SEC_PKCS12EnableCipher(PKCS12_RC2_CBC_40
, 1);
178 (void) SEC_PKCS12EnableCipher(PKCS12_RC2_CBC_128
, 1);
179 (void) SEC_PKCS12EnableCipher(PKCS12_DES_56
, 1);
180 (void) SEC_PKCS12EnableCipher(PKCS12_DES_EDE3_168
, 1);
181 (void) SEC_PKCS12SetPreferredCipher(PKCS12_DES_EDE3_168
, 1);
183 return (&nss_plugin_table
);
188 nss_getpassword(PK11SlotInfo
*slot
, PRBool retry
, void *arg
)
193 return ((char *)strdup(arg
));
199 nss_authenticate(KMF_HANDLE_T handle
,
200 PK11SlotInfo
*nss_slot
, KMF_CREDENTIAL
*cred
)
203 SECStatus nssrv
= SECSuccess
;
204 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
206 /* If a password was given, try to login to the slot */
207 if (cred
== NULL
|| cred
->cred
== NULL
|| cred
->credlen
== 0 ||
209 return (KMF_ERR_BAD_PARAMETER
);
212 if (PK11_IsLoggedIn(nss_slot
, NULL
)) {
216 PK11_SetPasswordFunc(nss_getpassword
);
217 nssrv
= PK11_Authenticate(nss_slot
, PR_TRUE
, (void *)cred
->cred
);
219 if (nssrv
!= SECSuccess
) {
220 SET_ERROR(kmfh
, nssrv
);
221 PK11_FreeSlot(nss_slot
);
222 return (KMF_ERR_AUTH_FAILED
);
229 Init_NSS_DBs(const char *configdir
,
230 const char *certPrefix
,
231 const char *keyPrefix
,
232 const char *secmodName
)
234 SECStatus rv
= NSS_OK
;
236 (void) mutex_lock(&init_lock
);
238 /* If another thread already did it, return OK. */
239 if (nss_initialized
) {
240 (void) mutex_unlock(&init_lock
);
244 rv
= NSS_Initialize((configdir
&& strlen(configdir
)) ?
245 configdir
: "./", certPrefix
, keyPrefix
,
246 secmodName
? secmodName
: "secmod.db", NSS_INIT_COOPERATE
);
247 if (rv
!= SECSuccess
) {
253 (void) mutex_unlock(&init_lock
);
258 * When it is called the first time, it will intialize NSS. Once the NSS
259 * is initialized, this function returns KMF_KEYSTORE_ALREADY_INITIALIZED
260 * if it is called again.
263 NSS_ConfigureKeystore(KMF_HANDLE_T handle
,
264 int numattr
, KMF_ATTRIBUTE
*attrlist
)
266 KMF_RETURN rv
= KMF_OK
;
267 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
273 configdir
= kmf_get_attr_ptr(KMF_DIRPATH_ATTR
, attrlist
, numattr
);
274 certPrefix
= kmf_get_attr_ptr(KMF_CERTPREFIX_ATTR
, attrlist
, numattr
);
275 keyPrefix
= kmf_get_attr_ptr(KMF_KEYPREFIX_ATTR
, attrlist
, numattr
);
276 secModName
= kmf_get_attr_ptr(KMF_SECMODNAME_ATTR
, attrlist
, numattr
);
278 (void) mutex_lock(&init_lock
);
279 if (nss_initialized
== 0) {
282 (void) mutex_unlock(&init_lock
);
283 err
= Init_NSS_DBs(configdir
, certPrefix
,
284 keyPrefix
, secModName
);
285 if (err
!= SECSuccess
) {
286 SET_ERROR(kmfh
, err
);
287 return (KMF_ERR_INTERNAL
);
290 rv
= KMF_KEYSTORE_ALREADY_INITIALIZED
;
291 (void) mutex_unlock(&init_lock
);
298 * This function sets up the slot to be used for other operations.
299 * This function is basically called by every NSS SPI function.
300 * For those functions that can only be performed in the internal slot, the
301 * boolean "internal_slot_only" argument needs to be TRUE.
302 * A slot pointer will be returned when this function is executed successfully.
305 do_nss_init(void *handle
, int numattr
,
306 KMF_ATTRIBUTE
*attrlist
,
307 boolean_t internal_slot_only
,
308 PK11SlotInfo
**nss_slot
)
310 KMF_RETURN rv
= KMF_OK
;
311 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
312 char *slotlabel
= NULL
;
314 if (!nss_initialized
)
315 return (KMF_ERR_PLUGIN_INIT
);
317 slotlabel
= kmf_get_attr_ptr(KMF_TOKEN_LABEL_ATTR
, attrlist
, numattr
);
319 * NSS Is already initialized, but we need to find
322 if (slotlabel
== NULL
||
323 strcmp(slotlabel
, "internal") == 0) {
324 *nss_slot
= PK11_GetInternalKeySlot();
325 } else if (internal_slot_only
== TRUE
) {
326 rv
= KMF_ERR_SLOTNAME
;
329 *nss_slot
= PK11_FindSlotByName(slotlabel
);
332 if (*nss_slot
== NULL
) {
333 SET_ERROR(kmfh
, PORT_GetError());
334 rv
= KMF_ERR_SLOTNAME
;
339 * If the token was not yet initialized, return an error.
341 if (PK11_NeedUserInit(*nss_slot
)) {
342 rv
= KMF_ERR_UNINITIALIZED_TOKEN
;
350 nss2kmf_cert(CERTCertificate
*nss_cert
, KMF_X509_DER_CERT
*kmf_cert
)
352 kmf_cert
->kmf_private
.keystore_type
= KMF_KEYSTORE_NSS
;
353 kmf_cert
->kmf_private
.flags
= KMF_FLAG_CERT_VALID
;
355 kmf_cert
->certificate
.Length
= nss_cert
->derCert
.len
;
357 if ((kmf_cert
->certificate
.Data
= malloc(nss_cert
->derCert
.len
)) ==
359 kmf_cert
->certificate
.Length
= 0;
360 return (KMF_ERR_MEMORY
);
362 (void) memcpy(kmf_cert
->certificate
.Data
, nss_cert
->derCert
.data
,
363 nss_cert
->derCert
.len
);
364 if (nss_cert
->nickname
!= NULL
)
365 kmf_cert
->kmf_private
.label
=
366 (char *)strdup(nss_cert
->nickname
);
371 nss_getcert_by_label(KMF_HANDLE
*kmfh
,
372 char *name
, KMF_X509_DER_CERT
*kmf_cert
,
373 uint32_t *num_certs
, KMF_CERT_VALIDITY find_criteria
)
375 KMF_RETURN rv
= KMF_OK
;
376 CERTCertificate
*nss_cert
;
377 SECCertTimeValidity validity
;
379 nss_cert
= PK11_FindCertFromNickname(name
, NULL
);
380 if (nss_cert
== NULL
) {
382 SET_ERROR(kmfh
, PORT_GetError());
384 return (KMF_ERR_CERT_NOT_FOUND
);
389 switch (find_criteria
) {
392 case KMF_NONEXPIRED_CERTS
:
393 validity
= CERT_CheckCertValidTimes(nss_cert
, PR_Now(),
395 if (validity
!= secCertTimeValid
) {
396 /* this is an invalid cert, reject it */
398 CERT_DestroyCertificate(nss_cert
);
402 case KMF_EXPIRED_CERTS
:
403 validity
= CERT_CheckCertValidTimes(nss_cert
, PR_Now(),
405 if (validity
== secCertTimeValid
) {
406 /* this is a valid cert, reject it in this case. */
408 CERT_DestroyCertificate(nss_cert
);
413 return (KMF_ERR_BAD_PARAMETER
);
416 if (kmf_cert
!= NULL
)
417 rv
= nss2kmf_cert(nss_cert
, kmf_cert
);
419 /* We copied the data we need, so cleanup the internal record */
420 CERT_DestroyCertificate(nss_cert
);
429 nss_find_matching_certs(PK11SlotInfo
*slot
,
430 char *issuer
, char *subject
, KMF_BIGINT
*serial
,
431 CERTCertList
**certlist
, KMF_CERT_VALIDITY find_criteria
)
433 KMF_RETURN rv
= KMF_OK
;
436 CERTCertListNode
*node
;
437 KMF_X509_NAME issuerDN
, subjectDN
;
438 boolean_t findIssuer
= FALSE
;
439 boolean_t findSubject
= FALSE
;
440 boolean_t findSerial
= FALSE
;
442 if (issuer
!= NULL
&& strlen(issuer
)) {
443 rv
= kmf_dn_parser(issuer
, &issuerDN
);
448 if (subject
!= NULL
&& strlen(subject
)) {
449 rv
= kmf_dn_parser(subject
, &subjectDN
);
454 if (serial
!= 0 && serial
->val
!= NULL
&& serial
->len
> 0)
457 list
= PK11_ListCertsInSlot(slot
);
459 node
= CERT_LIST_HEAD(list
);
460 while (!CERT_LIST_END(node
, list
)) {
464 CERTCertListNode
*freenode
;
467 der
.Data
= node
->cert
->derIssuer
.data
;
468 der
.Length
= node
->cert
->derIssuer
.len
;
469 rv
= DerDecodeName(&der
, &cmpDN
);
471 match
= !KMF_CompareRDNs(&issuerDN
,
475 goto delete_and_cont
;
477 goto delete_and_cont
;
481 der
.Data
= node
->cert
->derSubject
.data
;
482 der
.Length
= node
->cert
->derSubject
.len
;
483 rv
= DerDecodeName(&der
, &cmpDN
);
485 match
= !KMF_CompareRDNs(&subjectDN
,
489 goto delete_and_cont
;
491 goto delete_and_cont
;
497 sernum
= &node
->cert
->serialNumber
;
499 if (serial
->len
!= sernum
->len
)
500 goto delete_and_cont
;
502 if (memcmp(sernum
->data
, serial
->val
,
504 goto delete_and_cont
;
507 /* select the certs using find criteria */
508 switch (find_criteria
) {
511 case KMF_NONEXPIRED_CERTS
:
512 ret
= CERT_CertTimesValid(node
->cert
);
513 if (ret
== SECFailure
) {
514 /* this is an invalid cert */
519 case KMF_EXPIRED_CERTS
:
520 ret
= CERT_CertTimesValid(node
->cert
);
521 if (ret
!= SECFailure
) {
522 /* this is a valid cert */
528 node
= CERT_LIST_NEXT(node
);
532 node
= CERT_LIST_NEXT(node
);
533 CERT_RemoveCertListNode(freenode
);
537 if (rv
== KMF_OK
&& certlist
!= NULL
) {
540 CERT_DestroyCertList(list
);
546 convertCertList(void *kmfhandle
,
547 CERTCertList
*nsscerts
, KMF_X509_DER_CERT
*kmfcerts
,
550 KMF_RETURN rv
= KMF_OK
;
551 CERTCertListNode
*node
;
552 uint32_t maxcerts
= *numcerts
;
554 maxcerts
= *numcerts
;
556 maxcerts
= 0xFFFFFFFF;
561 * Don't copy more certs than the caller wanted.
563 for (node
= CERT_LIST_HEAD(nsscerts
);
564 !CERT_LIST_END(node
, nsscerts
) && rv
== KMF_OK
&&
565 (*numcerts
) < maxcerts
;
566 node
= CERT_LIST_NEXT(node
), (*numcerts
)++) {
567 if (kmfcerts
!= NULL
)
568 rv
= nss2kmf_cert(node
->cert
, &kmfcerts
[*numcerts
]);
572 * If we failed, delete any certs allocated so far.
576 for (i
= 0; i
< *numcerts
; i
++)
577 kmf_free_kmf_cert(kmfhandle
, &kmfcerts
[i
]);
585 NSS_FindCert(KMF_HANDLE_T handle
, int numattr
, KMF_ATTRIBUTE
*attrlist
)
587 KMF_RETURN rv
= KMF_OK
;
588 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
589 PK11SlotInfo
*nss_slot
= NULL
;
590 CERTCertList
*certlist
= NULL
;
593 KMF_X509_DER_CERT
*kmfcerts
= NULL
;
594 char *certlabel
= NULL
;
596 char *subject
= NULL
;
597 KMF_BIGINT
*serial
= NULL
;
598 KMF_CERT_VALIDITY validity
;
600 if (handle
== NULL
|| attrlist
== NULL
|| numattr
== 0) {
601 return (KMF_ERR_BAD_PARAMETER
);
603 rv
= do_nss_init(handle
, numattr
, attrlist
, FALSE
, &nss_slot
);
607 num_certs
= kmf_get_attr_ptr(KMF_COUNT_ATTR
, attrlist
, numattr
);
608 if (num_certs
== NULL
)
609 return (KMF_ERR_BAD_PARAMETER
);
611 maxcerts
= *num_certs
;
613 maxcerts
= 0xFFFFFFFF;
616 /* Get the optional returned certificate list */
617 kmfcerts
= kmf_get_attr_ptr(KMF_X509_DER_CERT_ATTR
, attrlist
, numattr
);
619 /* Get optional search criteria attributes */
620 certlabel
= kmf_get_attr_ptr(KMF_CERT_LABEL_ATTR
, attrlist
, numattr
);
621 issuer
= kmf_get_attr_ptr(KMF_ISSUER_NAME_ATTR
, attrlist
, numattr
);
622 subject
= kmf_get_attr_ptr(KMF_SUBJECT_NAME_ATTR
, attrlist
, numattr
);
623 serial
= kmf_get_attr_ptr(KMF_BIGINT_ATTR
, attrlist
, numattr
);
625 rv
= kmf_get_attr(KMF_CERT_VALIDITY_ATTR
, attrlist
, numattr
,
628 validity
= KMF_ALL_CERTS
;
632 if (certlabel
!= NULL
) {
633 /* This will only find 1 certificate */
634 rv
= nss_getcert_by_label(kmfh
, certlabel
, kmfcerts
, num_certs
,
638 * Build a list of matching certs.
640 rv
= nss_find_matching_certs(nss_slot
, issuer
, subject
, serial
,
641 &certlist
, validity
);
644 * If the caller supplied a pointer to storage for
645 * a list of certs, convert up to 'maxcerts' of the
648 if (rv
== KMF_OK
&& certlist
!= NULL
) {
649 rv
= convertCertList(handle
, certlist
, kmfcerts
,
651 CERT_DestroyCertList(certlist
);
653 *num_certs
= maxcerts
;
657 if (nss_slot
!= NULL
) {
658 PK11_FreeSlot(nss_slot
);
661 if (rv
== KMF_OK
&& *num_certs
== 0)
662 rv
= KMF_ERR_CERT_NOT_FOUND
;
669 NSS_FreeKMFCert(KMF_HANDLE_T handle
,
670 KMF_X509_DER_CERT
*kmf_cert
)
672 if (kmf_cert
!= NULL
) {
673 if (kmf_cert
->certificate
.Data
!= NULL
) {
674 free(kmf_cert
->certificate
.Data
);
675 kmf_cert
->certificate
.Data
= NULL
;
676 kmf_cert
->certificate
.Length
= 0;
678 if (kmf_cert
->kmf_private
.label
!= NULL
) {
679 free(kmf_cert
->kmf_private
.label
);
680 kmf_cert
->kmf_private
.label
= NULL
;
686 NSS_DeleteCert(KMF_HANDLE_T handle
, int numattr
, KMF_ATTRIBUTE
*attrlist
)
688 KMF_RETURN rv
= KMF_OK
;
690 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
691 CERTCertificate
*cert
= NULL
;
692 PK11SlotInfo
*nss_slot
= NULL
;
693 char *certlabel
= NULL
;
695 char *subject
= NULL
;
696 KMF_BIGINT
*serial
= NULL
;
697 KMF_CERT_VALIDITY validity
;
699 if (handle
== NULL
|| attrlist
== NULL
|| numattr
== 0) {
700 return (KMF_ERR_BAD_PARAMETER
);
702 rv
= do_nss_init(handle
, numattr
, attrlist
, FALSE
, &nss_slot
);
706 /* Get the search criteria attributes. They are all optional. */
707 certlabel
= kmf_get_attr_ptr(KMF_CERT_LABEL_ATTR
, attrlist
, numattr
);
708 issuer
= kmf_get_attr_ptr(KMF_ISSUER_NAME_ATTR
, attrlist
, numattr
);
709 subject
= kmf_get_attr_ptr(KMF_SUBJECT_NAME_ATTR
, attrlist
, numattr
);
710 serial
= kmf_get_attr_ptr(KMF_BIGINT_ATTR
, attrlist
, numattr
);
712 rv
= kmf_get_attr(KMF_CERT_VALIDITY_ATTR
, attrlist
, numattr
,
715 validity
= KMF_ALL_CERTS
;
719 /* Start finding the matched certificates and delete them. */
720 if (certlabel
!= NULL
) {
721 cert
= PK11_FindCertFromNickname(certlabel
, NULL
);
723 return (KMF_ERR_CERT_NOT_FOUND
);
729 case KMF_NONEXPIRED_CERTS
:
730 nssrv
= CERT_CertTimesValid(cert
);
731 if (nssrv
== SECFailure
) {
732 /* this is an invalid cert - skip it */
736 case KMF_EXPIRED_CERTS
:
737 nssrv
= CERT_CertTimesValid(cert
);
738 if (nssrv
!= SECFailure
) {
739 /* this is a valid cert - skip it */
744 /* delete it from database */
745 nssrv
= SEC_DeletePermCertificate(cert
);
747 SET_ERROR(kmfh
, nssrv
);
748 rv
= KMF_ERR_INTERNAL
;
751 CERTCertListNode
*node
;
752 CERTCertList
*certlist
= NULL
;
754 rv
= nss_find_matching_certs(nss_slot
, issuer
, subject
, serial
,
755 &certlist
, validity
);
757 for (node
= CERT_LIST_HEAD(certlist
);
758 !CERT_LIST_END(node
, certlist
) && rv
== KMF_OK
;
759 node
= CERT_LIST_NEXT(node
)) {
761 nssrv
= SEC_DeletePermCertificate(node
->cert
);
763 SET_ERROR(kmfh
, nssrv
);
764 rv
= KMF_ERR_INTERNAL
;
768 if (rv
== KMF_OK
&& certlist
!= NULL
) {
769 CERT_DestroyCertList(certlist
);
770 } else if (rv
== KMF_OK
&& certlist
== NULL
) {
771 rv
= KMF_ERR_CERT_NOT_FOUND
;
775 if (nss_slot
!= NULL
) {
776 PK11_FreeSlot(nss_slot
);
780 CERT_DestroyCertificate(cert
);
787 InitRandom(char *filename
)
793 fd
= open(filename
, O_RDONLY
);
797 count
= read(fd
, buf
, sizeof (buf
));
799 (void) PK11_RandomUpdate(buf
, count
);
806 NSS_CreateKeypair(KMF_HANDLE_T handle
,
807 int numattr
, KMF_ATTRIBUTE
*attrlist
)
809 KMF_RETURN rv
= KMF_OK
;
810 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
811 PK11RSAGenParams rsaparams
;
813 CK_MECHANISM_TYPE mechanism
;
814 ulong_t publicExponent
= 0x010001;
815 PK11SlotInfo
*nss_slot
= NULL
;
816 SECKEYPrivateKey
*NSSprivkey
= NULL
;
817 SECKEYPublicKey
*NSSpubkey
= NULL
;
818 SECKEYECParams
*ecparams
= NULL
;
819 PQGParams
*pqgParams
= NULL
;
821 boolean_t storekey
= TRUE
;
822 uint32_t keylen
= 1024, len
;
823 uint32_t keylen_size
= sizeof (uint32_t);
824 KMF_KEY_ALG keytype
= KMF_RSA
;
825 KMF_KEY_HANDLE
*pubkey
= NULL
;
826 KMF_KEY_HANDLE
*privkey
= NULL
;
827 char *keylabel
= NULL
;
829 if (handle
== NULL
|| attrlist
== NULL
|| numattr
== 0) {
830 return (KMF_ERR_BAD_PARAMETER
);
832 rv
= do_nss_init(handle
, numattr
, attrlist
, FALSE
, &nss_slot
);
837 rv
= kmf_get_attr(KMF_CREDENTIAL_ATTR
, attrlist
, numattr
,
838 (void *)&cred
, NULL
);
842 rv
= nss_authenticate(handle
, nss_slot
, &cred
);
847 /* "storekey" is optional. Default is TRUE */
848 (void) kmf_get_attr(KMF_STOREKEY_BOOL_ATTR
, attrlist
, numattr
,
851 /* keytype is optional. KMF_RSA is default */
852 (void) kmf_get_attr(KMF_KEYALG_ATTR
, attrlist
, numattr
,
853 (void *)&keytype
, NULL
);
855 rv
= kmf_get_attr(KMF_KEYLENGTH_ATTR
, attrlist
, numattr
,
856 &keylen
, &keylen_size
);
857 if (rv
== KMF_ERR_ATTR_NOT_FOUND
)
858 /* Default keylen = 1024 */
860 else if (rv
!= KMF_OK
)
861 return (KMF_ERR_BAD_PARAMETER
);
863 pubkey
= kmf_get_attr_ptr(KMF_PUBKEY_HANDLE_ATTR
, attrlist
, numattr
);
864 privkey
= kmf_get_attr_ptr(KMF_PRIVKEY_HANDLE_ATTR
, attrlist
, numattr
);
865 if (pubkey
== NULL
|| privkey
== NULL
)
866 return (KMF_ERR_BAD_PARAMETER
);
868 (void) memset(pubkey
, 0, sizeof (KMF_KEY_HANDLE
));
869 (void) memset(privkey
, 0, sizeof (KMF_KEY_HANDLE
));
871 rv
= kmf_get_attr(KMF_KEYLABEL_ATTR
, attrlist
, numattr
, NULL
, &len
);
872 if (rv
== KMF_OK
&& len
> 0) {
873 keylabel
= malloc(len
+ 1);
874 if (keylabel
== NULL
)
875 return (KMF_ERR_MEMORY
);
876 /* Now fill in the label value */
877 (void) memset(keylabel
, 0, len
+ 1);
878 rv
= kmf_get_attr(KMF_KEYLABEL_ATTR
, attrlist
, numattr
,
886 /* Get some random bits */
887 InitRandom("/dev/urandom");
888 if (keytype
== KMF_RSA
) {
891 rsaparams
.keySizeInBits
= keylen
;
893 * NSS only allows for a 4 byte exponent.
894 * Ignore the exponent parameter if it is too big.
896 if ((rv
= kmf_get_attr(KMF_RSAEXP_ATTR
, attrlist
, numattr
,
897 &rsaexp
, NULL
)) == KMF_OK
) {
898 if (rsaexp
.len
> 0 &&
899 rsaexp
.len
<= sizeof (publicExponent
) &&
900 rsaexp
.val
!= NULL
) {
901 (void) memcpy(&publicExponent
, rsaexp
.val
,
905 rsaparams
.pe
= publicExponent
;
906 mechanism
= CKM_RSA_PKCS_KEY_PAIR_GEN
;
907 nssparams
= &rsaparams
;
908 } else if (keytype
== KMF_DSA
) {
909 PQGVerify
*pqgVerify
= NULL
;
911 SECStatus nssrv
, passed
;
913 mechanism
= CKM_DSA_KEY_PAIR_GEN
;
915 ks
= PQG_PBITS_TO_INDEX(keylen
);
916 nssrv
= PK11_PQG_ParamGen(ks
, &pqgParams
, &pqgVerify
);
917 if (nssrv
!= SECSuccess
) {
919 PK11_PQG_DestroyVerify(pqgVerify
);
920 rv
= KMF_ERR_KEYGEN_FAILED
;
924 nssrv
= PK11_PQG_VerifyParams(pqgParams
, pqgVerify
, &passed
);
925 if (nssrv
!= SECSuccess
|| passed
!= SECSuccess
) {
927 rv
= KMF_ERR_KEYGEN_FAILED
;
930 PK11_PQG_DestroyVerify(pqgVerify
);
933 SET_ERROR(kmfh
, PORT_GetError());
937 nssparams
= pqgParams
;
938 } else if (keytype
== KMF_ECDSA
) {
939 KMF_OID
*eccoid
= kmf_get_attr_ptr(KMF_ECC_CURVE_OID_ATTR
,
942 return (KMF_ERR_BAD_PARAMETER
);
944 ecparams
= SECITEM_AllocItem(NULL
, NULL
, (eccoid
->Length
));
946 return (KMF_ERR_MEMORY
);
948 (void) memcpy(ecparams
->data
, eccoid
->Data
, eccoid
->Length
);
950 mechanism
= CKM_EC_KEY_PAIR_GEN
;
951 nssparams
= ecparams
;
953 rv
= KMF_ERR_BAD_PARAMETER
;
957 NSSprivkey
= PK11_GenerateKeyPair(nss_slot
, mechanism
, nssparams
,
959 storekey
, /* isPermanent */
960 PR_TRUE
, /* isSensitive */
963 if (NSSprivkey
== NULL
|| NSSpubkey
== NULL
) {
964 SET_ERROR(kmfh
, PORT_GetError());
965 rv
= KMF_ERR_KEYGEN_FAILED
;
967 if (keylabel
!= NULL
&& strlen(keylabel
)) {
968 (void) PK11_SetPrivateKeyNickname(NSSprivkey
,
970 (void) PK11_SetPublicKeyNickname(NSSpubkey
, keylabel
);
972 /* Now, convert it to a KMF_KEY object for the framework */
973 privkey
->kstype
= KMF_KEYSTORE_NSS
;
974 privkey
->keyalg
= keytype
;
975 privkey
->keyclass
= KMF_ASYM_PRI
;
976 privkey
->keylabel
= PK11_GetPrivateKeyNickname(NSSprivkey
);
977 privkey
->keyp
= (void *)NSSprivkey
;
979 pubkey
->kstype
= KMF_KEYSTORE_NSS
;
980 pubkey
->keyalg
= keytype
;
981 pubkey
->keyp
= (void *)NSSpubkey
;
982 pubkey
->keyclass
= KMF_ASYM_PUB
;
983 pubkey
->keylabel
= PK11_GetPublicKeyNickname(NSSpubkey
);
990 (void) PK11_DeleteTokenPublicKey(NSSpubkey
);
992 (void) PK11_DeleteTokenPrivateKey(NSSprivkey
, PR_TRUE
);
994 privkey
->keyp
= NULL
;
1001 if (pqgParams
!= NULL
)
1002 PK11_PQG_DestroyParams(pqgParams
);
1004 if (ecparams
!= NULL
)
1005 SECITEM_FreeItem(ecparams
, PR_TRUE
);
1007 if (nss_slot
!= NULL
)
1008 PK11_FreeSlot(nss_slot
);
1014 NSS_SignData(KMF_HANDLE_T handle
, KMF_KEY_HANDLE
*key
,
1015 KMF_OID
*AlgOID
, KMF_DATA
*tobesigned
,
1018 KMF_RETURN ret
= KMF_OK
;
1019 KMF_ALGORITHM_INDEX AlgId
;
1020 SECOidTag signAlgTag
;
1021 SECKEYPrivateKey
*NSSprivkey
= NULL
;
1023 SECItem signed_data
;
1024 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
1026 signed_data
.data
= 0;
1027 if (key
== NULL
|| AlgOID
== NULL
||
1028 tobesigned
== NULL
|| output
== NULL
||
1029 tobesigned
->Data
== NULL
||
1030 output
->Data
== NULL
)
1031 return (KMF_ERR_BAD_PARAMETER
);
1033 /* Map the OID to a NSS algorithm */
1034 AlgId
= x509_algoid_to_algid(AlgOID
);
1035 if (AlgId
== KMF_ALGID_NONE
)
1036 return (KMF_ERR_BAD_PARAMETER
);
1038 NSSprivkey
= (SECKEYPrivateKey
*)key
->keyp
;
1040 if (AlgId
== KMF_ALGID_MD5WithRSA
)
1041 signAlgTag
= SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION
;
1042 else if (AlgId
== KMF_ALGID_MD2WithRSA
)
1043 signAlgTag
= SEC_OID_PKCS1_MD2_WITH_RSA_ENCRYPTION
;
1044 else if (AlgId
== KMF_ALGID_SHA1WithRSA
)
1045 signAlgTag
= SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION
;
1046 else if (AlgId
== KMF_ALGID_SHA256WithRSA
)
1047 signAlgTag
= SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION
;
1048 else if (AlgId
== KMF_ALGID_SHA384WithRSA
)
1049 signAlgTag
= SEC_OID_PKCS1_SHA384_WITH_RSA_ENCRYPTION
;
1050 else if (AlgId
== KMF_ALGID_SHA512WithRSA
)
1051 signAlgTag
= SEC_OID_PKCS1_SHA512_WITH_RSA_ENCRYPTION
;
1052 else if (AlgId
== KMF_ALGID_SHA1WithDSA
)
1053 signAlgTag
= SEC_OID_ANSIX9_DSA_SIGNATURE_WITH_SHA1_DIGEST
;
1054 else if (AlgId
== KMF_ALGID_SHA1WithECDSA
|| AlgId
== KMF_ALGID_ECDSA
)
1055 signAlgTag
= SEC_OID_ANSIX962_ECDSA_SIGNATURE_WITH_SHA1_DIGEST
;
1056 else if (AlgId
== KMF_ALGID_SHA256WithECDSA
)
1057 signAlgTag
= SEC_OID_ANSIX962_ECDSA_SHA256_SIGNATURE
;
1058 else if (AlgId
== KMF_ALGID_SHA384WithECDSA
)
1059 signAlgTag
= SEC_OID_ANSIX962_ECDSA_SHA384_SIGNATURE
;
1060 else if (AlgId
== KMF_ALGID_SHA512WithECDSA
)
1061 signAlgTag
= SEC_OID_ANSIX962_ECDSA_SHA512_SIGNATURE
;
1062 else /* NSS does not support DSA with SHA2 hashes (FIPS 186-3) */
1063 return (KMF_ERR_BAD_PARAMETER
);
1065 rv
= SEC_SignData(&signed_data
, tobesigned
->Data
,
1066 tobesigned
->Length
, NSSprivkey
, signAlgTag
);
1069 SET_ERROR(kmfh
, rv
);
1070 return (KMF_ERR_INTERNAL
);
1073 if (signed_data
.len
<= output
->Length
) {
1074 (void) memcpy(output
->Data
, signed_data
.data
, signed_data
.len
);
1075 output
->Length
= signed_data
.len
;
1078 ret
= KMF_ERR_BAD_PARAMETER
;
1080 free(signed_data
.data
);
1086 NSS_EncodePubKeyData(KMF_HANDLE_T handle
, KMF_KEY_HANDLE
*keyp
,
1089 KMF_RETURN ret
= KMF_OK
;
1090 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
1092 CERTSubjectPublicKeyInfo
*spki
= NULL
;
1094 if (keyp
== NULL
|| encoded
== NULL
|| keyp
->keyp
== NULL
)
1095 return (KMF_ERR_BAD_PARAMETER
);
1097 spki
= SECKEY_CreateSubjectPublicKeyInfo(keyp
->keyp
);
1099 SET_ERROR(kmfh
, PORT_GetError());
1100 return (KMF_ERR_MEMORY
);
1103 rvitem
= SEC_ASN1EncodeItem(NULL
, NULL
, spki
,
1104 CERT_SubjectPublicKeyInfoTemplate
);
1105 if (rvitem
!= NULL
) {
1106 encoded
->Data
= malloc(rvitem
->len
);
1107 if (encoded
->Data
== NULL
) {
1108 ret
= KMF_ERR_MEMORY
;
1110 (void) memcpy(encoded
->Data
, rvitem
->data
, rvitem
->len
);
1111 encoded
->Length
= rvitem
->len
;
1113 SECITEM_FreeItem(rvitem
, TRUE
);
1115 SET_ERROR(kmfh
, PORT_GetError());
1116 encoded
->Data
= NULL
;
1117 encoded
->Length
= 0;
1118 ret
= KMF_ERR_ENCODING
;
1120 SECKEY_DestroySubjectPublicKeyInfo(spki
);
1126 NSS_DeleteKey(KMF_HANDLE_T handle
,
1127 int numattr
, KMF_ATTRIBUTE
*attrlist
)
1129 KMF_RETURN rv
= KMF_OK
;
1130 PK11SlotInfo
*nss_slot
= NULL
;
1131 KMF_KEY_HANDLE
*key
;
1132 KMF_CREDENTIAL cred
;
1133 boolean_t delete_token
= B_TRUE
;
1135 if (handle
== NULL
|| attrlist
== NULL
|| numattr
== 0) {
1136 return (KMF_ERR_BAD_PARAMETER
);
1139 * "delete_token" means to clear it from the token storage as well
1142 key
= kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR
, attrlist
, numattr
);
1143 if (key
== NULL
|| key
->keyp
== NULL
)
1144 return (KMF_ERR_BAD_PARAMETER
);
1146 rv
= kmf_get_attr(KMF_DESTROY_BOOL_ATTR
, attrlist
, numattr
,
1147 (void *)&delete_token
, NULL
);
1149 /* "delete_token" is optional. Default is TRUE */
1153 SECStatus nssrv
= SECSuccess
;
1154 if (key
->keyclass
!= KMF_ASYM_PUB
&&
1155 key
->keyclass
!= KMF_ASYM_PRI
&&
1156 key
->keyclass
!= KMF_SYMMETRIC
)
1157 return (KMF_ERR_BAD_KEY_CLASS
);
1159 rv
= do_nss_init(handle
, numattr
, attrlist
, FALSE
, &nss_slot
);
1164 rv
= kmf_get_attr(KMF_CREDENTIAL_ATTR
, attrlist
, numattr
,
1165 (void *)&cred
, NULL
);
1167 return (KMF_ERR_BAD_PARAMETER
);
1169 rv
= nss_authenticate(handle
, nss_slot
, &cred
);
1174 if (key
->keyclass
== KMF_ASYM_PUB
) {
1175 nssrv
= PK11_DeleteTokenPublicKey(
1176 (SECKEYPublicKey
*)key
->keyp
);
1177 } else if (key
->keyclass
== KMF_ASYM_PRI
) {
1178 nssrv
= PK11_DeleteTokenPrivateKey(
1179 (SECKEYPrivateKey
*)key
->keyp
, PR_TRUE
);
1180 } else if (key
->keyclass
== KMF_SYMMETRIC
) {
1181 nssrv
= PK11_DeleteTokenSymKey(
1182 (PK11SymKey
*) key
->keyp
);
1183 if (nssrv
== SECSuccess
)
1184 PK11_FreeSymKey((PK11SymKey
*) key
->keyp
);
1186 if (nssrv
!= SECSuccess
) {
1187 SET_ERROR(handle
, PORT_GetError());
1188 rv
= KMF_ERR_INTERNAL
;
1191 if (key
->keyclass
== KMF_ASYM_PUB
) {
1192 SECKEY_DestroyPublicKey((SECKEYPublicKey
*)key
->keyp
);
1193 } else if (key
->keyclass
== KMF_ASYM_PRI
) {
1194 SECKEY_DestroyPrivateKey((SECKEYPrivateKey
*)key
->keyp
);
1195 } else if (key
->keyclass
== KMF_SYMMETRIC
) {
1196 PK11_FreeSymKey((PK11SymKey
*) key
->keyp
);
1198 return (KMF_ERR_BAD_KEY_CLASS
);
1207 NSS_GetErrorString(KMF_HANDLE_T handle
, char **msgstr
)
1209 KMF_RETURN ret
= KMF_OK
;
1210 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
1213 /* Get the error string in the default language */
1214 str
= (char *)PR_ErrorToName((PRErrorCode
)kmfh
->lasterr
.errcode
);
1217 *msgstr
= (char *)strdup(str
);
1218 if ((*msgstr
) == NULL
)
1219 ret
= KMF_ERR_MEMORY
;
1228 NSS_FindPrikeyByCert(KMF_HANDLE_T handle
, int numattr
, KMF_ATTRIBUTE
*attrlist
)
1230 KMF_RETURN rv
= KMF_OK
;
1231 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
1232 PK11SlotInfo
*nss_slot
= NULL
;
1233 KMF_CREDENTIAL cred
;
1234 KMF_KEY_HANDLE
*key
= NULL
;
1235 KMF_DATA
*cert
= NULL
;
1236 CERTCertificate
*nss_cert
= NULL
;
1237 SECKEYPrivateKey
* privkey
= NULL
;
1239 if (handle
== NULL
|| attrlist
== NULL
|| numattr
== 0) {
1240 return (KMF_ERR_BAD_PARAMETER
);
1243 rv
= do_nss_init(handle
, numattr
, attrlist
, FALSE
, &nss_slot
);
1247 /* Get the credential */
1248 rv
= kmf_get_attr(KMF_CREDENTIAL_ATTR
, attrlist
, numattr
,
1249 (void *)&cred
, NULL
);
1251 return (KMF_ERR_BAD_PARAMETER
);
1252 rv
= nss_authenticate(handle
, nss_slot
, &cred
);
1256 /* Get the key handle */
1257 key
= kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR
, attrlist
, numattr
);
1259 return (KMF_ERR_BAD_PARAMETER
);
1261 /* Get the cert data and decode it */
1262 cert
= kmf_get_attr_ptr(KMF_CERT_DATA_ATTR
, attrlist
, numattr
);
1263 if (cert
== NULL
|| cert
->Data
== NULL
)
1264 return (KMF_ERR_BAD_PARAMETER
);
1266 nss_cert
= CERT_DecodeCertFromPackage((char *)cert
->Data
,
1268 if (nss_cert
== NULL
) {
1269 SET_ERROR(kmfh
, PORT_GetError());
1270 return (KMF_ERR_BAD_CERT_FORMAT
);
1273 privkey
= PK11_FindPrivateKeyFromCert(nss_slot
, nss_cert
, NULL
);
1274 if (privkey
== NULL
) {
1275 SET_ERROR(kmfh
, PORT_GetError());
1276 return (KMF_ERR_KEY_NOT_FOUND
);
1279 key
->kstype
= KMF_KEYSTORE_NSS
;
1280 key
->keyclass
= KMF_ASYM_PRI
;
1281 key
->keyp
= (void *)privkey
;
1282 key
->keylabel
= PK11_GetPrivateKeyNickname(privkey
);
1284 CERT_DestroyCertificate(nss_cert
);
1291 NSS_DecryptData(KMF_HANDLE_T handle
, KMF_KEY_HANDLE
*key
,
1292 KMF_OID
*AlgOID
, KMF_DATA
*ciphertext
,
1295 KMF_RETURN ret
= KMF_OK
;
1296 SECKEYPrivateKey
*NSSprivkey
= NULL
;
1298 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
1299 unsigned int in_len
= 0, out_len
= 0;
1300 unsigned int total_decrypted
= 0, modulus_len
= 0;
1301 uint8_t *in_data
, *out_data
;
1304 if (key
== NULL
|| AlgOID
== NULL
||
1305 ciphertext
== NULL
|| output
== NULL
||
1306 ciphertext
->Data
== NULL
||
1307 output
->Data
== NULL
)
1308 return (KMF_ERR_BAD_PARAMETER
);
1310 NSSprivkey
= (SECKEYPrivateKey
*)key
->keyp
;
1311 modulus_len
= PK11_GetPrivateModulusLen(NSSprivkey
);
1313 blocks
= ciphertext
->Length
/modulus_len
;
1314 out_data
= output
->Data
;
1315 in_data
= ciphertext
->Data
;
1316 out_len
= modulus_len
- 11;
1317 in_len
= modulus_len
;
1319 for (i
= 0; i
< blocks
; i
++) {
1320 rv
= PK11_PrivDecryptPKCS1(NSSprivkey
, out_data
,
1321 &out_len
, ciphertext
->Length
, in_data
, in_len
);
1324 SET_ERROR(kmfh
, rv
);
1325 return (KMF_ERR_INTERNAL
);
1328 out_data
+= out_len
;
1329 total_decrypted
+= out_len
;
1333 output
->Length
= total_decrypted
;
1339 pk11keytype2kmf(CK_KEY_TYPE type
)
1358 return (KMF_KEYALG_NONE
);
1363 NSS_FindKey(KMF_HANDLE_T handle
,
1364 int numattr
, KMF_ATTRIBUTE
*attrlist
)
1367 SECKEYPrivateKeyList
*prilist
;
1368 SECKEYPrivateKeyListNode
*prinode
;
1369 SECKEYPublicKeyList
*publist
;
1370 SECKEYPublicKeyListNode
*pubnode
;
1371 PK11SlotInfo
*nss_slot
= NULL
;
1372 PK11SymKey
*symlist
= NULL
;
1375 KMF_KEY_HANDLE
*keys
;
1377 KMF_CREDENTIAL
*cred
= NULL
;
1378 KMF_KEY_CLASS keyclass
;
1382 KMF_KEY_ALG keytype
= KMF_KEYALG_NONE
;
1384 if (handle
== NULL
|| attrlist
== NULL
|| numattr
== 0) {
1385 return (KMF_ERR_BAD_PARAMETER
);
1388 numkeys
= kmf_get_attr_ptr(KMF_COUNT_ATTR
, attrlist
, numattr
);
1389 if (numkeys
== NULL
)
1390 return (KMF_ERR_BAD_PARAMETER
);
1392 rv
= do_nss_init(handle
, numattr
, attrlist
, FALSE
, &nss_slot
);
1397 /* It is OK if this is NULL, we dont need a cred to find public keys */
1398 cred
= kmf_get_attr_ptr(KMF_CREDENTIAL_ATTR
, attrlist
, numattr
);
1401 rv
= nss_authenticate(handle
, nss_slot
, cred
);
1409 maxkeys
= 0xFFFFFFFF;
1412 rv
= kmf_get_attr(KMF_KEYCLASS_ATTR
, attrlist
, numattr
,
1413 (void *)&keyclass
, NULL
);
1415 return (KMF_ERR_BAD_PARAMETER
);
1417 findLabel
= kmf_get_attr_ptr(KMF_KEYLABEL_ATTR
, attrlist
, numattr
);
1419 if (keyclass
== KMF_ASYM_PUB
) {
1420 publist
= PK11_ListPublicKeysInSlot(nss_slot
, findLabel
);
1421 if (publist
== NULL
) {
1422 rv
= KMF_ERR_KEY_NOT_FOUND
;
1425 } else if (keyclass
== KMF_ASYM_PRI
) {
1426 prilist
= PK11_ListPrivKeysInSlot(nss_slot
, findLabel
, NULL
);
1427 if (prilist
== NULL
) {
1428 rv
= KMF_ERR_KEY_NOT_FOUND
;
1431 } else if (keyclass
== KMF_SYMMETRIC
) {
1432 symlist
= PK11_ListFixedKeysInSlot(nss_slot
, findLabel
, NULL
);
1433 if (symlist
== NULL
) {
1434 rv
= KMF_ERR_KEY_NOT_FOUND
;
1438 rv
= KMF_ERR_BAD_KEY_CLASS
;
1442 keys
= kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR
, attrlist
, numattr
);
1443 /* it is okay to have "keys" contains NULL */
1445 if (keyclass
== KMF_ASYM_PUB
) {
1446 for (count
= 0, pubnode
= PUBKEY_LIST_HEAD(publist
);
1447 !PUBKEY_LIST_END(pubnode
, publist
) && count
< maxkeys
;
1448 pubnode
= PUBKEY_LIST_NEXT(pubnode
)) {
1451 * Due to bug in NSS, we have to manually match
1452 * the labels to be sure we have a match.
1454 nick
= PK11_GetPublicKeyNickname(pubnode
->key
);
1457 (strcmp(nick
, findLabel
) == 0));
1459 /* always match if findLabel is NULL */
1462 if (keys
!= NULL
&& match
) {
1463 keys
[count
].kstype
= KMF_KEYSTORE_NSS
;
1464 keys
[count
].keyclass
= KMF_ASYM_PUB
;
1465 keys
[count
].keyp
= (void *)pubnode
->key
;
1466 keys
[count
].keylabel
= nick
;
1468 if (pubnode
->key
->keyType
== rsaKey
)
1469 keys
[count
].keyalg
= KMF_RSA
;
1470 else if (pubnode
->key
->keyType
== dsaKey
)
1471 keys
[count
].keyalg
= KMF_DSA
;
1472 else if (pubnode
->key
->keyType
== ecKey
)
1473 keys
[count
].keyalg
= KMF_ECDSA
;
1479 } else if (keyclass
== KMF_ASYM_PRI
) {
1480 for (count
= 0, prinode
= PRIVKEY_LIST_HEAD(prilist
);
1481 !PRIVKEY_LIST_END(prinode
, prilist
) && count
< maxkeys
;
1482 prinode
= PRIVKEY_LIST_NEXT(prinode
)) {
1485 * Due to bug in NSS, we have to manually match
1486 * the labels to be sure we have a match.
1488 nick
= PK11_GetPrivateKeyNickname(prinode
->key
);
1491 (strcmp(nick
, findLabel
) == 0));
1493 /* always match if findLabel is NULL */
1496 if (keys
!= NULL
&& match
) {
1497 keys
[count
].kstype
= KMF_KEYSTORE_NSS
;
1498 keys
[count
].keyclass
= KMF_ASYM_PRI
;
1499 keys
[count
].keyp
= (void *)prinode
->key
;
1500 keys
[count
].keylabel
= nick
;
1502 if (prinode
->key
->keyType
== rsaKey
)
1503 keys
[count
].keyalg
= KMF_RSA
;
1504 else if (prinode
->key
->keyType
== dsaKey
)
1505 keys
[count
].keyalg
= KMF_DSA
;
1506 else if (prinode
->key
->keyType
== ecKey
)
1507 keys
[count
].keyalg
= KMF_ECDSA
;
1513 } else if (keyclass
== KMF_SYMMETRIC
) {
1515 rv
= kmf_get_attr(KMF_KEYALG_ATTR
, attrlist
, numattr
,
1516 (void *)&keytype
, NULL
);
1519 while (symlist
&& count
< maxkeys
) {
1520 PK11SymKey
*symkey
= symlist
;
1525 type
= PK11_GetSymKeyType(symkey
);
1526 keyalg
= pk11keytype2kmf(type
);
1528 symlist
= PK11_GetNextSymKey(symkey
);
1531 * If keytype is specified in the searching parameter,
1532 * check the keytype and skip the key if its keytype
1535 if (keytype
!= KMF_KEYALG_NONE
&& keytype
!= keyalg
) {
1536 /* free that key since we arent using it */
1537 PK11_FreeSymKey(symkey
);
1541 * Due to bug in NSS, we have to manually match
1542 * the labels to be sure we have a match.
1544 nick
= PK11_GetSymKeyNickname(symkey
);
1547 (strcmp(nick
, findLabel
) == 0));
1549 /* always match if findLabel is NULL */
1553 if (keys
!= NULL
&& match
) {
1554 keys
[count
].kstype
= KMF_KEYSTORE_NSS
;
1555 keys
[count
].keyclass
= KMF_SYMMETRIC
;
1556 keys
[count
].keyp
= (void *) symkey
;
1557 keys
[count
].keylabel
= nick
;
1558 keys
[count
].keyalg
= keyalg
;
1560 PK11_FreeSymKey(symkey
);
1566 * Cleanup memory for unused keys.
1568 while (symlist
!= NULL
) {
1569 PK11SymKey
*symkey
= symlist
;
1571 PK11_FreeSymKey(symkey
);
1572 symlist
= PK11_GetNextSymKey(symkey
);
1578 if (nss_slot
!= NULL
) {
1579 PK11_FreeSlot(nss_slot
);
1586 p12u_SwapUnicodeBytes(SECItem
*uniItem
)
1590 if ((uniItem
== NULL
) || (uniItem
->len
% 2)) {
1591 return (SECFailure
);
1593 for (i
= 0; i
< uniItem
->len
; i
+= 2) {
1594 a
= uniItem
->data
[i
];
1595 uniItem
->data
[i
] = uniItem
->data
[i
+1];
1596 uniItem
->data
[i
+1] = a
;
1598 return (SECSuccess
);
1602 p12u_ucs2_ascii_conversion_function(
1604 unsigned char *inBuf
,
1605 unsigned int inBufLen
,
1606 unsigned char *outBuf
,
1607 unsigned int maxOutBufLen
,
1608 unsigned int *outBufLen
,
1611 SECItem it
= { siBuffer
, NULL
, 0 };
1612 SECItem
*dup
= NULL
;
1617 dup
= SECITEM_DupItem(&it
);
1619 * If converting Unicode to ASCII, swap bytes before conversion
1622 if (!toUnicode
&& swapBytes
) {
1623 if (p12u_SwapUnicodeBytes(dup
) != SECSuccess
) {
1624 SECITEM_ZfreeItem(dup
, PR_TRUE
);
1628 /* Perform the conversion. */
1629 ret
= PORT_UCS2_UTF8Conversion(toUnicode
, dup
->data
, dup
->len
,
1630 outBuf
, maxOutBufLen
, outBufLen
);
1632 SECITEM_ZfreeItem(dup
, PR_TRUE
);
1638 p12u_OpenFile(p12uContext
*p12ctx
, PRBool fileRead
)
1640 if (!p12ctx
|| !p12ctx
->filename
) {
1645 p12ctx
->file
= PR_Open(p12ctx
->filename
, PR_RDONLY
, 0400);
1647 p12ctx
->file
= PR_Open(p12ctx
->filename
,
1648 PR_CREATE_FILE
| PR_RDWR
| PR_TRUNCATE
, 0600);
1651 if (!p12ctx
->file
) {
1652 p12ctx
->error
= PR_TRUE
;
1660 p12u_DestroyContext(p12uContext
**ppCtx
, PRBool removeFile
)
1662 if (!ppCtx
|| !(*ppCtx
)) {
1666 if ((*ppCtx
)->file
!= NULL
) {
1667 (void) PR_Close((*ppCtx
)->file
);
1670 if ((*ppCtx
)->filename
!= NULL
) {
1672 (void) PR_Delete((*ppCtx
)->filename
);
1674 free((*ppCtx
)->filename
);
1681 static p12uContext
*
1682 p12u_InitContext(PRBool fileImport
, char *filename
)
1684 p12uContext
*p12ctx
;
1686 p12ctx
= PORT_ZNew(p12uContext
);
1691 p12ctx
->error
= PR_FALSE
;
1692 p12ctx
->errorValue
= 0;
1693 p12ctx
->filename
= strdup(filename
);
1695 if (!p12u_OpenFile(p12ctx
, fileImport
)) {
1696 p12u_DestroyContext(&p12ctx
, PR_FALSE
);
1704 p12u_WriteToExportFile(void *arg
, const char *buf
, unsigned long len
)
1706 p12uContext
*p12cxt
= arg
;
1709 if (!p12cxt
|| (p12cxt
->error
== PR_TRUE
)) {
1713 if (p12cxt
->file
== NULL
) {
1714 p12cxt
->errorValue
= SEC_ERROR_PKCS12_UNABLE_TO_WRITE
;
1715 p12cxt
->error
= PR_TRUE
;
1719 writeLen
= PR_Write(p12cxt
->file
, (unsigned char *)buf
, (int32
)len
);
1721 if (writeLen
!= (int)len
) {
1722 (void) PR_Close(p12cxt
->file
);
1723 free(p12cxt
->filename
);
1724 p12cxt
->filename
= NULL
;
1725 p12cxt
->file
= NULL
;
1726 p12cxt
->errorValue
= SEC_ERROR_PKCS12_UNABLE_TO_WRITE
;
1727 p12cxt
->error
= PR_TRUE
;
1731 #define HANDLE_NSS_ERROR(r) {\
1732 SET_ERROR(kmfh, PORT_GetError()); \
1737 add_cert_to_bag(SEC_PKCS12ExportContext
*p12ecx
,
1738 CERTCertificate
*cert
, SECItem
*pwitem
)
1740 KMF_RETURN rv
= KMF_OK
;
1741 SEC_PKCS12SafeInfo
*keySafe
= NULL
, *certSafe
= NULL
;
1743 keySafe
= SEC_PKCS12CreateUnencryptedSafe(p12ecx
);
1744 if (PK11_IsFIPS()) {
1747 certSafe
= SEC_PKCS12CreatePasswordPrivSafe(p12ecx
, pwitem
,
1748 SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC
);
1751 if (!certSafe
|| !keySafe
) {
1752 rv
= KMF_ERR_INTERNAL
;
1756 if (SEC_PKCS12AddCertAndKey(p12ecx
, certSafe
, NULL
, cert
,
1757 CERT_GetDefaultCertDB(), keySafe
, NULL
, PR_TRUE
, pwitem
,
1758 SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_3KEY_TRIPLE_DES_CBC
)
1760 rv
= KMF_ERR_INTERNAL
;
1767 NSS_ExportPK12(KMF_HANDLE_T handle
, int numattr
, KMF_ATTRIBUTE
*attrlist
)
1770 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
1771 SEC_PKCS12ExportContext
*p12ecx
= NULL
;
1772 p12uContext
*p12ctx
= NULL
;
1773 CERTCertList
*certlist
= NULL
;
1774 CERTCertificate
*nsscert
= NULL
;
1775 CERTCertListNode
* node
= NULL
;
1776 PK11SlotInfo
*slot
= NULL
;
1777 SECItem pwitem
= { siBuffer
, NULL
, 0 };
1778 KMF_CREDENTIAL
*cred
= NULL
;
1779 KMF_CREDENTIAL
*p12cred
= NULL
;
1780 char *certlabel
= NULL
;
1781 char *issuer
= NULL
;
1782 char *subject
= NULL
;
1783 KMF_BIGINT
*serial
= NULL
;
1784 char *filename
= NULL
;
1786 if (kmfh
== NULL
|| attrlist
== NULL
|| numattr
== 0) {
1787 return (KMF_ERR_BAD_PARAMETER
);
1790 rv
= do_nss_init(handle
, numattr
, attrlist
, FALSE
, &slot
);
1794 cred
= kmf_get_attr_ptr(KMF_CREDENTIAL_ATTR
, attrlist
, numattr
);
1796 return (KMF_ERR_BAD_PARAMETER
);
1798 rv
= nss_authenticate(handle
, slot
, cred
);
1802 p12cred
= kmf_get_attr_ptr(KMF_PK12CRED_ATTR
, attrlist
, numattr
);
1803 if (p12cred
== NULL
)
1804 return (KMF_ERR_BAD_PARAMETER
);
1806 filename
= kmf_get_attr_ptr(KMF_OUTPUT_FILENAME_ATTR
, attrlist
,
1808 if (filename
== NULL
)
1809 return (KMF_ERR_BAD_PARAMETER
);
1811 /* Get optional search criteria attributes */
1812 certlabel
= kmf_get_attr_ptr(KMF_CERT_LABEL_ATTR
, attrlist
, numattr
);
1813 issuer
= kmf_get_attr_ptr(KMF_ISSUER_NAME_ATTR
, attrlist
, numattr
);
1814 subject
= kmf_get_attr_ptr(KMF_SUBJECT_NAME_ATTR
, attrlist
, numattr
);
1815 serial
= kmf_get_attr_ptr(KMF_BIGINT_ATTR
, attrlist
, numattr
);
1818 * Find the certificate(s) first.
1820 if (certlabel
!= NULL
) {
1821 nsscert
= PK11_FindCertFromNickname(certlabel
, NULL
);
1822 if (nsscert
== NULL
) {
1823 HANDLE_NSS_ERROR(KMF_ERR_CERT_NOT_FOUND
)
1826 rv
= nss_find_matching_certs(slot
, issuer
, subject
, serial
,
1829 if (rv
== KMF_OK
&& certlist
== NULL
) {
1830 return (KMF_ERR_CERT_NOT_FOUND
);
1837 * The KMF_CREDENTIAL holds the password to use for
1838 * encrypting the PKCS12 key information.
1840 pwitem
.data
= (uchar_t
*)p12cred
->cred
;
1841 pwitem
.len
= p12cred
->credlen
;
1843 p12ctx
= p12u_InitContext(PR_FALSE
, filename
);
1845 HANDLE_NSS_ERROR(KMF_ERR_OPEN_FILE
)
1848 PORT_SetUCS2_ASCIIConversionFunction(
1849 p12u_ucs2_ascii_conversion_function
);
1851 p12ecx
= SEC_PKCS12CreateExportContext(NULL
, NULL
, slot
, NULL
);
1853 HANDLE_NSS_ERROR(KMF_ERR_OPEN_FILE
)
1856 if (SEC_PKCS12AddPasswordIntegrity(p12ecx
, &pwitem
, SEC_OID_SHA1
)
1858 HANDLE_NSS_ERROR(KMF_ERR_INTERNAL
)
1862 * NSS actually supports storing a list of keys and certs
1863 * in the PKCS#12 PDU. Nice feature.
1865 if (certlist
!= NULL
) {
1866 for (node
= CERT_LIST_HEAD(certlist
);
1867 !CERT_LIST_END(node
, certlist
) && rv
== KMF_OK
;
1868 node
= CERT_LIST_NEXT(node
)) {
1869 rv
= add_cert_to_bag(p12ecx
, node
->cert
, &pwitem
);
1871 } else if (nsscert
!= NULL
) {
1872 rv
= add_cert_to_bag(p12ecx
, nsscert
, &pwitem
);
1875 if (SEC_PKCS12Encode(p12ecx
, p12u_WriteToExportFile
, p12ctx
)
1877 HANDLE_NSS_ERROR(KMF_ERR_ENCODING
)
1881 CERT_DestroyCertificate(nsscert
);
1884 CERT_DestroyCertList(certlist
);
1887 p12u_DestroyContext(&p12ctx
, PR_FALSE
);
1890 SEC_PKCS12DestroyExportContext(p12ecx
);
1895 #define SETATTR(t, n, atype, value, size) \
1896 t[n].type = atype; \
1897 t[n].pValue = (CK_BYTE *)value; \
1898 t[n].ulValueLen = (CK_ULONG)size;
1901 NSS_CreateSymKey(KMF_HANDLE_T handle
,
1902 int numattr
, KMF_ATTRIBUTE
*attrlist
)
1904 KMF_RETURN rv
= KMF_OK
;
1905 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
1906 PK11SlotInfo
*nss_slot
= NULL
;
1907 PK11SymKey
*nsskey
= NULL
;
1908 CK_MECHANISM_TYPE keyType
;
1911 KMF_KEY_HANDLE
*symkey
;
1912 KMF_CREDENTIAL cred
;
1914 uint32_t keylen_size
= sizeof (uint32_t);
1915 KMF_KEY_ALG keytype
;
1916 char *keylabel
= NULL
;
1918 if (kmfh
== NULL
|| attrlist
== NULL
|| numattr
== 0) {
1919 return (KMF_ERR_BAD_PARAMETER
);
1922 symkey
= kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR
, attrlist
, numattr
);
1924 return (KMF_ERR_BAD_PARAMETER
);
1926 rv
= kmf_get_attr(KMF_KEYALG_ATTR
, attrlist
, numattr
, (void *)&keytype
,
1929 return (KMF_ERR_BAD_PARAMETER
);
1931 rv
= kmf_get_attr(KMF_KEYLENGTH_ATTR
, attrlist
, numattr
, &keylen
,
1933 if (rv
== KMF_ERR_ATTR_NOT_FOUND
&&
1934 (keytype
== KMF_DES
|| keytype
== KMF_DES3
))
1935 /* keylength is not required for DES and 3DES */
1938 return (KMF_ERR_BAD_PARAMETER
);
1940 keylabel
= kmf_get_attr_ptr(KMF_KEYLABEL_ATTR
, attrlist
, numattr
);
1941 if (keylabel
== NULL
)
1942 return (KMF_ERR_BAD_PARAMETER
);
1946 keyType
= CKM_AES_KEY_GEN
;
1948 if (keySize
== 0 || (keySize
% 8) != 0)
1949 return (KMF_ERR_BAD_KEY_SIZE
);
1952 keyType
= CKM_RC4_KEY_GEN
;
1954 if (keySize
== 0 || (keySize
% 8) != 0)
1955 return (KMF_ERR_BAD_KEY_SIZE
);
1958 keyType
= CKM_DES_KEY_GEN
;
1959 keySize
= 0; /* required by PK11_TokenKeyGen() */
1962 keyType
= CKM_DES3_KEY_GEN
;
1963 keySize
= 0; /* required by PK11_TokenKeyGen() */
1965 case KMF_GENERIC_SECRET
:
1966 keyType
= CKM_GENERIC_SECRET_KEY_GEN
;
1968 if (keySize
== 0 || (keySize
% 8) != 0)
1969 return (KMF_ERR_BAD_KEY_SIZE
);
1972 rv
= KMF_ERR_BAD_KEY_TYPE
;
1976 rv
= do_nss_init(handle
, numattr
, attrlist
, FALSE
, &nss_slot
);
1981 rv
= kmf_get_attr(KMF_CREDENTIAL_ATTR
, attrlist
, numattr
,
1982 (void *)&cred
, NULL
);
1984 return (KMF_ERR_BAD_PARAMETER
);
1986 rv
= nss_authenticate(handle
, nss_slot
, &cred
);
1991 /* convert key length to bytes */
1992 nsskey
= PK11_TokenKeyGen(nss_slot
, keyType
, NULL
, keySize
/ 8, NULL
,
1993 PR_TRUE
, (void *)cred
.cred
);
1994 if (nsskey
== NULL
) {
1995 SET_ERROR(kmfh
, PORT_GetError());
1996 rv
= KMF_ERR_KEYGEN_FAILED
;
2000 nssrv
= PK11_SetSymKeyNickname(nsskey
, keylabel
);
2001 if (nssrv
!= SECSuccess
) {
2002 SET_ERROR(kmfh
, PORT_GetError());
2003 rv
= KMF_ERR_KEYGEN_FAILED
;
2007 symkey
->kstype
= KMF_KEYSTORE_NSS
;
2008 symkey
->keyalg
= keytype
;
2009 symkey
->keyclass
= KMF_SYMMETRIC
;
2010 symkey
->israw
= FALSE
;
2011 symkey
->keyp
= (void *)nsskey
;
2014 if (nss_slot
!= NULL
)
2015 PK11_FreeSlot(nss_slot
);
2017 if (rv
!= KMF_OK
&& nsskey
!= NULL
) {
2018 (void) PK11_DeleteTokenSymKey(nsskey
);
2019 PK11_FreeSymKey(nsskey
);
2025 NSS_GetSymKeyValue(KMF_HANDLE_T handle
, KMF_KEY_HANDLE
*symkey
,
2026 KMF_RAW_SYM_KEY
*rkey
)
2028 KMF_RETURN rv
= KMF_OK
;
2029 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
2030 SECItem
*value
= NULL
;
2035 return (KMF_ERR_UNINITIALIZED
);
2037 if (symkey
== NULL
|| rkey
== NULL
)
2038 return (KMF_ERR_BAD_PARAMETER
);
2039 else if (symkey
->keyclass
!= KMF_SYMMETRIC
)
2040 return (KMF_ERR_BAD_KEY_CLASS
);
2042 if (symkey
->israw
) {
2043 KMF_RAW_KEY_DATA
*rawkey
= (KMF_RAW_KEY_DATA
*)symkey
->keyp
;
2045 if (rawkey
== NULL
||
2046 rawkey
->rawdata
.sym
.keydata
.val
== NULL
||
2047 rawkey
->rawdata
.sym
.keydata
.len
== 0)
2048 return (KMF_ERR_BAD_KEYHANDLE
);
2050 rkey
->keydata
.len
= rawkey
->rawdata
.sym
.keydata
.len
;
2051 if ((rkey
->keydata
.val
= malloc(rkey
->keydata
.len
)) == NULL
)
2052 return (KMF_ERR_MEMORY
);
2053 (void) memcpy(rkey
->keydata
.val
,
2054 rawkey
->rawdata
.sym
.keydata
.val
, rkey
->keydata
.len
);
2056 nsskey
= (PK11SymKey
*)(symkey
->keyp
);
2058 return (KMF_ERR_BAD_KEYHANDLE
);
2060 nss_rv
= PK11_ExtractKeyValue(nsskey
);
2061 if (nss_rv
!= SECSuccess
) {
2062 SET_ERROR(kmfh
, PORT_GetError());
2063 rv
= KMF_ERR_GETKEYVALUE_FAILED
;
2067 value
= PK11_GetKeyData(nsskey
);
2068 if (value
== NULL
) {
2069 SET_ERROR(kmfh
, PORT_GetError());
2070 rv
= KMF_ERR_GETKEYVALUE_FAILED
;
2074 if (value
->len
== 0 || value
->data
== NULL
) {
2075 rv
= KMF_ERR_GETKEYVALUE_FAILED
;
2079 rkey
->keydata
.val
= malloc(value
->len
);
2080 if (rkey
->keydata
.val
== NULL
) {
2081 rv
= KMF_ERR_MEMORY
;
2084 (void) memcpy(rkey
->keydata
.val
, value
->data
, value
->len
);
2085 rkey
->keydata
.len
= value
->len
;
2086 (void) memset(value
->data
, 0, value
->len
);
2090 SECITEM_FreeItem(value
, PR_TRUE
);
2095 NSS_SetTokenPin(KMF_HANDLE_T handle
, int numattr
, KMF_ATTRIBUTE
*attrlist
)
2097 KMF_RETURN ret
= KMF_OK
;
2098 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
2100 PK11SlotInfo
*nss_slot
= NULL
;
2101 KMF_CREDENTIAL oldcred
, newcred
;
2103 if (handle
== NULL
|| attrlist
== NULL
|| numattr
== 0)
2104 return (KMF_ERR_BAD_PARAMETER
);
2106 ret
= kmf_get_attr(KMF_CREDENTIAL_ATTR
, attrlist
, numattr
,
2107 (void *)&oldcred
, NULL
);
2109 return (KMF_ERR_BAD_PARAMETER
);
2110 ret
= kmf_get_attr(KMF_NEWPIN_ATTR
, attrlist
, numattr
,
2111 (void *)&newcred
, NULL
);
2113 return (KMF_ERR_BAD_PARAMETER
);
2115 ret
= do_nss_init(handle
, numattr
, attrlist
, FALSE
, &nss_slot
);
2116 /* If it was uninitialized, set it */
2117 if (ret
== KMF_ERR_UNINITIALIZED_TOKEN
) {
2118 rv
= PK11_InitPin(nss_slot
, NULL
, newcred
.cred
);
2119 if (rv
!= SECSuccess
) {
2120 SET_ERROR(kmfh
, PORT_GetError());
2121 ret
= KMF_ERR_AUTH_FAILED
;
2125 } else if (ret
== KMF_OK
) {
2126 ret
= nss_authenticate(handle
, nss_slot
, &oldcred
);
2127 if (ret
!= KMF_OK
) {
2130 rv
= PK11_ChangePW(nss_slot
, oldcred
.cred
, newcred
.cred
);
2131 if (rv
!= SECSuccess
) {
2132 SET_ERROR(kmfh
, PORT_GetError());
2133 ret
= KMF_ERR_AUTH_FAILED
;
2141 NSS_StoreKey(KMF_HANDLE_T handle
,
2142 int numattr
, KMF_ATTRIBUTE
*attrlist
)
2144 KMF_RETURN rv
= KMF_OK
;
2145 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
2146 PK11SlotInfo
*nss_slot
= NULL
;
2147 KMF_CREDENTIAL cred
= { NULL
, 0 };
2148 KMF_KEY_HANDLE
*pubkey
= NULL
, *prikey
= NULL
;
2149 KMF_RAW_KEY_DATA
*rawkey
= NULL
;
2150 char *keylabel
= NULL
;
2151 SECStatus ckrv
= SECSuccess
;
2152 SECItem nickname
= { siBuffer
, NULL
, 0 };
2153 CERTCertificate
*nss_cert
= NULL
;
2155 if (kmfh
== NULL
|| attrlist
== NULL
|| numattr
== 0) {
2156 return (KMF_ERR_BAD_PARAMETER
);
2159 rv
= do_nss_init(handle
, numattr
, attrlist
, FALSE
, &nss_slot
);
2164 rv
= kmf_get_attr(KMF_CREDENTIAL_ATTR
, attrlist
, numattr
,
2165 (void *)&cred
, NULL
);
2167 return (KMF_ERR_BAD_PARAMETER
);
2169 rv
= nss_authenticate(handle
, nss_slot
, &cred
);
2174 pubkey
= kmf_get_attr_ptr(KMF_PUBKEY_HANDLE_ATTR
, attrlist
, numattr
);
2175 if (pubkey
== NULL
) {
2176 /* look for private key */
2177 prikey
= kmf_get_attr_ptr(KMF_PRIVKEY_HANDLE_ATTR
, attrlist
,
2180 /* look for raw key */
2181 rawkey
= kmf_get_attr_ptr(KMF_RAW_KEY_ATTR
,
2185 /* If no keys were found, return error */
2186 if (pubkey
== NULL
&& prikey
== NULL
&& rawkey
== NULL
)
2187 return (KMF_ERR_ATTR_NOT_FOUND
);
2189 keylabel
= kmf_get_attr_ptr(KMF_KEYLABEL_ATTR
, attrlist
, numattr
);
2190 if (keylabel
!= NULL
) {
2191 nickname
.data
= (uchar_t
*)keylabel
;
2192 nickname
.len
= strlen(keylabel
);
2195 if (rawkey
!= NULL
) {
2197 SECKEYPrivateKeyInfo rpk
;
2198 KMF_DATA derkey
= { 0, NULL
};
2201 cert
= kmf_get_attr_ptr(KMF_CERT_DATA_ATTR
, attrlist
, numattr
);
2205 * Decode the cert into an NSS CERT object so we can access the
2206 * SPKI and KeyUsage data later.
2208 nss_cert
= CERT_DecodeCertFromPackage((char *)cert
->Data
,
2211 if (nss_cert
== NULL
) {
2212 SET_ERROR(kmfh
, PORT_GetError());
2213 rv
= KMF_ERR_BAD_CERT_FORMAT
;
2217 (void) memset(&rpk
, 0, sizeof (rpk
));
2219 rpk
.version
.type
= siUnsignedInteger
;
2220 rpk
.version
.data
= &ver
;
2221 rpk
.version
.len
= 1;
2222 if (rawkey
->keytype
== KMF_RSA
) {
2223 rv
= DerEncodeRSAPrivateKey(&derkey
,
2224 &rawkey
->rawdata
.rsa
);
2227 } else if (rawkey
->keytype
== KMF_DSA
) {
2228 rv
= DerEncodeDSAPrivateKey(&derkey
,
2229 &rawkey
->rawdata
.dsa
);
2232 } else if (rawkey
->keytype
== KMF_ECDSA
) {
2233 rv
= DerEncodeECPrivateKey(&derkey
,
2234 &rawkey
->rawdata
.ec
);
2238 rpk
.algorithm
= nss_cert
->subjectPublicKeyInfo
.algorithm
;
2239 rpk
.privateKey
.data
= derkey
.Data
;
2240 rpk
.privateKey
.len
= derkey
.Length
;
2241 rpk
.attributes
= NULL
;
2243 ckrv
= PK11_ImportPrivateKeyInfo(nss_slot
, &rpk
, &nickname
,
2244 &nss_cert
->subjectPublicKeyInfo
.subjectPublicKey
, TRUE
,
2245 TRUE
, nss_cert
->keyUsage
, NULL
);
2246 if (ckrv
!= CKR_OK
) {
2247 SET_ERROR(kmfh
, PORT_GetError());
2248 rv
= KMF_ERR_INTERNAL
;
2250 kmf_free_data(&derkey
);
2251 } else if (pubkey
!= NULL
&& pubkey
->kstype
== KMF_KEYSTORE_NSS
) {
2252 CK_OBJECT_HANDLE pk
;
2253 SECKEYPublicKey
*publicKey
= (SECKEYPublicKey
*) pubkey
->keyp
;
2255 pk
= PK11_ImportPublicKey(nss_slot
, publicKey
, PR_TRUE
);
2256 if (pk
== CK_INVALID_HANDLE
) {
2257 SET_ERROR(kmfh
, PORT_GetError());
2258 rv
= KMF_ERR_INTERNAL
;
2260 } else if (prikey
!= NULL
&& prikey
->kstype
== KMF_KEYSTORE_NSS
) {
2261 SECKEYPrivateKey
*pk
;
2262 SECKEYPrivateKey
*privKey
= (SECKEYPrivateKey
*) prikey
->keyp
;
2264 pk
= PK11_LoadPrivKey(nss_slot
, privKey
, NULL
, PR_TRUE
,
2266 if (pk
== CK_INVALID_HANDLE
) {
2267 SET_ERROR(kmfh
, PORT_GetError());
2268 rv
= KMF_ERR_INTERNAL
;
2270 /* We stored it, but don't need the handle anymore */
2271 SECKEY_DestroyPrivateKey(pk
);
2275 if (nss_cert
!= NULL
)
2276 CERT_DestroyCertificate(nss_cert
);
2277 PK11_FreeSlot(nss_slot
);
2282 * This function is called by NSS_StoreCert() and NSS_ImportCert().
2283 * The "label" and "trust_flag" arguments can be NULL.
2286 store_cert(KMF_HANDLE_T handle
, PK11SlotInfo
*nss_slot
, KMF_DATA
*cert
,
2287 char *label
, char *trust_flag
)
2289 KMF_RETURN ret
= KMF_OK
;
2290 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
2292 CERTCertDBHandle
*certHandle
= CERT_GetDefaultCertDB();
2293 CERTCertificate
*nss_cert
= NULL
;
2294 CERTCertTrust
*nss_trust
= NULL
;
2296 if (nss_slot
== NULL
|| cert
== NULL
)
2297 return (KMF_ERR_BAD_PARAMETER
);
2299 nss_cert
= CERT_DecodeCertFromPackage((char *)cert
->Data
,
2301 if (nss_cert
== NULL
) {
2302 SET_ERROR(kmfh
, PORT_GetError());
2303 ret
= KMF_ERR_BAD_CERT_FORMAT
;
2307 /* Store the cert into the NSS database */
2308 nss_rv
= PK11_ImportCert(nss_slot
, nss_cert
, CK_INVALID_HANDLE
,
2311 SET_ERROR(kmfh
, nss_rv
);
2312 ret
= KMF_ERR_BAD_CERT_FORMAT
;
2316 /* If trust_flag is NULL, then we are done */
2317 if (trust_flag
== NULL
)
2320 nss_trust
= (CERTCertTrust
*) malloc(sizeof (CERTCertTrust
));
2321 if (nss_trust
== NULL
) {
2322 ret
= KMF_ERR_MEMORY
;
2326 nss_rv
= CERT_DecodeTrustString(nss_trust
, trust_flag
);
2328 SET_ERROR(kmfh
, nss_rv
);
2329 ret
= KMF_ERR_BAD_PARAMETER
;
2333 nss_rv
= CERT_ChangeCertTrust(certHandle
, nss_cert
, nss_trust
);
2335 SET_ERROR(kmfh
, nss_rv
);
2336 ret
= KMF_ERR_BAD_PARAMETER
;
2340 if (nss_cert
!= NULL
) {
2341 CERT_DestroyCertificate(nss_cert
);
2344 if (nss_trust
!= NULL
) {
2353 NSS_StoreCert(KMF_HANDLE_T handle
, int numattr
, KMF_ATTRIBUTE
*attrlist
)
2355 KMF_RETURN ret
= KMF_OK
;
2356 PK11SlotInfo
*nss_slot
= NULL
;
2357 KMF_DATA
*cert
= NULL
;
2359 char *trust_flag
= NULL
;
2361 if (handle
== NULL
|| attrlist
== NULL
|| numattr
== 0) {
2362 return (KMF_ERR_BAD_PARAMETER
);
2365 ret
= do_nss_init(handle
, numattr
, attrlist
, FALSE
, &nss_slot
);
2369 /* Get the cert data */
2370 cert
= kmf_get_attr_ptr(KMF_CERT_DATA_ATTR
, attrlist
, numattr
);
2371 if (cert
== NULL
|| cert
->Data
== NULL
)
2372 return (KMF_ERR_BAD_PARAMETER
);
2374 /* The label attribute is optional */
2375 label
= kmf_get_attr_ptr(KMF_CERT_LABEL_ATTR
, attrlist
, numattr
);
2377 /* The trustflag attriburte is optional */
2378 trust_flag
= kmf_get_attr_ptr(KMF_TRUSTFLAG_ATTR
, attrlist
, numattr
);
2380 ret
= store_cert(handle
, nss_slot
, cert
, label
, trust_flag
);
2383 if (nss_slot
!= NULL
) {
2384 PK11_FreeSlot(nss_slot
);
2392 NSS_ImportCert(KMF_HANDLE_T handle
, int numattr
, KMF_ATTRIBUTE
*attrlist
)
2394 KMF_RETURN ret
= KMF_OK
;
2395 PK11SlotInfo
*nss_slot
= NULL
;
2396 KMF_DATA cert
= { 0, NULL
};
2397 KMF_DATA cert_der
= { 0, NULL
};
2398 KMF_DATA
*cptr
= NULL
;
2399 KMF_ENCODE_FORMAT format
;
2401 char *trust_flag
= NULL
;
2402 char *certfile
= NULL
;
2404 if (handle
== NULL
|| attrlist
== NULL
|| numattr
== 0) {
2405 return (KMF_ERR_BAD_PARAMETER
);
2408 ret
= do_nss_init(handle
, numattr
, attrlist
, FALSE
, &nss_slot
);
2412 /* Get the input cert filename attribute */
2413 certfile
= kmf_get_attr_ptr(KMF_CERT_FILENAME_ATTR
, attrlist
, numattr
);
2414 if (certfile
== NULL
)
2415 return (KMF_ERR_BAD_PARAMETER
);
2417 /* Check the cert file and auto-detect the file format of it. */
2418 ret
= kmf_is_cert_file(handle
, certfile
, &format
);
2422 ret
= kmf_read_input_file(handle
, certfile
, &cert
);
2423 if (ret
!= KMF_OK
) {
2428 * If the imported cert is in PEM format, convert it to
2429 * DER format in order to store it in NSS token.
2431 if (format
== KMF_FORMAT_PEM
) {
2433 ret
= kmf_pem_to_der(cert
.Data
, cert
.Length
,
2434 &cert_der
.Data
, &derlen
);
2435 if (ret
!= KMF_OK
) {
2438 cert_der
.Length
= (size_t)derlen
;
2444 label
= kmf_get_attr_ptr(KMF_CERT_LABEL_ATTR
, attrlist
, numattr
);
2445 trust_flag
= kmf_get_attr_ptr(KMF_TRUSTFLAG_ATTR
, attrlist
, numattr
);
2446 ret
= store_cert(handle
, nss_slot
, cptr
, label
, trust_flag
);
2449 if (format
== KMF_FORMAT_PEM
) {
2450 kmf_free_data(&cert_der
);
2453 kmf_free_data(&cert
);
2460 NSS_ImportCRL(KMF_HANDLE_T handle
, int numattr
, KMF_ATTRIBUTE
*attrlist
)
2462 KMF_RETURN ret
= KMF_OK
;
2463 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
2464 PK11SlotInfo
*nss_slot
= NULL
;
2465 CERTSignedCrl
*nss_crl
= NULL
;
2466 KMF_ENCODE_FORMAT format
;
2472 boolean_t crlcheck
= FALSE
;
2474 if (attrlist
== NULL
|| numattr
== 0) {
2475 return (KMF_ERR_BAD_PARAMETER
);
2478 ret
= do_nss_init(handle
, numattr
, attrlist
, FALSE
, &nss_slot
);
2479 if (ret
!= KMF_OK
) {
2483 crlfilename
= kmf_get_attr_ptr(KMF_CRL_FILENAME_ATTR
, attrlist
,
2485 if (crlfilename
== NULL
)
2486 return (KMF_ERR_BAD_CRLFILE
);
2489 * Check if the input CRL file is a valid CRL file and auto-detect
2490 * the encoded format of the file.
2492 ret
= kmf_is_crl_file(handle
, crlfilename
, &format
);
2496 ret
= kmf_get_attr(KMF_CRL_CHECK_ATTR
, attrlist
, numattr
,
2499 ret
= KMF_OK
; /* CRL_CHECK is optional */
2501 /* set importOptions */
2502 if (crlcheck
== B_FALSE
) {
2503 importOptions
= CRL_IMPORT_DEFAULT_OPTIONS
|
2504 CRL_IMPORT_BYPASS_CHECKS
;
2506 importOptions
= CRL_IMPORT_DEFAULT_OPTIONS
;
2510 /* Read in the CRL file */
2513 ret
= kmf_read_input_file(handle
, crlfilename
, &crl1
);
2514 if (ret
!= KMF_OK
) {
2518 /* If the input CRL is in PEM format, convert it to DER first. */
2519 if (format
== KMF_FORMAT_PEM
) {
2521 ret
= kmf_pem_to_der(crl1
.Data
, crl1
.Length
,
2523 if (ret
!= KMF_OK
) {
2526 crl2
.Length
= (size_t)len
;
2529 crlDER
.data
= format
== KMF_FORMAT_ASN1
? crl1
.Data
: crl2
.Data
;
2530 crlDER
.len
= format
== KMF_FORMAT_ASN1
? crl1
.Length
: crl2
.Length
;
2532 nss_crl
= PK11_ImportCRL(nss_slot
, &crlDER
, NULL
, SEC_CRL_TYPE
,
2533 NULL
, importOptions
, NULL
, CRL_DECODE_DEFAULT_OPTIONS
);
2535 if (nss_crl
== NULL
) {
2536 SET_ERROR(kmfh
, PORT_GetError());
2537 ret
= KMF_ERR_BAD_CRLFILE
;
2542 if (nss_slot
!= NULL
) {
2543 PK11_FreeSlot(nss_slot
);
2546 if (crl1
.Data
!= NULL
) {
2550 if (crl2
.Data
!= NULL
) {
2554 if (nss_crl
!= NULL
) {
2555 (void) SEC_DestroyCrl(nss_crl
);
2562 NSS_DeleteCRL(KMF_HANDLE_T handle
, int numattr
, KMF_ATTRIBUTE
*attrlist
)
2564 KMF_RETURN rv
= KMF_OK
;
2565 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
2566 CERTSignedCrl
*crl
= NULL
;
2567 CERTCertificate
*cert
= NULL
;
2568 PK11SlotInfo
*nss_slot
= NULL
;
2569 CERTCrlHeadNode
*crlList
= NULL
;
2570 CERTCrlNode
*crlNode
= NULL
;
2571 PRArenaPool
*arena
= NULL
;
2572 CERTName
*name
= NULL
;
2573 CERTCertDBHandle
*certHandle
= CERT_GetDefaultCertDB();
2574 char *issuername
, *subjectname
;
2577 if (numattr
== 0 || attrlist
== NULL
) {
2578 return (KMF_ERR_BAD_PARAMETER
);
2581 rv
= do_nss_init(handle
, numattr
, attrlist
, FALSE
, &nss_slot
);
2586 issuername
= kmf_get_attr_ptr(KMF_ISSUER_NAME_ATTR
, attrlist
,
2588 subjectname
= kmf_get_attr_ptr(KMF_SUBJECT_NAME_ATTR
, attrlist
,
2591 /* Caller must specify issuer or subject but not both */
2592 if ((issuername
== NULL
&& subjectname
== NULL
) ||
2593 (issuername
!= NULL
&& subjectname
!= NULL
))
2594 return (KMF_ERR_BAD_PARAMETER
);
2596 /* Find the CRL based on the deletion criteria. */
2597 if (issuername
!= NULL
) {
2599 * If the deletion is based on the issuer's certificate
2600 * nickname, we will get the issuer's cert first, then
2601 * get the CRL from the cert.
2603 cert
= CERT_FindCertByNicknameOrEmailAddr(certHandle
,
2606 SET_ERROR(kmfh
, PORT_GetError());
2607 rv
= KMF_ERR_CERT_NOT_FOUND
;
2611 crl
= SEC_FindCrlByName(certHandle
, &cert
->derSubject
,
2614 SET_ERROR(kmfh
, PORT_GetError());
2615 rv
= KMF_ERR_CRL_NOT_FOUND
;
2620 * If the deletion is based on the CRL's subject name, we will
2621 * get all the CRLs from the internal database and search
2622 * for the CRL with the same subject name.
2624 boolean_t found
= B_FALSE
;
2627 nssrv
= SEC_LookupCrls(certHandle
, &crlList
, SEC_CRL_TYPE
);
2629 SET_ERROR(kmfh
, nssrv
);
2630 rv
= KMF_ERR_CRL_NOT_FOUND
;
2634 if (crlList
== NULL
) {
2635 SET_ERROR(kmfh
, PORT_GetError());
2636 rv
= KMF_ERR_CRL_NOT_FOUND
;
2640 /* Allocate space for name */
2641 arena
= PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE
);
2642 if (arena
== NULL
) {
2643 rv
= KMF_ERR_MEMORY
;
2647 name
= PORT_ArenaZAlloc(arena
, sizeof (*name
));
2649 rv
= KMF_ERR_MEMORY
;
2652 name
->arena
= arena
;
2654 crlNode
= crlList
->first
;
2655 while (crlNode
&& !found
) {
2656 char *asciiname
= NULL
;
2659 name
= &crlNode
->crl
->crl
.name
;
2661 SET_ERROR(kmfh
, PORT_GetError());
2662 rv
= KMF_ERR_CRL_NOT_FOUND
;
2666 asciiname
= CERT_NameToAscii(name
);
2667 if (asciiname
== NULL
) {
2668 SET_ERROR(kmfh
, PORT_GetError());
2669 rv
= KMF_ERR_CRL_NOT_FOUND
;
2673 if (strcmp(subjectname
, asciiname
) == 0) {
2675 issuer
= &crlNode
->crl
->crl
.derName
;
2676 crl
= SEC_FindCrlByName(certHandle
, issuer
,
2679 /* We found a cert but no CRL */
2680 SET_ERROR(kmfh
, PORT_GetError());
2681 rv
= KMF_ERR_CRL_NOT_FOUND
;
2684 PORT_Free(asciiname
);
2685 crlNode
= crlNode
->next
;
2694 (void) SEC_DeletePermCRL(crl
);
2698 if (nss_slot
!= NULL
) {
2699 PK11_FreeSlot(nss_slot
);
2702 if (crlList
!= NULL
) {
2703 PORT_FreeArena(crlList
->arena
, PR_FALSE
);
2706 if (arena
!= NULL
) {
2707 PORT_FreeArena(arena
, PR_FALSE
);
2711 CERT_DestroyCertificate(cert
);
2715 (void) SEC_DestroyCrl(crl
);
2722 NSS_FindCRL(KMF_HANDLE_T handle
, int numattr
, KMF_ATTRIBUTE
*attrlist
)
2724 KMF_RETURN rv
= KMF_OK
;
2725 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
2726 PK11SlotInfo
*nss_slot
= NULL
;
2727 CERTCrlHeadNode
*crlList
= NULL
;
2728 CERTCrlNode
*crlNode
= NULL
;
2729 PRArenaPool
*arena
= NULL
;
2730 CERTName
*name
= NULL
;
2732 char *asciiname
= NULL
;
2735 CERTCertDBHandle
*certHandle
= CERT_GetDefaultCertDB();
2738 if (numattr
== 0 || attrlist
== NULL
) {
2739 return (KMF_ERR_BAD_PARAMETER
);
2742 rv
= do_nss_init(handle
, numattr
, attrlist
, FALSE
, &nss_slot
);
2747 CRLCount
= kmf_get_attr_ptr(KMF_CRL_COUNT_ATTR
, attrlist
, numattr
);
2748 if (CRLCount
== NULL
)
2749 return (KMF_ERR_BAD_PARAMETER
);
2751 CRLNameList
= (char **)kmf_get_attr_ptr(KMF_CRL_NAMELIST_ATTR
,
2755 nssrv
= SEC_LookupCrls(certHandle
, &crlList
, SEC_CRL_TYPE
);
2757 SET_ERROR(kmfh
, rv
);
2758 rv
= KMF_ERR_CRL_NOT_FOUND
;
2762 /* Allocate space for name first */
2763 arena
= PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE
);
2764 if (arena
== NULL
) {
2765 rv
= KMF_ERR_MEMORY
;
2769 name
= PORT_ArenaZAlloc(arena
, sizeof (*name
));
2771 rv
= KMF_ERR_MEMORY
;
2774 name
->arena
= arena
;
2777 * Loop thru the crlList and create a crl list with CRL's subject name.
2779 crlNode
= crlList
->first
;
2784 /* Get the CRL subject name */
2785 name
= &crlNode
->crl
->crl
.name
;
2787 SET_ERROR(kmfh
, PORT_GetError());
2788 rv
= KMF_ERR_CRL_NOT_FOUND
;
2793 if (CRLNameList
!= NULL
) {
2794 asciiname
= CERT_NameToAscii(name
);
2795 if (asciiname
== NULL
) {
2796 SET_ERROR(kmfh
, PORT_GetError());
2797 rv
= KMF_ERR_CRL_NOT_FOUND
;
2800 subj_name
= strdup(asciiname
);
2801 PORT_Free(asciiname
);
2802 if (subj_name
== NULL
) {
2803 rv
= KMF_ERR_MEMORY
;
2806 CRLNameList
[crl_num
] = subj_name
;
2810 crlNode
= crlNode
->next
;
2815 *CRLCount
= crl_num
;
2819 if (nss_slot
!= NULL
) {
2820 PK11_FreeSlot(nss_slot
);
2823 if (crlList
!= NULL
) {
2824 PORT_FreeArena(crlList
->arena
, PR_FALSE
);
2827 if (arena
!= NULL
) {
2828 PORT_FreeArena(arena
, PR_FALSE
);
2831 /* If failed, free memory allocated for the returning rlist */
2832 if (rv
&& (CRLNameList
!= NULL
)) {
2833 for (i
= 0; i
< crl_num
; i
++) {
2834 free(CRLNameList
[i
]);
2842 NSS_FindCertInCRL(KMF_HANDLE_T handle
, int numattr
, KMF_ATTRIBUTE
*attrlist
)
2844 KMF_RETURN rv
= KMF_OK
;
2845 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
2846 PK11SlotInfo
*nss_slot
= NULL
;
2847 CERTCertificate
*cert
= NULL
;
2848 CERTSignedCrl
*crl
= NULL
;
2849 CERTCrlEntry
*entry
;
2850 boolean_t match
= B_FALSE
;
2852 CERTCertDBHandle
*certHandle
= CERT_GetDefaultCertDB();
2857 if (numattr
== 0 || attrlist
== NULL
) {
2858 return (KMF_ERR_BAD_PARAMETER
);
2861 rv
= do_nss_init(handle
, numattr
, attrlist
, FALSE
, &nss_slot
);
2866 certlabel
= kmf_get_attr_ptr(KMF_CERT_LABEL_ATTR
, attrlist
, numattr
);
2868 /* Find the certificate first */
2869 if (certlabel
!= NULL
) {
2870 cert
= CERT_FindCertByNicknameOrEmailAddr(certHandle
,
2873 SECItem derCert
= { siBuffer
, NULL
, 0 };
2875 certdata
= kmf_get_attr_ptr(KMF_CERT_DATA_ATTR
,
2878 if (certdata
== NULL
)
2879 return (KMF_ERR_BAD_PARAMETER
);
2881 derCert
.data
= certdata
->Data
;
2882 derCert
.len
= certdata
->Length
;
2884 cert
= CERT_FindCertByDERCert(certHandle
, &derCert
);
2888 SET_ERROR(kmfh
, PORT_GetError());
2889 rv
= KMF_ERR_CERT_NOT_FOUND
;
2893 /* Find the CRL with the same issuer as the given certificate. */
2894 crl
= SEC_FindCrlByName(certHandle
, &cert
->derIssuer
, SEC_CRL_TYPE
);
2897 * Could not find the CRL issued by the same issuer. This
2898 * usually means that the CRL is not installed in the DB.
2900 SET_ERROR(kmfh
, PORT_GetError());
2901 rv
= KMF_ERR_CRL_NOT_FOUND
;
2906 /* Check if the certificate's serialNumber is revoked in the CRL */
2908 while ((entry
= (crl
->crl
).entries
[i
++]) != NULL
) {
2909 if (SECITEM_CompareItem(&(cert
->serialNumber
),
2910 &(entry
->serialNumber
)) == SECEqual
) {
2917 rv
= KMF_ERR_NOT_REVOKED
;
2921 if (nss_slot
!= NULL
) {
2922 PK11_FreeSlot(nss_slot
);
2926 CERT_DestroyCertificate(cert
);
2930 (void) SEC_DestroyCrl(crl
);