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
;
1000 if (pqgParams
!= NULL
)
1001 PK11_PQG_DestroyParams(pqgParams
);
1003 if (ecparams
!= NULL
)
1004 SECITEM_FreeItem(ecparams
, PR_TRUE
);
1006 if (nss_slot
!= NULL
)
1007 PK11_FreeSlot(nss_slot
);
1013 NSS_SignData(KMF_HANDLE_T handle
, KMF_KEY_HANDLE
*key
,
1014 KMF_OID
*AlgOID
, KMF_DATA
*tobesigned
,
1017 KMF_RETURN ret
= KMF_OK
;
1018 KMF_ALGORITHM_INDEX AlgId
;
1019 SECOidTag signAlgTag
;
1020 SECKEYPrivateKey
*NSSprivkey
= NULL
;
1022 SECItem signed_data
;
1023 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
1025 signed_data
.data
= 0;
1026 if (key
== NULL
|| AlgOID
== NULL
||
1027 tobesigned
== NULL
|| output
== NULL
||
1028 tobesigned
->Data
== NULL
||
1029 output
->Data
== NULL
)
1030 return (KMF_ERR_BAD_PARAMETER
);
1032 /* Map the OID to a NSS algorithm */
1033 AlgId
= x509_algoid_to_algid(AlgOID
);
1034 if (AlgId
== KMF_ALGID_NONE
)
1035 return (KMF_ERR_BAD_PARAMETER
);
1037 NSSprivkey
= (SECKEYPrivateKey
*)key
->keyp
;
1039 if (AlgId
== KMF_ALGID_MD5WithRSA
)
1040 signAlgTag
= SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION
;
1041 else if (AlgId
== KMF_ALGID_MD2WithRSA
)
1042 signAlgTag
= SEC_OID_PKCS1_MD2_WITH_RSA_ENCRYPTION
;
1043 else if (AlgId
== KMF_ALGID_SHA1WithRSA
)
1044 signAlgTag
= SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION
;
1045 else if (AlgId
== KMF_ALGID_SHA256WithRSA
)
1046 signAlgTag
= SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION
;
1047 else if (AlgId
== KMF_ALGID_SHA384WithRSA
)
1048 signAlgTag
= SEC_OID_PKCS1_SHA384_WITH_RSA_ENCRYPTION
;
1049 else if (AlgId
== KMF_ALGID_SHA512WithRSA
)
1050 signAlgTag
= SEC_OID_PKCS1_SHA512_WITH_RSA_ENCRYPTION
;
1051 else if (AlgId
== KMF_ALGID_SHA1WithDSA
)
1052 signAlgTag
= SEC_OID_ANSIX9_DSA_SIGNATURE_WITH_SHA1_DIGEST
;
1053 else if (AlgId
== KMF_ALGID_SHA1WithECDSA
|| AlgId
== KMF_ALGID_ECDSA
)
1054 signAlgTag
= SEC_OID_ANSIX962_ECDSA_SIGNATURE_WITH_SHA1_DIGEST
;
1055 else if (AlgId
== KMF_ALGID_SHA256WithECDSA
)
1056 signAlgTag
= SEC_OID_ANSIX962_ECDSA_SHA256_SIGNATURE
;
1057 else if (AlgId
== KMF_ALGID_SHA384WithECDSA
)
1058 signAlgTag
= SEC_OID_ANSIX962_ECDSA_SHA384_SIGNATURE
;
1059 else if (AlgId
== KMF_ALGID_SHA512WithECDSA
)
1060 signAlgTag
= SEC_OID_ANSIX962_ECDSA_SHA512_SIGNATURE
;
1061 else /* NSS does not support DSA with SHA2 hashes (FIPS 186-3) */
1062 return (KMF_ERR_BAD_PARAMETER
);
1064 rv
= SEC_SignData(&signed_data
, tobesigned
->Data
,
1065 tobesigned
->Length
, NSSprivkey
, signAlgTag
);
1068 SET_ERROR(kmfh
, rv
);
1069 return (KMF_ERR_INTERNAL
);
1072 if (signed_data
.len
<= output
->Length
) {
1073 (void) memcpy(output
->Data
, signed_data
.data
, signed_data
.len
);
1074 output
->Length
= signed_data
.len
;
1077 ret
= KMF_ERR_BAD_PARAMETER
;
1079 free(signed_data
.data
);
1085 NSS_EncodePubKeyData(KMF_HANDLE_T handle
, KMF_KEY_HANDLE
*keyp
,
1088 KMF_RETURN ret
= KMF_OK
;
1089 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
1091 CERTSubjectPublicKeyInfo
*spki
= NULL
;
1093 if (keyp
== NULL
|| encoded
== NULL
|| keyp
->keyp
== NULL
)
1094 return (KMF_ERR_BAD_PARAMETER
);
1096 spki
= SECKEY_CreateSubjectPublicKeyInfo(keyp
->keyp
);
1098 SET_ERROR(kmfh
, PORT_GetError());
1099 return (KMF_ERR_MEMORY
);
1102 rvitem
= SEC_ASN1EncodeItem(NULL
, NULL
, spki
,
1103 CERT_SubjectPublicKeyInfoTemplate
);
1104 if (rvitem
!= NULL
) {
1105 encoded
->Data
= malloc(rvitem
->len
);
1106 if (encoded
->Data
== NULL
) {
1107 ret
= KMF_ERR_MEMORY
;
1109 (void) memcpy(encoded
->Data
, rvitem
->data
, rvitem
->len
);
1110 encoded
->Length
= rvitem
->len
;
1112 SECITEM_FreeItem(rvitem
, TRUE
);
1114 SET_ERROR(kmfh
, PORT_GetError());
1115 encoded
->Data
= NULL
;
1116 encoded
->Length
= 0;
1117 ret
= KMF_ERR_ENCODING
;
1119 SECKEY_DestroySubjectPublicKeyInfo(spki
);
1125 NSS_DeleteKey(KMF_HANDLE_T handle
,
1126 int numattr
, KMF_ATTRIBUTE
*attrlist
)
1128 KMF_RETURN rv
= KMF_OK
;
1129 PK11SlotInfo
*nss_slot
= NULL
;
1130 KMF_KEY_HANDLE
*key
;
1131 KMF_CREDENTIAL cred
;
1132 boolean_t delete_token
= B_TRUE
;
1134 if (handle
== NULL
|| attrlist
== NULL
|| numattr
== 0) {
1135 return (KMF_ERR_BAD_PARAMETER
);
1138 * "delete_token" means to clear it from the token storage as well
1141 key
= kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR
, attrlist
, numattr
);
1142 if (key
== NULL
|| key
->keyp
== NULL
)
1143 return (KMF_ERR_BAD_PARAMETER
);
1145 rv
= kmf_get_attr(KMF_DESTROY_BOOL_ATTR
, attrlist
, numattr
,
1146 (void *)&delete_token
, NULL
);
1148 /* "delete_token" is optional. Default is TRUE */
1152 SECStatus nssrv
= SECSuccess
;
1153 if (key
->keyclass
!= KMF_ASYM_PUB
&&
1154 key
->keyclass
!= KMF_ASYM_PRI
&&
1155 key
->keyclass
!= KMF_SYMMETRIC
)
1156 return (KMF_ERR_BAD_KEY_CLASS
);
1158 rv
= do_nss_init(handle
, numattr
, attrlist
, FALSE
, &nss_slot
);
1163 rv
= kmf_get_attr(KMF_CREDENTIAL_ATTR
, attrlist
, numattr
,
1164 (void *)&cred
, NULL
);
1166 return (KMF_ERR_BAD_PARAMETER
);
1168 rv
= nss_authenticate(handle
, nss_slot
, &cred
);
1173 if (key
->keyclass
== KMF_ASYM_PUB
) {
1174 nssrv
= PK11_DeleteTokenPublicKey(
1175 (SECKEYPublicKey
*)key
->keyp
);
1176 } else if (key
->keyclass
== KMF_ASYM_PRI
) {
1177 nssrv
= PK11_DeleteTokenPrivateKey(
1178 (SECKEYPrivateKey
*)key
->keyp
, PR_TRUE
);
1179 } else if (key
->keyclass
== KMF_SYMMETRIC
) {
1180 nssrv
= PK11_DeleteTokenSymKey(
1181 (PK11SymKey
*) key
->keyp
);
1182 if (nssrv
== SECSuccess
)
1183 PK11_FreeSymKey((PK11SymKey
*) key
->keyp
);
1185 if (nssrv
!= SECSuccess
) {
1186 SET_ERROR(handle
, PORT_GetError());
1187 rv
= KMF_ERR_INTERNAL
;
1190 if (key
->keyclass
== KMF_ASYM_PUB
) {
1191 SECKEY_DestroyPublicKey((SECKEYPublicKey
*)key
->keyp
);
1192 } else if (key
->keyclass
== KMF_ASYM_PRI
) {
1193 SECKEY_DestroyPrivateKey((SECKEYPrivateKey
*)key
->keyp
);
1194 } else if (key
->keyclass
== KMF_SYMMETRIC
) {
1195 PK11_FreeSymKey((PK11SymKey
*) key
->keyp
);
1197 return (KMF_ERR_BAD_KEY_CLASS
);
1206 NSS_GetErrorString(KMF_HANDLE_T handle
, char **msgstr
)
1208 KMF_RETURN ret
= KMF_OK
;
1209 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
1212 /* Get the error string in the default language */
1213 str
= (char *)PR_ErrorToName((PRErrorCode
)kmfh
->lasterr
.errcode
);
1216 *msgstr
= (char *)strdup(str
);
1217 if ((*msgstr
) == NULL
)
1218 ret
= KMF_ERR_MEMORY
;
1227 NSS_FindPrikeyByCert(KMF_HANDLE_T handle
, int numattr
, KMF_ATTRIBUTE
*attrlist
)
1229 KMF_RETURN rv
= KMF_OK
;
1230 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
1231 PK11SlotInfo
*nss_slot
= NULL
;
1232 KMF_CREDENTIAL cred
;
1233 KMF_KEY_HANDLE
*key
= NULL
;
1234 KMF_DATA
*cert
= NULL
;
1235 CERTCertificate
*nss_cert
= NULL
;
1236 SECKEYPrivateKey
* privkey
= NULL
;
1238 if (handle
== NULL
|| attrlist
== NULL
|| numattr
== 0) {
1239 return (KMF_ERR_BAD_PARAMETER
);
1242 rv
= do_nss_init(handle
, numattr
, attrlist
, FALSE
, &nss_slot
);
1246 /* Get the credential */
1247 rv
= kmf_get_attr(KMF_CREDENTIAL_ATTR
, attrlist
, numattr
,
1248 (void *)&cred
, NULL
);
1250 return (KMF_ERR_BAD_PARAMETER
);
1251 rv
= nss_authenticate(handle
, nss_slot
, &cred
);
1255 /* Get the key handle */
1256 key
= kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR
, attrlist
, numattr
);
1258 return (KMF_ERR_BAD_PARAMETER
);
1260 /* Get the cert data and decode it */
1261 cert
= kmf_get_attr_ptr(KMF_CERT_DATA_ATTR
, attrlist
, numattr
);
1262 if (cert
== NULL
|| cert
->Data
== NULL
)
1263 return (KMF_ERR_BAD_PARAMETER
);
1265 nss_cert
= CERT_DecodeCertFromPackage((char *)cert
->Data
,
1267 if (nss_cert
== NULL
) {
1268 SET_ERROR(kmfh
, PORT_GetError());
1269 return (KMF_ERR_BAD_CERT_FORMAT
);
1272 privkey
= PK11_FindPrivateKeyFromCert(nss_slot
, nss_cert
, NULL
);
1273 if (privkey
== NULL
) {
1274 SET_ERROR(kmfh
, PORT_GetError());
1275 return (KMF_ERR_KEY_NOT_FOUND
);
1278 key
->kstype
= KMF_KEYSTORE_NSS
;
1279 key
->keyclass
= KMF_ASYM_PRI
;
1280 key
->keyp
= (void *)privkey
;
1281 key
->keylabel
= PK11_GetPrivateKeyNickname(privkey
);
1283 CERT_DestroyCertificate(nss_cert
);
1290 NSS_DecryptData(KMF_HANDLE_T handle
, KMF_KEY_HANDLE
*key
,
1291 KMF_OID
*AlgOID
, KMF_DATA
*ciphertext
,
1294 KMF_RETURN ret
= KMF_OK
;
1295 SECKEYPrivateKey
*NSSprivkey
= NULL
;
1297 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
1298 unsigned int in_len
= 0, out_len
= 0;
1299 unsigned int total_decrypted
= 0, modulus_len
= 0;
1300 uint8_t *in_data
, *out_data
;
1303 if (key
== NULL
|| AlgOID
== NULL
||
1304 ciphertext
== NULL
|| output
== NULL
||
1305 ciphertext
->Data
== NULL
||
1306 output
->Data
== NULL
)
1307 return (KMF_ERR_BAD_PARAMETER
);
1309 NSSprivkey
= (SECKEYPrivateKey
*)key
->keyp
;
1310 modulus_len
= PK11_GetPrivateModulusLen(NSSprivkey
);
1312 blocks
= ciphertext
->Length
/modulus_len
;
1313 out_data
= output
->Data
;
1314 in_data
= ciphertext
->Data
;
1315 out_len
= modulus_len
- 11;
1316 in_len
= modulus_len
;
1318 for (i
= 0; i
< blocks
; i
++) {
1319 rv
= PK11_PrivDecryptPKCS1(NSSprivkey
, out_data
,
1320 &out_len
, ciphertext
->Length
, in_data
, in_len
);
1323 SET_ERROR(kmfh
, rv
);
1324 return (KMF_ERR_INTERNAL
);
1327 out_data
+= out_len
;
1328 total_decrypted
+= out_len
;
1332 output
->Length
= total_decrypted
;
1338 pk11keytype2kmf(CK_KEY_TYPE type
)
1357 return (KMF_KEYALG_NONE
);
1362 NSS_FindKey(KMF_HANDLE_T handle
,
1363 int numattr
, KMF_ATTRIBUTE
*attrlist
)
1366 SECKEYPrivateKeyList
*prilist
;
1367 SECKEYPrivateKeyListNode
*prinode
;
1368 SECKEYPublicKeyList
*publist
;
1369 SECKEYPublicKeyListNode
*pubnode
;
1370 PK11SlotInfo
*nss_slot
= NULL
;
1371 PK11SymKey
*symlist
= NULL
;
1374 KMF_KEY_HANDLE
*keys
;
1376 KMF_CREDENTIAL
*cred
= NULL
;
1377 KMF_KEY_CLASS keyclass
;
1381 KMF_KEY_ALG keytype
= KMF_KEYALG_NONE
;
1383 if (handle
== NULL
|| attrlist
== NULL
|| numattr
== 0) {
1384 return (KMF_ERR_BAD_PARAMETER
);
1387 numkeys
= kmf_get_attr_ptr(KMF_COUNT_ATTR
, attrlist
, numattr
);
1388 if (numkeys
== NULL
)
1389 return (KMF_ERR_BAD_PARAMETER
);
1391 rv
= do_nss_init(handle
, numattr
, attrlist
, FALSE
, &nss_slot
);
1396 /* It is OK if this is NULL, we dont need a cred to find public keys */
1397 cred
= kmf_get_attr_ptr(KMF_CREDENTIAL_ATTR
, attrlist
, numattr
);
1400 rv
= nss_authenticate(handle
, nss_slot
, cred
);
1408 maxkeys
= 0xFFFFFFFF;
1411 rv
= kmf_get_attr(KMF_KEYCLASS_ATTR
, attrlist
, numattr
,
1412 (void *)&keyclass
, NULL
);
1414 return (KMF_ERR_BAD_PARAMETER
);
1416 findLabel
= kmf_get_attr_ptr(KMF_KEYLABEL_ATTR
, attrlist
, numattr
);
1418 if (keyclass
== KMF_ASYM_PUB
) {
1419 publist
= PK11_ListPublicKeysInSlot(nss_slot
, findLabel
);
1420 if (publist
== NULL
) {
1421 rv
= KMF_ERR_KEY_NOT_FOUND
;
1424 } else if (keyclass
== KMF_ASYM_PRI
) {
1425 prilist
= PK11_ListPrivKeysInSlot(nss_slot
, findLabel
, NULL
);
1426 if (prilist
== NULL
) {
1427 rv
= KMF_ERR_KEY_NOT_FOUND
;
1430 } else if (keyclass
== KMF_SYMMETRIC
) {
1431 symlist
= PK11_ListFixedKeysInSlot(nss_slot
, findLabel
, NULL
);
1432 if (symlist
== NULL
) {
1433 rv
= KMF_ERR_KEY_NOT_FOUND
;
1437 rv
= KMF_ERR_BAD_KEY_CLASS
;
1441 keys
= kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR
, attrlist
, numattr
);
1442 /* it is okay to have "keys" contains NULL */
1444 if (keyclass
== KMF_ASYM_PUB
) {
1445 for (count
= 0, pubnode
= PUBKEY_LIST_HEAD(publist
);
1446 !PUBKEY_LIST_END(pubnode
, publist
) && count
< maxkeys
;
1447 pubnode
= PUBKEY_LIST_NEXT(pubnode
)) {
1450 * Due to bug in NSS, we have to manually match
1451 * the labels to be sure we have a match.
1453 nick
= PK11_GetPublicKeyNickname(pubnode
->key
);
1456 (strcmp(nick
, findLabel
) == 0));
1458 /* always match if findLabel is NULL */
1461 if (keys
!= NULL
&& match
) {
1462 keys
[count
].kstype
= KMF_KEYSTORE_NSS
;
1463 keys
[count
].keyclass
= KMF_ASYM_PUB
;
1464 keys
[count
].keyp
= (void *)pubnode
->key
;
1465 keys
[count
].keylabel
= nick
;
1467 if (pubnode
->key
->keyType
== rsaKey
)
1468 keys
[count
].keyalg
= KMF_RSA
;
1469 else if (pubnode
->key
->keyType
== dsaKey
)
1470 keys
[count
].keyalg
= KMF_DSA
;
1471 else if (pubnode
->key
->keyType
== ecKey
)
1472 keys
[count
].keyalg
= KMF_ECDSA
;
1478 } else if (keyclass
== KMF_ASYM_PRI
) {
1479 for (count
= 0, prinode
= PRIVKEY_LIST_HEAD(prilist
);
1480 !PRIVKEY_LIST_END(prinode
, prilist
) && count
< maxkeys
;
1481 prinode
= PRIVKEY_LIST_NEXT(prinode
)) {
1484 * Due to bug in NSS, we have to manually match
1485 * the labels to be sure we have a match.
1487 nick
= PK11_GetPrivateKeyNickname(prinode
->key
);
1490 (strcmp(nick
, findLabel
) == 0));
1492 /* always match if findLabel is NULL */
1495 if (keys
!= NULL
&& match
) {
1496 keys
[count
].kstype
= KMF_KEYSTORE_NSS
;
1497 keys
[count
].keyclass
= KMF_ASYM_PRI
;
1498 keys
[count
].keyp
= (void *)prinode
->key
;
1499 keys
[count
].keylabel
= nick
;
1501 if (prinode
->key
->keyType
== rsaKey
)
1502 keys
[count
].keyalg
= KMF_RSA
;
1503 else if (prinode
->key
->keyType
== dsaKey
)
1504 keys
[count
].keyalg
= KMF_DSA
;
1505 else if (prinode
->key
->keyType
== ecKey
)
1506 keys
[count
].keyalg
= KMF_ECDSA
;
1512 } else if (keyclass
== KMF_SYMMETRIC
) {
1514 rv
= kmf_get_attr(KMF_KEYALG_ATTR
, attrlist
, numattr
,
1515 (void *)&keytype
, NULL
);
1518 while (symlist
&& count
< maxkeys
) {
1519 PK11SymKey
*symkey
= symlist
;
1524 type
= PK11_GetSymKeyType(symkey
);
1525 keyalg
= pk11keytype2kmf(type
);
1527 symlist
= PK11_GetNextSymKey(symkey
);
1530 * If keytype is specified in the searching parameter,
1531 * check the keytype and skip the key if its keytype
1534 if (keytype
!= KMF_KEYALG_NONE
&& keytype
!= keyalg
) {
1535 /* free that key since we arent using it */
1536 PK11_FreeSymKey(symkey
);
1540 * Due to bug in NSS, we have to manually match
1541 * the labels to be sure we have a match.
1543 nick
= PK11_GetSymKeyNickname(symkey
);
1546 (strcmp(nick
, findLabel
) == 0));
1548 /* always match if findLabel is NULL */
1552 if (keys
!= NULL
&& match
) {
1553 keys
[count
].kstype
= KMF_KEYSTORE_NSS
;
1554 keys
[count
].keyclass
= KMF_SYMMETRIC
;
1555 keys
[count
].keyp
= (void *) symkey
;
1556 keys
[count
].keylabel
= nick
;
1557 keys
[count
].keyalg
= keyalg
;
1559 PK11_FreeSymKey(symkey
);
1565 * Cleanup memory for unused keys.
1567 while (symlist
!= NULL
) {
1568 PK11SymKey
*symkey
= symlist
;
1570 PK11_FreeSymKey(symkey
);
1571 symlist
= PK11_GetNextSymKey(symkey
);
1577 if (nss_slot
!= NULL
) {
1578 PK11_FreeSlot(nss_slot
);
1585 p12u_SwapUnicodeBytes(SECItem
*uniItem
)
1589 if ((uniItem
== NULL
) || (uniItem
->len
% 2)) {
1590 return (SECFailure
);
1592 for (i
= 0; i
< uniItem
->len
; i
+= 2) {
1593 a
= uniItem
->data
[i
];
1594 uniItem
->data
[i
] = uniItem
->data
[i
+1];
1595 uniItem
->data
[i
+1] = a
;
1597 return (SECSuccess
);
1601 p12u_ucs2_ascii_conversion_function(
1603 unsigned char *inBuf
,
1604 unsigned int inBufLen
,
1605 unsigned char *outBuf
,
1606 unsigned int maxOutBufLen
,
1607 unsigned int *outBufLen
,
1610 SECItem it
= { siBuffer
, NULL
, 0 };
1611 SECItem
*dup
= NULL
;
1616 dup
= SECITEM_DupItem(&it
);
1618 * If converting Unicode to ASCII, swap bytes before conversion
1621 if (!toUnicode
&& swapBytes
) {
1622 if (p12u_SwapUnicodeBytes(dup
) != SECSuccess
) {
1623 SECITEM_ZfreeItem(dup
, PR_TRUE
);
1627 /* Perform the conversion. */
1628 ret
= PORT_UCS2_UTF8Conversion(toUnicode
, dup
->data
, dup
->len
,
1629 outBuf
, maxOutBufLen
, outBufLen
);
1631 SECITEM_ZfreeItem(dup
, PR_TRUE
);
1637 p12u_OpenFile(p12uContext
*p12ctx
, PRBool fileRead
)
1639 if (!p12ctx
|| !p12ctx
->filename
) {
1644 p12ctx
->file
= PR_Open(p12ctx
->filename
, PR_RDONLY
, 0400);
1646 p12ctx
->file
= PR_Open(p12ctx
->filename
,
1647 PR_CREATE_FILE
| PR_RDWR
| PR_TRUNCATE
, 0600);
1650 if (!p12ctx
->file
) {
1651 p12ctx
->error
= PR_TRUE
;
1659 p12u_DestroyContext(p12uContext
**ppCtx
, PRBool removeFile
)
1661 if (!ppCtx
|| !(*ppCtx
)) {
1665 if ((*ppCtx
)->file
!= NULL
) {
1666 (void) PR_Close((*ppCtx
)->file
);
1669 if ((*ppCtx
)->filename
!= NULL
) {
1671 (void) PR_Delete((*ppCtx
)->filename
);
1673 free((*ppCtx
)->filename
);
1680 static p12uContext
*
1681 p12u_InitContext(PRBool fileImport
, char *filename
)
1683 p12uContext
*p12ctx
;
1685 p12ctx
= PORT_ZNew(p12uContext
);
1690 p12ctx
->error
= PR_FALSE
;
1691 p12ctx
->errorValue
= 0;
1692 p12ctx
->filename
= strdup(filename
);
1694 if (!p12u_OpenFile(p12ctx
, fileImport
)) {
1695 p12u_DestroyContext(&p12ctx
, PR_FALSE
);
1703 p12u_WriteToExportFile(void *arg
, const char *buf
, unsigned long len
)
1705 p12uContext
*p12cxt
= arg
;
1708 if (!p12cxt
|| (p12cxt
->error
== PR_TRUE
)) {
1712 if (p12cxt
->file
== NULL
) {
1713 p12cxt
->errorValue
= SEC_ERROR_PKCS12_UNABLE_TO_WRITE
;
1714 p12cxt
->error
= PR_TRUE
;
1718 writeLen
= PR_Write(p12cxt
->file
, (unsigned char *)buf
, (int32
)len
);
1720 if (writeLen
!= (int)len
) {
1721 (void) PR_Close(p12cxt
->file
);
1722 free(p12cxt
->filename
);
1723 p12cxt
->filename
= NULL
;
1724 p12cxt
->file
= NULL
;
1725 p12cxt
->errorValue
= SEC_ERROR_PKCS12_UNABLE_TO_WRITE
;
1726 p12cxt
->error
= PR_TRUE
;
1730 #define HANDLE_NSS_ERROR(r) {\
1731 SET_ERROR(kmfh, PORT_GetError()); \
1736 add_cert_to_bag(SEC_PKCS12ExportContext
*p12ecx
,
1737 CERTCertificate
*cert
, SECItem
*pwitem
)
1739 KMF_RETURN rv
= KMF_OK
;
1740 SEC_PKCS12SafeInfo
*keySafe
= NULL
, *certSafe
= NULL
;
1742 keySafe
= SEC_PKCS12CreateUnencryptedSafe(p12ecx
);
1743 if (PK11_IsFIPS()) {
1746 certSafe
= SEC_PKCS12CreatePasswordPrivSafe(p12ecx
, pwitem
,
1747 SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC
);
1750 if (!certSafe
|| !keySafe
) {
1751 rv
= KMF_ERR_INTERNAL
;
1755 if (SEC_PKCS12AddCertAndKey(p12ecx
, certSafe
, NULL
, cert
,
1756 CERT_GetDefaultCertDB(), keySafe
, NULL
, PR_TRUE
, pwitem
,
1757 SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_3KEY_TRIPLE_DES_CBC
)
1759 rv
= KMF_ERR_INTERNAL
;
1766 NSS_ExportPK12(KMF_HANDLE_T handle
, int numattr
, KMF_ATTRIBUTE
*attrlist
)
1769 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
1770 SEC_PKCS12ExportContext
*p12ecx
= NULL
;
1771 p12uContext
*p12ctx
= NULL
;
1772 CERTCertList
*certlist
= NULL
;
1773 CERTCertificate
*nsscert
= NULL
;
1774 CERTCertListNode
* node
= NULL
;
1775 PK11SlotInfo
*slot
= NULL
;
1776 SECItem pwitem
= { siBuffer
, NULL
, 0 };
1777 KMF_CREDENTIAL
*cred
= NULL
;
1778 KMF_CREDENTIAL
*p12cred
= NULL
;
1779 char *certlabel
= NULL
;
1780 char *issuer
= NULL
;
1781 char *subject
= NULL
;
1782 KMF_BIGINT
*serial
= NULL
;
1783 char *filename
= NULL
;
1785 if (kmfh
== NULL
|| attrlist
== NULL
|| numattr
== 0) {
1786 return (KMF_ERR_BAD_PARAMETER
);
1789 rv
= do_nss_init(handle
, numattr
, attrlist
, FALSE
, &slot
);
1793 cred
= kmf_get_attr_ptr(KMF_CREDENTIAL_ATTR
, attrlist
, numattr
);
1795 return (KMF_ERR_BAD_PARAMETER
);
1797 rv
= nss_authenticate(handle
, slot
, cred
);
1801 p12cred
= kmf_get_attr_ptr(KMF_PK12CRED_ATTR
, attrlist
, numattr
);
1802 if (p12cred
== NULL
)
1803 return (KMF_ERR_BAD_PARAMETER
);
1805 filename
= kmf_get_attr_ptr(KMF_OUTPUT_FILENAME_ATTR
, attrlist
,
1807 if (filename
== NULL
)
1808 return (KMF_ERR_BAD_PARAMETER
);
1810 /* Get optional search criteria attributes */
1811 certlabel
= kmf_get_attr_ptr(KMF_CERT_LABEL_ATTR
, attrlist
, numattr
);
1812 issuer
= kmf_get_attr_ptr(KMF_ISSUER_NAME_ATTR
, attrlist
, numattr
);
1813 subject
= kmf_get_attr_ptr(KMF_SUBJECT_NAME_ATTR
, attrlist
, numattr
);
1814 serial
= kmf_get_attr_ptr(KMF_BIGINT_ATTR
, attrlist
, numattr
);
1817 * Find the certificate(s) first.
1819 if (certlabel
!= NULL
) {
1820 nsscert
= PK11_FindCertFromNickname(certlabel
, NULL
);
1821 if (nsscert
== NULL
) {
1822 HANDLE_NSS_ERROR(KMF_ERR_CERT_NOT_FOUND
)
1825 rv
= nss_find_matching_certs(slot
, issuer
, subject
, serial
,
1828 if (rv
== KMF_OK
&& certlist
== NULL
) {
1829 return (KMF_ERR_CERT_NOT_FOUND
);
1836 * The KMF_CREDENTIAL holds the password to use for
1837 * encrypting the PKCS12 key information.
1839 pwitem
.data
= (uchar_t
*)p12cred
->cred
;
1840 pwitem
.len
= p12cred
->credlen
;
1842 p12ctx
= p12u_InitContext(PR_FALSE
, filename
);
1844 HANDLE_NSS_ERROR(KMF_ERR_OPEN_FILE
)
1847 PORT_SetUCS2_ASCIIConversionFunction(
1848 p12u_ucs2_ascii_conversion_function
);
1850 p12ecx
= SEC_PKCS12CreateExportContext(NULL
, NULL
, slot
, NULL
);
1852 HANDLE_NSS_ERROR(KMF_ERR_OPEN_FILE
)
1855 if (SEC_PKCS12AddPasswordIntegrity(p12ecx
, &pwitem
, SEC_OID_SHA1
)
1857 HANDLE_NSS_ERROR(KMF_ERR_INTERNAL
)
1861 * NSS actually supports storing a list of keys and certs
1862 * in the PKCS#12 PDU. Nice feature.
1864 if (certlist
!= NULL
) {
1865 for (node
= CERT_LIST_HEAD(certlist
);
1866 !CERT_LIST_END(node
, certlist
) && rv
== KMF_OK
;
1867 node
= CERT_LIST_NEXT(node
)) {
1868 rv
= add_cert_to_bag(p12ecx
, node
->cert
, &pwitem
);
1870 } else if (nsscert
!= NULL
) {
1871 rv
= add_cert_to_bag(p12ecx
, nsscert
, &pwitem
);
1874 if (SEC_PKCS12Encode(p12ecx
, p12u_WriteToExportFile
, p12ctx
)
1876 HANDLE_NSS_ERROR(KMF_ERR_ENCODING
)
1880 CERT_DestroyCertificate(nsscert
);
1883 CERT_DestroyCertList(certlist
);
1886 p12u_DestroyContext(&p12ctx
, PR_FALSE
);
1889 SEC_PKCS12DestroyExportContext(p12ecx
);
1894 #define SETATTR(t, n, atype, value, size) \
1895 t[n].type = atype; \
1896 t[n].pValue = (CK_BYTE *)value; \
1897 t[n].ulValueLen = (CK_ULONG)size;
1900 NSS_CreateSymKey(KMF_HANDLE_T handle
,
1901 int numattr
, KMF_ATTRIBUTE
*attrlist
)
1903 KMF_RETURN rv
= KMF_OK
;
1904 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
1905 PK11SlotInfo
*nss_slot
= NULL
;
1906 PK11SymKey
*nsskey
= NULL
;
1907 CK_MECHANISM_TYPE keyType
;
1910 KMF_KEY_HANDLE
*symkey
;
1911 KMF_CREDENTIAL cred
;
1913 uint32_t keylen_size
= sizeof (uint32_t);
1914 KMF_KEY_ALG keytype
;
1915 char *keylabel
= NULL
;
1917 if (kmfh
== NULL
|| attrlist
== NULL
|| numattr
== 0) {
1918 return (KMF_ERR_BAD_PARAMETER
);
1921 symkey
= kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR
, attrlist
, numattr
);
1923 return (KMF_ERR_BAD_PARAMETER
);
1925 rv
= kmf_get_attr(KMF_KEYALG_ATTR
, attrlist
, numattr
, (void *)&keytype
,
1928 return (KMF_ERR_BAD_PARAMETER
);
1930 rv
= kmf_get_attr(KMF_KEYLENGTH_ATTR
, attrlist
, numattr
, &keylen
,
1932 if (rv
== KMF_ERR_ATTR_NOT_FOUND
&&
1933 (keytype
== KMF_DES
|| keytype
== KMF_DES3
))
1934 /* keylength is not required for DES and 3DES */
1937 return (KMF_ERR_BAD_PARAMETER
);
1939 keylabel
= kmf_get_attr_ptr(KMF_KEYLABEL_ATTR
, attrlist
, numattr
);
1940 if (keylabel
== NULL
)
1941 return (KMF_ERR_BAD_PARAMETER
);
1945 keyType
= CKM_AES_KEY_GEN
;
1947 if (keySize
== 0 || (keySize
% 8) != 0)
1948 return (KMF_ERR_BAD_KEY_SIZE
);
1951 keyType
= CKM_RC4_KEY_GEN
;
1953 if (keySize
== 0 || (keySize
% 8) != 0)
1954 return (KMF_ERR_BAD_KEY_SIZE
);
1957 keyType
= CKM_DES_KEY_GEN
;
1958 keySize
= 0; /* required by PK11_TokenKeyGen() */
1961 keyType
= CKM_DES3_KEY_GEN
;
1962 keySize
= 0; /* required by PK11_TokenKeyGen() */
1964 case KMF_GENERIC_SECRET
:
1965 keyType
= CKM_GENERIC_SECRET_KEY_GEN
;
1967 if (keySize
== 0 || (keySize
% 8) != 0)
1968 return (KMF_ERR_BAD_KEY_SIZE
);
1971 rv
= KMF_ERR_BAD_KEY_TYPE
;
1975 rv
= do_nss_init(handle
, numattr
, attrlist
, FALSE
, &nss_slot
);
1980 rv
= kmf_get_attr(KMF_CREDENTIAL_ATTR
, attrlist
, numattr
,
1981 (void *)&cred
, NULL
);
1983 return (KMF_ERR_BAD_PARAMETER
);
1985 rv
= nss_authenticate(handle
, nss_slot
, &cred
);
1990 /* convert key length to bytes */
1991 nsskey
= PK11_TokenKeyGen(nss_slot
, keyType
, NULL
, keySize
/ 8, NULL
,
1992 PR_TRUE
, (void *)cred
.cred
);
1993 if (nsskey
== NULL
) {
1994 SET_ERROR(kmfh
, PORT_GetError());
1995 rv
= KMF_ERR_KEYGEN_FAILED
;
1999 nssrv
= PK11_SetSymKeyNickname(nsskey
, keylabel
);
2000 if (nssrv
!= SECSuccess
) {
2001 SET_ERROR(kmfh
, PORT_GetError());
2002 rv
= KMF_ERR_KEYGEN_FAILED
;
2006 symkey
->kstype
= KMF_KEYSTORE_NSS
;
2007 symkey
->keyalg
= keytype
;
2008 symkey
->keyclass
= KMF_SYMMETRIC
;
2009 symkey
->israw
= FALSE
;
2010 symkey
->keyp
= (void *)nsskey
;
2013 if (nss_slot
!= NULL
)
2014 PK11_FreeSlot(nss_slot
);
2016 if (rv
!= KMF_OK
&& nsskey
!= NULL
) {
2017 (void) PK11_DeleteTokenSymKey(nsskey
);
2018 PK11_FreeSymKey(nsskey
);
2024 NSS_GetSymKeyValue(KMF_HANDLE_T handle
, KMF_KEY_HANDLE
*symkey
,
2025 KMF_RAW_SYM_KEY
*rkey
)
2027 KMF_RETURN rv
= KMF_OK
;
2028 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
2029 SECItem
*value
= NULL
;
2034 return (KMF_ERR_UNINITIALIZED
);
2036 if (symkey
== NULL
|| rkey
== NULL
)
2037 return (KMF_ERR_BAD_PARAMETER
);
2038 else if (symkey
->keyclass
!= KMF_SYMMETRIC
)
2039 return (KMF_ERR_BAD_KEY_CLASS
);
2041 if (symkey
->israw
) {
2042 KMF_RAW_KEY_DATA
*rawkey
= (KMF_RAW_KEY_DATA
*)symkey
->keyp
;
2044 if (rawkey
== NULL
||
2045 rawkey
->rawdata
.sym
.keydata
.val
== NULL
||
2046 rawkey
->rawdata
.sym
.keydata
.len
== 0)
2047 return (KMF_ERR_BAD_KEYHANDLE
);
2049 rkey
->keydata
.len
= rawkey
->rawdata
.sym
.keydata
.len
;
2050 if ((rkey
->keydata
.val
= malloc(rkey
->keydata
.len
)) == NULL
)
2051 return (KMF_ERR_MEMORY
);
2052 (void) memcpy(rkey
->keydata
.val
,
2053 rawkey
->rawdata
.sym
.keydata
.val
, rkey
->keydata
.len
);
2055 nsskey
= (PK11SymKey
*)(symkey
->keyp
);
2057 return (KMF_ERR_BAD_KEYHANDLE
);
2059 nss_rv
= PK11_ExtractKeyValue(nsskey
);
2060 if (nss_rv
!= SECSuccess
) {
2061 SET_ERROR(kmfh
, PORT_GetError());
2062 rv
= KMF_ERR_GETKEYVALUE_FAILED
;
2066 value
= PK11_GetKeyData(nsskey
);
2067 if (value
== NULL
) {
2068 SET_ERROR(kmfh
, PORT_GetError());
2069 rv
= KMF_ERR_GETKEYVALUE_FAILED
;
2073 if (value
->len
== 0 || value
->data
== NULL
) {
2074 rv
= KMF_ERR_GETKEYVALUE_FAILED
;
2078 rkey
->keydata
.val
= malloc(value
->len
);
2079 if (rkey
->keydata
.val
== NULL
) {
2080 rv
= KMF_ERR_MEMORY
;
2083 (void) memcpy(rkey
->keydata
.val
, value
->data
, value
->len
);
2084 rkey
->keydata
.len
= value
->len
;
2085 (void) memset(value
->data
, 0, value
->len
);
2089 SECITEM_FreeItem(value
, PR_TRUE
);
2094 NSS_SetTokenPin(KMF_HANDLE_T handle
, int numattr
, KMF_ATTRIBUTE
*attrlist
)
2096 KMF_RETURN ret
= KMF_OK
;
2097 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
2099 PK11SlotInfo
*nss_slot
= NULL
;
2100 KMF_CREDENTIAL oldcred
, newcred
;
2102 if (handle
== NULL
|| attrlist
== NULL
|| numattr
== 0)
2103 return (KMF_ERR_BAD_PARAMETER
);
2105 ret
= kmf_get_attr(KMF_CREDENTIAL_ATTR
, attrlist
, numattr
,
2106 (void *)&oldcred
, NULL
);
2108 return (KMF_ERR_BAD_PARAMETER
);
2109 ret
= kmf_get_attr(KMF_NEWPIN_ATTR
, attrlist
, numattr
,
2110 (void *)&newcred
, NULL
);
2112 return (KMF_ERR_BAD_PARAMETER
);
2114 ret
= do_nss_init(handle
, numattr
, attrlist
, FALSE
, &nss_slot
);
2115 /* If it was uninitialized, set it */
2116 if (ret
== KMF_ERR_UNINITIALIZED_TOKEN
) {
2117 rv
= PK11_InitPin(nss_slot
, NULL
, newcred
.cred
);
2118 if (rv
!= SECSuccess
) {
2119 SET_ERROR(kmfh
, PORT_GetError());
2120 ret
= KMF_ERR_AUTH_FAILED
;
2124 } else if (ret
== KMF_OK
) {
2125 ret
= nss_authenticate(handle
, nss_slot
, &oldcred
);
2126 if (ret
!= KMF_OK
) {
2129 rv
= PK11_ChangePW(nss_slot
, oldcred
.cred
, newcred
.cred
);
2130 if (rv
!= SECSuccess
) {
2131 SET_ERROR(kmfh
, PORT_GetError());
2132 ret
= KMF_ERR_AUTH_FAILED
;
2140 NSS_StoreKey(KMF_HANDLE_T handle
,
2141 int numattr
, KMF_ATTRIBUTE
*attrlist
)
2143 KMF_RETURN rv
= KMF_OK
;
2144 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
2145 PK11SlotInfo
*nss_slot
= NULL
;
2146 KMF_CREDENTIAL cred
= { NULL
, 0 };
2147 KMF_KEY_HANDLE
*pubkey
= NULL
, *prikey
= NULL
;
2148 KMF_RAW_KEY_DATA
*rawkey
= NULL
;
2149 char *keylabel
= NULL
;
2150 SECStatus ckrv
= SECSuccess
;
2151 SECItem nickname
= { siBuffer
, NULL
, 0 };
2152 CERTCertificate
*nss_cert
= NULL
;
2154 if (kmfh
== NULL
|| attrlist
== NULL
|| numattr
== 0) {
2155 return (KMF_ERR_BAD_PARAMETER
);
2158 rv
= do_nss_init(handle
, numattr
, attrlist
, FALSE
, &nss_slot
);
2163 rv
= kmf_get_attr(KMF_CREDENTIAL_ATTR
, attrlist
, numattr
,
2164 (void *)&cred
, NULL
);
2166 return (KMF_ERR_BAD_PARAMETER
);
2168 rv
= nss_authenticate(handle
, nss_slot
, &cred
);
2173 pubkey
= kmf_get_attr_ptr(KMF_PUBKEY_HANDLE_ATTR
, attrlist
, numattr
);
2174 if (pubkey
== NULL
) {
2175 /* look for private key */
2176 prikey
= kmf_get_attr_ptr(KMF_PRIVKEY_HANDLE_ATTR
, attrlist
,
2179 /* look for raw key */
2180 rawkey
= kmf_get_attr_ptr(KMF_RAW_KEY_ATTR
,
2184 /* If no keys were found, return error */
2185 if (pubkey
== NULL
&& prikey
== NULL
&& rawkey
== NULL
)
2186 return (KMF_ERR_ATTR_NOT_FOUND
);
2188 keylabel
= kmf_get_attr_ptr(KMF_KEYLABEL_ATTR
, attrlist
, numattr
);
2189 if (keylabel
!= NULL
) {
2190 nickname
.data
= (uchar_t
*)keylabel
;
2191 nickname
.len
= strlen(keylabel
);
2194 if (rawkey
!= NULL
) {
2196 SECKEYPrivateKeyInfo rpk
;
2197 KMF_DATA derkey
= { 0, NULL
};
2200 cert
= kmf_get_attr_ptr(KMF_CERT_DATA_ATTR
, attrlist
, numattr
);
2204 * Decode the cert into an NSS CERT object so we can access the
2205 * SPKI and KeyUsage data later.
2207 nss_cert
= CERT_DecodeCertFromPackage((char *)cert
->Data
,
2210 if (nss_cert
== NULL
) {
2211 SET_ERROR(kmfh
, PORT_GetError());
2212 rv
= KMF_ERR_BAD_CERT_FORMAT
;
2216 (void) memset(&rpk
, 0, sizeof (rpk
));
2218 rpk
.version
.type
= siUnsignedInteger
;
2219 rpk
.version
.data
= &ver
;
2220 rpk
.version
.len
= 1;
2221 if (rawkey
->keytype
== KMF_RSA
) {
2222 rv
= DerEncodeRSAPrivateKey(&derkey
,
2223 &rawkey
->rawdata
.rsa
);
2226 } else if (rawkey
->keytype
== KMF_DSA
) {
2227 rv
= DerEncodeDSAPrivateKey(&derkey
,
2228 &rawkey
->rawdata
.dsa
);
2231 } else if (rawkey
->keytype
== KMF_ECDSA
) {
2232 rv
= DerEncodeECPrivateKey(&derkey
,
2233 &rawkey
->rawdata
.ec
);
2237 rpk
.algorithm
= nss_cert
->subjectPublicKeyInfo
.algorithm
;
2238 rpk
.privateKey
.data
= derkey
.Data
;
2239 rpk
.privateKey
.len
= derkey
.Length
;
2240 rpk
.attributes
= NULL
;
2242 ckrv
= PK11_ImportPrivateKeyInfo(nss_slot
, &rpk
, &nickname
,
2243 &nss_cert
->subjectPublicKeyInfo
.subjectPublicKey
, TRUE
,
2244 TRUE
, nss_cert
->keyUsage
, NULL
);
2245 if (ckrv
!= CKR_OK
) {
2246 SET_ERROR(kmfh
, PORT_GetError());
2247 rv
= KMF_ERR_INTERNAL
;
2249 kmf_free_data(&derkey
);
2250 } else if (pubkey
!= NULL
&& pubkey
->kstype
== KMF_KEYSTORE_NSS
) {
2251 CK_OBJECT_HANDLE pk
;
2252 SECKEYPublicKey
*publicKey
= (SECKEYPublicKey
*) pubkey
->keyp
;
2254 pk
= PK11_ImportPublicKey(nss_slot
, publicKey
, PR_TRUE
);
2255 if (pk
== CK_INVALID_HANDLE
) {
2256 SET_ERROR(kmfh
, PORT_GetError());
2257 rv
= KMF_ERR_INTERNAL
;
2259 } else if (prikey
!= NULL
&& prikey
->kstype
== KMF_KEYSTORE_NSS
) {
2260 SECKEYPrivateKey
*pk
;
2261 SECKEYPrivateKey
*privKey
= (SECKEYPrivateKey
*) prikey
->keyp
;
2263 pk
= PK11_LoadPrivKey(nss_slot
, privKey
, NULL
, PR_TRUE
,
2265 if (pk
== CK_INVALID_HANDLE
) {
2266 SET_ERROR(kmfh
, PORT_GetError());
2267 rv
= KMF_ERR_INTERNAL
;
2269 /* We stored it, but don't need the handle anymore */
2270 SECKEY_DestroyPrivateKey(pk
);
2274 if (nss_cert
!= NULL
)
2275 CERT_DestroyCertificate(nss_cert
);
2276 PK11_FreeSlot(nss_slot
);
2281 * This function is called by NSS_StoreCert() and NSS_ImportCert().
2282 * The "label" and "trust_flag" arguments can be NULL.
2285 store_cert(KMF_HANDLE_T handle
, PK11SlotInfo
*nss_slot
, KMF_DATA
*cert
,
2286 char *label
, char *trust_flag
)
2288 KMF_RETURN ret
= KMF_OK
;
2289 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
2291 CERTCertDBHandle
*certHandle
= CERT_GetDefaultCertDB();
2292 CERTCertificate
*nss_cert
= NULL
;
2293 CERTCertTrust
*nss_trust
= NULL
;
2295 if (nss_slot
== NULL
|| cert
== NULL
)
2296 return (KMF_ERR_BAD_PARAMETER
);
2298 nss_cert
= CERT_DecodeCertFromPackage((char *)cert
->Data
,
2300 if (nss_cert
== NULL
) {
2301 SET_ERROR(kmfh
, PORT_GetError());
2302 ret
= KMF_ERR_BAD_CERT_FORMAT
;
2306 /* Store the cert into the NSS database */
2307 nss_rv
= PK11_ImportCert(nss_slot
, nss_cert
, CK_INVALID_HANDLE
,
2310 SET_ERROR(kmfh
, nss_rv
);
2311 ret
= KMF_ERR_BAD_CERT_FORMAT
;
2315 /* If trust_flag is NULL, then we are done */
2316 if (trust_flag
== NULL
)
2319 nss_trust
= (CERTCertTrust
*) malloc(sizeof (CERTCertTrust
));
2320 if (nss_trust
== NULL
) {
2321 ret
= KMF_ERR_MEMORY
;
2325 nss_rv
= CERT_DecodeTrustString(nss_trust
, trust_flag
);
2327 SET_ERROR(kmfh
, nss_rv
);
2328 ret
= KMF_ERR_BAD_PARAMETER
;
2332 nss_rv
= CERT_ChangeCertTrust(certHandle
, nss_cert
, nss_trust
);
2334 SET_ERROR(kmfh
, nss_rv
);
2335 ret
= KMF_ERR_BAD_PARAMETER
;
2339 if (nss_cert
!= NULL
) {
2340 CERT_DestroyCertificate(nss_cert
);
2343 if (nss_trust
!= NULL
) {
2352 NSS_StoreCert(KMF_HANDLE_T handle
, int numattr
, KMF_ATTRIBUTE
*attrlist
)
2354 KMF_RETURN ret
= KMF_OK
;
2355 PK11SlotInfo
*nss_slot
= NULL
;
2356 KMF_DATA
*cert
= NULL
;
2358 char *trust_flag
= NULL
;
2360 if (handle
== NULL
|| attrlist
== NULL
|| numattr
== 0) {
2361 return (KMF_ERR_BAD_PARAMETER
);
2364 ret
= do_nss_init(handle
, numattr
, attrlist
, FALSE
, &nss_slot
);
2368 /* Get the cert data */
2369 cert
= kmf_get_attr_ptr(KMF_CERT_DATA_ATTR
, attrlist
, numattr
);
2370 if (cert
== NULL
|| cert
->Data
== NULL
)
2371 return (KMF_ERR_BAD_PARAMETER
);
2373 /* The label attribute is optional */
2374 label
= kmf_get_attr_ptr(KMF_CERT_LABEL_ATTR
, attrlist
, numattr
);
2376 /* The trustflag attriburte is optional */
2377 trust_flag
= kmf_get_attr_ptr(KMF_TRUSTFLAG_ATTR
, attrlist
, numattr
);
2379 ret
= store_cert(handle
, nss_slot
, cert
, label
, trust_flag
);
2382 if (nss_slot
!= NULL
) {
2383 PK11_FreeSlot(nss_slot
);
2391 NSS_ImportCert(KMF_HANDLE_T handle
, int numattr
, KMF_ATTRIBUTE
*attrlist
)
2393 KMF_RETURN ret
= KMF_OK
;
2394 PK11SlotInfo
*nss_slot
= NULL
;
2395 KMF_DATA cert
= { 0, NULL
};
2396 KMF_DATA cert_der
= { 0, NULL
};
2397 KMF_DATA
*cptr
= NULL
;
2398 KMF_ENCODE_FORMAT format
;
2400 char *trust_flag
= NULL
;
2401 char *certfile
= NULL
;
2403 if (handle
== NULL
|| attrlist
== NULL
|| numattr
== 0) {
2404 return (KMF_ERR_BAD_PARAMETER
);
2407 ret
= do_nss_init(handle
, numattr
, attrlist
, FALSE
, &nss_slot
);
2411 /* Get the input cert filename attribute */
2412 certfile
= kmf_get_attr_ptr(KMF_CERT_FILENAME_ATTR
, attrlist
, numattr
);
2413 if (certfile
== NULL
)
2414 return (KMF_ERR_BAD_PARAMETER
);
2416 /* Check the cert file and auto-detect the file format of it. */
2417 ret
= kmf_is_cert_file(handle
, certfile
, &format
);
2421 ret
= kmf_read_input_file(handle
, certfile
, &cert
);
2422 if (ret
!= KMF_OK
) {
2427 * If the imported cert is in PEM format, convert it to
2428 * DER format in order to store it in NSS token.
2430 if (format
== KMF_FORMAT_PEM
) {
2432 ret
= kmf_pem_to_der(cert
.Data
, cert
.Length
,
2433 &cert_der
.Data
, &derlen
);
2434 if (ret
!= KMF_OK
) {
2437 cert_der
.Length
= (size_t)derlen
;
2443 label
= kmf_get_attr_ptr(KMF_CERT_LABEL_ATTR
, attrlist
, numattr
);
2444 trust_flag
= kmf_get_attr_ptr(KMF_TRUSTFLAG_ATTR
, attrlist
, numattr
);
2445 ret
= store_cert(handle
, nss_slot
, cptr
, label
, trust_flag
);
2448 if (format
== KMF_FORMAT_PEM
) {
2449 kmf_free_data(&cert_der
);
2452 kmf_free_data(&cert
);
2459 NSS_ImportCRL(KMF_HANDLE_T handle
, int numattr
, KMF_ATTRIBUTE
*attrlist
)
2461 KMF_RETURN ret
= KMF_OK
;
2462 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
2463 PK11SlotInfo
*nss_slot
= NULL
;
2464 CERTSignedCrl
*nss_crl
= NULL
;
2465 KMF_ENCODE_FORMAT format
;
2471 boolean_t crlcheck
= FALSE
;
2473 if (attrlist
== NULL
|| numattr
== 0) {
2474 return (KMF_ERR_BAD_PARAMETER
);
2477 ret
= do_nss_init(handle
, numattr
, attrlist
, FALSE
, &nss_slot
);
2478 if (ret
!= KMF_OK
) {
2482 crlfilename
= kmf_get_attr_ptr(KMF_CRL_FILENAME_ATTR
, attrlist
,
2484 if (crlfilename
== NULL
)
2485 return (KMF_ERR_BAD_CRLFILE
);
2488 * Check if the input CRL file is a valid CRL file and auto-detect
2489 * the encoded format of the file.
2491 ret
= kmf_is_crl_file(handle
, crlfilename
, &format
);
2495 ret
= kmf_get_attr(KMF_CRL_CHECK_ATTR
, attrlist
, numattr
,
2498 ret
= KMF_OK
; /* CRL_CHECK is optional */
2500 /* set importOptions */
2501 if (crlcheck
== B_FALSE
) {
2502 importOptions
= CRL_IMPORT_DEFAULT_OPTIONS
|
2503 CRL_IMPORT_BYPASS_CHECKS
;
2505 importOptions
= CRL_IMPORT_DEFAULT_OPTIONS
;
2509 /* Read in the CRL file */
2512 ret
= kmf_read_input_file(handle
, crlfilename
, &crl1
);
2513 if (ret
!= KMF_OK
) {
2517 /* If the input CRL is in PEM format, convert it to DER first. */
2518 if (format
== KMF_FORMAT_PEM
) {
2520 ret
= kmf_pem_to_der(crl1
.Data
, crl1
.Length
,
2522 if (ret
!= KMF_OK
) {
2525 crl2
.Length
= (size_t)len
;
2528 crlDER
.data
= format
== KMF_FORMAT_ASN1
? crl1
.Data
: crl2
.Data
;
2529 crlDER
.len
= format
== KMF_FORMAT_ASN1
? crl1
.Length
: crl2
.Length
;
2531 nss_crl
= PK11_ImportCRL(nss_slot
, &crlDER
, NULL
, SEC_CRL_TYPE
,
2532 NULL
, importOptions
, NULL
, CRL_DECODE_DEFAULT_OPTIONS
);
2534 if (nss_crl
== NULL
) {
2535 SET_ERROR(kmfh
, PORT_GetError());
2536 ret
= KMF_ERR_BAD_CRLFILE
;
2541 if (nss_slot
!= NULL
) {
2542 PK11_FreeSlot(nss_slot
);
2545 if (crl1
.Data
!= NULL
) {
2549 if (crl2
.Data
!= NULL
) {
2553 if (nss_crl
!= NULL
) {
2554 (void) SEC_DestroyCrl(nss_crl
);
2561 NSS_DeleteCRL(KMF_HANDLE_T handle
, int numattr
, KMF_ATTRIBUTE
*attrlist
)
2563 KMF_RETURN rv
= KMF_OK
;
2564 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
2565 CERTSignedCrl
*crl
= NULL
;
2566 CERTCertificate
*cert
= NULL
;
2567 PK11SlotInfo
*nss_slot
= NULL
;
2568 CERTCrlHeadNode
*crlList
= NULL
;
2569 CERTCrlNode
*crlNode
= NULL
;
2570 PRArenaPool
*arena
= NULL
;
2571 CERTName
*name
= NULL
;
2572 CERTCertDBHandle
*certHandle
= CERT_GetDefaultCertDB();
2573 char *issuername
, *subjectname
;
2576 if (numattr
== 0 || attrlist
== NULL
) {
2577 return (KMF_ERR_BAD_PARAMETER
);
2580 rv
= do_nss_init(handle
, numattr
, attrlist
, FALSE
, &nss_slot
);
2585 issuername
= kmf_get_attr_ptr(KMF_ISSUER_NAME_ATTR
, attrlist
,
2587 subjectname
= kmf_get_attr_ptr(KMF_SUBJECT_NAME_ATTR
, attrlist
,
2590 /* Caller must specify issuer or subject but not both */
2591 if ((issuername
== NULL
&& subjectname
== NULL
) ||
2592 (issuername
!= NULL
&& subjectname
!= NULL
))
2593 return (KMF_ERR_BAD_PARAMETER
);
2595 /* Find the CRL based on the deletion criteria. */
2596 if (issuername
!= NULL
) {
2598 * If the deletion is based on the issuer's certificate
2599 * nickname, we will get the issuer's cert first, then
2600 * get the CRL from the cert.
2602 cert
= CERT_FindCertByNicknameOrEmailAddr(certHandle
,
2605 SET_ERROR(kmfh
, PORT_GetError());
2606 rv
= KMF_ERR_CERT_NOT_FOUND
;
2610 crl
= SEC_FindCrlByName(certHandle
, &cert
->derSubject
,
2613 SET_ERROR(kmfh
, PORT_GetError());
2614 rv
= KMF_ERR_CRL_NOT_FOUND
;
2619 * If the deletion is based on the CRL's subject name, we will
2620 * get all the CRLs from the internal database and search
2621 * for the CRL with the same subject name.
2623 boolean_t found
= B_FALSE
;
2626 nssrv
= SEC_LookupCrls(certHandle
, &crlList
, SEC_CRL_TYPE
);
2628 SET_ERROR(kmfh
, nssrv
);
2629 rv
= KMF_ERR_CRL_NOT_FOUND
;
2633 if (crlList
== NULL
) {
2634 SET_ERROR(kmfh
, PORT_GetError());
2635 rv
= KMF_ERR_CRL_NOT_FOUND
;
2639 /* Allocate space for name */
2640 arena
= PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE
);
2641 if (arena
== NULL
) {
2642 rv
= KMF_ERR_MEMORY
;
2646 name
= PORT_ArenaZAlloc(arena
, sizeof (*name
));
2648 rv
= KMF_ERR_MEMORY
;
2651 name
->arena
= arena
;
2653 crlNode
= crlList
->first
;
2654 while (crlNode
&& !found
) {
2655 char *asciiname
= NULL
;
2658 name
= &crlNode
->crl
->crl
.name
;
2660 SET_ERROR(kmfh
, PORT_GetError());
2661 rv
= KMF_ERR_CRL_NOT_FOUND
;
2665 asciiname
= CERT_NameToAscii(name
);
2666 if (asciiname
== NULL
) {
2667 SET_ERROR(kmfh
, PORT_GetError());
2668 rv
= KMF_ERR_CRL_NOT_FOUND
;
2672 if (strcmp(subjectname
, asciiname
) == 0) {
2674 issuer
= &crlNode
->crl
->crl
.derName
;
2675 crl
= SEC_FindCrlByName(certHandle
, issuer
,
2678 /* We found a cert but no CRL */
2679 SET_ERROR(kmfh
, PORT_GetError());
2680 rv
= KMF_ERR_CRL_NOT_FOUND
;
2683 PORT_Free(asciiname
);
2684 crlNode
= crlNode
->next
;
2693 (void) SEC_DeletePermCRL(crl
);
2697 if (nss_slot
!= NULL
) {
2698 PK11_FreeSlot(nss_slot
);
2701 if (crlList
!= NULL
) {
2702 PORT_FreeArena(crlList
->arena
, PR_FALSE
);
2705 if (arena
!= NULL
) {
2706 PORT_FreeArena(arena
, PR_FALSE
);
2710 CERT_DestroyCertificate(cert
);
2714 (void) SEC_DestroyCrl(crl
);
2721 NSS_FindCRL(KMF_HANDLE_T handle
, int numattr
, KMF_ATTRIBUTE
*attrlist
)
2723 KMF_RETURN rv
= KMF_OK
;
2724 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
2725 PK11SlotInfo
*nss_slot
= NULL
;
2726 CERTCrlHeadNode
*crlList
= NULL
;
2727 CERTCrlNode
*crlNode
= NULL
;
2728 PRArenaPool
*arena
= NULL
;
2729 CERTName
*name
= NULL
;
2731 char *asciiname
= NULL
;
2734 CERTCertDBHandle
*certHandle
= CERT_GetDefaultCertDB();
2737 if (numattr
== 0 || attrlist
== NULL
) {
2738 return (KMF_ERR_BAD_PARAMETER
);
2741 rv
= do_nss_init(handle
, numattr
, attrlist
, FALSE
, &nss_slot
);
2746 CRLCount
= kmf_get_attr_ptr(KMF_CRL_COUNT_ATTR
, attrlist
, numattr
);
2747 if (CRLCount
== NULL
)
2748 return (KMF_ERR_BAD_PARAMETER
);
2750 CRLNameList
= (char **)kmf_get_attr_ptr(KMF_CRL_NAMELIST_ATTR
,
2754 nssrv
= SEC_LookupCrls(certHandle
, &crlList
, SEC_CRL_TYPE
);
2756 SET_ERROR(kmfh
, rv
);
2757 rv
= KMF_ERR_CRL_NOT_FOUND
;
2761 /* Allocate space for name first */
2762 arena
= PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE
);
2763 if (arena
== NULL
) {
2764 rv
= KMF_ERR_MEMORY
;
2768 name
= PORT_ArenaZAlloc(arena
, sizeof (*name
));
2770 rv
= KMF_ERR_MEMORY
;
2773 name
->arena
= arena
;
2776 * Loop thru the crlList and create a crl list with CRL's subject name.
2778 crlNode
= crlList
->first
;
2783 /* Get the CRL subject name */
2784 name
= &crlNode
->crl
->crl
.name
;
2786 SET_ERROR(kmfh
, PORT_GetError());
2787 rv
= KMF_ERR_CRL_NOT_FOUND
;
2792 if (CRLNameList
!= NULL
) {
2793 asciiname
= CERT_NameToAscii(name
);
2794 if (asciiname
== NULL
) {
2795 SET_ERROR(kmfh
, PORT_GetError());
2796 rv
= KMF_ERR_CRL_NOT_FOUND
;
2799 subj_name
= strdup(asciiname
);
2800 PORT_Free(asciiname
);
2801 if (subj_name
== NULL
) {
2802 rv
= KMF_ERR_MEMORY
;
2805 CRLNameList
[crl_num
] = subj_name
;
2809 crlNode
= crlNode
->next
;
2814 *CRLCount
= crl_num
;
2818 if (nss_slot
!= NULL
) {
2819 PK11_FreeSlot(nss_slot
);
2822 if (crlList
!= NULL
) {
2823 PORT_FreeArena(crlList
->arena
, PR_FALSE
);
2826 if (arena
!= NULL
) {
2827 PORT_FreeArena(arena
, PR_FALSE
);
2830 /* If failed, free memory allocated for the returning rlist */
2831 if (rv
&& (CRLNameList
!= NULL
)) {
2832 for (i
= 0; i
< crl_num
; i
++) {
2833 free(CRLNameList
[i
]);
2841 NSS_FindCertInCRL(KMF_HANDLE_T handle
, int numattr
, KMF_ATTRIBUTE
*attrlist
)
2843 KMF_RETURN rv
= KMF_OK
;
2844 KMF_HANDLE
*kmfh
= (KMF_HANDLE
*)handle
;
2845 PK11SlotInfo
*nss_slot
= NULL
;
2846 CERTCertificate
*cert
= NULL
;
2847 CERTSignedCrl
*crl
= NULL
;
2848 CERTCrlEntry
*entry
;
2849 boolean_t match
= B_FALSE
;
2851 CERTCertDBHandle
*certHandle
= CERT_GetDefaultCertDB();
2856 if (numattr
== 0 || attrlist
== NULL
) {
2857 return (KMF_ERR_BAD_PARAMETER
);
2860 rv
= do_nss_init(handle
, numattr
, attrlist
, FALSE
, &nss_slot
);
2865 certlabel
= kmf_get_attr_ptr(KMF_CERT_LABEL_ATTR
, attrlist
, numattr
);
2867 /* Find the certificate first */
2868 if (certlabel
!= NULL
) {
2869 cert
= CERT_FindCertByNicknameOrEmailAddr(certHandle
,
2872 SECItem derCert
= { siBuffer
, NULL
, 0 };
2874 certdata
= kmf_get_attr_ptr(KMF_CERT_DATA_ATTR
,
2877 if (certdata
== NULL
)
2878 return (KMF_ERR_BAD_PARAMETER
);
2880 derCert
.data
= certdata
->Data
;
2881 derCert
.len
= certdata
->Length
;
2883 cert
= CERT_FindCertByDERCert(certHandle
, &derCert
);
2887 SET_ERROR(kmfh
, PORT_GetError());
2888 rv
= KMF_ERR_CERT_NOT_FOUND
;
2892 /* Find the CRL with the same issuer as the given certificate. */
2893 crl
= SEC_FindCrlByName(certHandle
, &cert
->derIssuer
, SEC_CRL_TYPE
);
2896 * Could not find the CRL issued by the same issuer. This
2897 * usually means that the CRL is not installed in the DB.
2899 SET_ERROR(kmfh
, PORT_GetError());
2900 rv
= KMF_ERR_CRL_NOT_FOUND
;
2905 /* Check if the certificate's serialNumber is revoked in the CRL */
2907 while ((entry
= (crl
->crl
).entries
[i
++]) != NULL
) {
2908 if (SECITEM_CompareItem(&(cert
->serialNumber
),
2909 &(entry
->serialNumber
)) == SECEqual
) {
2916 rv
= KMF_ERR_NOT_REVOKED
;
2920 if (nss_slot
!= NULL
) {
2921 PK11_FreeSlot(nss_slot
);
2925 CERT_DestroyCertificate(cert
);
2929 (void) SEC_DestroyCrl(crl
);