xref: /onnv-gate/usr/src/lib/libkmf/plugins/kmf_nss/common/nss_spi.c (revision 11973:480f5412d630)
13089Swyllys /*
23089Swyllys  * CDDL HEADER START
33089Swyllys  *
43089Swyllys  * The contents of this file are subject to the terms of the
53089Swyllys  * Common Development and Distribution License (the "License").
63089Swyllys  * You may not use this file except in compliance with the License.
73089Swyllys  *
83089Swyllys  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
93089Swyllys  * or http://www.opensolaris.org/os/licensing.
103089Swyllys  * See the License for the specific language governing permissions
113089Swyllys  * and limitations under the License.
123089Swyllys  *
133089Swyllys  * When distributing Covered Code, include this CDDL HEADER in each
143089Swyllys  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
153089Swyllys  * If applicable, add the following below this CDDL HEADER, with the
163089Swyllys  * fields enclosed by brackets "[]" replaced with your own identifying
173089Swyllys  * information: Portions Copyright [yyyy] [name of copyright owner]
183089Swyllys  *
193089Swyllys  * CDDL HEADER END
203089Swyllys  */
2111411SSurya.Prakki@Sun.COM 
223089Swyllys /*
233089Swyllys  * NSS keystore wrapper
243089Swyllys  *
25*11973Swyllys.ingersoll@sun.com  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
263089Swyllys  * Use is subject to license terms.
273089Swyllys  */
283089Swyllys 
293089Swyllys #include <sys/types.h>
303089Swyllys #include <sys/stat.h>
313089Swyllys #include <errno.h>
323089Swyllys #include <fcntl.h>
333089Swyllys #include <synch.h>
343089Swyllys 
353089Swyllys #include <kmfapiP.h>
363089Swyllys #include <ber_der.h>
373089Swyllys /* NSS related headers */
383089Swyllys 
393089Swyllys #include <mps/nss.h>
403089Swyllys #include <mps/cert.h>
413089Swyllys #include <mps/certdb.h>
423089Swyllys #include <mps/secoid.h>
433089Swyllys #include <mps/secder.h>
443089Swyllys #include <mps/secerr.h>
453089Swyllys #include <mps/cryptohi.h>
463089Swyllys #include <mps/keyhi.h>
473089Swyllys #include <mps/keythi.h>
483089Swyllys #include <mps/pk11func.h>
493089Swyllys #include <mps/pk11pqg.h>
503089Swyllys #include <mps/pkcs12.h>
513089Swyllys #include <mps/p12plcy.h>
523089Swyllys #include <mps/prerror.h>
533089Swyllys 
543089Swyllys #define	NSS_OK		0
553089Swyllys 
563089Swyllys mutex_t init_lock = DEFAULTMUTEX;
573089Swyllys static int nss_initialized = 0;
583089Swyllys 
593089Swyllys KMF_RETURN
605051Swyllys NSS_ConfigureKeystore(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
613089Swyllys 
623089Swyllys KMF_RETURN
635051Swyllys NSS_FindCert(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
643089Swyllys 
653089Swyllys void
663089Swyllys NSS_FreeKMFCert(KMF_HANDLE_T, KMF_X509_DER_CERT *);
673089Swyllys 
683089Swyllys KMF_RETURN
695051Swyllys NSS_StoreCert(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
705051Swyllys 
715051Swyllys KMF_RETURN
725051Swyllys NSS_ImportCert(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
733089Swyllys 
743089Swyllys KMF_RETURN
755051Swyllys NSS_DeleteCert(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
763089Swyllys 
773089Swyllys KMF_RETURN
785051Swyllys NSS_CreateKeypair(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
793089Swyllys 
803089Swyllys KMF_RETURN
815051Swyllys NSS_StoreKey(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
823089Swyllys 
833089Swyllys KMF_RETURN
843089Swyllys NSS_EncodePubKeyData(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_DATA *);
853089Swyllys 
863089Swyllys KMF_RETURN
873089Swyllys NSS_SignData(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_OID *,
883089Swyllys 	KMF_DATA *, KMF_DATA *);
893089Swyllys 
903089Swyllys KMF_RETURN
915051Swyllys NSS_ImportCRL(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
923089Swyllys 
933089Swyllys KMF_RETURN
945051Swyllys NSS_DeleteCRL(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
953089Swyllys 
963089Swyllys KMF_RETURN
975051Swyllys NSS_FindCRL(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
983089Swyllys 
993089Swyllys KMF_RETURN
1005051Swyllys NSS_FindKey(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
1013089Swyllys 
1023089Swyllys KMF_RETURN
1035051Swyllys NSS_FindCertInCRL(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
1043089Swyllys 
1053089Swyllys KMF_RETURN
1063089Swyllys NSS_GetErrorString(KMF_HANDLE_T, char **);
1073089Swyllys 
1083089Swyllys KMF_RETURN
1095051Swyllys NSS_DeleteKey(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
1103089Swyllys 
1113089Swyllys KMF_RETURN
1125051Swyllys NSS_FindPrikeyByCert(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
1133089Swyllys 
1143089Swyllys KMF_RETURN
1153089Swyllys NSS_DecryptData(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_OID *,
1163089Swyllys 	KMF_DATA *, KMF_DATA *);
1173089Swyllys 
1183089Swyllys KMF_RETURN
1195051Swyllys NSS_ExportPK12(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
1203089Swyllys 
1213089Swyllys KMF_RETURN
1225051Swyllys NSS_CreateSymKey(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
1233089Swyllys 
1243089Swyllys KMF_RETURN
1253089Swyllys NSS_GetSymKeyValue(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_RAW_SYM_KEY *);
1263089Swyllys 
1273089Swyllys KMF_RETURN
1285051Swyllys NSS_SetTokenPin(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
1293089Swyllys 
1303089Swyllys static
1313089Swyllys KMF_PLUGIN_FUNCLIST nss_plugin_table =
1323089Swyllys {
1333089Swyllys 	1,				/* Version */
1343089Swyllys 	NSS_ConfigureKeystore,
1353089Swyllys 	NSS_FindCert,
1363089Swyllys 	NSS_FreeKMFCert,
1373089Swyllys 	NSS_StoreCert,
1383089Swyllys 	NSS_ImportCert,
1393089Swyllys 	NSS_ImportCRL,
1403089Swyllys 	NSS_DeleteCert,
1413089Swyllys 	NSS_DeleteCRL,
1423089Swyllys 	NSS_CreateKeypair,
1433089Swyllys 	NSS_FindKey,
1443089Swyllys 	NSS_EncodePubKeyData,
1453089Swyllys 	NSS_SignData,
1463089Swyllys 	NSS_DeleteKey,
1473089Swyllys 	NULL    /* ListCRL */,
1483089Swyllys 	NSS_FindCRL,
1493089Swyllys 	NSS_FindCertInCRL,
1503089Swyllys 	NSS_GetErrorString,
1515051Swyllys 	NSS_FindPrikeyByCert,
1523089Swyllys 	NSS_DecryptData,
1535051Swyllys 	NSS_ExportPK12,
1543089Swyllys 	NSS_CreateSymKey,
1553089Swyllys 	NSS_GetSymKeyValue,
1563089Swyllys 	NSS_SetTokenPin,
1575051Swyllys 	NSS_StoreKey,
1583089Swyllys 	NULL /* Finalize */
1593089Swyllys };
1603089Swyllys 
1613089Swyllys /* additions for importing and exporting PKCS 12 files */
1623089Swyllys typedef struct p12uContextStr {
1633089Swyllys 	char		*filename;	/* name of file */
1643089Swyllys 	PRFileDesc	*file;		/* pointer to file */
1653089Swyllys 	PRBool		error;		/* error occurred? */
1663089Swyllys 	int		errorValue;	/* which error occurred? */
1673089Swyllys } p12uContext;
1683089Swyllys 
1693089Swyllys #define	SET_ERROR(h, c) h->lasterr.kstype = KMF_KEYSTORE_NSS; \
1703089Swyllys 	h->lasterr.errcode = c;
1713089Swyllys 
1723089Swyllys KMF_PLUGIN_FUNCLIST *
KMF_Plugin_Initialize()1733089Swyllys KMF_Plugin_Initialize()
1743089Swyllys {
17511411SSurya.Prakki@Sun.COM 	(void) SEC_PKCS12EnableCipher(PKCS12_RC4_40, 1);
17611411SSurya.Prakki@Sun.COM 	(void) SEC_PKCS12EnableCipher(PKCS12_RC4_128, 1);
17711411SSurya.Prakki@Sun.COM 	(void) SEC_PKCS12EnableCipher(PKCS12_RC2_CBC_40, 1);
17811411SSurya.Prakki@Sun.COM 	(void) SEC_PKCS12EnableCipher(PKCS12_RC2_CBC_128, 1);
17911411SSurya.Prakki@Sun.COM 	(void) SEC_PKCS12EnableCipher(PKCS12_DES_56, 1);
18011411SSurya.Prakki@Sun.COM 	(void) SEC_PKCS12EnableCipher(PKCS12_DES_EDE3_168, 1);
18111411SSurya.Prakki@Sun.COM 	(void) SEC_PKCS12SetPreferredCipher(PKCS12_DES_EDE3_168, 1);
1823089Swyllys 
1833089Swyllys 	return (&nss_plugin_table);
1843089Swyllys }
1853089Swyllys 
1863089Swyllys static char *
1873089Swyllys /*ARGSUSED*/
nss_getpassword(PK11SlotInfo * slot,PRBool retry,void * arg)1883089Swyllys nss_getpassword(PK11SlotInfo *slot, PRBool retry, void *arg)
1893089Swyllys {
1903089Swyllys 	if (retry)
1913089Swyllys 		return (NULL);
1923089Swyllys 	if (arg != NULL)
1933089Swyllys 		return ((char *)strdup(arg));
1943089Swyllys 	else
1953089Swyllys 		return (NULL);
1963089Swyllys }
1973089Swyllys 
1983089Swyllys static KMF_RETURN
nss_authenticate(KMF_HANDLE_T handle,PK11SlotInfo * nss_slot,KMF_CREDENTIAL * cred)1993089Swyllys nss_authenticate(KMF_HANDLE_T handle,
2003089Swyllys 	PK11SlotInfo *nss_slot, KMF_CREDENTIAL *cred)
2013089Swyllys {
2023089Swyllys 
2033089Swyllys 	SECStatus nssrv = SECSuccess;
2043089Swyllys 	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
2053089Swyllys 
2063089Swyllys 	/* If a password was given, try to login to the slot */
2073089Swyllys 	if (cred == NULL || cred->cred == NULL || cred->credlen == 0 ||
2085051Swyllys 	    nss_slot == NULL) {
2093089Swyllys 		return (KMF_ERR_BAD_PARAMETER);
2103089Swyllys 	}
2113089Swyllys 
2123089Swyllys 	if (PK11_IsLoggedIn(nss_slot, NULL)) {
2133089Swyllys 		return (KMF_OK);
2143089Swyllys 	}
2153089Swyllys 
2163089Swyllys 	PK11_SetPasswordFunc(nss_getpassword);
2175051Swyllys 	nssrv = PK11_Authenticate(nss_slot, PR_TRUE, (void *)cred->cred);
2183089Swyllys 
2193089Swyllys 	if (nssrv != SECSuccess) {
2203089Swyllys 		SET_ERROR(kmfh, nssrv);
2213089Swyllys 		PK11_FreeSlot(nss_slot);
2223089Swyllys 		return (KMF_ERR_AUTH_FAILED);
2233089Swyllys 	}
2243089Swyllys 
2253089Swyllys 	return (KMF_OK);
2263089Swyllys }
2273089Swyllys 
2283089Swyllys static SECStatus
Init_NSS_DBs(const char * configdir,const char * certPrefix,const char * keyPrefix,const char * secmodName)2293089Swyllys Init_NSS_DBs(const char *configdir,
2303089Swyllys 	const char *certPrefix,
2313089Swyllys 	const char *keyPrefix,
2323089Swyllys 	const char *secmodName)
2333089Swyllys {
2343089Swyllys 	SECStatus rv = NSS_OK;
2353089Swyllys 
2363089Swyllys 	(void) mutex_lock(&init_lock);
2373089Swyllys 
2383089Swyllys 	/* If another thread already did it, return OK. */
2393089Swyllys 	if (nss_initialized) {
2403089Swyllys 		(void) mutex_unlock(&init_lock);
2413089Swyllys 		return (SECSuccess);
2423089Swyllys 	}
2433089Swyllys 
2443089Swyllys 	rv = NSS_Initialize((configdir && strlen(configdir)) ?
2455051Swyllys 	    configdir : "./", certPrefix, keyPrefix,
2465051Swyllys 	    secmodName ? secmodName : "secmod.db", NSS_INIT_COOPERATE);
2473089Swyllys 	if (rv != SECSuccess) {
2483089Swyllys 		goto end;
2493089Swyllys 	}
2503089Swyllys 
2513089Swyllys 	nss_initialized++;
2523089Swyllys end:
2533089Swyllys 	(void) mutex_unlock(&init_lock);
2543089Swyllys 	return (rv);
2553089Swyllys }
2563089Swyllys 
2573089Swyllys /*
2583089Swyllys  * When it is called the first time, it will intialize NSS.  Once the NSS
2593089Swyllys  * is initialized, this function returns KMF_KEYSTORE_ALREADY_INITIALIZED
2603089Swyllys  * if it is called again.
2613089Swyllys  */
2623089Swyllys KMF_RETURN
NSS_ConfigureKeystore(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)2635051Swyllys NSS_ConfigureKeystore(KMF_HANDLE_T handle,
2645051Swyllys 	int numattr, KMF_ATTRIBUTE *attrlist)
2653089Swyllys {
2663089Swyllys 	KMF_RETURN rv = KMF_OK;
2673089Swyllys 	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
2685051Swyllys 	char    *configdir;
2695051Swyllys 	char    *certPrefix;
2705051Swyllys 	char    *keyPrefix;
2715051Swyllys 	char    *secModName;
2725051Swyllys 
2735051Swyllys 	configdir = kmf_get_attr_ptr(KMF_DIRPATH_ATTR, attrlist, numattr);
2745051Swyllys 	certPrefix = kmf_get_attr_ptr(KMF_CERTPREFIX_ATTR, attrlist, numattr);
2755051Swyllys 	keyPrefix = kmf_get_attr_ptr(KMF_KEYPREFIX_ATTR, attrlist, numattr);
2765051Swyllys 	secModName = kmf_get_attr_ptr(KMF_SECMODNAME_ATTR, attrlist, numattr);
2773089Swyllys 
2783089Swyllys 	(void) mutex_lock(&init_lock);
2793089Swyllys 	if (nss_initialized == 0) {
2803089Swyllys 		SECStatus err;
2813089Swyllys 
2823089Swyllys 		(void) mutex_unlock(&init_lock);
2835051Swyllys 		err = Init_NSS_DBs(configdir, certPrefix,
2845051Swyllys 		    keyPrefix, secModName);
2853089Swyllys 		if (err != SECSuccess) {
2863089Swyllys 			SET_ERROR(kmfh, err);
2873089Swyllys 			return (KMF_ERR_INTERNAL);
2883089Swyllys 		}
2893089Swyllys 	} else {
2903089Swyllys 		rv = KMF_KEYSTORE_ALREADY_INITIALIZED;
2913089Swyllys 		(void) mutex_unlock(&init_lock);
2923089Swyllys 	}
2933089Swyllys 
2943089Swyllys 	return (rv);
2953089Swyllys }
2963089Swyllys 
2973089Swyllys /*
2983089Swyllys  * This function sets up the slot to be used for other operations.
2993089Swyllys  * This function is basically called by every NSS SPI function.
3003089Swyllys  * For those functions that can only be performed in the internal slot, the
3013089Swyllys  * boolean "internal_slot_only" argument needs to be TRUE.
3023089Swyllys  * A slot pointer will be returned when this function is executed successfully.
3033089Swyllys  */
3045051Swyllys KMF_RETURN
do_nss_init(void * handle,int numattr,KMF_ATTRIBUTE * attrlist,boolean_t internal_slot_only,PK11SlotInfo ** nss_slot)3055051Swyllys do_nss_init(void *handle, int numattr,
3065051Swyllys 	KMF_ATTRIBUTE *attrlist,
3073089Swyllys 	boolean_t internal_slot_only,
3083089Swyllys 	PK11SlotInfo **nss_slot)
3093089Swyllys {
3105051Swyllys 	KMF_RETURN rv = KMF_OK;
3113089Swyllys 	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
3125051Swyllys 	char *slotlabel = NULL;
3133089Swyllys 
3143089Swyllys 	if (!nss_initialized)
3153089Swyllys 		return (KMF_ERR_PLUGIN_INIT);
3163089Swyllys 
3175051Swyllys 	slotlabel = kmf_get_attr_ptr(KMF_TOKEN_LABEL_ATTR, attrlist, numattr);
3183089Swyllys 	/*
3193089Swyllys 	 * NSS Is already initialized, but we need to find
3203089Swyllys 	 * the right slot.
3213089Swyllys 	 */
3225051Swyllys 	if (slotlabel == NULL ||
3235051Swyllys 	    strcmp(slotlabel, "internal") == 0) {
3243089Swyllys 		*nss_slot = PK11_GetInternalKeySlot();
3253089Swyllys 	} else if (internal_slot_only == TRUE)  {
3265051Swyllys 		rv = KMF_ERR_SLOTNAME;
3275051Swyllys 		goto end;
3283089Swyllys 	} else {
3295051Swyllys 		*nss_slot = PK11_FindSlotByName(slotlabel);
3303089Swyllys 	}
3313089Swyllys 
3323089Swyllys 	if (*nss_slot == NULL) {
3333089Swyllys 		SET_ERROR(kmfh, PORT_GetError());
3345051Swyllys 		rv = KMF_ERR_SLOTNAME;
3355051Swyllys 		goto end;
3363089Swyllys 	}
3373089Swyllys 
3383089Swyllys 	/*
3393089Swyllys 	 * If the token was not yet initialized, return an error.
3403089Swyllys 	 */
3413089Swyllys 	if (PK11_NeedUserInit(*nss_slot)) {
3425051Swyllys 		rv = KMF_ERR_UNINITIALIZED_TOKEN;
3433089Swyllys 	}
3443089Swyllys 
3455051Swyllys end:
3465051Swyllys 	return (rv);
3473089Swyllys }
3483089Swyllys 
3493089Swyllys static KMF_RETURN
nss2kmf_cert(CERTCertificate * nss_cert,KMF_X509_DER_CERT * kmf_cert)3503089Swyllys nss2kmf_cert(CERTCertificate *nss_cert, KMF_X509_DER_CERT *kmf_cert)
3513089Swyllys {
3523089Swyllys 	kmf_cert->kmf_private.keystore_type = KMF_KEYSTORE_NSS;
3533089Swyllys 	kmf_cert->kmf_private.flags = KMF_FLAG_CERT_VALID;
3543089Swyllys 
3553089Swyllys 	kmf_cert->certificate.Length = nss_cert->derCert.len;
3563089Swyllys 
3573089Swyllys 	if ((kmf_cert->certificate.Data = malloc(nss_cert->derCert.len)) ==
3585051Swyllys 	    NULL) {
3593089Swyllys 		kmf_cert->certificate.Length = 0;
3603089Swyllys 		return (KMF_ERR_MEMORY);
3613089Swyllys 	}
3623089Swyllys 	(void) memcpy(kmf_cert->certificate.Data, nss_cert->derCert.data,
3635051Swyllys 	    nss_cert->derCert.len);
3643089Swyllys 	if (nss_cert->nickname != NULL)
3653089Swyllys 		kmf_cert->kmf_private.label =
3665051Swyllys 		    (char *)strdup(nss_cert->nickname);
3673089Swyllys 	return (KMF_OK);
3683089Swyllys }
3693089Swyllys 
3703089Swyllys static KMF_RETURN
nss_getcert_by_label(KMF_HANDLE * kmfh,char * name,KMF_X509_DER_CERT * kmf_cert,uint32_t * num_certs,KMF_CERT_VALIDITY find_criteria)3713089Swyllys nss_getcert_by_label(KMF_HANDLE *kmfh,
3723089Swyllys 	char *name, KMF_X509_DER_CERT *kmf_cert,
3733089Swyllys 	uint32_t *num_certs, KMF_CERT_VALIDITY find_criteria)
3743089Swyllys {
3753089Swyllys 	KMF_RETURN rv = KMF_OK;
3763089Swyllys 	CERTCertificate *nss_cert;
3773089Swyllys 	SECCertTimeValidity validity;
3783089Swyllys 
3793089Swyllys 	nss_cert = PK11_FindCertFromNickname(name, NULL);
3803089Swyllys 	if (nss_cert == NULL) {
3813089Swyllys 		*num_certs = 0;
3823089Swyllys 		SET_ERROR(kmfh, PORT_GetError());
3833089Swyllys 		*num_certs = 0;
3843089Swyllys 		return (KMF_ERR_CERT_NOT_FOUND);
3853089Swyllys 	} else {
3863089Swyllys 		*num_certs = 1;
3873089Swyllys 	}
3883089Swyllys 
3893089Swyllys 	switch (find_criteria) {
3903089Swyllys 	case KMF_ALL_CERTS:
3913089Swyllys 		break;
3923089Swyllys 	case KMF_NONEXPIRED_CERTS:
3933089Swyllys 		validity = CERT_CheckCertValidTimes(nss_cert, PR_Now(),
3945051Swyllys 		    PR_FALSE);
3953089Swyllys 		if (validity != secCertTimeValid) {
3963089Swyllys 			/* this is an invalid cert, reject it */
3973089Swyllys 			*num_certs = 0;
3983089Swyllys 			CERT_DestroyCertificate(nss_cert);
3993089Swyllys 			return (KMF_OK);
4003089Swyllys 		}
4013089Swyllys 		break;
4023089Swyllys 	case KMF_EXPIRED_CERTS:
4033089Swyllys 		validity = CERT_CheckCertValidTimes(nss_cert, PR_Now(),
4045051Swyllys 		    PR_FALSE);
4053089Swyllys 		if (validity == secCertTimeValid) {
4063089Swyllys 			/* this is a valid cert, reject it in this case. */
4073089Swyllys 			*num_certs = 0;
4083089Swyllys 			CERT_DestroyCertificate(nss_cert);
4093089Swyllys 			return (KMF_OK);
4103089Swyllys 		}
4113089Swyllys 		break;
4123089Swyllys 	default:
4133089Swyllys 		return (KMF_ERR_BAD_PARAMETER);
4143089Swyllys 	}
4153089Swyllys 
4163089Swyllys 	if (kmf_cert != NULL)
4173089Swyllys 		rv = nss2kmf_cert(nss_cert, kmf_cert);
4183089Swyllys 
4193089Swyllys 	/* We copied the data we need, so cleanup the internal record */
4203089Swyllys 	CERT_DestroyCertificate(nss_cert);
4213089Swyllys 
4223089Swyllys 	if (rv != KMF_OK)
4233089Swyllys 		*num_certs = 0;
4243089Swyllys 
4253089Swyllys 	return (rv);
4263089Swyllys }
4273089Swyllys 
4283089Swyllys static KMF_RETURN
nss_find_matching_certs(PK11SlotInfo * slot,char * issuer,char * subject,KMF_BIGINT * serial,CERTCertList ** certlist,KMF_CERT_VALIDITY find_criteria)4293089Swyllys nss_find_matching_certs(PK11SlotInfo *slot,
4303089Swyllys 	char *issuer, char *subject, KMF_BIGINT *serial,
4313089Swyllys 	CERTCertList **certlist, KMF_CERT_VALIDITY find_criteria)
4323089Swyllys {
4333089Swyllys 	KMF_RETURN rv = KMF_OK;
4343089Swyllys 	SECStatus ret;
4353089Swyllys 	CERTCertList *list;
4363089Swyllys 	CERTCertListNode *node;
4373089Swyllys 	KMF_X509_NAME issuerDN, subjectDN;
4383089Swyllys 	boolean_t findIssuer = FALSE;
4393089Swyllys 	boolean_t findSubject = FALSE;
4403089Swyllys 	boolean_t findSerial = FALSE;
4413089Swyllys 
4423089Swyllys 	if (issuer != NULL && strlen(issuer)) {
4435051Swyllys 		rv = kmf_dn_parser(issuer,  &issuerDN);
4443089Swyllys 		if (rv != KMF_OK)
4453089Swyllys 			return (rv);
4463089Swyllys 		findIssuer = TRUE;
4473089Swyllys 	}
4483089Swyllys 	if (subject != NULL && strlen(subject)) {
4495051Swyllys 		rv = kmf_dn_parser(subject, &subjectDN);
4503089Swyllys 		if (rv != KMF_OK)
4513089Swyllys 			return (rv);
4523089Swyllys 		findSubject = TRUE;
4533089Swyllys 	}
4543089Swyllys 	if (serial != 0 && serial->val != NULL && serial->len > 0)
4553089Swyllys 		findSerial = TRUE;
4563089Swyllys 
4573089Swyllys 	list = PK11_ListCertsInSlot(slot);
4583089Swyllys 	if (list) {
4593089Swyllys 		node = CERT_LIST_HEAD(list);
4603089Swyllys 		while (!CERT_LIST_END(node, list)) {
4613089Swyllys 			KMF_X509_NAME cmpDN;
4623089Swyllys 			KMF_DATA der;
4633089Swyllys 			boolean_t match;
4643089Swyllys 			CERTCertListNode *freenode;
4653089Swyllys 
4663089Swyllys 			if (findIssuer) {
4673089Swyllys 				der.Data = node->cert->derIssuer.data;
4683089Swyllys 				der.Length = node->cert->derIssuer.len;
4693089Swyllys 				rv = DerDecodeName(&der, &cmpDN);
4703089Swyllys 				if (rv == KMF_OK) {
4713089Swyllys 					match = !KMF_CompareRDNs(&issuerDN,
4725051Swyllys 					    &cmpDN);
4735051Swyllys 					kmf_free_dn(&cmpDN);
4743089Swyllys 					if (!match)
4753089Swyllys 						goto delete_and_cont;
4763089Swyllys 				} else {
4773089Swyllys 					goto delete_and_cont;
4783089Swyllys 				}
4793089Swyllys 			}
4803089Swyllys 			if (findSubject) {
4813089Swyllys 				der.Data = node->cert->derSubject.data;
4823089Swyllys 				der.Length = node->cert->derSubject.len;
4833089Swyllys 				rv = DerDecodeName(&der, &cmpDN);
4843089Swyllys 				if (rv == KMF_OK) {
4853089Swyllys 					match = !KMF_CompareRDNs(&subjectDN,
4865051Swyllys 					    &cmpDN);
4875051Swyllys 					kmf_free_dn(&cmpDN);
4883089Swyllys 					if (!match)
4893089Swyllys 						goto delete_and_cont;
4903089Swyllys 				} else {
4913089Swyllys 					goto delete_and_cont;
4923089Swyllys 				}
4933089Swyllys 			}
4943089Swyllys 			if (findSerial) {
4953089Swyllys 				SECItem *sernum;
4963089Swyllys 
4973089Swyllys 				sernum = &node->cert->serialNumber;
4983089Swyllys 
4993089Swyllys 				if (serial->len != sernum->len)
5003089Swyllys 					goto delete_and_cont;
5013089Swyllys 
5023089Swyllys 				if (memcmp(sernum->data, serial->val,
5035051Swyllys 				    serial->len))
5043089Swyllys 					goto delete_and_cont;
5053089Swyllys 			}
5063089Swyllys 
5073089Swyllys 			/* select the certs using find criteria */
5083089Swyllys 			switch (find_criteria) {
5093089Swyllys 			case KMF_ALL_CERTS:
5103089Swyllys 				break;
5113089Swyllys 			case KMF_NONEXPIRED_CERTS:
5123089Swyllys 				ret = CERT_CertTimesValid(node->cert);
5133089Swyllys 				if (ret == SECFailure) {
5143089Swyllys 					/* this is an invalid cert */
5153089Swyllys 					goto skip;
5163089Swyllys 				}
5173089Swyllys 				break;
5183089Swyllys 
5193089Swyllys 			case KMF_EXPIRED_CERTS:
5203089Swyllys 				ret = CERT_CertTimesValid(node->cert);
5213089Swyllys 				if (ret != SECFailure) {
5223089Swyllys 					/* this is a valid cert */
5233089Swyllys 					goto skip;
5243089Swyllys 				}
5253089Swyllys 				break;
5263089Swyllys 			}
5273089Swyllys skip:
5283089Swyllys 			node = CERT_LIST_NEXT(node);
5293089Swyllys 			continue;
5303089Swyllys delete_and_cont:
5313089Swyllys 			freenode = node;
5323089Swyllys 			node = CERT_LIST_NEXT(node);
5333089Swyllys 			CERT_RemoveCertListNode(freenode);
5343089Swyllys 		}
5353089Swyllys 	}
5363089Swyllys 
5373089Swyllys 	if (rv == KMF_OK && certlist != NULL) {
5383089Swyllys 		*certlist = list;
5393089Swyllys 	} else {
5403089Swyllys 		CERT_DestroyCertList(list);
5413089Swyllys 	}
5423089Swyllys 	return (rv);
5433089Swyllys }
5443089Swyllys 
5453089Swyllys static KMF_RETURN
convertCertList(void * kmfhandle,CERTCertList * nsscerts,KMF_X509_DER_CERT * kmfcerts,uint32_t * numcerts)5463089Swyllys convertCertList(void *kmfhandle,
5473089Swyllys 	CERTCertList *nsscerts, KMF_X509_DER_CERT *kmfcerts,
5483089Swyllys 	uint32_t *numcerts)
5493089Swyllys {
5503089Swyllys 	KMF_RETURN rv = KMF_OK;
5513089Swyllys 	CERTCertListNode *node;
5524025Swyllys 	uint32_t maxcerts = *numcerts;
5533089Swyllys 
5545051Swyllys 	maxcerts = *numcerts;
5555051Swyllys 	if (maxcerts == 0)
5565051Swyllys 		maxcerts = 0xFFFFFFFF;
5575051Swyllys 
5583089Swyllys 	*numcerts = 0;
5593089Swyllys 
5605051Swyllys 	/*
5615051Swyllys 	 * Don't copy more certs than the caller wanted.
5625051Swyllys 	 */
5633089Swyllys 	for (node = CERT_LIST_HEAD(nsscerts);
5645051Swyllys 	    !CERT_LIST_END(node, nsscerts) && rv == KMF_OK &&
5655051Swyllys 	    (*numcerts) < maxcerts;
5665051Swyllys 	    node = CERT_LIST_NEXT(node), (*numcerts)++) {
5673089Swyllys 		if (kmfcerts != NULL)
5683089Swyllys 			rv = nss2kmf_cert(node->cert, &kmfcerts[*numcerts]);
5693089Swyllys 	}
5703089Swyllys 
5713089Swyllys 	/*
5723089Swyllys 	 * If we failed, delete any certs allocated so far.
5733089Swyllys 	 */
5743089Swyllys 	if (rv != KMF_OK) {
5753089Swyllys 		int i;
5763089Swyllys 		for (i = 0; i < *numcerts; i++)
5775051Swyllys 			kmf_free_kmf_cert(kmfhandle, &kmfcerts[i]);
5785051Swyllys 
5794025Swyllys 		*numcerts = 0;
5803089Swyllys 	}
5813089Swyllys 	return (rv);
5823089Swyllys }
5833089Swyllys 
5843089Swyllys KMF_RETURN
NSS_FindCert(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)5855051Swyllys NSS_FindCert(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
5863089Swyllys {
5873089Swyllys 	KMF_RETURN rv = KMF_OK;
5883089Swyllys 	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
5893089Swyllys 	PK11SlotInfo *nss_slot = NULL;
5903089Swyllys 	CERTCertList *certlist = NULL;
5914025Swyllys 	uint32_t maxcerts;
5925051Swyllys 	uint32_t *num_certs;
5935051Swyllys 	KMF_X509_DER_CERT *kmfcerts = NULL;
5945051Swyllys 	char *certlabel = NULL;
5955051Swyllys 	char *issuer = NULL;
5965051Swyllys 	char *subject = NULL;
5975051Swyllys 	KMF_BIGINT *serial = NULL;
5985051Swyllys 	KMF_CERT_VALIDITY  validity;
5995051Swyllys 
6005051Swyllys 	if (handle == NULL || attrlist == NULL || numattr == 0) {
6015051Swyllys 		return (KMF_ERR_BAD_PARAMETER);
6025051Swyllys 	}
6035051Swyllys 	rv = do_nss_init(handle, numattr, attrlist, FALSE, &nss_slot);
6045051Swyllys 	if (rv != KMF_OK)
6053089Swyllys 		return (rv);
6065051Swyllys 
6075051Swyllys 	num_certs = kmf_get_attr_ptr(KMF_COUNT_ATTR, attrlist, numattr);
6085051Swyllys 	if (num_certs == NULL)
6095051Swyllys 		return (KMF_ERR_BAD_PARAMETER);
6105051Swyllys 
6115051Swyllys 	maxcerts = *num_certs;
6125051Swyllys 	if (maxcerts == 0)
6134025Swyllys 		maxcerts = 0xFFFFFFFF;
6143089Swyllys 	*num_certs = 0;
6155051Swyllys 
6165051Swyllys 	/* Get the optional returned certificate list  */
6175051Swyllys 	kmfcerts = kmf_get_attr_ptr(KMF_X509_DER_CERT_ATTR, attrlist, numattr);
6185051Swyllys 
6195051Swyllys 	/* Get optional search criteria attributes */
6205051Swyllys 	certlabel = kmf_get_attr_ptr(KMF_CERT_LABEL_ATTR, attrlist, numattr);
6215051Swyllys 	issuer = kmf_get_attr_ptr(KMF_ISSUER_NAME_ATTR, attrlist, numattr);
6225051Swyllys 	subject = kmf_get_attr_ptr(KMF_SUBJECT_NAME_ATTR, attrlist, numattr);
6235051Swyllys 	serial = kmf_get_attr_ptr(KMF_BIGINT_ATTR, attrlist, numattr);
6245051Swyllys 
6255051Swyllys 	rv = kmf_get_attr(KMF_CERT_VALIDITY_ATTR, attrlist, numattr,
6265051Swyllys 	    &validity, NULL);
6275051Swyllys 	if (rv != KMF_OK) {
6285051Swyllys 		validity = KMF_ALL_CERTS;
6295051Swyllys 		rv = KMF_OK;
6305051Swyllys 	}
6315051Swyllys 
6325051Swyllys 	if (certlabel != NULL) {
6334025Swyllys 		/* This will only find 1 certificate */
6345051Swyllys 		rv = nss_getcert_by_label(kmfh,	certlabel, kmfcerts, num_certs,
6355051Swyllys 		    validity);
6363089Swyllys 	} else {
6374025Swyllys 		/*
6384025Swyllys 		 * Build a list of matching certs.
6394025Swyllys 		 */
6405051Swyllys 		rv = nss_find_matching_certs(nss_slot, issuer, subject, serial,
6415051Swyllys 		    &certlist, validity);
6423089Swyllys 
6434025Swyllys 		/*
6444025Swyllys 		 * If the caller supplied a pointer to storage for
6454025Swyllys 		 * a list of certs, convert up to 'maxcerts' of the
6464025Swyllys 		 * matching certs.
6474025Swyllys 		 */
6483089Swyllys 		if (rv == KMF_OK && certlist != NULL) {
6495051Swyllys 			rv = convertCertList(handle, certlist, kmfcerts,
6505051Swyllys 			    &maxcerts);
6513089Swyllys 			CERT_DestroyCertList(certlist);
6524025Swyllys 			if (rv == KMF_OK)
6534025Swyllys 				*num_certs = maxcerts;
6543089Swyllys 		}
6553089Swyllys 	}
6563089Swyllys 
6573089Swyllys 	if (nss_slot != NULL) {
6583089Swyllys 		PK11_FreeSlot(nss_slot);
6593089Swyllys 	}
6603089Swyllys 
6613089Swyllys 	if (rv == KMF_OK && *num_certs == 0)
6623089Swyllys 		rv = KMF_ERR_CERT_NOT_FOUND;
6633089Swyllys 
6643089Swyllys 	return (rv);
6653089Swyllys }
6663089Swyllys 
6673089Swyllys void
6683089Swyllys /*ARGSUSED*/
NSS_FreeKMFCert(KMF_HANDLE_T handle,KMF_X509_DER_CERT * kmf_cert)6693089Swyllys NSS_FreeKMFCert(KMF_HANDLE_T handle,
6703089Swyllys 	KMF_X509_DER_CERT *kmf_cert)
6713089Swyllys {
6723089Swyllys 	if (kmf_cert != NULL) {
6733089Swyllys 		if (kmf_cert->certificate.Data != NULL) {
6743089Swyllys 			free(kmf_cert->certificate.Data);
6753089Swyllys 			kmf_cert->certificate.Data = NULL;
6763089Swyllys 			kmf_cert->certificate.Length = 0;
6773089Swyllys 		}
6783089Swyllys 		if (kmf_cert->kmf_private.label != NULL) {
6793089Swyllys 			free(kmf_cert->kmf_private.label);
6803089Swyllys 			kmf_cert->kmf_private.label = NULL;
6813089Swyllys 		}
6823089Swyllys 	}
6833089Swyllys }
6843089Swyllys 
6853089Swyllys KMF_RETURN
NSS_DeleteCert(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)6865051Swyllys NSS_DeleteCert(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
6873089Swyllys {
6883089Swyllys 	KMF_RETURN rv = KMF_OK;
6893089Swyllys 	int nssrv;
6903089Swyllys 	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
6913089Swyllys 	CERTCertificate *cert = NULL;
6923089Swyllys 	PK11SlotInfo *nss_slot = NULL;
6935051Swyllys 	char *certlabel = NULL;
6945051Swyllys 	char *issuer = NULL;
6955051Swyllys 	char *subject = NULL;
6965051Swyllys 	KMF_BIGINT *serial = NULL;
6975051Swyllys 	KMF_CERT_VALIDITY  validity;
6985051Swyllys 
6995051Swyllys 	if (handle == NULL || attrlist == NULL || numattr == 0) {
7003089Swyllys 		return (KMF_ERR_BAD_PARAMETER);
7013089Swyllys 	}
7025051Swyllys 	rv = do_nss_init(handle, numattr, attrlist, FALSE, &nss_slot);
7035051Swyllys 	if (rv != KMF_OK)
7045051Swyllys 		return (rv);
7055051Swyllys 
7065051Swyllys 	/* Get the search criteria attributes.  They are all optional. */
7075051Swyllys 	certlabel = kmf_get_attr_ptr(KMF_CERT_LABEL_ATTR, attrlist, numattr);
7085051Swyllys 	issuer = kmf_get_attr_ptr(KMF_ISSUER_NAME_ATTR, attrlist, numattr);
7095051Swyllys 	subject = kmf_get_attr_ptr(KMF_SUBJECT_NAME_ATTR, attrlist, numattr);
7105051Swyllys 	serial = kmf_get_attr_ptr(KMF_BIGINT_ATTR, attrlist, numattr);
7115051Swyllys 
7125051Swyllys 	rv = kmf_get_attr(KMF_CERT_VALIDITY_ATTR, attrlist, numattr,
7135051Swyllys 	    &validity, NULL);
7143089Swyllys 	if (rv != KMF_OK) {
7155051Swyllys 		validity = KMF_ALL_CERTS;
7165051Swyllys 		rv = KMF_OK;
7173089Swyllys 	}
7183089Swyllys 
7195051Swyllys 	/* Start finding the matched certificates and delete them. */
7205051Swyllys 	if (certlabel != NULL) {
7215051Swyllys 		cert = PK11_FindCertFromNickname(certlabel, NULL);
7223089Swyllys 		if (cert == NULL) {
7233089Swyllys 			return (KMF_ERR_CERT_NOT_FOUND);
7243089Swyllys 		}
7253089Swyllys 
7265051Swyllys 		switch (validity) {
7273089Swyllys 		case KMF_ALL_CERTS:
7283089Swyllys 			break;
7293089Swyllys 		case KMF_NONEXPIRED_CERTS:
7303089Swyllys 			nssrv = CERT_CertTimesValid(cert);
7313089Swyllys 			if (nssrv == SECFailure) {
7323089Swyllys 				/* this is an invalid cert - skip it */
7333089Swyllys 				goto out;
7343089Swyllys 			}
7353089Swyllys 			break;
7363089Swyllys 		case KMF_EXPIRED_CERTS:
7373089Swyllys 			nssrv = CERT_CertTimesValid(cert);
7383089Swyllys 			if (nssrv != SECFailure) {
7393089Swyllys 				/* this is a valid cert - skip it */
7403089Swyllys 				goto out;
7413089Swyllys 			}
7423089Swyllys 			break;
7433089Swyllys 		}
7443089Swyllys 		/* delete it from database */
7453089Swyllys 		nssrv = SEC_DeletePermCertificate(cert);
7463089Swyllys 		if (nssrv) {
7473089Swyllys 			SET_ERROR(kmfh, nssrv);
7483089Swyllys 			rv = KMF_ERR_INTERNAL;
7493089Swyllys 		}
7503089Swyllys 	} else {
7513089Swyllys 		CERTCertListNode *node;
7523089Swyllys 		CERTCertList *certlist = NULL;
7533089Swyllys 
7545051Swyllys 		rv = nss_find_matching_certs(nss_slot, issuer, subject, serial,
7555051Swyllys 		    &certlist, validity);
7563089Swyllys 
7573089Swyllys 		for (node = CERT_LIST_HEAD(certlist);
7585051Swyllys 		    !CERT_LIST_END(node, certlist) && rv == KMF_OK;
7595051Swyllys 		    node = CERT_LIST_NEXT(node)) {
7603089Swyllys 
7613089Swyllys 			nssrv = SEC_DeletePermCertificate(node->cert);
7623089Swyllys 			if (nssrv) {
7633089Swyllys 				SET_ERROR(kmfh, nssrv);
7643089Swyllys 				rv = KMF_ERR_INTERNAL;
7653089Swyllys 			}
7663089Swyllys 		}
7673089Swyllys 
7683089Swyllys 		if (rv == KMF_OK && certlist != NULL) {
7693089Swyllys 			CERT_DestroyCertList(certlist);
7703089Swyllys 		} else if (rv == KMF_OK && certlist == NULL) {
7713089Swyllys 			rv = KMF_ERR_CERT_NOT_FOUND;
7723089Swyllys 		}
7733089Swyllys 	}
7743089Swyllys out:
7753089Swyllys 	if (nss_slot != NULL) {
7763089Swyllys 		PK11_FreeSlot(nss_slot);
7773089Swyllys 	}
7783089Swyllys 
7793089Swyllys 	if (cert != NULL) {
7803089Swyllys 		CERT_DestroyCertificate(cert);
7813089Swyllys 	}
7823089Swyllys 
7833089Swyllys 	return (rv);
7843089Swyllys }
7853089Swyllys 
7863089Swyllys static void
InitRandom(char * filename)7873089Swyllys InitRandom(char *filename)
7883089Swyllys {
7893089Swyllys 	char buf[2048];
7903089Swyllys 	int fd;
7913089Swyllys 	PRInt32 count;
7923089Swyllys 
7933089Swyllys 	fd = open(filename, O_RDONLY);
7943089Swyllys 	if (!fd)
7953089Swyllys 		return;
7963089Swyllys 
7973089Swyllys 	count = read(fd, buf, sizeof (buf));
7983089Swyllys 	if (count > 0) {
79911411SSurya.Prakki@Sun.COM 		(void) PK11_RandomUpdate(buf, count);
8003089Swyllys 	}
8013089Swyllys 
8023089Swyllys 	(void) close(fd);
8033089Swyllys }
8043089Swyllys 
8053089Swyllys KMF_RETURN
NSS_CreateKeypair(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)8063089Swyllys NSS_CreateKeypair(KMF_HANDLE_T handle,
8075051Swyllys 	int numattr, KMF_ATTRIBUTE *attrlist)
8083089Swyllys {
8093089Swyllys 	KMF_RETURN rv = KMF_OK;
8103089Swyllys 	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
8115051Swyllys 	PK11RSAGenParams rsaparams;
8125051Swyllys 	void *nssparams;
8133089Swyllys 	CK_MECHANISM_TYPE mechanism;
8143089Swyllys 	ulong_t publicExponent = 0x010001;
8153089Swyllys 	PK11SlotInfo *nss_slot = NULL;
8163089Swyllys 	SECKEYPrivateKey *NSSprivkey = NULL;
8173089Swyllys 	SECKEYPublicKey *NSSpubkey = NULL;
818*11973Swyllys.ingersoll@sun.com 	SECKEYECParams *ecparams = NULL;
8193089Swyllys 	PQGParams *pqgParams = NULL;
8205051Swyllys 	KMF_CREDENTIAL cred;
8215051Swyllys 	boolean_t storekey = TRUE;
8225051Swyllys 	uint32_t keylen = 1024, len;
8235051Swyllys 	uint32_t keylen_size = sizeof (uint32_t);
8245051Swyllys 	KMF_KEY_ALG keytype = KMF_RSA;
8255051Swyllys 	KMF_KEY_HANDLE *pubkey = NULL;
8265051Swyllys 	KMF_KEY_HANDLE *privkey = NULL;
8275051Swyllys 	char *keylabel = NULL;
8285051Swyllys 
8295051Swyllys 	if (handle == NULL || attrlist == NULL || numattr == 0) {
8303089Swyllys 		return (KMF_ERR_BAD_PARAMETER);
8313089Swyllys 	}
8325051Swyllys 	rv = do_nss_init(handle, numattr, attrlist, FALSE, &nss_slot);
8335051Swyllys 	if (rv != KMF_OK) {
8345051Swyllys 		return (rv);
8355051Swyllys 	}
8365051Swyllys 
8375051Swyllys 	rv = kmf_get_attr(KMF_CREDENTIAL_ATTR, attrlist, numattr,
8385051Swyllys 	    (void *)&cred, NULL);
8395051Swyllys 	if (rv != KMF_OK)
8405051Swyllys 		return (rv);
8415051Swyllys 
8425051Swyllys 	rv = nss_authenticate(handle, nss_slot, &cred);
8433089Swyllys 	if (rv != KMF_OK) {
8443089Swyllys 		return (rv);
8453089Swyllys 	}
8463089Swyllys 
8475051Swyllys 	/* "storekey" is optional. Default is TRUE */
8485051Swyllys 	(void) kmf_get_attr(KMF_STOREKEY_BOOL_ATTR, attrlist, numattr,
8495051Swyllys 	    &storekey, NULL);
8505051Swyllys 
8515051Swyllys 	/* keytype is optional.  KMF_RSA is default */
8525051Swyllys 	(void) kmf_get_attr(KMF_KEYALG_ATTR, attrlist, numattr,
8535051Swyllys 	    (void *)&keytype, NULL);
8545051Swyllys 
8555051Swyllys 	rv = kmf_get_attr(KMF_KEYLENGTH_ATTR, attrlist, numattr,
8565051Swyllys 	    &keylen, &keylen_size);
8575051Swyllys 	if (rv == KMF_ERR_ATTR_NOT_FOUND)
8585051Swyllys 		/* Default keylen = 1024 */
8595051Swyllys 		rv = KMF_OK;
8605051Swyllys 	else if (rv != KMF_OK)
8615051Swyllys 		return (KMF_ERR_BAD_PARAMETER);
8625051Swyllys 
8635051Swyllys 	pubkey = kmf_get_attr_ptr(KMF_PUBKEY_HANDLE_ATTR, attrlist, numattr);
8645051Swyllys 	privkey = kmf_get_attr_ptr(KMF_PRIVKEY_HANDLE_ATTR, attrlist, numattr);
8655051Swyllys 	if (pubkey == NULL || privkey == NULL)
8665051Swyllys 		return (KMF_ERR_BAD_PARAMETER);
8675051Swyllys 
8685051Swyllys 	(void) memset(pubkey, 0, sizeof (KMF_KEY_HANDLE));
8695051Swyllys 	(void) memset(privkey, 0, sizeof (KMF_KEY_HANDLE));
8705051Swyllys 
8715051Swyllys 	rv = kmf_get_attr(KMF_KEYLABEL_ATTR, attrlist, numattr,	NULL, &len);
8725051Swyllys 	if (rv == KMF_OK && len > 0) {
8735051Swyllys 		keylabel = malloc(len + 1);
8745051Swyllys 		if (keylabel == NULL)
8755051Swyllys 			return (KMF_ERR_MEMORY);
8765051Swyllys 		/* Now fill in the label value */
8775051Swyllys 		(void) memset(keylabel, 0, len + 1);
8785051Swyllys 		rv = kmf_get_attr(KMF_KEYLABEL_ATTR, attrlist, numattr,
8795051Swyllys 		    keylabel, NULL);
8805051Swyllys 		if (rv != KMF_OK) {
8815051Swyllys 			free(keylabel);
8825051Swyllys 			goto cleanup;
8835051Swyllys 		}
8843089Swyllys 	}
8853089Swyllys 
8863089Swyllys 	/* Get some random bits */
8873089Swyllys 	InitRandom("/dev/urandom");
8885051Swyllys 	if (keytype == KMF_RSA) {
8895051Swyllys 		KMF_BIGINT rsaexp;
8905051Swyllys 
8915051Swyllys 		rsaparams.keySizeInBits = keylen;
8923089Swyllys 		/*
8933089Swyllys 		 * NSS only allows for a 4 byte exponent.
8943089Swyllys 		 * Ignore the exponent parameter if it is too big.
8953089Swyllys 		 */
8965051Swyllys 		if ((rv = kmf_get_attr(KMF_RSAEXP_ATTR, attrlist, numattr,
8975051Swyllys 		    &rsaexp, NULL)) == KMF_OK) {
8985051Swyllys 			if (rsaexp.len > 0 &&
8995051Swyllys 			    rsaexp.len <= sizeof (publicExponent) &&
9005051Swyllys 			    rsaexp.val != NULL) {
9015051Swyllys 				(void) memcpy(&publicExponent, rsaexp.val,
9025051Swyllys 				    rsaexp.len);
9035051Swyllys 			}
9043089Swyllys 		}
9053089Swyllys 		rsaparams.pe = publicExponent;
9063089Swyllys 		mechanism = CKM_RSA_PKCS_KEY_PAIR_GEN;
9073089Swyllys 		nssparams = &rsaparams;
9085051Swyllys 	} else if (keytype == KMF_DSA) {
9093089Swyllys 		PQGVerify *pqgVerify = NULL;
9103089Swyllys 		int ks;
9113089Swyllys 		SECStatus	nssrv, passed;
9123089Swyllys 
9133089Swyllys 		mechanism = CKM_DSA_KEY_PAIR_GEN;
9143089Swyllys 
9155051Swyllys 		ks = PQG_PBITS_TO_INDEX(keylen);
9163089Swyllys 		nssrv = PK11_PQG_ParamGen(ks, &pqgParams, &pqgVerify);
9173089Swyllys 		if (nssrv != SECSuccess) {
9183089Swyllys 			SET_ERROR(kmfh, rv);
9193089Swyllys 			PK11_PQG_DestroyVerify(pqgVerify);
9203089Swyllys 			rv = KMF_ERR_KEYGEN_FAILED;
9213089Swyllys 			goto cleanup;
9223089Swyllys 		}
9233089Swyllys 
9243089Swyllys 		nssrv = PK11_PQG_VerifyParams(pqgParams, pqgVerify, &passed);
9253089Swyllys 		if (nssrv != SECSuccess || passed != SECSuccess) {
9263089Swyllys 			SET_ERROR(kmfh, rv);
9273089Swyllys 			rv = KMF_ERR_KEYGEN_FAILED;
9283089Swyllys 		}
9293089Swyllys 
9303089Swyllys 		PK11_PQG_DestroyVerify(pqgVerify);
9313089Swyllys 
9323089Swyllys 		if (rv != KMF_OK) {
9333089Swyllys 			SET_ERROR(kmfh, PORT_GetError());
9343089Swyllys 			goto cleanup;
9353089Swyllys 		}
9363089Swyllys 
9373089Swyllys 		nssparams = pqgParams;
938*11973Swyllys.ingersoll@sun.com 	} else if (keytype == KMF_ECDSA) {
939*11973Swyllys.ingersoll@sun.com 		KMF_OID *eccoid = kmf_get_attr_ptr(KMF_ECC_CURVE_OID_ATTR,
940*11973Swyllys.ingersoll@sun.com 		    attrlist, numattr);
941*11973Swyllys.ingersoll@sun.com 		if (eccoid == NULL)
942*11973Swyllys.ingersoll@sun.com 			return (KMF_ERR_BAD_PARAMETER);
943*11973Swyllys.ingersoll@sun.com 
944*11973Swyllys.ingersoll@sun.com 		ecparams = SECITEM_AllocItem(NULL, NULL, (eccoid->Length));
945*11973Swyllys.ingersoll@sun.com 		if (!ecparams)
946*11973Swyllys.ingersoll@sun.com 			return (KMF_ERR_MEMORY);
947*11973Swyllys.ingersoll@sun.com 
948*11973Swyllys.ingersoll@sun.com 		(void) memcpy(ecparams->data, eccoid->Data, eccoid->Length);
949*11973Swyllys.ingersoll@sun.com 
950*11973Swyllys.ingersoll@sun.com 		mechanism = CKM_EC_KEY_PAIR_GEN;
951*11973Swyllys.ingersoll@sun.com 		nssparams = ecparams;
9523089Swyllys 	} else {
9533089Swyllys 		rv = KMF_ERR_BAD_PARAMETER;
9543089Swyllys 		goto cleanup;
9553089Swyllys 	}
9563089Swyllys 
9575051Swyllys 	NSSprivkey = PK11_GenerateKeyPair(nss_slot, mechanism, nssparams,
9585051Swyllys 	    &NSSpubkey,
9595051Swyllys 	    storekey, /* isPermanent */
9605051Swyllys 	    PR_TRUE, /* isSensitive */
9615051Swyllys 	    (void *)cred.cred);
9623089Swyllys 
9633089Swyllys 	if (NSSprivkey == NULL || NSSpubkey == NULL) {
9643089Swyllys 		SET_ERROR(kmfh, PORT_GetError());
9653089Swyllys 		rv = KMF_ERR_KEYGEN_FAILED;
9663089Swyllys 	} else {
9675051Swyllys 		if (keylabel != NULL && strlen(keylabel)) {
9683089Swyllys 			(void) PK11_SetPrivateKeyNickname(NSSprivkey,
9695051Swyllys 			    keylabel);
9705051Swyllys 			(void) PK11_SetPublicKeyNickname(NSSpubkey, keylabel);
9713089Swyllys 		}
9723089Swyllys 		/* Now, convert it to a KMF_KEY object for the framework */
9735051Swyllys 		privkey->kstype = KMF_KEYSTORE_NSS;
9745051Swyllys 		privkey->keyalg = keytype;
9755051Swyllys 		privkey->keyclass = KMF_ASYM_PRI;
9765051Swyllys 		privkey->keylabel = PK11_GetPrivateKeyNickname(NSSprivkey);
9775051Swyllys 		privkey->keyp = (void *)NSSprivkey;
9785051Swyllys 
9795051Swyllys 		pubkey->kstype = KMF_KEYSTORE_NSS;
9805051Swyllys 		pubkey->keyalg = keytype;
9815051Swyllys 		pubkey->keyp = (void *)NSSpubkey;
9825051Swyllys 		pubkey->keyclass = KMF_ASYM_PUB;
9835051Swyllys 		pubkey->keylabel = PK11_GetPublicKeyNickname(NSSpubkey);
9845051Swyllys 
9853089Swyllys 		rv = KMF_OK;
9863089Swyllys 	}
9873089Swyllys cleanup:
9883089Swyllys 	if (rv != KMF_OK) {
9893089Swyllys 		if (NSSpubkey)
99011411SSurya.Prakki@Sun.COM 			(void) PK11_DeleteTokenPublicKey(NSSpubkey);
9913089Swyllys 		if (NSSprivkey)
99211411SSurya.Prakki@Sun.COM 			(void) PK11_DeleteTokenPrivateKey(NSSprivkey, PR_TRUE);
9933089Swyllys 
9943089Swyllys 		privkey->keyp = NULL;
9953089Swyllys 		pubkey->keyp = NULL;
9963089Swyllys 	}
9973089Swyllys 
9985051Swyllys 	if (keylabel)
9995051Swyllys 		free(keylabel);
10005051Swyllys 
10013089Swyllys 	if (pqgParams != NULL)
10023089Swyllys 		PK11_PQG_DestroyParams(pqgParams);
10033089Swyllys 
1004*11973Swyllys.ingersoll@sun.com 	if (ecparams != NULL)
1005*11973Swyllys.ingersoll@sun.com 		SECITEM_FreeItem(ecparams, PR_TRUE);
1006*11973Swyllys.ingersoll@sun.com 
10073089Swyllys 	if (nss_slot != NULL)
10083089Swyllys 		PK11_FreeSlot(nss_slot);
10093089Swyllys 
10103089Swyllys 	return (rv);
10113089Swyllys }
10123089Swyllys 
10133089Swyllys KMF_RETURN
NSS_SignData(KMF_HANDLE_T handle,KMF_KEY_HANDLE * key,KMF_OID * AlgOID,KMF_DATA * tobesigned,KMF_DATA * output)10143089Swyllys NSS_SignData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *key,
10155051Swyllys     KMF_OID *AlgOID, KMF_DATA *tobesigned,
10165051Swyllys     KMF_DATA *output)
10173089Swyllys {
10183089Swyllys 	KMF_RETURN		ret = KMF_OK;
10195051Swyllys 	KMF_ALGORITHM_INDEX	AlgId;
10203089Swyllys 	SECOidTag		signAlgTag;
10213089Swyllys 	SECKEYPrivateKey	*NSSprivkey = NULL;
10223089Swyllys 	SECStatus		rv;
10233089Swyllys 	SECItem			signed_data;
10243089Swyllys 	KMF_HANDLE		*kmfh = (KMF_HANDLE *)handle;
10253089Swyllys 
10263089Swyllys 	signed_data.data = 0;
10273089Swyllys 	if (key == NULL || AlgOID == NULL ||
10283089Swyllys 	    tobesigned == NULL || output == NULL ||
10293089Swyllys 	    tobesigned->Data == NULL ||
10303089Swyllys 	    output->Data == NULL)
10313089Swyllys 		return (KMF_ERR_BAD_PARAMETER);
10323089Swyllys 
10333089Swyllys 	/* Map the OID to a NSS algorithm */
10345051Swyllys 	AlgId = x509_algoid_to_algid(AlgOID);
10353089Swyllys 	if (AlgId == KMF_ALGID_NONE)
10363089Swyllys 		return (KMF_ERR_BAD_PARAMETER);
10373089Swyllys 
10383089Swyllys 	NSSprivkey = (SECKEYPrivateKey *)key->keyp;
10393089Swyllys 
10403089Swyllys 	if (AlgId == KMF_ALGID_MD5WithRSA)
10413089Swyllys 		signAlgTag = SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION;
10423089Swyllys 	else if (AlgId == KMF_ALGID_MD2WithRSA)
10433089Swyllys 		signAlgTag = SEC_OID_PKCS1_MD2_WITH_RSA_ENCRYPTION;
10443089Swyllys 	else if (AlgId == KMF_ALGID_SHA1WithRSA)
10453089Swyllys 		signAlgTag = SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION;
1046*11973Swyllys.ingersoll@sun.com 	else if (AlgId == KMF_ALGID_SHA256WithRSA)
1047*11973Swyllys.ingersoll@sun.com 		signAlgTag = SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION;
1048*11973Swyllys.ingersoll@sun.com 	else if (AlgId == KMF_ALGID_SHA384WithRSA)
1049*11973Swyllys.ingersoll@sun.com 		signAlgTag = SEC_OID_PKCS1_SHA384_WITH_RSA_ENCRYPTION;
1050*11973Swyllys.ingersoll@sun.com 	else if (AlgId == KMF_ALGID_SHA512WithRSA)
1051*11973Swyllys.ingersoll@sun.com 		signAlgTag = SEC_OID_PKCS1_SHA512_WITH_RSA_ENCRYPTION;
10523089Swyllys 	else if (AlgId == KMF_ALGID_SHA1WithDSA)
10533089Swyllys 		signAlgTag = SEC_OID_ANSIX9_DSA_SIGNATURE_WITH_SHA1_DIGEST;
1054*11973Swyllys.ingersoll@sun.com 	else if (AlgId == KMF_ALGID_SHA1WithECDSA || AlgId == KMF_ALGID_ECDSA)
1055*11973Swyllys.ingersoll@sun.com 		signAlgTag = SEC_OID_ANSIX962_ECDSA_SIGNATURE_WITH_SHA1_DIGEST;
1056*11973Swyllys.ingersoll@sun.com 	else if (AlgId == KMF_ALGID_SHA256WithECDSA)
1057*11973Swyllys.ingersoll@sun.com 		signAlgTag = SEC_OID_ANSIX962_ECDSA_SHA256_SIGNATURE;
1058*11973Swyllys.ingersoll@sun.com 	else if (AlgId == KMF_ALGID_SHA384WithECDSA)
1059*11973Swyllys.ingersoll@sun.com 		signAlgTag = SEC_OID_ANSIX962_ECDSA_SHA384_SIGNATURE;
1060*11973Swyllys.ingersoll@sun.com 	else if (AlgId == KMF_ALGID_SHA512WithECDSA)
1061*11973Swyllys.ingersoll@sun.com 		signAlgTag = SEC_OID_ANSIX962_ECDSA_SHA512_SIGNATURE;
1062*11973Swyllys.ingersoll@sun.com 	else	/* NSS does not support DSA with SHA2 hashes (FIPS 186-3) */
10633089Swyllys 		return (KMF_ERR_BAD_PARAMETER);
10643089Swyllys 
10653089Swyllys 	rv = SEC_SignData(&signed_data, tobesigned->Data,
10663089Swyllys 	    tobesigned->Length, NSSprivkey, signAlgTag);
10673089Swyllys 
10683089Swyllys 	if (rv != 0) {
10693089Swyllys 		SET_ERROR(kmfh, rv);
10703089Swyllys 		return (KMF_ERR_INTERNAL);
10713089Swyllys 	}
10723089Swyllys 
10733089Swyllys 	if (signed_data.len <= output->Length) {
10743089Swyllys 		(void) memcpy(output->Data, signed_data.data, signed_data.len);
10753089Swyllys 		output->Length = signed_data.len;
10763089Swyllys 	} else {
10773089Swyllys 		output->Length = 0;
10783089Swyllys 		ret = KMF_ERR_BAD_PARAMETER;
10793089Swyllys 	}
10803089Swyllys 	free(signed_data.data);
10813089Swyllys 
10823089Swyllys 	return (ret);
10833089Swyllys }
10843089Swyllys 
10853089Swyllys KMF_RETURN
NSS_EncodePubKeyData(KMF_HANDLE_T handle,KMF_KEY_HANDLE * keyp,KMF_DATA * encoded)10863089Swyllys NSS_EncodePubKeyData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *keyp,
10873089Swyllys 	KMF_DATA *encoded)
10883089Swyllys {
10893089Swyllys 	KMF_RETURN ret = KMF_OK;
10903089Swyllys 	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
10913089Swyllys 	SECItem *rvitem;
10923089Swyllys 	CERTSubjectPublicKeyInfo *spki = NULL;
10933089Swyllys 
10943089Swyllys 	if (keyp == NULL || encoded == NULL || keyp->keyp == NULL)
10953089Swyllys 		return (KMF_ERR_BAD_PARAMETER);
10963089Swyllys 
10973089Swyllys 	spki = SECKEY_CreateSubjectPublicKeyInfo(keyp->keyp);
10983089Swyllys 	if (spki == NULL) {
10993089Swyllys 		SET_ERROR(kmfh, PORT_GetError());
11003089Swyllys 		return (KMF_ERR_MEMORY);
11013089Swyllys 	}
11023089Swyllys 
11033089Swyllys 	rvitem = SEC_ASN1EncodeItem(NULL, NULL, spki,
11045051Swyllys 	    CERT_SubjectPublicKeyInfoTemplate);
11053089Swyllys 	if (rvitem != NULL) {
11063089Swyllys 		encoded->Data = malloc(rvitem->len);
11073089Swyllys 		if (encoded->Data == NULL) {
11083089Swyllys 			ret = KMF_ERR_MEMORY;
11093089Swyllys 		} else {
11103089Swyllys 			(void) memcpy(encoded->Data, rvitem->data, rvitem->len);
11113089Swyllys 			encoded->Length = rvitem->len;
11123089Swyllys 		}
11133089Swyllys 		SECITEM_FreeItem(rvitem, TRUE);
11143089Swyllys 	} else {
11153089Swyllys 		SET_ERROR(kmfh, PORT_GetError());
11163089Swyllys 		encoded->Data = NULL;
11173089Swyllys 		encoded->Length = 0;
11183089Swyllys 		ret = KMF_ERR_ENCODING;
11193089Swyllys 	}
11203089Swyllys 	SECKEY_DestroySubjectPublicKeyInfo(spki);
11213089Swyllys 
11223089Swyllys 	return (ret);
11233089Swyllys }
11243089Swyllys 
11253089Swyllys KMF_RETURN
NSS_DeleteKey(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)11265051Swyllys NSS_DeleteKey(KMF_HANDLE_T handle,
11275051Swyllys 	int numattr, KMF_ATTRIBUTE *attrlist)
11283089Swyllys {
11293089Swyllys 	KMF_RETURN rv = KMF_OK;
11303089Swyllys 	PK11SlotInfo *nss_slot = NULL;
11315051Swyllys 	KMF_KEY_HANDLE *key;
11325051Swyllys 	KMF_CREDENTIAL cred;
11335051Swyllys 	boolean_t delete_token = B_TRUE;
11345051Swyllys 
11355051Swyllys 	if (handle == NULL || attrlist == NULL || numattr == 0) {
11365051Swyllys 		return (KMF_ERR_BAD_PARAMETER);
11375051Swyllys 	}
11383089Swyllys 	/*
11393089Swyllys 	 * "delete_token" means to clear it from the token storage as well
11403089Swyllys 	 * as from memory.
11413089Swyllys 	 */
11425051Swyllys 	key = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, numattr);
11433089Swyllys 	if (key == NULL || key->keyp == NULL)
11443089Swyllys 		return (KMF_ERR_BAD_PARAMETER);
11453089Swyllys 
11465051Swyllys 	rv = kmf_get_attr(KMF_DESTROY_BOOL_ATTR, attrlist, numattr,
11475051Swyllys 	    (void *)&delete_token, NULL);
11485051Swyllys 	if (rv != KMF_OK)
11495051Swyllys 		/* "delete_token" is optional. Default is TRUE */
11505051Swyllys 		rv = KMF_OK;
11515051Swyllys 
11523089Swyllys 	if (delete_token) {
11533089Swyllys 		SECStatus nssrv = SECSuccess;
11543089Swyllys 		if (key->keyclass != KMF_ASYM_PUB &&
11555051Swyllys 		    key->keyclass != KMF_ASYM_PRI &&
11565051Swyllys 		    key->keyclass != KMF_SYMMETRIC)
11573089Swyllys 			return (KMF_ERR_BAD_KEY_CLASS);
11583089Swyllys 
11595051Swyllys 		rv = do_nss_init(handle, numattr, attrlist, FALSE, &nss_slot);
11603089Swyllys 		if (rv != KMF_OK) {
11613089Swyllys 			return (rv);
11623089Swyllys 		}
11635051Swyllys 
11645051Swyllys 		rv = kmf_get_attr(KMF_CREDENTIAL_ATTR, attrlist, numattr,
11655051Swyllys 		    (void *)&cred, NULL);
11665051Swyllys 		if (rv != KMF_OK)
11675051Swyllys 			return (KMF_ERR_BAD_PARAMETER);
11685051Swyllys 
11695051Swyllys 		rv = nss_authenticate(handle, nss_slot, &cred);
11703089Swyllys 		if (rv != KMF_OK) {
11713089Swyllys 			return (rv);
11723089Swyllys 		}
11733089Swyllys 
11743089Swyllys 		if (key->keyclass == KMF_ASYM_PUB) {
11753089Swyllys 			nssrv = PK11_DeleteTokenPublicKey(
11765051Swyllys 			    (SECKEYPublicKey *)key->keyp);
11773089Swyllys 		} else if (key->keyclass == KMF_ASYM_PRI) {
11783089Swyllys 			nssrv = PK11_DeleteTokenPrivateKey(
11795051Swyllys 			    (SECKEYPrivateKey *)key->keyp, PR_TRUE);
11803089Swyllys 		} else if (key->keyclass == KMF_SYMMETRIC) {
11813089Swyllys 			nssrv = PK11_DeleteTokenSymKey(
11825051Swyllys 			    (PK11SymKey *) key->keyp);
11833089Swyllys 			if (nssrv == SECSuccess)
11845051Swyllys 				PK11_FreeSymKey((PK11SymKey *) key->keyp);
11853089Swyllys 		}
11863089Swyllys 		if (nssrv != SECSuccess) {
11873089Swyllys 			SET_ERROR(handle, PORT_GetError());
11883089Swyllys 			rv = KMF_ERR_INTERNAL;
11893089Swyllys 		}
11903089Swyllys 	} else {
11913089Swyllys 		if (key->keyclass == KMF_ASYM_PUB) {
11923089Swyllys 			SECKEY_DestroyPublicKey((SECKEYPublicKey *)key->keyp);
11933089Swyllys 		} else if (key->keyclass == KMF_ASYM_PRI) {
11943089Swyllys 			SECKEY_DestroyPrivateKey((SECKEYPrivateKey *)key->keyp);
11953089Swyllys 		} else if (key->keyclass == KMF_SYMMETRIC) {
11963089Swyllys 			PK11_FreeSymKey((PK11SymKey *) key->keyp);
11973089Swyllys 		} else {
11983089Swyllys 			return (KMF_ERR_BAD_KEY_CLASS);
11993089Swyllys 		}
12003089Swyllys 	}
12013089Swyllys 	key->keyp = NULL;
12023089Swyllys 
12033089Swyllys 	return (rv);
12043089Swyllys }
12053089Swyllys 
12063089Swyllys KMF_RETURN
NSS_GetErrorString(KMF_HANDLE_T handle,char ** msgstr)12073089Swyllys NSS_GetErrorString(KMF_HANDLE_T handle, char **msgstr)
12083089Swyllys {
12093089Swyllys 	KMF_RETURN ret = KMF_OK;
12103089Swyllys 	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
12113089Swyllys 	char *str;
12123089Swyllys 
12133089Swyllys 	/* Get the error string in the default language */
12143089Swyllys 	str = (char *)PR_ErrorToName((PRErrorCode)kmfh->lasterr.errcode);
12153089Swyllys 
12163089Swyllys 	if (str != NULL) {
12173089Swyllys 		*msgstr = (char *)strdup(str);
12183089Swyllys 		if ((*msgstr) == NULL)
12193089Swyllys 			ret = KMF_ERR_MEMORY;
12203089Swyllys 	} else {
12213089Swyllys 		*msgstr = NULL;
12223089Swyllys 	}
12233089Swyllys 
12243089Swyllys 	return (ret);
12253089Swyllys }
12263089Swyllys 
12273089Swyllys KMF_RETURN
NSS_FindPrikeyByCert(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)12285051Swyllys NSS_FindPrikeyByCert(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
12293089Swyllys {
12303089Swyllys 	KMF_RETURN rv = KMF_OK;
12313089Swyllys 	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
12325051Swyllys 	PK11SlotInfo *nss_slot = NULL;
12335051Swyllys 	KMF_CREDENTIAL cred;
12345051Swyllys 	KMF_KEY_HANDLE *key = NULL;
12355051Swyllys 	KMF_DATA *cert = NULL;
12365051Swyllys 	CERTCertificate *nss_cert = NULL;
12375051Swyllys 	SECKEYPrivateKey* privkey = NULL;
12385051Swyllys 
12395051Swyllys 	if (handle == NULL || attrlist == NULL || numattr == 0) {
12405051Swyllys 		return (KMF_ERR_BAD_PARAMETER);
12413089Swyllys 	}
12423089Swyllys 
12435051Swyllys 	rv = do_nss_init(handle, numattr, attrlist, FALSE, &nss_slot);
12445051Swyllys 	if (rv != KMF_OK)
12455051Swyllys 		return (rv);
12465051Swyllys 
12475051Swyllys 	/* Get the credential */
12485051Swyllys 	rv = kmf_get_attr(KMF_CREDENTIAL_ATTR, attrlist, numattr,
12495051Swyllys 	    (void *)&cred, NULL);
12505051Swyllys 	if (rv != KMF_OK)
12515051Swyllys 		return (KMF_ERR_BAD_PARAMETER);
12525051Swyllys 	rv = nss_authenticate(handle, nss_slot, &cred);
12535051Swyllys 	if (rv != KMF_OK)
12543089Swyllys 		return (rv);
12555051Swyllys 
12565051Swyllys 	/* Get the key handle */
12575051Swyllys 	key = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, numattr);
12585051Swyllys 	if (key == NULL)
12595051Swyllys 		return (KMF_ERR_BAD_PARAMETER);
12605051Swyllys 
12615051Swyllys 	/* Get the cert data and decode it */
12625051Swyllys 	cert = kmf_get_attr_ptr(KMF_CERT_DATA_ATTR, attrlist, numattr);
12635051Swyllys 	if (cert == NULL || cert->Data == NULL)
12645051Swyllys 		return (KMF_ERR_BAD_PARAMETER);
12655051Swyllys 
12665051Swyllys 	nss_cert = CERT_DecodeCertFromPackage((char *)cert->Data,
12675051Swyllys 	    cert->Length);
12683089Swyllys 	if (nss_cert == NULL) {
12693089Swyllys 		SET_ERROR(kmfh, PORT_GetError());
12703089Swyllys 		return (KMF_ERR_BAD_CERT_FORMAT);
12713089Swyllys 	}
12723089Swyllys 
12733089Swyllys 	privkey = PK11_FindPrivateKeyFromCert(nss_slot, nss_cert, NULL);
12743089Swyllys 	if (privkey == NULL) {
12753089Swyllys 		SET_ERROR(kmfh, PORT_GetError());
12763089Swyllys 		return (KMF_ERR_KEY_NOT_FOUND);
12773089Swyllys 	}
12783089Swyllys 
12793089Swyllys 	key->kstype = KMF_KEYSTORE_NSS;
12803089Swyllys 	key->keyclass = KMF_ASYM_PRI;
12813089Swyllys 	key->keyp = (void *)privkey;
12823089Swyllys 	key->keylabel = PK11_GetPrivateKeyNickname(privkey);
12833089Swyllys 
12843089Swyllys 	CERT_DestroyCertificate(nss_cert);
12853089Swyllys 
12863089Swyllys 	return (KMF_OK);
12873089Swyllys }
12883089Swyllys 
12895051Swyllys 
12903089Swyllys KMF_RETURN
NSS_DecryptData(KMF_HANDLE_T handle,KMF_KEY_HANDLE * key,KMF_OID * AlgOID,KMF_DATA * ciphertext,KMF_DATA * output)12913089Swyllys NSS_DecryptData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *key,
12923089Swyllys 	KMF_OID *AlgOID, KMF_DATA *ciphertext,
12933089Swyllys 	KMF_DATA *output)
12943089Swyllys {
12953089Swyllys 	KMF_RETURN		ret = KMF_OK;
12963089Swyllys 	SECKEYPrivateKey	*NSSprivkey = NULL;
12973089Swyllys 	SECStatus		rv;
12983089Swyllys 	KMF_HANDLE		*kmfh = (KMF_HANDLE *)handle;
12993089Swyllys 	unsigned int in_len = 0, out_len = 0;
13003089Swyllys 	unsigned int total_decrypted = 0, modulus_len = 0;
13013089Swyllys 	uint8_t *in_data, *out_data;
13023089Swyllys 	int i, blocks;
13033089Swyllys 
13043089Swyllys 	if (key == NULL || AlgOID == NULL ||
13053089Swyllys 	    ciphertext == NULL || output == NULL ||
13063089Swyllys 	    ciphertext->Data == NULL ||
13073089Swyllys 	    output->Data == NULL)
13083089Swyllys 		return (KMF_ERR_BAD_PARAMETER);
13093089Swyllys 
13103089Swyllys 	NSSprivkey = (SECKEYPrivateKey *)key->keyp;
13113089Swyllys 	modulus_len = PK11_GetPrivateModulusLen(NSSprivkey);
13123089Swyllys 
13133089Swyllys 	blocks = ciphertext->Length/modulus_len;
13143089Swyllys 	out_data = output->Data;
13153089Swyllys 	in_data = ciphertext->Data;
13163089Swyllys 	out_len = modulus_len - 11;
13173089Swyllys 	in_len = modulus_len;
13183089Swyllys 
13193089Swyllys 	for (i = 0; i < blocks; i++) {
13203089Swyllys 		rv = PK11_PrivDecryptPKCS1(NSSprivkey, out_data,
13213089Swyllys 		    &out_len, ciphertext->Length, in_data, in_len);
13223089Swyllys 
13233089Swyllys 		if (rv != 0) {
13243089Swyllys 			SET_ERROR(kmfh, rv);
13253089Swyllys 			return (KMF_ERR_INTERNAL);
13263089Swyllys 		}
13273089Swyllys 
13283089Swyllys 		out_data += out_len;
13293089Swyllys 		total_decrypted += out_len;
13303089Swyllys 		in_data += in_len;
13313089Swyllys 	}
13323089Swyllys 
13333089Swyllys 	output->Length = total_decrypted;
13343089Swyllys 
13353089Swyllys 	return (ret);
13363089Swyllys }
13373089Swyllys 
13383089Swyllys static KMF_KEY_ALG
pk11keytype2kmf(CK_KEY_TYPE type)13393089Swyllys pk11keytype2kmf(CK_KEY_TYPE type)
13403089Swyllys {
13413089Swyllys 	switch (type) {
13423089Swyllys 	case CKK_RSA:
13433089Swyllys 		return (KMF_RSA);
13443089Swyllys 	case CKK_DSA:
13453089Swyllys 		return (KMF_RSA);
13463089Swyllys 	case CKK_AES:
13473089Swyllys 		return (KMF_AES);
13483089Swyllys 	case CKK_RC4:
13493089Swyllys 		return (KMF_RC4);
13503089Swyllys 	case CKK_DES:
13513089Swyllys 		return (KMF_DES);
13523089Swyllys 	case CKK_DES3:
13533089Swyllys 		return (KMF_DES3);
1354*11973Swyllys.ingersoll@sun.com 	case CKK_EC:
1355*11973Swyllys.ingersoll@sun.com 		return (KMF_ECDSA);
13563089Swyllys 	default:
13573089Swyllys 		/* not supported */
13583089Swyllys 		return (KMF_KEYALG_NONE);
13593089Swyllys 	}
13603089Swyllys }
13613089Swyllys 
13623089Swyllys KMF_RETURN
NSS_FindKey(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)13635051Swyllys NSS_FindKey(KMF_HANDLE_T handle,
13645051Swyllys 	int numattr, KMF_ATTRIBUTE *attrlist)
13653089Swyllys {
13663089Swyllys 	KMF_RETURN rv;
13673089Swyllys 	SECKEYPrivateKeyList *prilist;
13683089Swyllys 	SECKEYPrivateKeyListNode *prinode;
13693089Swyllys 	SECKEYPublicKeyList *publist;
13703089Swyllys 	SECKEYPublicKeyListNode *pubnode;
13713089Swyllys 	PK11SlotInfo *nss_slot = NULL;
13724025Swyllys 	PK11SymKey *symlist = NULL;
13733089Swyllys 	int count;
13744025Swyllys 	uint32_t maxkeys;
13755051Swyllys 	KMF_KEY_HANDLE *keys;
13765051Swyllys 	uint32_t *numkeys;
13775221Swyllys 	KMF_CREDENTIAL *cred = NULL;
13785051Swyllys 	KMF_KEY_CLASS keyclass;
13795051Swyllys 	char *findLabel;
13805221Swyllys 	char *nick;
13815221Swyllys 	int match = 0;
13825051Swyllys 	KMF_KEY_ALG keytype = KMF_KEYALG_NONE;
13835051Swyllys 
13845051Swyllys 	if (handle == NULL || attrlist == NULL || numattr == 0) {
13855051Swyllys 		return (KMF_ERR_BAD_PARAMETER);
13865051Swyllys 	}
13875051Swyllys 
13885051Swyllys 	numkeys = kmf_get_attr_ptr(KMF_COUNT_ATTR, attrlist, numattr);
13895051Swyllys 	if (numkeys == NULL)
13905051Swyllys 		return (KMF_ERR_BAD_PARAMETER);
13915051Swyllys 
13925051Swyllys 	rv = do_nss_init(handle, numattr, attrlist, FALSE, &nss_slot);
13933089Swyllys 	if (rv != KMF_OK) {
13943089Swyllys 		return (rv);
13953089Swyllys 	}
13963089Swyllys 
13975221Swyllys 	/* It is OK if this is NULL, we dont need a cred to find public keys */
13985221Swyllys 	cred = kmf_get_attr_ptr(KMF_CREDENTIAL_ATTR, attrlist, numattr);
13995221Swyllys 
14005221Swyllys 	if (cred != NULL) {
14015221Swyllys 		rv = nss_authenticate(handle, nss_slot, cred);
14025221Swyllys 		if (rv != KMF_OK) {
14035221Swyllys 			return (rv);
14045221Swyllys 		}
14053089Swyllys 	}
14063089Swyllys 
14074025Swyllys 	maxkeys = *numkeys;
14084025Swyllys 	if (maxkeys == 0)
14094025Swyllys 		maxkeys = 0xFFFFFFFF;
14103089Swyllys 	*numkeys = 0;
14115051Swyllys 
14125051Swyllys 	rv = kmf_get_attr(KMF_KEYCLASS_ATTR, attrlist, numattr,
14135051Swyllys 	    (void *)&keyclass, NULL);
14145051Swyllys 	if (rv != KMF_OK)
14155051Swyllys 		return (KMF_ERR_BAD_PARAMETER);
14165051Swyllys 
14175051Swyllys 	findLabel = kmf_get_attr_ptr(KMF_KEYLABEL_ATTR, attrlist, numattr);
14185051Swyllys 
14195051Swyllys 	if (keyclass == KMF_ASYM_PUB) {
14205051Swyllys 		publist = PK11_ListPublicKeysInSlot(nss_slot, findLabel);
14213089Swyllys 		if (publist == NULL) {
14223089Swyllys 			rv = KMF_ERR_KEY_NOT_FOUND;
14233089Swyllys 			goto cleanup;
14243089Swyllys 		}
14255051Swyllys 	} else if (keyclass == KMF_ASYM_PRI) {
14265051Swyllys 		prilist = PK11_ListPrivKeysInSlot(nss_slot, findLabel, NULL);
14273089Swyllys 		if (prilist == NULL) {
14283089Swyllys 			rv = KMF_ERR_KEY_NOT_FOUND;
14293089Swyllys 			goto cleanup;
14303089Swyllys 		}
14315051Swyllys 	} else if (keyclass == KMF_SYMMETRIC) {
14325051Swyllys 		symlist = PK11_ListFixedKeysInSlot(nss_slot, findLabel, NULL);
14333089Swyllys 		if (symlist == NULL) {
14343089Swyllys 			rv = KMF_ERR_KEY_NOT_FOUND;
14353089Swyllys 			goto cleanup;
14363089Swyllys 		}
14373089Swyllys 	} else {
14383089Swyllys 		rv = KMF_ERR_BAD_KEY_CLASS;
14393089Swyllys 		goto cleanup;
14403089Swyllys 	}
14413089Swyllys 
14425051Swyllys 	keys = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, numattr);
14435051Swyllys 	/* it is okay to have "keys" contains NULL */
14445051Swyllys 
14455051Swyllys 	if (keyclass == KMF_ASYM_PUB) {
14463089Swyllys 		for (count = 0, pubnode = PUBKEY_LIST_HEAD(publist);
14475051Swyllys 		    !PUBKEY_LIST_END(pubnode, publist) && count < maxkeys;
14485221Swyllys 		    pubnode = PUBKEY_LIST_NEXT(pubnode)) {
14495221Swyllys 			match = 0;
14505221Swyllys 			/*
14515221Swyllys 			 * Due to bug in NSS, we have to manually match
14525221Swyllys 			 * the labels to be sure we have a match.
14535221Swyllys 			 */
14545221Swyllys 			nick = PK11_GetPublicKeyNickname(pubnode->key);
14555221Swyllys 			if (findLabel) {
14565221Swyllys 				match = (nick &&
14575221Swyllys 				    (strcmp(nick, findLabel) == 0));
14585221Swyllys 			} else {
14595221Swyllys 				/* always match if findLabel is NULL */
14605221Swyllys 				match = 1;
14615221Swyllys 			}
14625221Swyllys 			if (keys != NULL && match) {
14633089Swyllys 				keys[count].kstype = KMF_KEYSTORE_NSS;
14643089Swyllys 				keys[count].keyclass = KMF_ASYM_PUB;
14653089Swyllys 				keys[count].keyp = (void *)pubnode->key;
14665221Swyllys 				keys[count].keylabel = nick;
14673089Swyllys 
14683089Swyllys 				if (pubnode->key->keyType == rsaKey)
14693089Swyllys 					keys[count].keyalg = KMF_RSA;
14703089Swyllys 				else if (pubnode->key->keyType == dsaKey)
14713089Swyllys 					keys[count].keyalg = KMF_DSA;
1472*11973Swyllys.ingersoll@sun.com 				else if (pubnode->key->keyType == ecKey)
1473*11973Swyllys.ingersoll@sun.com 					keys[count].keyalg = KMF_ECDSA;
14743089Swyllys 			}
14755221Swyllys 			if (match)
14765221Swyllys 				count++;
14773089Swyllys 		}
14783089Swyllys 		*numkeys = count;
14795051Swyllys 	} else if (keyclass == KMF_ASYM_PRI) {
14803089Swyllys 		for (count = 0, prinode = PRIVKEY_LIST_HEAD(prilist);
14815051Swyllys 		    !PRIVKEY_LIST_END(prinode, prilist) && count < maxkeys;
14825221Swyllys 		    prinode = PRIVKEY_LIST_NEXT(prinode)) {
14835221Swyllys 			match = 0;
14845221Swyllys 			/*
14855221Swyllys 			 * Due to bug in NSS, we have to manually match
14865221Swyllys 			 * the labels to be sure we have a match.
14875221Swyllys 			 */
14885221Swyllys 			nick = PK11_GetPrivateKeyNickname(prinode->key);
14895221Swyllys 			if (findLabel) {
14905221Swyllys 				match = (nick &&
14915221Swyllys 				    (strcmp(nick, findLabel) == 0));
14925221Swyllys 			} else {
14935221Swyllys 				/* always match if findLabel is NULL */
14945221Swyllys 				match = 1;
14955221Swyllys 			}
14965221Swyllys 			if (keys != NULL && match) {
14973089Swyllys 				keys[count].kstype = KMF_KEYSTORE_NSS;
14983089Swyllys 				keys[count].keyclass = KMF_ASYM_PRI;
14993089Swyllys 				keys[count].keyp = (void *)prinode->key;
15005221Swyllys 				keys[count].keylabel = nick;
15013089Swyllys 
15023089Swyllys 				if (prinode->key->keyType == rsaKey)
15033089Swyllys 					keys[count].keyalg = KMF_RSA;
15043089Swyllys 				else if (prinode->key->keyType == dsaKey)
15053089Swyllys 					keys[count].keyalg = KMF_DSA;
1506*11973Swyllys.ingersoll@sun.com 				else if (prinode->key->keyType == ecKey)
1507*11973Swyllys.ingersoll@sun.com 					keys[count].keyalg = KMF_ECDSA;
15083089Swyllys 			}
15095221Swyllys 			if (match)
15105221Swyllys 				count++;
15113089Swyllys 		}
15123089Swyllys 		*numkeys = count;
15135051Swyllys 	} else if (keyclass == KMF_SYMMETRIC) {
15143089Swyllys 		count = 0;
15155051Swyllys 		rv = kmf_get_attr(KMF_KEYALG_ATTR, attrlist, numattr,
15165051Swyllys 		    (void *)&keytype, NULL);
15175051Swyllys 		if (rv != KMF_OK)
15185051Swyllys 			rv = KMF_OK;
15194025Swyllys 		while (symlist && count < maxkeys) {
15203089Swyllys 			PK11SymKey *symkey = symlist;
15213089Swyllys 			CK_KEY_TYPE type;
15223089Swyllys 			KMF_KEY_ALG keyalg;
15233089Swyllys 
15245221Swyllys 			match = 0;
15253089Swyllys 			type = PK11_GetSymKeyType(symkey);
15263089Swyllys 			keyalg = pk11keytype2kmf(type);
15273089Swyllys 
15285051Swyllys 			symlist = PK11_GetNextSymKey(symkey);
15295051Swyllys 
15303089Swyllys 			/*
15313089Swyllys 			 * If keytype is specified in the searching parameter,
15323089Swyllys 			 * check the keytype and skip the key if its keytype
15333089Swyllys 			 * doesn't match.
15343089Swyllys 			 */
15355051Swyllys 			if (keytype != KMF_KEYALG_NONE && keytype != keyalg) {
15365051Swyllys 				/* free that key since we arent using it */
15374025Swyllys 				PK11_FreeSymKey(symkey);
15383089Swyllys 				continue;
15393089Swyllys 			}
15405221Swyllys 			/*
15415221Swyllys 			 * Due to bug in NSS, we have to manually match
15425221Swyllys 			 * the labels to be sure we have a match.
15435221Swyllys 			 */
15445221Swyllys 			nick = PK11_GetSymKeyNickname(symkey);
15455221Swyllys 			if (findLabel) {
15465221Swyllys 				match = (nick &&
15475221Swyllys 				    (strcmp(nick, findLabel) == 0));
15485221Swyllys 			} else {
15495221Swyllys 				/* always match if findLabel is NULL */
15505221Swyllys 				match = 1;
15515221Swyllys 			}
15525221Swyllys 
15535221Swyllys 			if (keys != NULL && match) {
15543089Swyllys 				keys[count].kstype = KMF_KEYSTORE_NSS;
15553089Swyllys 				keys[count].keyclass = KMF_SYMMETRIC;
15563089Swyllys 				keys[count].keyp = (void *) symkey;
15575221Swyllys 				keys[count].keylabel = nick;
15583089Swyllys 				keys[count].keyalg = keyalg;
15593089Swyllys 			} else {
15603089Swyllys 				PK11_FreeSymKey(symkey);
15613089Swyllys 			}
15625221Swyllys 			if (match)
15635221Swyllys 				count++;
15643089Swyllys 		}
15654025Swyllys 		/*
15664025Swyllys 		 * Cleanup memory for unused keys.
15674025Swyllys 		 */
15684025Swyllys 		while (symlist != NULL) {
15694025Swyllys 			PK11SymKey *symkey = symlist;
15705051Swyllys 
15714025Swyllys 			PK11_FreeSymKey(symkey);
15724025Swyllys 			symlist = PK11_GetNextSymKey(symkey);
15734025Swyllys 		}
15745051Swyllys 		*numkeys = count;
15753089Swyllys 	}
15763089Swyllys 
15773089Swyllys cleanup:
15783089Swyllys 	if (nss_slot != NULL) {
15793089Swyllys 		PK11_FreeSlot(nss_slot);
15803089Swyllys 	}
15813089Swyllys 
15823089Swyllys 	return (rv);
15833089Swyllys }
15843089Swyllys 
15853089Swyllys static SECStatus
p12u_SwapUnicodeBytes(SECItem * uniItem)15863089Swyllys p12u_SwapUnicodeBytes(SECItem *uniItem)
15873089Swyllys {
15883089Swyllys 	unsigned int i;
15893089Swyllys 	unsigned char a;
15903089Swyllys 	if ((uniItem == NULL) || (uniItem->len % 2)) {
15913089Swyllys 		return (SECFailure);
15923089Swyllys 		}
15933089Swyllys 	for (i = 0; i < uniItem->len; i += 2) {
15943089Swyllys 		a = uniItem->data[i];
15953089Swyllys 		uniItem->data[i] = uniItem->data[i+1];
15963089Swyllys 		uniItem->data[i+1] = a;
15973089Swyllys 	}
15983089Swyllys 	return (SECSuccess);
15993089Swyllys }
16003089Swyllys 
16013089Swyllys static PRBool
p12u_ucs2_ascii_conversion_function(PRBool toUnicode,unsigned char * inBuf,unsigned int inBufLen,unsigned char * outBuf,unsigned int maxOutBufLen,unsigned int * outBufLen,PRBool swapBytes)16023089Swyllys p12u_ucs2_ascii_conversion_function(
16033089Swyllys 	PRBool		toUnicode,
16043089Swyllys 	unsigned char	*inBuf,
16053089Swyllys 	unsigned int	inBufLen,
16063089Swyllys 	unsigned char	*outBuf,
16073089Swyllys 	unsigned int	maxOutBufLen,
16083089Swyllys 	unsigned int	*outBufLen,
16093089Swyllys 	PRBool		swapBytes)
16103089Swyllys {
16113089Swyllys 	SECItem it = { 0 };
16123089Swyllys 	SECItem *dup = NULL;
16133089Swyllys 	PRBool ret;
16143089Swyllys 
16153089Swyllys 	it.data = inBuf;
16163089Swyllys 	it.len = inBufLen;
16173089Swyllys 	dup = SECITEM_DupItem(&it);
16183089Swyllys 	/*
16193089Swyllys 	 * If converting Unicode to ASCII, swap bytes before conversion
16203089Swyllys 	 * as neccessary.
16213089Swyllys 	 */
16223089Swyllys 	if (!toUnicode && swapBytes) {
16233089Swyllys 		if (p12u_SwapUnicodeBytes(dup) != SECSuccess) {
16243089Swyllys 			SECITEM_ZfreeItem(dup, PR_TRUE);
16253089Swyllys 			return (PR_FALSE);
16263089Swyllys 		}
16273089Swyllys 	}
16283089Swyllys 	/* Perform the conversion. */
16293089Swyllys 	ret = PORT_UCS2_UTF8Conversion(toUnicode, dup->data, dup->len,
16305051Swyllys 	    outBuf, maxOutBufLen, outBufLen);
16313089Swyllys 	if (dup)
16323089Swyllys 		SECITEM_ZfreeItem(dup, PR_TRUE);
16333089Swyllys 
16343089Swyllys 	return (ret);
16353089Swyllys }
16363089Swyllys 
16373089Swyllys static PRBool
p12u_OpenFile(p12uContext * p12ctx,PRBool fileRead)16383089Swyllys p12u_OpenFile(p12uContext *p12ctx, PRBool fileRead)
16393089Swyllys {
16403089Swyllys 	if (!p12ctx || !p12ctx->filename) {
16413089Swyllys 		return (PR_FALSE);
16423089Swyllys 	}
16433089Swyllys 
16443089Swyllys 	if (fileRead) {
16455051Swyllys 		p12ctx->file = PR_Open(p12ctx->filename, PR_RDONLY, 0400);
16463089Swyllys 	} else {
16473089Swyllys 		p12ctx->file = PR_Open(p12ctx->filename,
16485051Swyllys 		    PR_CREATE_FILE | PR_RDWR | PR_TRUNCATE, 0600);
16493089Swyllys 	}
16503089Swyllys 
16513089Swyllys 	if (!p12ctx->file) {
16523089Swyllys 		p12ctx->error = PR_TRUE;
16533089Swyllys 		return (PR_FALSE);
16543089Swyllys 	}
16553089Swyllys 
16563089Swyllys 	return (PR_TRUE);
16573089Swyllys }
16583089Swyllys 
16593089Swyllys static void
p12u_DestroyContext(p12uContext ** ppCtx,PRBool removeFile)16603089Swyllys p12u_DestroyContext(p12uContext **ppCtx, PRBool removeFile)
16613089Swyllys {
16623089Swyllys 	if (!ppCtx || !(*ppCtx)) {
16633089Swyllys 		return;
16643089Swyllys 	}
16653089Swyllys 
16663089Swyllys 	if ((*ppCtx)->file != NULL) {
166711411SSurya.Prakki@Sun.COM 		(void) PR_Close((*ppCtx)->file);
16683089Swyllys 	}
16693089Swyllys 
16703089Swyllys 	if ((*ppCtx)->filename != NULL) {
16713089Swyllys 		if (removeFile) {
167211411SSurya.Prakki@Sun.COM 			(void) PR_Delete((*ppCtx)->filename);
16733089Swyllys 		}
16743089Swyllys 		free((*ppCtx)->filename);
16753089Swyllys 	}
16763089Swyllys 
16773089Swyllys 	free(*ppCtx);
16783089Swyllys 	*ppCtx = NULL;
16793089Swyllys }
16803089Swyllys 
16813089Swyllys static p12uContext *
p12u_InitContext(PRBool fileImport,char * filename)16823089Swyllys p12u_InitContext(PRBool fileImport, char *filename)
16833089Swyllys {
16843089Swyllys 	p12uContext *p12ctx;
16853089Swyllys 
16863089Swyllys 	p12ctx = PORT_ZNew(p12uContext);
16873089Swyllys 	if (!p12ctx) {
16883089Swyllys 		return (NULL);
16893089Swyllys 	}
16903089Swyllys 
16913089Swyllys 	p12ctx->error = PR_FALSE;
16923089Swyllys 	p12ctx->errorValue = 0;
16933089Swyllys 	p12ctx->filename = strdup(filename);
16943089Swyllys 
16953089Swyllys 	if (!p12u_OpenFile(p12ctx, fileImport)) {
16963089Swyllys 		p12u_DestroyContext(&p12ctx, PR_FALSE);
16973089Swyllys 		return (NULL);
16983089Swyllys 	}
16993089Swyllys 
17003089Swyllys 	return (p12ctx);
17013089Swyllys }
17023089Swyllys 
17033089Swyllys static void
p12u_WriteToExportFile(void * arg,const char * buf,unsigned long len)17043089Swyllys p12u_WriteToExportFile(void *arg, const char *buf, unsigned long len)
17053089Swyllys {
17063089Swyllys 	p12uContext *p12cxt = arg;
17073089Swyllys 	int writeLen;
17083089Swyllys 
17093089Swyllys 	if (!p12cxt || (p12cxt->error == PR_TRUE)) {
17103089Swyllys 		return;
17113089Swyllys 	}
17123089Swyllys 
17133089Swyllys 	if (p12cxt->file == NULL) {
17143089Swyllys 		p12cxt->errorValue = SEC_ERROR_PKCS12_UNABLE_TO_WRITE;
17153089Swyllys 		p12cxt->error = PR_TRUE;
17163089Swyllys 		return;
17173089Swyllys 	}
17183089Swyllys 
17193089Swyllys 	writeLen = PR_Write(p12cxt->file, (unsigned char *)buf, (int32)len);
17203089Swyllys 
17213089Swyllys 	if (writeLen != (int)len) {
172211411SSurya.Prakki@Sun.COM 		(void) PR_Close(p12cxt->file);
17233089Swyllys 		free(p12cxt->filename);
17243089Swyllys 		p12cxt->filename = NULL;
17253089Swyllys 		p12cxt->file = NULL;
17263089Swyllys 		p12cxt->errorValue = SEC_ERROR_PKCS12_UNABLE_TO_WRITE;
17273089Swyllys 		p12cxt->error = PR_TRUE;
17283089Swyllys 	}
17293089Swyllys }
17303089Swyllys 
17313089Swyllys #define	HANDLE_NSS_ERROR(r) {\
17323089Swyllys 	SET_ERROR(kmfh, PORT_GetError()); \
17333089Swyllys 	rv = r; \
17343089Swyllys 	goto out; }
17353089Swyllys 
17363089Swyllys static KMF_RETURN
add_cert_to_bag(SEC_PKCS12ExportContext * p12ecx,CERTCertificate * cert,SECItem * pwitem)17373089Swyllys add_cert_to_bag(SEC_PKCS12ExportContext *p12ecx,
17383089Swyllys 	CERTCertificate *cert, SECItem *pwitem)
17393089Swyllys {
17403089Swyllys 	KMF_RETURN rv = KMF_OK;
17413089Swyllys 	SEC_PKCS12SafeInfo *keySafe = NULL, *certSafe = NULL;
17423089Swyllys 
17433089Swyllys 	keySafe = SEC_PKCS12CreateUnencryptedSafe(p12ecx);
17443089Swyllys 	if (PK11_IsFIPS()) {
17453089Swyllys 		certSafe = keySafe;
17463089Swyllys 	} else {
17473089Swyllys 		certSafe = SEC_PKCS12CreatePasswordPrivSafe(p12ecx, pwitem,
17485051Swyllys 		    SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC);
17493089Swyllys 	}
17503089Swyllys 
17513089Swyllys 	if (!certSafe || !keySafe) {
17523089Swyllys 		rv = KMF_ERR_INTERNAL;
17533089Swyllys 		goto out;
17543089Swyllys 	}
17553089Swyllys 
17563089Swyllys 	if (SEC_PKCS12AddCertAndKey(p12ecx, certSafe, NULL, cert,
17575051Swyllys 	    CERT_GetDefaultCertDB(), keySafe, NULL, PR_TRUE, pwitem,
17585051Swyllys 	    SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_3KEY_TRIPLE_DES_CBC)
17595051Swyllys 	    != SECSuccess) {
17603089Swyllys 		rv = KMF_ERR_INTERNAL;
17613089Swyllys 	}
17623089Swyllys out:
17633089Swyllys 	return (rv);
17643089Swyllys }
17653089Swyllys 
17663089Swyllys KMF_RETURN
NSS_ExportPK12(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)17675051Swyllys NSS_ExportPK12(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
17683089Swyllys {
17693089Swyllys 	KMF_RETURN rv;
17703089Swyllys 	KMF_HANDLE *kmfh = (KMF_HANDLE  *)handle;
17713089Swyllys 	SEC_PKCS12ExportContext *p12ecx = NULL;
17723089Swyllys 	p12uContext *p12ctx = NULL;
17733089Swyllys 	CERTCertList *certlist = NULL;
17743089Swyllys 	CERTCertificate *nsscert = NULL;
17753089Swyllys 	CERTCertListNode* node = NULL;
17763089Swyllys 	PK11SlotInfo	*slot = NULL;
17773089Swyllys 	SECItem pwitem = {NULL, 0};
17785051Swyllys 	KMF_CREDENTIAL *cred = NULL;
17795051Swyllys 	KMF_CREDENTIAL *p12cred = NULL;
17805051Swyllys 	char *certlabel = NULL;
17815051Swyllys 	char *issuer = NULL;
17825051Swyllys 	char *subject = NULL;
17835051Swyllys 	KMF_BIGINT *serial = NULL;
17845051Swyllys 	char *filename = NULL;
17855051Swyllys 
17865051Swyllys 	if (kmfh == NULL || attrlist == NULL || numattr == 0) {
17875051Swyllys 		return (KMF_ERR_BAD_PARAMETER);
17883089Swyllys 	}
17893089Swyllys 
17905051Swyllys 	rv = do_nss_init(handle, numattr, attrlist, FALSE, &slot);
17915051Swyllys 	if (rv != KMF_OK)
17925051Swyllys 		return (rv);
17935051Swyllys 
17945051Swyllys 	cred = kmf_get_attr_ptr(KMF_CREDENTIAL_ATTR, attrlist, numattr);
17955051Swyllys 	if (cred == NULL)
17965051Swyllys 		return (KMF_ERR_BAD_PARAMETER);
17975051Swyllys 
17985051Swyllys 	rv = nss_authenticate(handle, slot, cred);
17995051Swyllys 	if (rv != KMF_OK)
18003089Swyllys 		return (rv);
18015051Swyllys 
18025051Swyllys 	p12cred = kmf_get_attr_ptr(KMF_PK12CRED_ATTR, attrlist, numattr);
18035051Swyllys 	if (p12cred  == NULL)
18045051Swyllys 		return (KMF_ERR_BAD_PARAMETER);
18055051Swyllys 
18065051Swyllys 	filename = kmf_get_attr_ptr(KMF_OUTPUT_FILENAME_ATTR, attrlist,
18075051Swyllys 	    numattr);
18085051Swyllys 	if (filename == NULL)
18095051Swyllys 		return (KMF_ERR_BAD_PARAMETER);
18105051Swyllys 
18115051Swyllys 	/* Get optional search criteria attributes */
18125051Swyllys 	certlabel = kmf_get_attr_ptr(KMF_CERT_LABEL_ATTR, attrlist, numattr);
18135051Swyllys 	issuer = kmf_get_attr_ptr(KMF_ISSUER_NAME_ATTR, attrlist, numattr);
18145051Swyllys 	subject = kmf_get_attr_ptr(KMF_SUBJECT_NAME_ATTR, attrlist, numattr);
18155051Swyllys 	serial = kmf_get_attr_ptr(KMF_BIGINT_ATTR, attrlist, numattr);
18163089Swyllys 
18173089Swyllys 	/*
18183089Swyllys 	 * Find the certificate(s) first.
18193089Swyllys 	 */
18205051Swyllys 	if (certlabel != NULL) {
18215051Swyllys 		nsscert = PK11_FindCertFromNickname(certlabel, NULL);
18223089Swyllys 		if (nsscert == NULL) {
18233089Swyllys 			HANDLE_NSS_ERROR(KMF_ERR_CERT_NOT_FOUND)
18243089Swyllys 		}
18253089Swyllys 	} else {
18265051Swyllys 		rv = nss_find_matching_certs(slot, issuer, subject, serial,
18275051Swyllys 		    &certlist, 0);
18283089Swyllys 
18293089Swyllys 		if (rv == KMF_OK && certlist == NULL) {
18303089Swyllys 			return (KMF_ERR_CERT_NOT_FOUND);
18313089Swyllys 		}
18323089Swyllys 		if (rv != KMF_OK)
18333089Swyllys 			return (rv);
18343089Swyllys 	}
18353089Swyllys 
18363089Swyllys 	/*
18373089Swyllys 	 * The KMF_CREDENTIAL holds the password to use for
18383089Swyllys 	 * encrypting the PKCS12 key information.
18393089Swyllys 	 */
18405051Swyllys 	pwitem.data = (uchar_t *)p12cred->cred;
18415051Swyllys 	pwitem.len = p12cred->credlen;
18423089Swyllys 
18433089Swyllys 	p12ctx = p12u_InitContext(PR_FALSE, filename);
18443089Swyllys 	if (!p12ctx) {
18453089Swyllys 		HANDLE_NSS_ERROR(KMF_ERR_OPEN_FILE)
18463089Swyllys 	}
18473089Swyllys 
18483089Swyllys 	PORT_SetUCS2_ASCIIConversionFunction(
18495051Swyllys 	    p12u_ucs2_ascii_conversion_function);
18505051Swyllys 
18515051Swyllys 	p12ecx = SEC_PKCS12CreateExportContext(NULL, NULL, slot, NULL);
18523089Swyllys 	if (!p12ecx) {
18533089Swyllys 		HANDLE_NSS_ERROR(KMF_ERR_OPEN_FILE)
18543089Swyllys 	}
18553089Swyllys 
18563089Swyllys 	if (SEC_PKCS12AddPasswordIntegrity(p12ecx, &pwitem, SEC_OID_SHA1)
18575051Swyllys 	    != SECSuccess) {
18583089Swyllys 		HANDLE_NSS_ERROR(KMF_ERR_INTERNAL)
18593089Swyllys 	}
18603089Swyllys 
18613089Swyllys 	/*
18623089Swyllys 	 * NSS actually supports storing a list of keys and certs
18633089Swyllys 	 * in the PKCS#12 PDU.  Nice feature.
18643089Swyllys 	 */
18653089Swyllys 	if (certlist != NULL) {
18663089Swyllys 		for (node = CERT_LIST_HEAD(certlist);
18675051Swyllys 		    !CERT_LIST_END(node, certlist) && rv == KMF_OK;
18685051Swyllys 		    node = CERT_LIST_NEXT(node)) {
18693089Swyllys 			rv = add_cert_to_bag(p12ecx, node->cert, &pwitem);
18703089Swyllys 		}
18713089Swyllys 	} else if (nsscert != NULL) {
18723089Swyllys 		rv = add_cert_to_bag(p12ecx, nsscert, &pwitem);
18733089Swyllys 	}
18743089Swyllys 
18753089Swyllys 	if (SEC_PKCS12Encode(p12ecx, p12u_WriteToExportFile, p12ctx)
18765051Swyllys 	    != SECSuccess) {
18773089Swyllys 		HANDLE_NSS_ERROR(KMF_ERR_ENCODING)
18783089Swyllys 	}
18793089Swyllys out:
18803089Swyllys 	if (nsscert)
18813089Swyllys 		CERT_DestroyCertificate(nsscert);
18823089Swyllys 
18833089Swyllys 	if (certlist)
18843089Swyllys 		CERT_DestroyCertList(certlist);
18853089Swyllys 
18863089Swyllys 	if (p12ctx)
18873089Swyllys 		p12u_DestroyContext(&p12ctx, PR_FALSE);
18883089Swyllys 
18893089Swyllys 	if (p12ecx)
18903089Swyllys 		SEC_PKCS12DestroyExportContext(p12ecx);
18913089Swyllys 
18923089Swyllys 	return (rv);
18933089Swyllys }
18943089Swyllys 
18953089Swyllys #define	SETATTR(t, n, atype, value, size) \
18963089Swyllys 	t[n].type = atype; \
18973089Swyllys 	t[n].pValue = (CK_BYTE *)value; \
18983089Swyllys 	t[n].ulValueLen = (CK_ULONG)size;
18993089Swyllys 
19003089Swyllys KMF_RETURN
NSS_CreateSymKey(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)19013089Swyllys NSS_CreateSymKey(KMF_HANDLE_T handle,
19025051Swyllys 	int numattr, KMF_ATTRIBUTE *attrlist)
19033089Swyllys {
19043089Swyllys 	KMF_RETURN rv = KMF_OK;
19053089Swyllys 	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
19063089Swyllys 	PK11SlotInfo *nss_slot = NULL;
19073089Swyllys 	PK11SymKey *nsskey = NULL;
19083089Swyllys 	CK_MECHANISM_TYPE keyType;
19093089Swyllys 	SECStatus nssrv;
19103089Swyllys 	int keySize;
19115051Swyllys 	KMF_KEY_HANDLE *symkey;
19125051Swyllys 	KMF_CREDENTIAL cred;
19135051Swyllys 	uint32_t keylen;
19145051Swyllys 	uint32_t keylen_size = sizeof (uint32_t);
19155051Swyllys 	KMF_KEY_ALG keytype;
19165051Swyllys 	char *keylabel = NULL;
19175051Swyllys 
19185051Swyllys 	if (kmfh == NULL || attrlist == NULL || numattr == 0) {
19193089Swyllys 		return (KMF_ERR_BAD_PARAMETER);
19203089Swyllys 	}
19213089Swyllys 
19225051Swyllys 	symkey = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, numattr);
19235051Swyllys 	if (symkey == NULL)
19245051Swyllys 		return (KMF_ERR_BAD_PARAMETER);
19255051Swyllys 
19265051Swyllys 	rv = kmf_get_attr(KMF_KEYALG_ATTR, attrlist, numattr, (void *)&keytype,
19275051Swyllys 	    NULL);
19285051Swyllys 	if (rv != KMF_OK)
19295051Swyllys 		return (KMF_ERR_BAD_PARAMETER);
19305051Swyllys 
19315051Swyllys 	rv = kmf_get_attr(KMF_KEYLENGTH_ATTR, attrlist, numattr, &keylen,
19325051Swyllys 	    &keylen_size);
19335051Swyllys 	if (rv == KMF_ERR_ATTR_NOT_FOUND &&
19345051Swyllys 	    (keytype == KMF_DES || keytype == KMF_DES3))
19355051Swyllys 		/* keylength is not required for DES and 3DES */
19365051Swyllys 		rv = KMF_OK;
19375051Swyllys 	if (rv != KMF_OK)
19385051Swyllys 		return (KMF_ERR_BAD_PARAMETER);
19395051Swyllys 
19405051Swyllys 	keylabel = kmf_get_attr_ptr(KMF_KEYLABEL_ATTR, attrlist, numattr);
19415051Swyllys 	if (keylabel == NULL)
19425051Swyllys 		return (KMF_ERR_BAD_PARAMETER);
19435051Swyllys 
19445051Swyllys 	switch (keytype) {
19453089Swyllys 	case KMF_AES:
19463089Swyllys 		keyType = CKM_AES_KEY_GEN;
19475051Swyllys 		keySize = keylen;
19483089Swyllys 		if (keySize == 0 || (keySize % 8) != 0)
19493089Swyllys 			return (KMF_ERR_BAD_KEY_SIZE);
19503089Swyllys 		break;
19513089Swyllys 	case KMF_RC4:
19523089Swyllys 		keyType = CKM_RC4_KEY_GEN;
19535051Swyllys 		keySize = keylen;
19543089Swyllys 		if (keySize == 0 || (keySize % 8) != 0)
19553089Swyllys 			return (KMF_ERR_BAD_KEY_SIZE);
19563089Swyllys 		break;
19573089Swyllys 	case KMF_DES:
19583089Swyllys 		keyType = CKM_DES_KEY_GEN;
19593089Swyllys 		keySize = 0; /* required by PK11_TokenKeyGen()  */
19603089Swyllys 		break;
19613089Swyllys 	case KMF_DES3:
19623089Swyllys 		keyType = CKM_DES3_KEY_GEN;
19633089Swyllys 		keySize = 0; /* required by PK11_TokenKeyGen() */
19643089Swyllys 		break;
19653812Shylee 	case KMF_GENERIC_SECRET:
19663812Shylee 		keyType = CKM_GENERIC_SECRET_KEY_GEN;
19675051Swyllys 		keySize = keylen;
19683812Shylee 		if (keySize == 0 || (keySize % 8) != 0)
19693812Shylee 			return (KMF_ERR_BAD_KEY_SIZE);
19703812Shylee 		break;
19713089Swyllys 	default:
19723089Swyllys 		rv = KMF_ERR_BAD_KEY_TYPE;
19733089Swyllys 		goto out;
19743089Swyllys 	}
19753089Swyllys 
19765051Swyllys 	rv = do_nss_init(handle, numattr, attrlist, FALSE, &nss_slot);
19773089Swyllys 	if (rv != KMF_OK) {
19783089Swyllys 		return (rv);
19793089Swyllys 	}
19803089Swyllys 
19815051Swyllys 	rv = kmf_get_attr(KMF_CREDENTIAL_ATTR, attrlist, numattr,
19825051Swyllys 	    (void *)&cred, NULL);
19835051Swyllys 	if (rv != KMF_OK)
19845051Swyllys 		return (KMF_ERR_BAD_PARAMETER);
19855051Swyllys 
19865051Swyllys 	rv = nss_authenticate(handle, nss_slot, &cred);
19873089Swyllys 	if (rv != KMF_OK) {
19883089Swyllys 		return (rv);
19893089Swyllys 	}
19903089Swyllys 
199110442Swyllys.ingersoll@sun.com 	/* convert key length to bytes */
199210442Swyllys.ingersoll@sun.com 	nsskey = PK11_TokenKeyGen(nss_slot, keyType, NULL, keySize / 8,  NULL,
19935051Swyllys 	    PR_TRUE, (void *)cred.cred);
19943089Swyllys 	if (nsskey == NULL) {
19953089Swyllys 		SET_ERROR(kmfh, PORT_GetError());
19963089Swyllys 		rv = KMF_ERR_KEYGEN_FAILED;
19973089Swyllys 		goto out;
19983089Swyllys 	}
19993089Swyllys 
20005051Swyllys 	nssrv = PK11_SetSymKeyNickname(nsskey, keylabel);
20013089Swyllys 	if (nssrv != SECSuccess) {
20023089Swyllys 		SET_ERROR(kmfh, PORT_GetError());
20033089Swyllys 		rv = KMF_ERR_KEYGEN_FAILED;
20043089Swyllys 		goto out;
20053089Swyllys 	}
20063089Swyllys 
20073089Swyllys 	symkey->kstype = KMF_KEYSTORE_NSS;
20085051Swyllys 	symkey->keyalg = keytype;
20093089Swyllys 	symkey->keyclass = KMF_SYMMETRIC;
20103089Swyllys 	symkey->israw = FALSE;
20113089Swyllys 	symkey->keyp = (void *)nsskey;
20123089Swyllys 
20133089Swyllys out:
20143089Swyllys 	if (nss_slot != NULL)
20153089Swyllys 		PK11_FreeSlot(nss_slot);
20163089Swyllys 
20173089Swyllys 	if (rv != KMF_OK && nsskey != NULL) {
201811411SSurya.Prakki@Sun.COM 		(void) PK11_DeleteTokenSymKey(nsskey);
20193089Swyllys 		PK11_FreeSymKey(nsskey);
20203089Swyllys 	}
20213089Swyllys 	return (rv);
20223089Swyllys }
20233089Swyllys 
20243089Swyllys KMF_RETURN
NSS_GetSymKeyValue(KMF_HANDLE_T handle,KMF_KEY_HANDLE * symkey,KMF_RAW_SYM_KEY * rkey)20253089Swyllys NSS_GetSymKeyValue(KMF_HANDLE_T handle, KMF_KEY_HANDLE *symkey,
20263089Swyllys 	KMF_RAW_SYM_KEY *rkey)
20273089Swyllys {
20283089Swyllys 	KMF_RETURN rv = KMF_OK;
20293089Swyllys 	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
20303089Swyllys 	SECItem *value = NULL;
20313089Swyllys 	PK11SymKey *nsskey;
20323089Swyllys 	SECStatus nss_rv;
20333089Swyllys 
20343089Swyllys 	if (kmfh == NULL)
20353089Swyllys 		return (KMF_ERR_UNINITIALIZED);
20363089Swyllys 
20373089Swyllys 	if (symkey == NULL || rkey == NULL)
20383089Swyllys 		return (KMF_ERR_BAD_PARAMETER);
20393089Swyllys 	else if (symkey->keyclass != KMF_SYMMETRIC)
20403089Swyllys 		return (KMF_ERR_BAD_KEY_CLASS);
20413089Swyllys 
20423089Swyllys 	if (symkey->israw) {
20433089Swyllys 		KMF_RAW_KEY_DATA *rawkey = (KMF_RAW_KEY_DATA *)symkey->keyp;
20443089Swyllys 
20453089Swyllys 		if (rawkey == NULL ||
20463089Swyllys 		    rawkey->rawdata.sym.keydata.val == NULL ||
20473089Swyllys 		    rawkey->rawdata.sym.keydata.len == 0)
20483089Swyllys 			return (KMF_ERR_BAD_KEYHANDLE);
20493089Swyllys 
20503089Swyllys 		rkey->keydata.len = rawkey->rawdata.sym.keydata.len;
20513089Swyllys 		if ((rkey->keydata.val = malloc(rkey->keydata.len)) == NULL)
20523089Swyllys 			return (KMF_ERR_MEMORY);
20533089Swyllys 		(void) memcpy(rkey->keydata.val,
20545051Swyllys 		    rawkey->rawdata.sym.keydata.val, rkey->keydata.len);
20553089Swyllys 	} else {
20563089Swyllys 		nsskey = (PK11SymKey *)(symkey->keyp);
20573089Swyllys 		if (nsskey == NULL)
20583089Swyllys 			return (KMF_ERR_BAD_KEYHANDLE);
20593089Swyllys 
20603089Swyllys 		nss_rv = PK11_ExtractKeyValue(nsskey);
20613089Swyllys 		if (nss_rv != SECSuccess) {
20623089Swyllys 			SET_ERROR(kmfh, PORT_GetError());
20633089Swyllys 			rv = KMF_ERR_GETKEYVALUE_FAILED;
20643089Swyllys 			goto out;
20653089Swyllys 		}
20663089Swyllys 
20673089Swyllys 		value = PK11_GetKeyData(nsskey);
20683089Swyllys 		if (value == NULL) {
20693089Swyllys 			SET_ERROR(kmfh, PORT_GetError());
20703089Swyllys 			rv = KMF_ERR_GETKEYVALUE_FAILED;
20713089Swyllys 			goto out;
20723089Swyllys 		}
20733089Swyllys 
20743089Swyllys 		if (value->len == 0 || value->data == NULL) {
20753089Swyllys 			rv = KMF_ERR_GETKEYVALUE_FAILED;
20763089Swyllys 			goto out;
20773089Swyllys 		}
20783089Swyllys 
20793089Swyllys 		rkey->keydata.val = malloc(value->len);
20803089Swyllys 		if (rkey->keydata.val == NULL) {
20813089Swyllys 			rv = KMF_ERR_MEMORY;
20823089Swyllys 			goto out;
20833089Swyllys 		}
20843089Swyllys 		(void) memcpy(rkey->keydata.val, value->data, value->len);
20853089Swyllys 		rkey->keydata.len = value->len;
20863089Swyllys 		(void) memset(value->data, 0, value->len);
20873089Swyllys 	}
20883089Swyllys out:
20893089Swyllys 	if (value != NULL)
20903089Swyllys 		SECITEM_FreeItem(value, PR_TRUE);
20913089Swyllys 	return (rv);
20923089Swyllys }
20933089Swyllys 
20943089Swyllys KMF_RETURN
NSS_SetTokenPin(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)20955051Swyllys NSS_SetTokenPin(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
20963089Swyllys {
20973089Swyllys 	KMF_RETURN ret = KMF_OK;
20983089Swyllys 	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
20993089Swyllys 	int rv;
21003089Swyllys 	PK11SlotInfo *nss_slot = NULL;
21015051Swyllys 	KMF_CREDENTIAL oldcred, newcred;
21025051Swyllys 
21035051Swyllys 	if (handle == NULL || attrlist == NULL || numattr == 0)
21043089Swyllys 		return (KMF_ERR_BAD_PARAMETER);
21055051Swyllys 
21065051Swyllys 	ret = kmf_get_attr(KMF_CREDENTIAL_ATTR, attrlist, numattr,
21075051Swyllys 	    (void *)&oldcred, NULL);
21085051Swyllys 	if (ret != KMF_OK)
21095051Swyllys 		return (KMF_ERR_BAD_PARAMETER);
21105051Swyllys 	ret = kmf_get_attr(KMF_NEWPIN_ATTR, attrlist, numattr,
21115051Swyllys 	    (void *)&newcred, NULL);
21125051Swyllys 	if (ret != KMF_OK)
21135051Swyllys 		return (KMF_ERR_BAD_PARAMETER);
21145051Swyllys 
21155051Swyllys 	ret = do_nss_init(handle, numattr, attrlist, FALSE, &nss_slot);
21163089Swyllys 	/* If it was uninitialized, set it */
21173089Swyllys 	if (ret == KMF_ERR_UNINITIALIZED_TOKEN) {
21185051Swyllys 		rv = PK11_InitPin(nss_slot, NULL, newcred.cred);
21193089Swyllys 		if (rv != SECSuccess) {
21203089Swyllys 			SET_ERROR(kmfh, PORT_GetError());
21213089Swyllys 			ret = KMF_ERR_AUTH_FAILED;
21223089Swyllys 		} else {
21233089Swyllys 			ret = KMF_OK;
21243089Swyllys 		}
21253089Swyllys 	} else if (ret == KMF_OK) {
21265051Swyllys 		ret = nss_authenticate(handle, nss_slot, &oldcred);
21273089Swyllys 		if (ret != KMF_OK) {
21283089Swyllys 			return (ret);
21293089Swyllys 		}
21305051Swyllys 		rv = PK11_ChangePW(nss_slot, oldcred.cred, newcred.cred);
21313089Swyllys 		if (rv != SECSuccess) {
21323089Swyllys 			SET_ERROR(kmfh, PORT_GetError());
21333089Swyllys 			ret = KMF_ERR_AUTH_FAILED;
21343089Swyllys 		}
21353089Swyllys 	}
21363089Swyllys 
21373089Swyllys 	return (ret);
21383089Swyllys }
21395051Swyllys 
21405051Swyllys KMF_RETURN
NSS_StoreKey(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)21415051Swyllys NSS_StoreKey(KMF_HANDLE_T handle,
21425051Swyllys 	int numattr, KMF_ATTRIBUTE *attrlist)
21435051Swyllys {
21445051Swyllys 	KMF_RETURN rv = KMF_OK;
21455051Swyllys 	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
21465051Swyllys 	PK11SlotInfo *nss_slot = NULL;
21475051Swyllys 	KMF_CREDENTIAL cred = {NULL, 0};
21485051Swyllys 	KMF_KEY_HANDLE *pubkey = NULL, *prikey = NULL;
21495051Swyllys 	KMF_RAW_KEY_DATA *rawkey = NULL;
21505051Swyllys 	char *keylabel = NULL;
21515051Swyllys 	SECStatus ckrv = SECSuccess;
21525051Swyllys 	SECItem nickname = {NULL, 0};
21535051Swyllys 	CERTCertificate *nss_cert = NULL;
21545051Swyllys 
21555051Swyllys 	if (kmfh == NULL || attrlist == NULL || numattr == 0) {
21565051Swyllys 		return (KMF_ERR_BAD_PARAMETER);
21575051Swyllys 	}
21585051Swyllys 
21595051Swyllys 	rv = do_nss_init(handle, numattr, attrlist, FALSE, &nss_slot);
21605051Swyllys 	if (rv != KMF_OK) {
21615051Swyllys 		return (rv);
21625051Swyllys 	}
21635051Swyllys 
21645051Swyllys 	rv = kmf_get_attr(KMF_CREDENTIAL_ATTR, attrlist, numattr,
21655051Swyllys 	    (void *)&cred, NULL);
21665051Swyllys 	if (rv != KMF_OK)
21675051Swyllys 		return (KMF_ERR_BAD_PARAMETER);
21685051Swyllys 
21695051Swyllys 	rv = nss_authenticate(handle, nss_slot, &cred);
21705051Swyllys 	if (rv != KMF_OK) {
21715051Swyllys 		return (rv);
21725051Swyllys 	}
21735051Swyllys 
21745051Swyllys 	pubkey = kmf_get_attr_ptr(KMF_PUBKEY_HANDLE_ATTR, attrlist, numattr);
21755051Swyllys 	if (pubkey == NULL) {
21765051Swyllys 		/* look for private key */
21775051Swyllys 		prikey = kmf_get_attr_ptr(KMF_PRIVKEY_HANDLE_ATTR, attrlist,
21785051Swyllys 		    numattr);
21795051Swyllys 		if (prikey == NULL)
21805051Swyllys 			/* look for raw key */
21815051Swyllys 			rawkey = kmf_get_attr_ptr(KMF_RAW_KEY_ATTR,
21825051Swyllys 			    attrlist, numattr);
21835051Swyllys 	}
21845051Swyllys 
21855051Swyllys 	/* If no keys were found, return error */
21865051Swyllys 	if (pubkey == NULL && prikey == NULL && rawkey == NULL)
21875051Swyllys 		return (KMF_ERR_ATTR_NOT_FOUND);
21885051Swyllys 
21895051Swyllys 	keylabel = kmf_get_attr_ptr(KMF_KEYLABEL_ATTR, attrlist, numattr);
21905051Swyllys 	if (keylabel != NULL) {
21915051Swyllys 		nickname.data = (uchar_t *)keylabel;
21925051Swyllys 		nickname.len = strlen(keylabel);
21935051Swyllys 	}
21945051Swyllys 
21955051Swyllys 	if (rawkey != NULL) {
21965051Swyllys 		uchar_t ver = 0;
21975051Swyllys 		SECKEYPrivateKeyInfo rpk;
21985051Swyllys 		KMF_DATA derkey = {NULL, 0};
21995051Swyllys 		KMF_DATA *cert;
22005051Swyllys 
22015051Swyllys 		cert = kmf_get_attr_ptr(KMF_CERT_DATA_ATTR, attrlist, numattr);
22025051Swyllys 		if (cert == NULL)
22035051Swyllys 			return (rv);
22045051Swyllys 		/*
22055051Swyllys 		 * Decode the cert into an NSS CERT object so we can access the
22065051Swyllys 		 * SPKI and KeyUsage data later.
22075051Swyllys 		 */
22085051Swyllys 		nss_cert = CERT_DecodeCertFromPackage((char *)cert->Data,
22095051Swyllys 		    cert->Length);
22105051Swyllys 
22115051Swyllys 		if (nss_cert == NULL) {
22125051Swyllys 			SET_ERROR(kmfh, PORT_GetError());
22135051Swyllys 			rv = KMF_ERR_BAD_CERT_FORMAT;
22145051Swyllys 			goto cleanup;
22155051Swyllys 		}
22165051Swyllys 
22175051Swyllys 		(void) memset(&rpk, 0, sizeof (rpk));
22185051Swyllys 		rpk.arena = NULL;
22195051Swyllys 		rpk.version.type = siUnsignedInteger;
22205051Swyllys 		rpk.version.data = &ver;
22215051Swyllys 		rpk.version.len = 1;
22225051Swyllys 		if (rawkey->keytype == KMF_RSA) {
22235051Swyllys 			rv = DerEncodeRSAPrivateKey(&derkey,
22245051Swyllys 			    &rawkey->rawdata.rsa);
22255051Swyllys 			if (rv != KMF_OK)
22265051Swyllys 				goto cleanup;
22275051Swyllys 		} else if (rawkey->keytype == KMF_DSA) {
22285051Swyllys 			rv = DerEncodeDSAPrivateKey(&derkey,
22295051Swyllys 			    &rawkey->rawdata.dsa);
22305051Swyllys 			if (rv != KMF_OK)
22315051Swyllys 				goto cleanup;
2232*11973Swyllys.ingersoll@sun.com 		} else if (rawkey->keytype == KMF_ECDSA) {
2233*11973Swyllys.ingersoll@sun.com 			rv = DerEncodeECPrivateKey(&derkey,
2234*11973Swyllys.ingersoll@sun.com 			    &rawkey->rawdata.ec);
2235*11973Swyllys.ingersoll@sun.com 			if (rv != KMF_OK)
2236*11973Swyllys.ingersoll@sun.com 				goto cleanup;
22375051Swyllys 		}
22385051Swyllys 		rpk.algorithm = nss_cert->subjectPublicKeyInfo.algorithm;
22395051Swyllys 		rpk.privateKey.data = derkey.Data;
22405051Swyllys 		rpk.privateKey.len = derkey.Length;
22415051Swyllys 		rpk.attributes = NULL;
22425051Swyllys 
22435051Swyllys 		ckrv = PK11_ImportPrivateKeyInfo(nss_slot, &rpk, &nickname,
22445051Swyllys 		    &nss_cert->subjectPublicKeyInfo.subjectPublicKey, TRUE,
22455051Swyllys 		    TRUE, nss_cert->keyUsage, NULL);
22465051Swyllys 		if (ckrv != CKR_OK) {
22475051Swyllys 			SET_ERROR(kmfh, PORT_GetError());
22485051Swyllys 			rv = KMF_ERR_INTERNAL;
22495051Swyllys 		}
22505051Swyllys 		kmf_free_data(&derkey);
22515051Swyllys 	} else if (pubkey != NULL && pubkey->kstype == KMF_KEYSTORE_NSS) {
22525051Swyllys 		CK_OBJECT_HANDLE pk;
22535051Swyllys 		SECKEYPublicKey *publicKey = (SECKEYPublicKey *) pubkey->keyp;
22545051Swyllys 
22555051Swyllys 		pk = PK11_ImportPublicKey(nss_slot, publicKey, PR_TRUE);
22565051Swyllys 		if (pk == CK_INVALID_HANDLE) {
22575051Swyllys 			SET_ERROR(kmfh, PORT_GetError());
22585051Swyllys 			rv = KMF_ERR_INTERNAL;
22595051Swyllys 		}
22605051Swyllys 	} else if (prikey != NULL && prikey->kstype == KMF_KEYSTORE_NSS) {
22615051Swyllys 		SECKEYPrivateKey *pk;
22625051Swyllys 		SECKEYPrivateKey *privKey = (SECKEYPrivateKey *) prikey->keyp;
22635051Swyllys 
22645051Swyllys 		pk = PK11_LoadPrivKey(nss_slot, privKey, NULL, PR_TRUE,
22655051Swyllys 		    PR_TRUE);
22665051Swyllys 		if (pk == CK_INVALID_HANDLE) {
22675051Swyllys 			SET_ERROR(kmfh, PORT_GetError());
22685051Swyllys 			rv = KMF_ERR_INTERNAL;
22695051Swyllys 		}
22705051Swyllys 		/* We stored it, but don't need the handle anymore */
22715051Swyllys 		SECKEY_DestroyPrivateKey(pk);
22725051Swyllys 	}
22735051Swyllys 
22745051Swyllys cleanup:
22755051Swyllys 	if (nss_cert != NULL)
22765051Swyllys 		CERT_DestroyCertificate(nss_cert);
22775051Swyllys 	PK11_FreeSlot(nss_slot);
22785051Swyllys 	return (rv);
22795051Swyllys }
22805051Swyllys 
22815051Swyllys /*
22825051Swyllys  * This function is called by NSS_StoreCert() and NSS_ImportCert().
22835051Swyllys  * The "label" and "trust_flag" arguments can be NULL.
22845051Swyllys  */
22855051Swyllys static KMF_RETURN
store_cert(KMF_HANDLE_T handle,PK11SlotInfo * nss_slot,KMF_DATA * cert,char * label,char * trust_flag)22865051Swyllys store_cert(KMF_HANDLE_T handle, PK11SlotInfo *nss_slot, KMF_DATA *cert,
22875051Swyllys     char *label, char *trust_flag)
22885051Swyllys {
22895051Swyllys 	KMF_RETURN ret = KMF_OK;
22905051Swyllys 	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
22915051Swyllys 	SECStatus nss_rv;
22925051Swyllys 	CERTCertDBHandle *certHandle = CERT_GetDefaultCertDB();
22935051Swyllys 	CERTCertificate *nss_cert = NULL;
22945051Swyllys 	CERTCertTrust *nss_trust = NULL;
22955051Swyllys 
22965051Swyllys 	if (nss_slot == NULL || cert == NULL)
22975051Swyllys 		return (KMF_ERR_BAD_PARAMETER);
22985051Swyllys 
22995051Swyllys 	nss_cert = CERT_DecodeCertFromPackage((char *)cert->Data,
23005051Swyllys 	    cert->Length);
23015051Swyllys 	if (nss_cert == NULL) {
23025051Swyllys 		SET_ERROR(kmfh, PORT_GetError());
23035051Swyllys 		ret = KMF_ERR_BAD_CERT_FORMAT;
23045051Swyllys 		goto out;
23055051Swyllys 	}
23065051Swyllys 
23075051Swyllys 	/* Store the cert into the NSS database */
23085051Swyllys 	nss_rv = PK11_ImportCert(nss_slot, nss_cert, CK_INVALID_HANDLE,
23095051Swyllys 	    label, 0);
23105051Swyllys 	if (nss_rv) {
23115051Swyllys 		SET_ERROR(kmfh, nss_rv);
23125051Swyllys 		ret = KMF_ERR_BAD_CERT_FORMAT;
23135051Swyllys 		goto out;
23145051Swyllys 	}
23155051Swyllys 
23165051Swyllys 	/* If trust_flag is NULL, then we are done */
23175051Swyllys 	if (trust_flag == NULL)
23185051Swyllys 		goto out;
23195051Swyllys 
23205051Swyllys 	nss_trust = (CERTCertTrust *) malloc(sizeof (CERTCertTrust));
23215051Swyllys 	if (nss_trust == NULL) {
23225051Swyllys 		ret = KMF_ERR_MEMORY;
23235051Swyllys 		goto out;
23245051Swyllys 	}
23255051Swyllys 
23265051Swyllys 	nss_rv = CERT_DecodeTrustString(nss_trust, trust_flag);
23275051Swyllys 	if (nss_rv) {
23285051Swyllys 		SET_ERROR(kmfh, nss_rv);
23295051Swyllys 		ret = KMF_ERR_BAD_PARAMETER;
23305051Swyllys 		goto out;
23315051Swyllys 	}
23325051Swyllys 
23335051Swyllys 	nss_rv = CERT_ChangeCertTrust(certHandle, nss_cert, nss_trust);
23345051Swyllys 	if (nss_rv) {
23355051Swyllys 		SET_ERROR(kmfh, nss_rv);
23365051Swyllys 		ret = KMF_ERR_BAD_PARAMETER;
23375051Swyllys 	}
23385051Swyllys 
23395051Swyllys out:
23405051Swyllys 	if (nss_cert != NULL) {
23415051Swyllys 		CERT_DestroyCertificate(nss_cert);
23425051Swyllys 	}
23435051Swyllys 
23445051Swyllys 	if (nss_trust != NULL) {
23455051Swyllys 		free(nss_trust);
23465051Swyllys 	}
23475051Swyllys 
23485051Swyllys 	return (ret);
23495051Swyllys }
23505051Swyllys 
23515051Swyllys 
23525051Swyllys KMF_RETURN
NSS_StoreCert(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)23535051Swyllys NSS_StoreCert(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
23545051Swyllys {
23555051Swyllys 	KMF_RETURN ret = KMF_OK;
23565051Swyllys 	PK11SlotInfo *nss_slot = NULL;
23575051Swyllys 	KMF_DATA *cert = NULL;
23585051Swyllys 	char *label = NULL;
23595051Swyllys 	char *trust_flag = NULL;
23605051Swyllys 
23615051Swyllys 	if (handle == NULL || attrlist == NULL || numattr == 0) {
23625051Swyllys 		return (KMF_ERR_BAD_PARAMETER);
23635051Swyllys 	}
23645051Swyllys 
23655051Swyllys 	ret = do_nss_init(handle, numattr, attrlist, FALSE, &nss_slot);
23665051Swyllys 	if (ret != KMF_OK)
23675051Swyllys 		return (ret);
23685051Swyllys 
23695051Swyllys 	/* Get the cert data  */
23705051Swyllys 	cert = kmf_get_attr_ptr(KMF_CERT_DATA_ATTR, attrlist, numattr);
23715051Swyllys 	if (cert == NULL || cert->Data == NULL)
23725051Swyllys 		return (KMF_ERR_BAD_PARAMETER);
23735051Swyllys 
23745051Swyllys 	/* The label attribute is optional */
23755051Swyllys 	label = kmf_get_attr_ptr(KMF_CERT_LABEL_ATTR, attrlist, numattr);
23765051Swyllys 
23775051Swyllys 	/* The trustflag attriburte is optional */
23785051Swyllys 	trust_flag = kmf_get_attr_ptr(KMF_TRUSTFLAG_ATTR, attrlist, numattr);
23795051Swyllys 
23805051Swyllys 	ret = store_cert(handle, nss_slot, cert, label, trust_flag);
23815051Swyllys 
23825051Swyllys out:
23835051Swyllys 	if (nss_slot != NULL) {
23845051Swyllys 		PK11_FreeSlot(nss_slot);
23855051Swyllys 	}
23865051Swyllys 
23875051Swyllys 	return (ret);
23885051Swyllys }
23895051Swyllys 
23905051Swyllys 
23915051Swyllys KMF_RETURN
NSS_ImportCert(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)23925051Swyllys NSS_ImportCert(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
23935051Swyllys {
23945051Swyllys 	KMF_RETURN ret = KMF_OK;
23955051Swyllys 	PK11SlotInfo *nss_slot = NULL;
23965051Swyllys 	KMF_DATA cert = {NULL, 0};
23975051Swyllys 	KMF_DATA cert_der = {NULL, 0};
23985051Swyllys 	KMF_DATA *cptr = NULL;
23995051Swyllys 	KMF_ENCODE_FORMAT format;
24005051Swyllys 	char *label = NULL;
24015051Swyllys 	char *trust_flag = NULL;
24025051Swyllys 	char *certfile = NULL;
24035051Swyllys 
24045051Swyllys 	if (handle == NULL || attrlist == NULL || numattr == 0) {
24055051Swyllys 		return (KMF_ERR_BAD_PARAMETER);
24065051Swyllys 	}
24075051Swyllys 
24085051Swyllys 	ret = do_nss_init(handle, numattr, attrlist, FALSE, &nss_slot);
24095051Swyllys 	if (ret != KMF_OK)
24105051Swyllys 		return (ret);
24115051Swyllys 
24125051Swyllys 	/* Get the input cert filename attribute */
24135051Swyllys 	certfile = kmf_get_attr_ptr(KMF_CERT_FILENAME_ATTR, attrlist, numattr);
24145051Swyllys 	if (certfile == NULL)
24155051Swyllys 		return (KMF_ERR_BAD_PARAMETER);
24165051Swyllys 
24175051Swyllys 	/* Check the cert file and auto-detect the file format of it. */
24185051Swyllys 	ret = kmf_is_cert_file(handle, certfile, &format);
24195051Swyllys 	if (ret != KMF_OK)
24205051Swyllys 		return (ret);
24215051Swyllys 
24225051Swyllys 	ret = kmf_read_input_file(handle, certfile, &cert);
24235051Swyllys 	if (ret != KMF_OK) {
24245051Swyllys 		return (ret);
24255051Swyllys 	}
24265051Swyllys 
24275051Swyllys 	/*
24285051Swyllys 	 * If the imported cert is in PEM format, convert it to
24295051Swyllys 	 * DER format in order to store it in NSS token.
24305051Swyllys 	 */
24315051Swyllys 	if (format == KMF_FORMAT_PEM) {
24325051Swyllys 		int derlen;
24335051Swyllys 		ret = kmf_pem_to_der(cert.Data, cert.Length,
24345051Swyllys 		    &cert_der.Data, &derlen);
24355051Swyllys 		if (ret != KMF_OK) {
24365051Swyllys 			goto cleanup;
24375051Swyllys 		}
24385051Swyllys 		cert_der.Length = (size_t)derlen;
24395051Swyllys 		cptr = &cert_der;
24405051Swyllys 	} else {
24415051Swyllys 		cptr = &cert;
24425051Swyllys 	}
24435051Swyllys 
24445051Swyllys 	label = kmf_get_attr_ptr(KMF_CERT_LABEL_ATTR, attrlist, numattr);
24455051Swyllys 	trust_flag = kmf_get_attr_ptr(KMF_TRUSTFLAG_ATTR, attrlist, numattr);
24465051Swyllys 	ret = store_cert(handle, nss_slot, cptr, label, trust_flag);
24475051Swyllys 
24485051Swyllys cleanup:
24495051Swyllys 	if (format == KMF_FORMAT_PEM) {
24505051Swyllys 		kmf_free_data(&cert_der);
24515051Swyllys 	}
24525051Swyllys 
24535051Swyllys 	kmf_free_data(&cert);
24545051Swyllys 
24555051Swyllys 	return (ret);
24565051Swyllys }
24575051Swyllys 
24585051Swyllys 
24595051Swyllys KMF_RETURN
NSS_ImportCRL(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)24605051Swyllys NSS_ImportCRL(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
24615051Swyllys {
24625051Swyllys 	KMF_RETURN ret = KMF_OK;
24635051Swyllys 	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
24645051Swyllys 	PK11SlotInfo *nss_slot = NULL;
24655051Swyllys 	CERTSignedCrl *nss_crl = NULL;
24665051Swyllys 	KMF_ENCODE_FORMAT format;
24675051Swyllys 	int importOptions;
24685051Swyllys 	SECItem crlDER;
24695051Swyllys 	KMF_DATA crl1;
24705051Swyllys 	KMF_DATA crl2;
24715051Swyllys 	char *crlfilename;
24725051Swyllys 	boolean_t crlcheck = FALSE;
24735051Swyllys 
24745051Swyllys 	if (attrlist == NULL || numattr == 0) {
24755051Swyllys 		return (KMF_ERR_BAD_PARAMETER);
24765051Swyllys 	}
24775051Swyllys 
24785051Swyllys 	ret = do_nss_init(handle, numattr, attrlist, FALSE, &nss_slot);
24795051Swyllys 	if (ret != KMF_OK) {
24805051Swyllys 		return (ret);
24815051Swyllys 	}
24825051Swyllys 
24835051Swyllys 	crlfilename = kmf_get_attr_ptr(KMF_CRL_FILENAME_ATTR, attrlist,
24845051Swyllys 	    numattr);
24855051Swyllys 	if (crlfilename == NULL)
24865051Swyllys 		return (KMF_ERR_BAD_CRLFILE);
24875051Swyllys 
24885051Swyllys 	/*
24895051Swyllys 	 * Check if the input CRL file is a valid CRL file and auto-detect
24905051Swyllys 	 * the encoded format of the file.
24915051Swyllys 	 */
24925051Swyllys 	ret = kmf_is_crl_file(handle, crlfilename, &format);
24935051Swyllys 	if (ret != KMF_OK)
24945051Swyllys 		return (ret);
24955051Swyllys 
24965051Swyllys 	ret = kmf_get_attr(KMF_CRL_CHECK_ATTR, attrlist, numattr,
24975051Swyllys 	    &crlcheck, NULL);
24985051Swyllys 	if (ret != KMF_OK)
24995051Swyllys 		ret = KMF_OK; /* CRL_CHECK is optional */
25005051Swyllys 
25015051Swyllys 	/* set importOptions */
25025051Swyllys 	if (crlcheck == B_FALSE) {
25035051Swyllys 		importOptions = CRL_IMPORT_DEFAULT_OPTIONS |
25045051Swyllys 		    CRL_IMPORT_BYPASS_CHECKS;
25055051Swyllys 	} else {
25065051Swyllys 		importOptions = CRL_IMPORT_DEFAULT_OPTIONS;
25075051Swyllys 	}
25085051Swyllys 
25095051Swyllys 
25105051Swyllys 	/* Read in the CRL file */
25115051Swyllys 	crl1.Data = NULL;
25125051Swyllys 	crl2.Data = NULL;
25135051Swyllys 	ret = kmf_read_input_file(handle, crlfilename, &crl1);
25145051Swyllys 	if (ret != KMF_OK) {
25155051Swyllys 		return (ret);
25165051Swyllys 	}
25175051Swyllys 
25185051Swyllys 	/* If the input CRL is in PEM format, convert it to DER first. */
25195051Swyllys 	if (format == KMF_FORMAT_PEM) {
25205051Swyllys 		int len;
25215051Swyllys 		ret = kmf_pem_to_der(crl1.Data, crl1.Length,
25225051Swyllys 		    &crl2.Data, &len);
25235051Swyllys 		if (ret != KMF_OK) {
25245051Swyllys 			goto out;
25255051Swyllys 		}
25265051Swyllys 		crl2.Length = (size_t)len;
25275051Swyllys 	}
25285051Swyllys 
25295051Swyllys 	crlDER.data = format == KMF_FORMAT_ASN1 ? crl1.Data : crl2.Data;
25305051Swyllys 	crlDER.len = format == KMF_FORMAT_ASN1 ? crl1.Length : crl2.Length;
25315051Swyllys 
25325051Swyllys 	nss_crl = PK11_ImportCRL(nss_slot, &crlDER, NULL, SEC_CRL_TYPE,
25335051Swyllys 	    NULL, importOptions, NULL, CRL_DECODE_DEFAULT_OPTIONS);
25345051Swyllys 
25355051Swyllys 	if (nss_crl == NULL) {
25365051Swyllys 		SET_ERROR(kmfh, PORT_GetError());
25375051Swyllys 		ret = KMF_ERR_BAD_CRLFILE;
25385051Swyllys 		goto out;
25395051Swyllys 	}
25405051Swyllys 
25415051Swyllys out:
25425051Swyllys 	if (nss_slot != NULL) {
25435051Swyllys 		PK11_FreeSlot(nss_slot);
25445051Swyllys 	}
25455051Swyllys 
25465051Swyllys 	if (crl1.Data != NULL) {
25475051Swyllys 		free(crl1.Data);
25485051Swyllys 	}
25495051Swyllys 
25505051Swyllys 	if (crl2.Data != NULL) {
25515051Swyllys 		free(crl2.Data);
25525051Swyllys 	}
25535051Swyllys 
25545051Swyllys 	if (nss_crl != NULL) {
255511411SSurya.Prakki@Sun.COM 		(void) SEC_DestroyCrl(nss_crl);
25565051Swyllys 	}
25575051Swyllys 
25585051Swyllys 	return (ret);
25595051Swyllys }
25605051Swyllys 
25615051Swyllys KMF_RETURN
NSS_DeleteCRL(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)25625051Swyllys NSS_DeleteCRL(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
25635051Swyllys {
25645051Swyllys 	KMF_RETURN rv = KMF_OK;
25655051Swyllys 	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
25665051Swyllys 	CERTSignedCrl *crl = NULL;
25675051Swyllys 	CERTCertificate *cert = NULL;
25685051Swyllys 	PK11SlotInfo *nss_slot = NULL;
25695051Swyllys 	CERTCrlHeadNode *crlList = NULL;
25705051Swyllys 	CERTCrlNode *crlNode = NULL;
25715051Swyllys 	PRArenaPool *arena = NULL;
25725051Swyllys 	CERTName *name = NULL;
25735051Swyllys 	CERTCertDBHandle *certHandle = CERT_GetDefaultCertDB();
25745051Swyllys 	char *issuername, *subjectname;
25755051Swyllys 
25765051Swyllys 	/* check params */
25775051Swyllys 	if (numattr == 0 || attrlist == NULL) {
25785051Swyllys 		return (KMF_ERR_BAD_PARAMETER);
25795051Swyllys 	}
25805051Swyllys 
25815051Swyllys 	rv = do_nss_init(handle, numattr, attrlist, FALSE, &nss_slot);
25825051Swyllys 	if (rv != KMF_OK) {
25835051Swyllys 		return (rv);
25845051Swyllys 	}
25855051Swyllys 
25865051Swyllys 	issuername = kmf_get_attr_ptr(KMF_ISSUER_NAME_ATTR, attrlist,
25875051Swyllys 	    numattr);
25885051Swyllys 	subjectname = kmf_get_attr_ptr(KMF_SUBJECT_NAME_ATTR, attrlist,
25895051Swyllys 	    numattr);
25905051Swyllys 
25915051Swyllys 	/* Caller must specify issuer or subject but not both */
25925051Swyllys 	if ((issuername == NULL && subjectname == NULL) ||
25935051Swyllys 	    (issuername != NULL && subjectname != NULL))
25945051Swyllys 		return (KMF_ERR_BAD_PARAMETER);
25955051Swyllys 
25965051Swyllys 	/* Find the CRL based on the deletion criteria. */
25975051Swyllys 	if (issuername != NULL) {
25985051Swyllys 		/*
25995051Swyllys 		 * If the deletion is based on the issuer's certificate
26005051Swyllys 		 * nickname, we will get the issuer's cert first, then
26015051Swyllys 		 * get the CRL from the cert.
26025051Swyllys 		 */
26035051Swyllys 		cert = CERT_FindCertByNicknameOrEmailAddr(certHandle,
26045051Swyllys 		    issuername);
26055051Swyllys 		if (!cert) {
26065051Swyllys 			SET_ERROR(kmfh, PORT_GetError());
26075051Swyllys 			rv = KMF_ERR_CERT_NOT_FOUND;
26085051Swyllys 			goto out;
26095051Swyllys 		}
26105051Swyllys 
26115051Swyllys 		crl = SEC_FindCrlByName(certHandle, &cert->derSubject,
26125051Swyllys 		    SEC_CRL_TYPE);
26135051Swyllys 		if (crl == NULL) {
26145051Swyllys 			SET_ERROR(kmfh, PORT_GetError());
26155051Swyllys 			rv = KMF_ERR_CRL_NOT_FOUND;
26165051Swyllys 			goto out;
26175051Swyllys 		}
26185051Swyllys 	} else {
26195051Swyllys 		/*
26205051Swyllys 		 * If the deletion is based on the CRL's subject name, we will
26215051Swyllys 		 * get all the CRLs from the internal database and search
26225051Swyllys 		 * for the CRL with the same subject name.
26235051Swyllys 		 */
26245051Swyllys 		boolean_t found = B_FALSE;
26255051Swyllys 		int nssrv;
26265051Swyllys 
26275051Swyllys 		nssrv = SEC_LookupCrls(certHandle, &crlList, SEC_CRL_TYPE);
26285051Swyllys 		if (nssrv) {
26295051Swyllys 			SET_ERROR(kmfh, nssrv);
26305051Swyllys 			rv = KMF_ERR_CRL_NOT_FOUND;
26315051Swyllys 			goto out;
26325051Swyllys 		}
26335051Swyllys 
26345051Swyllys 		if (crlList == NULL) {
26355051Swyllys 			SET_ERROR(kmfh, PORT_GetError());
26365051Swyllys 			rv = KMF_ERR_CRL_NOT_FOUND;
26375051Swyllys 			goto out;
26385051Swyllys 		}
26395051Swyllys 
26405051Swyllys 		/* Allocate space for name */
26415051Swyllys 		arena = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE);
26425051Swyllys 		if (arena == NULL) {
26435051Swyllys 			rv = KMF_ERR_MEMORY;
26445051Swyllys 			goto out;
26455051Swyllys 		}
26465051Swyllys 
26475051Swyllys 		name = PORT_ArenaZAlloc(arena, sizeof (*name));
26485051Swyllys 		if (name == NULL) {
26495051Swyllys 			rv = KMF_ERR_MEMORY;
26505051Swyllys 			goto out;
26515051Swyllys 		}
26525051Swyllys 		name->arena = arena;
26535051Swyllys 
26545051Swyllys 		crlNode  = crlList->first;
26555051Swyllys 		while (crlNode && !found) {
26565051Swyllys 			char *asciiname = NULL;
26575051Swyllys 			SECItem* issuer;
26585051Swyllys 
26595051Swyllys 			name = &crlNode->crl->crl.name;
26605051Swyllys 			if (!name) {
26615051Swyllys 				SET_ERROR(kmfh, PORT_GetError());
26625051Swyllys 				rv = KMF_ERR_CRL_NOT_FOUND;
26635051Swyllys 				break;
26645051Swyllys 			}
26655051Swyllys 
26665051Swyllys 			asciiname = CERT_NameToAscii(name);
26675051Swyllys 			if (asciiname == NULL) {
26685051Swyllys 				SET_ERROR(kmfh, PORT_GetError());
26695051Swyllys 				rv = KMF_ERR_CRL_NOT_FOUND;
26705051Swyllys 				break;
26715051Swyllys 			}
26725051Swyllys 
26735051Swyllys 			if (strcmp(subjectname, asciiname) == 0) {
26745051Swyllys 				found = B_TRUE;
26755051Swyllys 				issuer = &crlNode->crl->crl.derName;
26765051Swyllys 				crl = SEC_FindCrlByName(certHandle, issuer,
26775051Swyllys 				    SEC_CRL_TYPE);
26785051Swyllys 				if (crl == NULL) {
26795051Swyllys 					/* We found a cert but no CRL */
26805051Swyllys 					SET_ERROR(kmfh,  PORT_GetError());
26815051Swyllys 					rv = KMF_ERR_CRL_NOT_FOUND;
26825051Swyllys 				}
26835051Swyllys 			}
26845051Swyllys 			PORT_Free(asciiname);
26855051Swyllys 			crlNode = crlNode->next;
26865051Swyllys 		}
26875051Swyllys 
26885051Swyllys 		if (rv) {
26895051Swyllys 			goto out;
26905051Swyllys 		}
26915051Swyllys 	}
26925051Swyllys 
26935051Swyllys 	if (crl) {
26945051Swyllys 		(void) SEC_DeletePermCRL(crl);
26955051Swyllys 	}
26965051Swyllys 
26975051Swyllys out:
26985051Swyllys 	if (nss_slot != NULL) {
26995051Swyllys 		PK11_FreeSlot(nss_slot);
27005051Swyllys 	}
27015051Swyllys 
27025051Swyllys 	if (crlList != NULL) {
27035051Swyllys 		PORT_FreeArena(crlList->arena, PR_FALSE);
27045051Swyllys 	}
27055051Swyllys 
27065051Swyllys 	if (arena != NULL) {
27075051Swyllys 		PORT_FreeArena(arena, PR_FALSE);
27085051Swyllys 	}
27095051Swyllys 
27105051Swyllys 	if (cert != NULL) {
27115051Swyllys 		CERT_DestroyCertificate(cert);
27125051Swyllys 	}
27135051Swyllys 
27145051Swyllys 	if (crl != NULL) {
271511411SSurya.Prakki@Sun.COM 		(void) SEC_DestroyCrl(crl);
27165051Swyllys 	}
27175051Swyllys 
27185051Swyllys 	return (rv);
27195051Swyllys }
27205051Swyllys 
27215051Swyllys KMF_RETURN
NSS_FindCRL(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)27225051Swyllys NSS_FindCRL(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
27235051Swyllys {
27245051Swyllys 	KMF_RETURN rv = KMF_OK;
27255051Swyllys 	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
27265051Swyllys 	PK11SlotInfo *nss_slot = NULL;
27275051Swyllys 	CERTCrlHeadNode *crlList = NULL;
27285051Swyllys 	CERTCrlNode *crlNode = NULL;
27295051Swyllys 	PRArenaPool *arena = NULL;
27305051Swyllys 	CERTName *name = NULL;
27315051Swyllys 	SECStatus nssrv;
27325051Swyllys 	char *asciiname = NULL;
27335051Swyllys 	int crl_num;
27345051Swyllys 	int i, *CRLCount;
27355051Swyllys 	CERTCertDBHandle *certHandle = CERT_GetDefaultCertDB();
27365051Swyllys 	char **CRLNameList;
27375051Swyllys 
27385051Swyllys 	if (numattr == 0 || attrlist == NULL) {
27395051Swyllys 		return (KMF_ERR_BAD_PARAMETER);
27405051Swyllys 	}
27415051Swyllys 
27425051Swyllys 	rv = do_nss_init(handle, numattr, attrlist, FALSE, &nss_slot);
27435051Swyllys 	if (rv != KMF_OK) {
27445051Swyllys 		return (rv);
27455051Swyllys 	}
27465051Swyllys 
27475051Swyllys 	CRLCount = kmf_get_attr_ptr(KMF_CRL_COUNT_ATTR,	attrlist, numattr);
27485051Swyllys 	if (CRLCount == NULL)
27495051Swyllys 		return (KMF_ERR_BAD_PARAMETER);
27505051Swyllys 
27515051Swyllys 	CRLNameList = (char **)kmf_get_attr_ptr(KMF_CRL_NAMELIST_ATTR,
27525051Swyllys 	    attrlist, numattr);
27535051Swyllys 
27545051Swyllys 	/* Look up Crls */
27555051Swyllys 	nssrv = SEC_LookupCrls(certHandle, &crlList, SEC_CRL_TYPE);
27565051Swyllys 	if (nssrv) {
27575051Swyllys 		SET_ERROR(kmfh, rv);
27585051Swyllys 		rv = KMF_ERR_CRL_NOT_FOUND;
27595051Swyllys 		goto out;
27605051Swyllys 	}
27615051Swyllys 
27625051Swyllys 	/* Allocate space for name first */
27635051Swyllys 	arena = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE);
27645051Swyllys 	if (arena == NULL) {
27655051Swyllys 		rv = KMF_ERR_MEMORY;
27665051Swyllys 		goto out;
27675051Swyllys 	}
27685051Swyllys 
27695051Swyllys 	name = PORT_ArenaZAlloc(arena, sizeof (*name));
27705051Swyllys 	if (name == NULL) {
27715051Swyllys 		rv = KMF_ERR_MEMORY;
27725051Swyllys 		goto out;
27735051Swyllys 	}
27745051Swyllys 	name->arena = arena;
27755051Swyllys 
27765051Swyllys 	/*
27775051Swyllys 	 * Loop thru the crlList and create a crl list with CRL's subject name.
27785051Swyllys 	 */
27795051Swyllys 	crlNode  = crlList->first;
27805051Swyllys 	crl_num = 0;
27815051Swyllys 	while (crlNode) {
27825051Swyllys 		char *subj_name;
27835051Swyllys 
27845051Swyllys 		/* Get the CRL subject name */
27855051Swyllys 		name = &crlNode->crl->crl.name;
27865051Swyllys 		if (!name) {
27875051Swyllys 			SET_ERROR(kmfh, PORT_GetError());
27885051Swyllys 			rv = KMF_ERR_CRL_NOT_FOUND;
27895051Swyllys 			break;
27905051Swyllys 		}
27915051Swyllys 
27925051Swyllys 
27935051Swyllys 		if (CRLNameList != NULL) {
27945051Swyllys 			asciiname = CERT_NameToAscii(name);
27955051Swyllys 			if (asciiname == NULL) {
27965051Swyllys 				SET_ERROR(kmfh, PORT_GetError());
27975051Swyllys 				rv = KMF_ERR_CRL_NOT_FOUND;
27985051Swyllys 				break;
27995051Swyllys 			}
28005051Swyllys 			subj_name = strdup(asciiname);
28015051Swyllys 			PORT_Free(asciiname);
28025051Swyllys 			if (subj_name == NULL) {
28035051Swyllys 				rv = KMF_ERR_MEMORY;
28045051Swyllys 				break;
28055051Swyllys 			}
28065051Swyllys 			CRLNameList[crl_num] = subj_name;
28075051Swyllys 		}
28085051Swyllys 
28095051Swyllys 		crl_num++;
28105051Swyllys 		crlNode = crlNode->next;
28115051Swyllys 	}
28125051Swyllys 
28135051Swyllys 	if (rv == KMF_OK) {
28145051Swyllys 		/* success */
28155051Swyllys 		*CRLCount = crl_num;
28165051Swyllys 	}
28175051Swyllys 
28185051Swyllys out:
28195051Swyllys 	if (nss_slot != NULL) {
28205051Swyllys 		PK11_FreeSlot(nss_slot);
28215051Swyllys 	}
28225051Swyllys 
28235051Swyllys 	if (crlList != NULL) {
28245051Swyllys 		PORT_FreeArena(crlList->arena, PR_FALSE);
28255051Swyllys 	}
28265051Swyllys 
28275051Swyllys 	if (arena != NULL) {
28285051Swyllys 		PORT_FreeArena(arena, PR_FALSE);
28295051Swyllys 	}
28305051Swyllys 
28315051Swyllys 	/* If failed, free memory allocated for the returning rlist */
28325051Swyllys 	if (rv && (CRLNameList != NULL)) {
28335051Swyllys 		for (i = 0; i < crl_num; i++) {
28345051Swyllys 			free(CRLNameList[i]);
28355051Swyllys 		}
28365051Swyllys 	}
28375051Swyllys 
28385051Swyllys 	return (rv);
28395051Swyllys }
28405051Swyllys 
28415051Swyllys KMF_RETURN
NSS_FindCertInCRL(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)28425051Swyllys NSS_FindCertInCRL(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
28435051Swyllys {
28445051Swyllys 	KMF_RETURN rv = KMF_OK;
28455051Swyllys 	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
28465051Swyllys 	PK11SlotInfo *nss_slot = NULL;
28475051Swyllys 	CERTCertificate *cert = NULL;
28485051Swyllys 	CERTSignedCrl *crl = NULL;
28495051Swyllys 	CERTCrlEntry *entry;
28505051Swyllys 	boolean_t match = B_FALSE;
28515051Swyllys 	int i;
28525051Swyllys 	CERTCertDBHandle *certHandle = CERT_GetDefaultCertDB();
28535051Swyllys 	char *certlabel;
28545051Swyllys 	KMF_DATA *certdata;
28555051Swyllys 
28565051Swyllys 	/* check params */
28575051Swyllys 	if (numattr == 0 || attrlist == NULL) {
28585051Swyllys 		return (KMF_ERR_BAD_PARAMETER);
28595051Swyllys 	}
28605051Swyllys 
28615051Swyllys 	rv = do_nss_init(handle, numattr, attrlist, FALSE, &nss_slot);
28625051Swyllys 	if (rv != KMF_OK) {
28635051Swyllys 		return (rv);
28645051Swyllys 	}
28655051Swyllys 
28665051Swyllys 	certlabel = kmf_get_attr_ptr(KMF_CERT_LABEL_ATTR, attrlist, numattr);
28675051Swyllys 
28685051Swyllys 	/* Find the certificate first */
28695051Swyllys 	if (certlabel != NULL) {
28705051Swyllys 		cert = CERT_FindCertByNicknameOrEmailAddr(certHandle,
28715051Swyllys 		    certlabel);
28725051Swyllys 	} else {
28735051Swyllys 		SECItem derCert = { NULL, 0};
28745051Swyllys 
28755051Swyllys 		certdata = kmf_get_attr_ptr(KMF_CERT_DATA_ATTR,
28765051Swyllys 		    attrlist, numattr);
28775051Swyllys 
28785051Swyllys 		if (certdata == NULL)
28795051Swyllys 			return (KMF_ERR_BAD_PARAMETER);
28805051Swyllys 
28815051Swyllys 		derCert.data = certdata->Data;
28825051Swyllys 		derCert.len = certdata->Length;
28835051Swyllys 
28845051Swyllys 		cert = CERT_FindCertByDERCert(certHandle, &derCert);
28855051Swyllys 	}
28865051Swyllys 
28875051Swyllys 	if (cert == NULL) {
28885051Swyllys 		SET_ERROR(kmfh, PORT_GetError());
28895051Swyllys 		rv = KMF_ERR_CERT_NOT_FOUND;
28905051Swyllys 		goto out;
28915051Swyllys 	}
28925051Swyllys 
28935051Swyllys 	/* Find the CRL with the same issuer as the given certificate. */
28945051Swyllys 	crl = SEC_FindCrlByName(certHandle, &cert->derIssuer, SEC_CRL_TYPE);
28955051Swyllys 	if (crl == NULL) {
28965051Swyllys 		/*
28975051Swyllys 		 * Could not find the CRL issued by the same issuer. This
28985051Swyllys 		 * usually means that the CRL is not installed in the DB.
28995051Swyllys 		 */
29005051Swyllys 		SET_ERROR(kmfh, PORT_GetError());
29015051Swyllys 		rv = KMF_ERR_CRL_NOT_FOUND;
29025051Swyllys 		goto out;
29035051Swyllys 
29045051Swyllys 	}
29055051Swyllys 
29065051Swyllys 	/* Check if the certificate's serialNumber is revoked in the CRL */
29075051Swyllys 	i = 0;
29085051Swyllys 	while ((entry = (crl->crl).entries[i++]) != NULL) {
29095051Swyllys 		if (SECITEM_CompareItem(&(cert->serialNumber),
29105051Swyllys 		    &(entry->serialNumber)) == SECEqual) {
29115051Swyllys 			match = B_TRUE;
29125051Swyllys 			break;
29135051Swyllys 		}
29145051Swyllys 	}
29155051Swyllys 
29165051Swyllys 	if (!match) {
29175051Swyllys 		rv = KMF_ERR_NOT_REVOKED;
29185051Swyllys 	}
29195051Swyllys 
29205051Swyllys out:
29215051Swyllys 	if (nss_slot != NULL) {
29225051Swyllys 		PK11_FreeSlot(nss_slot);
29235051Swyllys 	}
29245051Swyllys 
29255051Swyllys 	if (cert != NULL) {
29265051Swyllys 		CERT_DestroyCertificate(cert);
29275051Swyllys 	}
29285051Swyllys 
29295051Swyllys 	if (crl != NULL) {
293011411SSurya.Prakki@Sun.COM 		(void) SEC_DestroyCrl(crl);
29315051Swyllys 	}
29325051Swyllys 
29335051Swyllys 	return (rv);
29345051Swyllys }
2935