xref: /onnv-gate/usr/src/lib/libkmf/plugins/kmf_pkcs11/common/pkcs11_spi.c (revision 12234:cd6642d6b7dd)
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
20*12234Swyllys.ingersoll@sun.com  *
213089Swyllys  * PKCS11 token KMF Plugin
223089Swyllys  *
23*12234Swyllys.ingersoll@sun.com  * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
243089Swyllys  */
253089Swyllys 
263089Swyllys #include <stdio.h> /* debugging only */
273089Swyllys #include <errno.h>
283089Swyllys #include <values.h>
293089Swyllys 
303089Swyllys #include <kmfapiP.h>
313089Swyllys #include <ber_der.h>
323825Swyllys #include <fcntl.h>
333825Swyllys #include <sha1.h>
345051Swyllys #include <bignum.h>
353089Swyllys 
363089Swyllys #include <cryptoutil.h>
373089Swyllys #include <security/cryptoki.h>
383089Swyllys #include <security/pkcs11.h>
393089Swyllys 
403812Shylee #define	DEV_RANDOM	"/dev/random"
413812Shylee 
423089Swyllys #define	SETATTR(t, n, atype, value, size) \
433089Swyllys 	t[n].type = atype; \
443089Swyllys 	t[n].pValue = (CK_BYTE *)value; \
453089Swyllys 	t[n].ulValueLen = (CK_ULONG)size;
463089Swyllys 
473089Swyllys #define	SET_ERROR(h, c) h->lasterr.kstype = KMF_KEYSTORE_PK11TOKEN; \
483089Swyllys 	h->lasterr.errcode = c;
493089Swyllys 
503089Swyllys typedef struct _objlist {
513089Swyllys 	CK_OBJECT_HANDLE handle;
523089Swyllys 	struct _objlist *next;
533089Swyllys } OBJLIST;
543089Swyllys 
553089Swyllys static KMF_RETURN
563089Swyllys search_certs(KMF_HANDLE_T, char *, char *, char *, KMF_BIGINT *,
573089Swyllys 	boolean_t, KMF_CERT_VALIDITY, OBJLIST **, uint32_t *);
583089Swyllys 
593408Swyllys static CK_RV
603408Swyllys getObjectLabel(KMF_HANDLE_T, CK_OBJECT_HANDLE, char **);
613408Swyllys 
623089Swyllys static KMF_RETURN
633089Swyllys keyObj2RawKey(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_RAW_KEY_DATA **);
643089Swyllys 
653812Shylee static KMF_RETURN
665051Swyllys create_generic_secret_key(KMF_HANDLE_T,
675051Swyllys 	int, KMF_ATTRIBUTE *, CK_OBJECT_HANDLE *);
683812Shylee 
693089Swyllys KMF_RETURN
705051Swyllys KMFPK11_ConfigureKeystore(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
713089Swyllys 
723089Swyllys KMF_RETURN
735051Swyllys KMFPK11_FindCert(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
743089Swyllys 
753089Swyllys void
763089Swyllys KMFPK11_FreeKMFCert(KMF_HANDLE_T,
773089Swyllys 	KMF_X509_DER_CERT *kmf_cert);
783089Swyllys 
793089Swyllys KMF_RETURN
805051Swyllys KMFPK11_StoreCert(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
813089Swyllys 
823089Swyllys KMF_RETURN
835051Swyllys KMFPK11_ImportCert(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
843089Swyllys 
853089Swyllys KMF_RETURN
865051Swyllys KMFPK11_DeleteCert(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
873089Swyllys 
883089Swyllys KMF_RETURN
895051Swyllys KMFPK11_CreateKeypair(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
903089Swyllys 
913089Swyllys KMF_RETURN
925051Swyllys KMFPK11_StoreKey(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
935051Swyllys 
945051Swyllys KMF_RETURN
955051Swyllys KMFPK11_DeleteKey(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
963089Swyllys 
973089Swyllys KMF_RETURN
983089Swyllys KMFPK11_EncodePubKeyData(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_DATA *);
993089Swyllys 
1003089Swyllys KMF_RETURN
1013089Swyllys KMFPK11_SignData(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_OID *,
1023089Swyllys 	KMF_DATA *, KMF_DATA *);
1033089Swyllys 
1043089Swyllys KMF_RETURN
1053089Swyllys KMFPK11_GetErrorString(KMF_HANDLE_T, char **);
1063089Swyllys 
1073089Swyllys KMF_RETURN
1085051Swyllys KMFPK11_FindPrikeyByCert(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
1093089Swyllys 
1103089Swyllys KMF_RETURN
1113089Swyllys KMFPK11_DecryptData(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_OID *,
1123089Swyllys 	KMF_DATA *, KMF_DATA *);
1133089Swyllys 
1143089Swyllys KMF_RETURN
1155051Swyllys KMFPK11_FindKey(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
1163089Swyllys 
1173089Swyllys KMF_RETURN
1185051Swyllys KMFPK11_CreateSymKey(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
1193089Swyllys 
1203089Swyllys KMF_RETURN
1213089Swyllys KMFPK11_GetSymKeyValue(KMF_HANDLE_T, KMF_KEY_HANDLE *, KMF_RAW_SYM_KEY *);
1223089Swyllys 
1233089Swyllys KMF_RETURN
1245051Swyllys KMFPK11_SetTokenPin(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
1253089Swyllys 
1263754Swyllys KMF_RETURN
1275051Swyllys KMFPK11_ExportPK12(KMF_HANDLE_T, int, KMF_ATTRIBUTE *);
1285051Swyllys 
1295051Swyllys 
1303089Swyllys static
1313089Swyllys KMF_PLUGIN_FUNCLIST pk11token_plugin_table =
1323089Swyllys {
1333089Swyllys 	1,			/* Version */
1343089Swyllys 	KMFPK11_ConfigureKeystore,
1353089Swyllys 	KMFPK11_FindCert,
1363089Swyllys 	KMFPK11_FreeKMFCert,
1373089Swyllys 	KMFPK11_StoreCert,
1383089Swyllys 	KMFPK11_ImportCert,
1393089Swyllys 	NULL,			/* ImportCRL */
1403089Swyllys 	KMFPK11_DeleteCert,
1413089Swyllys 	NULL,			/* DeleteCRL */
1423089Swyllys 	KMFPK11_CreateKeypair,
1433089Swyllys 	KMFPK11_FindKey,
1443089Swyllys 	KMFPK11_EncodePubKeyData,
1453089Swyllys 	KMFPK11_SignData,
1463089Swyllys 	KMFPK11_DeleteKey,
1473089Swyllys 	NULL,			/* ListCRL */
1483089Swyllys 	NULL,			/* FindCRL */
1493089Swyllys 	NULL,			/* FindCertInCRL */
1503089Swyllys 	KMFPK11_GetErrorString,
1515051Swyllys 	KMFPK11_FindPrikeyByCert,
1523089Swyllys 	KMFPK11_DecryptData,
1535051Swyllys 	KMFPK11_ExportPK12,
1543089Swyllys 	KMFPK11_CreateSymKey,
1553089Swyllys 	KMFPK11_GetSymKeyValue,
1563089Swyllys 	KMFPK11_SetTokenPin,
1575051Swyllys 	KMFPK11_StoreKey,
1583089Swyllys 	NULL			/* Finalize */
1593089Swyllys };
1603089Swyllys 
1613089Swyllys KMF_PLUGIN_FUNCLIST *
KMF_Plugin_Initialize()1623089Swyllys KMF_Plugin_Initialize()
1633089Swyllys {
1643089Swyllys 	return (&pk11token_plugin_table);
1653089Swyllys }
1663089Swyllys 
1673089Swyllys KMF_RETURN
KMFPK11_ConfigureKeystore(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)1685051Swyllys KMFPK11_ConfigureKeystore(KMF_HANDLE_T handle,
1695051Swyllys 	int numattr, KMF_ATTRIBUTE *attrlist)
1703089Swyllys {
1713089Swyllys 	KMF_RETURN rv = KMF_OK;
1725051Swyllys 	char *label;
1735051Swyllys 	boolean_t readonly = B_TRUE;
1745051Swyllys 
1755051Swyllys 	label = kmf_get_attr_ptr(KMF_TOKEN_LABEL_ATTR, attrlist, numattr);
1765051Swyllys 	if (label == NULL) {
1773089Swyllys 		return (KMF_ERR_BAD_PARAMETER);
1785051Swyllys 	}
1795051Swyllys 
1805051Swyllys 	/* "readonly" is optional. Default is TRUE */
1815051Swyllys 	(void) kmf_get_attr(KMF_READONLY_ATTR, attrlist, numattr,
1825051Swyllys 	    (void *)&readonly, NULL);
1835051Swyllys 
1845051Swyllys 	rv = kmf_select_token(handle, label, readonly);
1853089Swyllys 
1863089Swyllys 	return (rv);
1873089Swyllys }
1883089Swyllys 
1893089Swyllys static KMF_RETURN
pk11_authenticate(KMF_HANDLE_T handle,KMF_CREDENTIAL * cred)1903089Swyllys pk11_authenticate(KMF_HANDLE_T handle,
1913089Swyllys 	KMF_CREDENTIAL *cred)
1923089Swyllys {
1933089Swyllys 
1943089Swyllys 	CK_RV ck_rv = CKR_OK;
1953089Swyllys 	CK_SESSION_HANDLE hSession = (CK_SESSION_HANDLE)handle->pk11handle;
1963089Swyllys 
1973089Swyllys 	if (hSession == NULL)
1983089Swyllys 		return (KMF_ERR_NO_TOKEN_SELECTED);
1993089Swyllys 
2006354Swyllys 	if (cred == NULL || cred->cred == NULL) {
2013089Swyllys 		return (KMF_ERR_BAD_PARAMETER);
2023089Swyllys 	}
2033089Swyllys 
2045051Swyllys 	if ((ck_rv = C_Login(hSession, CKU_USER, (uchar_t *)cred->cred,
2055051Swyllys 	    cred->credlen)) != CKR_OK) {
2063089Swyllys 		if (ck_rv != CKR_USER_ALREADY_LOGGED_IN) {
2073089Swyllys 			handle->lasterr.kstype = KMF_KEYSTORE_PK11TOKEN;
2083089Swyllys 			handle->lasterr.errcode = ck_rv;
2093089Swyllys 			return (KMF_ERR_AUTH_FAILED);
2103089Swyllys 		}
2113089Swyllys 	}
2123089Swyllys 
2133089Swyllys 	return (KMF_OK);
2143089Swyllys }
2153089Swyllys 
2163089Swyllys static KMF_RETURN
PK11Cert2KMFCert(KMF_HANDLE * kmfh,CK_OBJECT_HANDLE hObj,KMF_X509_DER_CERT * kmfcert)2173089Swyllys PK11Cert2KMFCert(KMF_HANDLE *kmfh, CK_OBJECT_HANDLE hObj,
2183089Swyllys 		KMF_X509_DER_CERT *kmfcert)
2193089Swyllys {
2203089Swyllys 	KMF_RETURN rv = 0;
2213089Swyllys 	CK_RV ckrv = CKR_OK;
2223089Swyllys 
2233089Swyllys 	CK_CERTIFICATE_TYPE cktype;
2243089Swyllys 	CK_OBJECT_CLASS	class;
2253089Swyllys 	CK_ULONG subject_len, value_len, issuer_len, serno_len, id_len;
2263089Swyllys 	CK_BYTE *subject = NULL, *value = NULL;
2273408Swyllys 	char *label = NULL;
2283089Swyllys 	CK_ATTRIBUTE templ[10];
2293089Swyllys 
2303408Swyllys 	(void) memset(templ, 0, 10 * sizeof (CK_ATTRIBUTE));
2313089Swyllys 	SETATTR(templ, 0, CKA_CLASS, &class, sizeof (class));
2323089Swyllys 
2333089Swyllys 	/*  Is this a certificate object ? */
2343089Swyllys 	ckrv = C_GetAttributeValue(kmfh->pk11handle, hObj, templ, 1);
2353089Swyllys 	if (ckrv != CKR_OK || class != CKO_CERTIFICATE)  {
2363089Swyllys 		SET_ERROR(kmfh, ckrv);
2373089Swyllys 		return (KMF_ERR_INTERNAL);
2383089Swyllys 	}
2393089Swyllys 
2403089Swyllys 	SETATTR(templ, 0, CKA_CERTIFICATE_TYPE, &cktype, sizeof (cktype));
2413408Swyllys 	ckrv = C_GetAttributeValue(kmfh->pk11handle, hObj, templ, 1);
2423089Swyllys 
2433089Swyllys 	if (ckrv != CKR_OK || cktype != CKC_X_509)  {
2443089Swyllys 		SET_ERROR(kmfh, ckrv);
2453089Swyllys 		return (ckrv);
2463089Swyllys 	} else {
2473408Swyllys 		int i = 0;
2483089Swyllys 		/* What attributes are available and how big are they? */
2493408Swyllys 		subject_len = issuer_len = serno_len = id_len = value_len = 0;
2503408Swyllys 
2513408Swyllys 		SETATTR(templ, i, CKA_SUBJECT,	NULL, subject_len);
2523408Swyllys 		i++;
2533408Swyllys 		SETATTR(templ, i, CKA_ISSUER,	NULL, issuer_len);
2543408Swyllys 		i++;
2553408Swyllys 		SETATTR(templ, i, CKA_SERIAL_NUMBER, NULL, serno_len);
2563408Swyllys 		i++;
2573408Swyllys 		SETATTR(templ, i, CKA_ID, NULL, id_len);
2583408Swyllys 		i++;
2593408Swyllys 		SETATTR(templ, i, CKA_VALUE, NULL, value_len);
2603408Swyllys 		i++;
2613089Swyllys 
2623089Swyllys 		/*
2633089Swyllys 		 * Query the object with NULL values in the pValue spot
2643089Swyllys 		 * so we know how much space to allocate for each field.
2653089Swyllys 		 */
2663408Swyllys 		ckrv = C_GetAttributeValue(kmfh->pk11handle, hObj, templ, i);
2673089Swyllys 		if (ckrv != CKR_OK)  {
2683089Swyllys 			SET_ERROR(kmfh, ckrv);
2693089Swyllys 			return (KMF_ERR_INTERNAL); /* TODO - Error messages ? */
2703089Swyllys 		}
2713089Swyllys 
2723089Swyllys 		subject_len	= templ[0].ulValueLen;
2733089Swyllys 		issuer_len	= templ[1].ulValueLen;
2743089Swyllys 		serno_len	= templ[2].ulValueLen;
2753089Swyllys 		id_len		= templ[3].ulValueLen;
2763089Swyllys 		value_len	= templ[4].ulValueLen;
2773089Swyllys 
2783089Swyllys 		/*
2793089Swyllys 		 * For PKCS#11 CKC_X_509 certificate objects,
2803089Swyllys 		 * the following attributes must be defined.
2813089Swyllys 		 * CKA_SUBJECT, CKA_ID, CKA_ISSUER, CKA_SERIAL_NUMBER,
2823089Swyllys 		 * CKA_VALUE.
2833089Swyllys 		 */
2843089Swyllys 		if (subject_len == 0 || issuer_len == 0 ||
2853089Swyllys 		    serno_len == 0 || value_len == 0) {
2863089Swyllys 			return (KMF_ERR_INTERNAL);
2873089Swyllys 		}
2883089Swyllys 
2893089Swyllys 		/* Only fetch the value field if we are saving the data */
2903089Swyllys 		if (kmfcert != NULL) {
2913089Swyllys 			int i = 0;
2923089Swyllys 			value = malloc(value_len);
2933089Swyllys 			if (value == NULL) {
2943089Swyllys 				rv = KMF_ERR_MEMORY;
2953089Swyllys 				goto errout;
2963089Swyllys 			}
2973089Swyllys 
2983089Swyllys 			SETATTR(templ, i, CKA_VALUE, value, value_len);
2993089Swyllys 			i++;
3003089Swyllys 
3013089Swyllys 			/* re-query the object with room for the value attr */
3023089Swyllys 			ckrv = C_GetAttributeValue(kmfh->pk11handle, hObj,
3035051Swyllys 			    templ, i);
3043089Swyllys 
3053089Swyllys 			if (ckrv != CKR_OK)  {
3063089Swyllys 				SET_ERROR(kmfh, ckrv);
3073089Swyllys 				rv = KMF_ERR_INTERNAL;
3083089Swyllys 				goto errout;
3093089Swyllys 			}
3103089Swyllys 
3113089Swyllys 			kmfcert->certificate.Data = value;
3123089Swyllys 			kmfcert->certificate.Length = value_len;
3133089Swyllys 			kmfcert->kmf_private.flags |= KMF_FLAG_CERT_SIGNED;
3143089Swyllys 			kmfcert->kmf_private.keystore_type =
3155051Swyllys 			    KMF_KEYSTORE_PK11TOKEN;
3163408Swyllys 
3173408Swyllys 			ckrv = getObjectLabel(kmfh, hObj, &label);
3183408Swyllys 			if (ckrv == CKR_OK && label != NULL) {
3193408Swyllys 				kmfcert->kmf_private.label = (char *)label;
3203408Swyllys 			}
3213089Swyllys 
3223089Swyllys 			rv = KMF_OK;
3233089Swyllys 		}
3243089Swyllys 	}
3253089Swyllys 
3263089Swyllys errout:
3273089Swyllys 	if (rv != KMF_OK) {
3283089Swyllys 		if (subject)
3293089Swyllys 			free(subject);
3303089Swyllys 		if (value)
3313089Swyllys 			free(value);
3323089Swyllys 
3333089Swyllys 		if (kmfcert) {
3343089Swyllys 			kmfcert->certificate.Data = NULL;
3353089Swyllys 			kmfcert->certificate.Length = 0;
3363089Swyllys 		}
3373089Swyllys 	}
3383089Swyllys 	return (rv);
3393089Swyllys }
3403089Swyllys 
3413089Swyllys static void
free_objlist(OBJLIST * head)3423089Swyllys free_objlist(OBJLIST *head)
3433089Swyllys {
3443089Swyllys 	OBJLIST *temp = head;
3453089Swyllys 
3463089Swyllys 	while (temp != NULL) {
3473089Swyllys 		head = head->next;
3483089Swyllys 		free(temp);
3493089Swyllys 		temp = head;
3503089Swyllys 	}
3513089Swyllys }
3523089Swyllys 
3533089Swyllys /*
3543089Swyllys  * The caller should make sure that the templ->pValue is NULL since
3553089Swyllys  * it will be overwritten below.
3563089Swyllys  */
3573089Swyllys static KMF_RETURN
get_attr(KMF_HANDLE * kmfh,CK_OBJECT_HANDLE obj,CK_ATTRIBUTE * templ)3583089Swyllys get_attr(KMF_HANDLE *kmfh, CK_OBJECT_HANDLE obj,
3593089Swyllys 	CK_ATTRIBUTE *templ)
3603089Swyllys {
3613089Swyllys 	CK_RV rv;
3623089Swyllys 
3633089Swyllys 	rv = C_GetAttributeValue(kmfh->pk11handle, obj, templ, 1);
3643089Swyllys 	if (rv != CKR_OK) {
3653089Swyllys 		SET_ERROR(kmfh, rv);
3663089Swyllys 		return (KMF_ERR_INTERNAL);
3673089Swyllys 	}
3683089Swyllys 
3693089Swyllys 	if (templ->ulValueLen > 0) {
3703089Swyllys 		templ->pValue = malloc(templ->ulValueLen);
3713089Swyllys 		if (templ->pValue == NULL)
3723089Swyllys 			return (KMF_ERR_MEMORY);
3733089Swyllys 
3743089Swyllys 		rv = C_GetAttributeValue(kmfh->pk11handle, obj, templ, 1);
3753089Swyllys 		if (rv != CKR_OK) {
3763089Swyllys 			SET_ERROR(kmfh, rv);
3773089Swyllys 			return (KMF_ERR_INTERNAL);
3783089Swyllys 		}
3793089Swyllys 	}
3803089Swyllys 
3813089Swyllys 	return (KMF_OK);
3823089Swyllys }
3833089Swyllys 
3843089Swyllys /*
3853089Swyllys  * Match a certificate with an issuer and/or subject name.
3863089Swyllys  * This is tricky because we cannot reliably compare DER encodings
3873089Swyllys  * because RDNs may have their AV-pairs in different orders even
3883089Swyllys  * if the values are the same.  You must compare individual
3893089Swyllys  * AV pairs for the RDNs.
3903089Swyllys  *
3913089Swyllys  * RETURN: 0 for a match, non-zero for a non-match.
3923089Swyllys  */
3933089Swyllys static KMF_RETURN
matchcert(KMF_HANDLE * kmfh,CK_OBJECT_HANDLE obj,KMF_X509_NAME * issuer,KMF_X509_NAME * subject)3943089Swyllys matchcert(KMF_HANDLE *kmfh, CK_OBJECT_HANDLE obj,
3953089Swyllys 	KMF_X509_NAME *issuer, KMF_X509_NAME *subject)
3963089Swyllys {
3973089Swyllys 	KMF_RETURN rv = KMF_OK;
3983089Swyllys 	CK_ATTRIBUTE certattr;
3993089Swyllys 	KMF_DATA name;
4003089Swyllys 	KMF_X509_NAME dn;
4013089Swyllys 
4023089Swyllys 	if (issuer->numberOfRDNs > 0) {
4033089Swyllys 		certattr.type = CKA_ISSUER;
4043089Swyllys 		certattr.pValue = NULL;
4053089Swyllys 		certattr.ulValueLen = 0;
4063089Swyllys 
4073089Swyllys 		rv = get_attr(kmfh, obj, &certattr);
4083089Swyllys 
4093089Swyllys 		if (rv == KMF_OK) {
4103089Swyllys 			name.Data = certattr.pValue;
4113089Swyllys 			name.Length = certattr.ulValueLen;
4123089Swyllys 			rv = DerDecodeName(&name, &dn);
4133089Swyllys 			if (rv == KMF_OK) {
4145051Swyllys 				rv = kmf_compare_rdns(issuer, &dn);
4155051Swyllys 				kmf_free_dn(&dn);
4163089Swyllys 			}
4173089Swyllys 			free(certattr.pValue);
4183089Swyllys 		}
4193089Swyllys 
4203089Swyllys 		if (rv != KMF_OK)
4213089Swyllys 			return (rv);
4223089Swyllys 	}
4233089Swyllys 	if (subject->numberOfRDNs > 0) {
4243089Swyllys 		certattr.type = CKA_SUBJECT;
4253089Swyllys 		certattr.pValue = NULL;
4263089Swyllys 		certattr.ulValueLen = 0;
4273089Swyllys 
4283089Swyllys 		rv = get_attr(kmfh, obj, &certattr);
4293089Swyllys 
4303089Swyllys 		if (rv == KMF_OK) {
4313089Swyllys 			name.Data = certattr.pValue;
4323089Swyllys 			name.Length = certattr.ulValueLen;
4333089Swyllys 			rv = DerDecodeName(&name, &dn);
4343089Swyllys 			if (rv == KMF_OK) {
4355051Swyllys 				rv = kmf_compare_rdns(subject, &dn);
4365051Swyllys 				kmf_free_dn(&dn);
4373089Swyllys 			}
4383089Swyllys 			free(certattr.pValue);
4393089Swyllys 		}
4403089Swyllys 	}
4413089Swyllys 
4423089Swyllys 	return (rv);
4433089Swyllys }
4443089Swyllys 
4453089Swyllys /*
4463089Swyllys  * delete "curr" node from the "newlist".
4473089Swyllys  */
4483089Swyllys static void
pk11_delete_obj_from_list(OBJLIST ** newlist,OBJLIST ** prev,OBJLIST ** curr)4493089Swyllys pk11_delete_obj_from_list(OBJLIST **newlist,
4503089Swyllys 	OBJLIST **prev, OBJLIST **curr)
4513089Swyllys {
4523089Swyllys 
4533089Swyllys 	if (*curr == *newlist) {
4543089Swyllys 		/* first node in the list */
4553089Swyllys 		*newlist = (*curr)->next;
4563089Swyllys 		*prev = (*curr)->next;
4573089Swyllys 		free(*curr);
4583089Swyllys 		*curr = *newlist;
4593089Swyllys 	} else {
4603089Swyllys 		(*prev)->next = (*curr)->next;
4613089Swyllys 		free(*curr);
4623089Swyllys 		*curr = (*prev)->next;
4633089Swyllys 	}
4643089Swyllys }
4653089Swyllys 
4663089Swyllys /*
4675051Swyllys  * search_certs
4683089Swyllys  *
4693089Swyllys  * Because this code is shared by the FindCert and
4703089Swyllys  * DeleteCert functions, put it in a separate routine
4713089Swyllys  * to save some work and make code easier to debug and
4723089Swyllys  * read.
4733089Swyllys  */
4743089Swyllys static KMF_RETURN
search_certs(KMF_HANDLE_T handle,char * label,char * issuer,char * subject,KMF_BIGINT * serial,boolean_t private,KMF_CERT_VALIDITY validity,OBJLIST ** objlist,uint32_t * numobj)4753089Swyllys search_certs(KMF_HANDLE_T handle,
4763089Swyllys 	char *label, char *issuer, char *subject, KMF_BIGINT *serial,
4773089Swyllys 	boolean_t private, KMF_CERT_VALIDITY validity,
4783089Swyllys 	OBJLIST **objlist, uint32_t *numobj)
4793089Swyllys {
4803089Swyllys 	KMF_RETURN rv = KMF_OK;
4813089Swyllys 	CK_RV ckrv = CKR_OK;
4823089Swyllys 	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
4833089Swyllys 	CK_ATTRIBUTE templ[10];
4843089Swyllys 	CK_BBOOL true = TRUE;
4853089Swyllys 	CK_OBJECT_CLASS	oclass = CKO_CERTIFICATE;
4863089Swyllys 	CK_CERTIFICATE_TYPE ctype = CKC_X_509;
4873089Swyllys 	KMF_X509_NAME subjectDN, issuerDN;
4883089Swyllys 	int i;
4893089Swyllys 	OBJLIST *newlist, *tail;
4903089Swyllys 	CK_ULONG num = 0;
4913089Swyllys 	uint32_t num_ok_certs = 0; /* number of non-expired or expired certs */
4923089Swyllys 
4933089Swyllys 	(void) memset(&templ, 0, 10 * sizeof (CK_ATTRIBUTE));
4943089Swyllys 	(void) memset(&issuerDN, 0, sizeof (KMF_X509_NAME));
4953089Swyllys 	(void) memset(&subjectDN, 0, sizeof (KMF_X509_NAME));
4963089Swyllys 	i = 0;
4973089Swyllys 	SETATTR(templ, i, CKA_TOKEN, &true, sizeof (true)); i++;
4983089Swyllys 	SETATTR(templ, i, CKA_CLASS, &oclass, sizeof (oclass)); i++;
4995051Swyllys 	SETATTR(templ, i, CKA_CERTIFICATE_TYPE, &ctype,	sizeof (ctype)); i++;
5003089Swyllys 
5013089Swyllys 	if (label != NULL && strlen(label)) {
5023089Swyllys 		SETATTR(templ, i, CKA_LABEL, label, strlen(label));
5033089Swyllys 		i++;
5043089Swyllys 	}
5053089Swyllys 	if (private) {
5063089Swyllys 		SETATTR(templ, i, CKA_PRIVATE, &true, sizeof (true)); i++;
5073089Swyllys 	}
5083089Swyllys 
5093089Swyllys 	if (issuer != NULL && strlen(issuer)) {
5105051Swyllys 		if ((rv = kmf_dn_parser(issuer, &issuerDN)) != KMF_OK)
5113089Swyllys 			return (rv);
5123089Swyllys 	}
5133089Swyllys 	if (subject != NULL && strlen(subject)) {
5145051Swyllys 		if ((rv = kmf_dn_parser(subject, &subjectDN)) != KMF_OK)
5153089Swyllys 			return (rv);
5163089Swyllys 	}
5173089Swyllys 
5183089Swyllys 	if (serial != NULL && serial->val != NULL && serial->len > 0) {
5195051Swyllys 		SETATTR(templ, i, CKA_SERIAL_NUMBER, serial->val, serial->len);
5203089Swyllys 		i++;
5213089Swyllys 	}
5223089Swyllys 
5233089Swyllys 	(*numobj) = 0;
5243089Swyllys 	*objlist = NULL;
5253089Swyllys 	newlist = NULL;
5263089Swyllys 
5273089Swyllys 	ckrv = C_FindObjectsInit(kmfh->pk11handle, templ, i);
5283089Swyllys 	if (ckrv != CKR_OK)
5293089Swyllys 		goto cleanup;
5303089Swyllys 
5313089Swyllys 	tail = newlist = NULL;
5323089Swyllys 	while (ckrv == CKR_OK) {
5333089Swyllys 		CK_OBJECT_HANDLE tObj;
5343089Swyllys 		ckrv = C_FindObjects(kmfh->pk11handle, &tObj, 1, &num);
5353089Swyllys 		if (ckrv != CKR_OK || num == 0)
5363089Swyllys 			break;
5373089Swyllys 
5383089Swyllys 		/*
5393089Swyllys 		 * 'matchcert' returns 0 if subject/issuer match
5403089Swyllys 		 *
5413089Swyllys 		 * If no match, move on to the next one
5423089Swyllys 		 */
5433089Swyllys 		if (matchcert(kmfh, tObj, &issuerDN, &subjectDN))
5443089Swyllys 			continue;
5453089Swyllys 
5463089Swyllys 		if (newlist == NULL) {
5473089Swyllys 			newlist = malloc(sizeof (OBJLIST));
5483089Swyllys 			if (newlist == NULL) {
5493089Swyllys 				rv = KMF_ERR_MEMORY;
5503089Swyllys 				break;
5513089Swyllys 			}
5523089Swyllys 			newlist->handle = tObj;
5533089Swyllys 			newlist->next = NULL;
5543089Swyllys 			tail = newlist;
5553089Swyllys 		} else {
5563089Swyllys 			tail->next = malloc(sizeof (OBJLIST));
5573089Swyllys 			if (tail->next != NULL) {
5583089Swyllys 				tail = tail->next;
5593089Swyllys 			} else {
5603089Swyllys 				rv = KMF_ERR_MEMORY;
5613089Swyllys 				break;
5623089Swyllys 			}
5633089Swyllys 			tail->handle = tObj;
5643089Swyllys 			tail->next = NULL;
5653089Swyllys 		}
5663089Swyllys 		(*numobj)++;
5673089Swyllys 	}
5683089Swyllys 	ckrv = C_FindObjectsFinal(kmfh->pk11handle);
5693089Swyllys 
5703089Swyllys cleanup:
5713089Swyllys 	if (ckrv != CKR_OK) {
5723089Swyllys 		SET_ERROR(kmfh, ckrv);
5733089Swyllys 		rv = KMF_ERR_INTERNAL;
5743089Swyllys 		if (newlist != NULL) {
5753089Swyllys 			free_objlist(newlist);
5763089Swyllys 			*numobj = 0;
5773089Swyllys 			newlist = NULL;
5783089Swyllys 		}
5793089Swyllys 	} else {
5803089Swyllys 		if (validity == KMF_ALL_CERTS) {
5813089Swyllys 			*objlist = newlist;
5823089Swyllys 		} else {
5833089Swyllys 			OBJLIST *node, *prev;
5843089Swyllys 			KMF_X509_DER_CERT  tmp_kmf_cert;
5853089Swyllys 			uint32_t i = 0;
5863089Swyllys 
5873089Swyllys 			node = prev = newlist;
5883089Swyllys 			/*
5893089Swyllys 			 * Now check to see if any found certificate is expired
5903089Swyllys 			 * or valid.
5913089Swyllys 			 */
5923089Swyllys 			while (node != NULL && i < (*numobj)) {
5933089Swyllys 				(void) memset(&tmp_kmf_cert, 0,
5943089Swyllys 				    sizeof (KMF_X509_DER_CERT));
5953089Swyllys 				rv = PK11Cert2KMFCert(kmfh, node->handle,
5963089Swyllys 				    &tmp_kmf_cert);
5973089Swyllys 				if (rv != KMF_OK) {
5983089Swyllys 					goto cleanup1;
5993089Swyllys 				}
6003089Swyllys 
6015051Swyllys 				rv = kmf_check_cert_date(handle,
6023089Swyllys 				    &tmp_kmf_cert.certificate);
6033089Swyllys 
6043089Swyllys 				if (validity == KMF_NONEXPIRED_CERTS) {
6053089Swyllys 					if (rv == KMF_OK)  {
6063089Swyllys 						num_ok_certs++;
6073089Swyllys 						prev = node;
6083089Swyllys 						node = node->next;
6093089Swyllys 					} else if (rv ==
6103089Swyllys 					    KMF_ERR_VALIDITY_PERIOD) {
6113089Swyllys 						/*
6123089Swyllys 						 * expired - remove it from list
6133089Swyllys 						 */
6143089Swyllys 						pk11_delete_obj_from_list(
6153089Swyllys 						    &newlist, &prev, &node);
6163089Swyllys 					} else {
6173089Swyllys 						goto cleanup1;
6183089Swyllys 					}
6193089Swyllys 				}
6203089Swyllys 
6213089Swyllys 				if (validity == KMF_EXPIRED_CERTS) {
6223089Swyllys 					if (rv == KMF_ERR_VALIDITY_PERIOD)  {
6233089Swyllys 						num_ok_certs++;
6243089Swyllys 						prev = node;
6253089Swyllys 						node = node->next;
6263089Swyllys 						rv = KMF_OK;
6273089Swyllys 					} else if (rv == KMF_OK) {
6283089Swyllys 						/*
6293089Swyllys 						 * valid - remove it from list
6303089Swyllys 						 */
6313089Swyllys 						pk11_delete_obj_from_list(
6323089Swyllys 						    &newlist, &prev, &node);
6333089Swyllys 					} else {
6343089Swyllys 						goto cleanup1;
6353089Swyllys 					}
6363089Swyllys 				}
6373089Swyllys 				i++;
6385051Swyllys 				kmf_free_kmf_cert(handle, &tmp_kmf_cert);
6393089Swyllys 			}
6403089Swyllys 			*numobj = num_ok_certs;
6413089Swyllys 			*objlist = newlist;
6423089Swyllys 		}
6433089Swyllys 	}
6443089Swyllys 
6453089Swyllys cleanup1:
6463089Swyllys 	if (rv != KMF_OK && newlist != NULL) {
6473089Swyllys 		free_objlist(newlist);
6483089Swyllys 		*numobj = 0;
6493089Swyllys 		*objlist = NULL;
6503089Swyllys 	}
6513089Swyllys 
6523089Swyllys 	if (issuer != NULL)
6535051Swyllys 		kmf_free_dn(&issuerDN);
6543089Swyllys 
6553089Swyllys 	if (subject != NULL)
6565051Swyllys 		kmf_free_dn(&subjectDN);
6573089Swyllys 
6583089Swyllys 	return (rv);
6593089Swyllys }
6603089Swyllys 
6613089Swyllys /*
6623089Swyllys  * The caller may pass a NULL value for kmf_cert below and the function will
6633089Swyllys  * just return the number of certs found (in num_certs).
6643089Swyllys  */
6653089Swyllys KMF_RETURN
KMFPK11_FindCert(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)6665051Swyllys KMFPK11_FindCert(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
6673089Swyllys {
6683089Swyllys 	KMF_RETURN rv = 0;
6693089Swyllys 	uint32_t want_certs;
6703089Swyllys 	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
6713089Swyllys 	OBJLIST *objlist = NULL;
6725051Swyllys 	uint32_t *num_certs;
6735051Swyllys 	KMF_X509_DER_CERT *kmf_cert = NULL;
6745051Swyllys 	char *certlabel = NULL;
6755051Swyllys 	char *issuer = NULL;
6765051Swyllys 	char *subject = NULL;
6775051Swyllys 	KMF_BIGINT *serial = NULL;
6785051Swyllys 	KMF_CERT_VALIDITY validity;
6796354Swyllys 	KMF_CREDENTIAL *cred = NULL;
6805051Swyllys 	boolean_t private;
6815051Swyllys 
6825051Swyllys 	if (kmfh == NULL)
6833089Swyllys 		return (KMF_ERR_UNINITIALIZED); /* Plugin Not Initialized */
6843089Swyllys 
6853089Swyllys 	if (kmfh->pk11handle == CK_INVALID_HANDLE)
6863089Swyllys 		return (KMF_ERR_NO_TOKEN_SELECTED);
6873089Swyllys 
6885051Swyllys 	num_certs = kmf_get_attr_ptr(KMF_COUNT_ATTR, attrlist, numattr);
6895051Swyllys 	if (num_certs == NULL)
6903089Swyllys 		return (KMF_ERR_BAD_PARAMETER);
6913089Swyllys 
6923089Swyllys 	if (*num_certs > 0)
6933089Swyllys 		want_certs = *num_certs;
6943089Swyllys 	else
6953089Swyllys 		want_certs = MAXINT; /* count them all */
6963089Swyllys 
6973089Swyllys 	*num_certs = 0;
6983089Swyllys 
6995051Swyllys 	/* Get the optional returned certificate list */
7005051Swyllys 	kmf_cert = kmf_get_attr_ptr(KMF_X509_DER_CERT_ATTR, attrlist,
7015051Swyllys 	    numattr);
7025051Swyllys 
7035051Swyllys 	/* Get optional search criteria attributes */
7045051Swyllys 	certlabel = kmf_get_attr_ptr(KMF_CERT_LABEL_ATTR, attrlist, numattr);
7055051Swyllys 	issuer = kmf_get_attr_ptr(KMF_ISSUER_NAME_ATTR, attrlist, numattr);
7065051Swyllys 	subject = kmf_get_attr_ptr(KMF_SUBJECT_NAME_ATTR, attrlist, numattr);
7075051Swyllys 	serial = kmf_get_attr_ptr(KMF_BIGINT_ATTR, attrlist, numattr);
7085051Swyllys 
7095051Swyllys 	rv = kmf_get_attr(KMF_CERT_VALIDITY_ATTR, attrlist, numattr,
7105051Swyllys 	    &validity, NULL);
7115051Swyllys 	if (rv != KMF_OK) {
7125051Swyllys 		validity = KMF_ALL_CERTS;
7135051Swyllys 		rv = KMF_OK;
7145051Swyllys 	}
7155051Swyllys 
7165051Swyllys 	rv = kmf_get_attr(KMF_PRIVATE_BOOL_ATTR, attrlist, numattr,
7175051Swyllys 	    (void *)&private, NULL);
7185051Swyllys 	if (rv != KMF_OK) {
7195051Swyllys 		private = B_FALSE;
7205051Swyllys 		rv = KMF_OK;
7215051Swyllys 	}
7225051Swyllys 
7236354Swyllys 	cred = kmf_get_attr_ptr(KMF_CREDENTIAL_ATTR, attrlist, numattr);
7246354Swyllys 	if (cred != NULL) {
7256354Swyllys 		rv = pk11_authenticate(handle, cred);
7266354Swyllys 		if (rv != KMF_OK)
7276354Swyllys 			return (rv);
7286354Swyllys 	}
7296354Swyllys 
7305051Swyllys 	/* Start searching */
7315051Swyllys 	rv = search_certs(handle, certlabel, issuer, subject, serial, private,
7325051Swyllys 	    validity, &objlist, num_certs);
7333089Swyllys 
7343089Swyllys 	if (rv == KMF_OK && objlist != NULL && kmf_cert != NULL) {
7353089Swyllys 		OBJLIST *node = objlist;
7363089Swyllys 		int i = 0;
7373089Swyllys 		while (node != NULL && i < want_certs) {
7383089Swyllys 			rv = PK11Cert2KMFCert(kmfh, node->handle,
7395051Swyllys 			    &kmf_cert[i]);
7403089Swyllys 			i++;
7413089Swyllys 			node = node->next;
7423089Swyllys 		}
7433089Swyllys 	}
7443089Swyllys 
7453089Swyllys 	if (objlist != NULL)
7463089Swyllys 		free_objlist(objlist);
7473089Swyllys 
7483089Swyllys 	if (*num_certs == 0)
7493089Swyllys 		rv = KMF_ERR_CERT_NOT_FOUND;
7503089Swyllys 
7513089Swyllys 	return (rv);
7523089Swyllys }
7533089Swyllys 
7543089Swyllys /*ARGSUSED*/
7553089Swyllys void
KMFPK11_FreeKMFCert(KMF_HANDLE_T handle,KMF_X509_DER_CERT * kmf_cert)7565051Swyllys KMFPK11_FreeKMFCert(KMF_HANDLE_T handle, KMF_X509_DER_CERT *kmf_cert)
7573089Swyllys {
7583089Swyllys 	if (kmf_cert != NULL && kmf_cert->certificate.Data != NULL) {
7593089Swyllys 		free(kmf_cert->certificate.Data);
7603089Swyllys 		kmf_cert->certificate.Data = NULL;
7613089Swyllys 		kmf_cert->certificate.Length = 0;
7623089Swyllys 
7633089Swyllys 		if (kmf_cert->kmf_private.label != NULL) {
7643089Swyllys 			free(kmf_cert->kmf_private.label);
7653089Swyllys 			kmf_cert->kmf_private.label = NULL;
7663089Swyllys 		}
7673089Swyllys 	}
7683089Swyllys }
7693089Swyllys 
7703089Swyllys KMF_RETURN
KMFPK11_EncodePubKeyData(KMF_HANDLE_T handle,KMF_KEY_HANDLE * pKey,KMF_DATA * eData)7713089Swyllys KMFPK11_EncodePubKeyData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *pKey,
77211973Swyllys.ingersoll@sun.com 	KMF_DATA *eData)
7733089Swyllys {
7743089Swyllys 	KMF_RETURN ret = KMF_OK;
7753089Swyllys 	CK_RV rv;
7763089Swyllys 	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
7773089Swyllys 	CK_OBJECT_CLASS ckObjClass = CKO_PUBLIC_KEY;
7783089Swyllys 	CK_KEY_TYPE ckKeyType;
7793089Swyllys 	KMF_DATA Modulus, Exponent, Prime, Subprime, Base, Value;
7803089Swyllys 	KMF_OID *Algorithm;
7813089Swyllys 	BerElement *asn1 = NULL;
7823089Swyllys 	BerValue *PubKeyParams = NULL, *EncodedKey = NULL;
7833089Swyllys 	KMF_X509_SPKI spki;
78411973Swyllys.ingersoll@sun.com 	CK_BYTE ec_params[256], ec_point[256];
7853089Swyllys 
7863089Swyllys 	CK_ATTRIBUTE rsaTemplate[4];
7873089Swyllys 	CK_ATTRIBUTE dsaTemplate[6];
78811973Swyllys.ingersoll@sun.com 	CK_ATTRIBUTE ecdsaTemplate[6];
7893089Swyllys 
7905051Swyllys 	if (kmfh == NULL)
7913089Swyllys 		return (KMF_ERR_UNINITIALIZED); /* Plugin Not Initialized */
7923089Swyllys 
7933089Swyllys 	if (kmfh->pk11handle == CK_INVALID_HANDLE)
7943089Swyllys 		return (KMF_ERR_NO_TOKEN_SELECTED);
7953089Swyllys 
7963089Swyllys 	if (pKey == NULL || pKey->keyp == CK_INVALID_HANDLE)
7973089Swyllys 		return (KMF_ERR_BAD_PARAMETER);
7983089Swyllys 
7993089Swyllys 	(void) memset(&Modulus, 0, sizeof (Modulus));
8003089Swyllys 	(void) memset(&Exponent, 0, sizeof (Exponent));
8013089Swyllys 	(void) memset(&Prime, 0, sizeof (Prime));
8023089Swyllys 	(void) memset(&Subprime, 0, sizeof (Subprime));
8033089Swyllys 	(void) memset(&Base, 0, sizeof (Base));
8043089Swyllys 	(void) memset(&Value, 0, sizeof (Value));
8053089Swyllys 
8063089Swyllys 	switch (pKey->keyalg) {
8073089Swyllys 		case KMF_RSA:
80811973Swyllys.ingersoll@sun.com 			SETATTR(rsaTemplate, 0, CKA_CLASS, &ckObjClass,
80911973Swyllys.ingersoll@sun.com 			    sizeof (ckObjClass));
81011973Swyllys.ingersoll@sun.com 			SETATTR(rsaTemplate, 1, CKA_KEY_TYPE, &ckKeyType,
81111973Swyllys.ingersoll@sun.com 			    sizeof (ckKeyType));
81211973Swyllys.ingersoll@sun.com 			SETATTR(rsaTemplate, 2, CKA_MODULUS, Modulus.Data,
81311973Swyllys.ingersoll@sun.com 			    Modulus.Length);
81411973Swyllys.ingersoll@sun.com 			SETATTR(rsaTemplate, 3, CKA_PUBLIC_EXPONENT,
81511973Swyllys.ingersoll@sun.com 			    Exponent.Data, Exponent.Length);
8163089Swyllys 			/* Get the length of the fields */
8173089Swyllys 			rv = C_GetAttributeValue(kmfh->pk11handle,
8185051Swyllys 			    (CK_OBJECT_HANDLE)pKey->keyp, rsaTemplate, 4);
8193089Swyllys 			if (rv != CKR_OK) {
8203089Swyllys 				SET_ERROR(kmfh, rv);
8213089Swyllys 				return (KMF_ERR_BAD_PARAMETER);
8223089Swyllys 			}
8233089Swyllys 
8243089Swyllys 			Modulus.Length = rsaTemplate[2].ulValueLen;
8253089Swyllys 			Modulus.Data = malloc(Modulus.Length);
8263089Swyllys 			if (Modulus.Data == NULL)
8273089Swyllys 				return (KMF_ERR_MEMORY);
8283089Swyllys 
8293089Swyllys 			Exponent.Length = rsaTemplate[3].ulValueLen;
8303089Swyllys 			Exponent.Data = malloc(Exponent.Length);
8313089Swyllys 			if (Exponent.Data == NULL) {
8323089Swyllys 				free(Modulus.Data);
8333089Swyllys 				return (KMF_ERR_MEMORY);
8343089Swyllys 			}
8353089Swyllys 
8363089Swyllys 			SETATTR(rsaTemplate, 2, CKA_MODULUS, Modulus.Data,
8375051Swyllys 			    Modulus.Length);
8383089Swyllys 			SETATTR(rsaTemplate, 3, CKA_PUBLIC_EXPONENT,
8395051Swyllys 			    Exponent.Data, Exponent.Length);
8403089Swyllys 			/* Now get the values */
8413089Swyllys 			rv = C_GetAttributeValue(kmfh->pk11handle,
8425051Swyllys 			    (CK_OBJECT_HANDLE)pKey->keyp, rsaTemplate, 4);
8433089Swyllys 			if (rv != CKR_OK) {
8443089Swyllys 				SET_ERROR(kmfh, rv);
8453089Swyllys 				free(Modulus.Data);
8463089Swyllys 				free(Exponent.Data);
8473089Swyllys 				return (KMF_ERR_BAD_PARAMETER);
8483089Swyllys 			}
8493089Swyllys 
8503089Swyllys 			/*
8513089Swyllys 			 * This is the KEY algorithm, not the
8523089Swyllys 			 * signature algorithm.
8533089Swyllys 			 */
8545051Swyllys 			Algorithm = x509_algid_to_algoid(KMF_ALGID_RSA);
8553089Swyllys 			if (Algorithm != NULL) {
8563089Swyllys 
8573089Swyllys 				/* Encode the RSA Key Data */
8583089Swyllys 				if ((asn1 = kmfder_alloc()) == NULL) {
8593089Swyllys 					free(Modulus.Data);
8603089Swyllys 					free(Exponent.Data);
8613089Swyllys 					return (KMF_ERR_MEMORY);
8623089Swyllys 				}
8635051Swyllys 				if (kmfber_printf(asn1, "{II}",	Modulus.Data,
8645051Swyllys 				    Modulus.Length, Exponent.Data,
8655051Swyllys 				    Exponent.Length) == -1) {
8663089Swyllys 					kmfber_free(asn1, 1);
8673089Swyllys 					free(Modulus.Data);
8683089Swyllys 					free(Exponent.Data);
8693089Swyllys 					return (KMF_ERR_ENCODING);
8703089Swyllys 				}
8713089Swyllys 				if (kmfber_flatten(asn1, &EncodedKey) == -1) {
8723089Swyllys 					kmfber_free(asn1, 1);
8733089Swyllys 					free(Modulus.Data);
8743089Swyllys 					free(Exponent.Data);
8753089Swyllys 					return (KMF_ERR_ENCODING);
8763089Swyllys 				}
8773089Swyllys 				kmfber_free(asn1, 1);
8783089Swyllys 			}
8793089Swyllys 
8803089Swyllys 			free(Exponent.Data);
8813089Swyllys 			free(Modulus.Data);
8823089Swyllys 
8833089Swyllys 			break;
8843089Swyllys 		case KMF_DSA:
88511973Swyllys.ingersoll@sun.com 			SETATTR(dsaTemplate, 0, CKA_CLASS, &ckObjClass,
88611973Swyllys.ingersoll@sun.com 			    sizeof (ckObjClass));
88711973Swyllys.ingersoll@sun.com 			SETATTR(dsaTemplate, 1, CKA_KEY_TYPE, &ckKeyType,
88811973Swyllys.ingersoll@sun.com 			    sizeof (ckKeyType));
88911973Swyllys.ingersoll@sun.com 			SETATTR(dsaTemplate, 2, CKA_PRIME, Prime.Data,
89011973Swyllys.ingersoll@sun.com 			    Prime.Length);
89111973Swyllys.ingersoll@sun.com 			SETATTR(dsaTemplate, 3, CKA_SUBPRIME, Subprime.Data,
89211973Swyllys.ingersoll@sun.com 			    Subprime.Length);
89311973Swyllys.ingersoll@sun.com 			SETATTR(dsaTemplate, 4, CKA_BASE, Base.Data,
89411973Swyllys.ingersoll@sun.com 			    Base.Length);
89511973Swyllys.ingersoll@sun.com 			SETATTR(dsaTemplate, 5, CKA_VALUE, Value.Data,
89611973Swyllys.ingersoll@sun.com 			    Value.Length);
89711973Swyllys.ingersoll@sun.com 
8983089Swyllys 			/* Get the length of the fields */
8993089Swyllys 			rv = C_GetAttributeValue(kmfh->pk11handle,
9005051Swyllys 			    (CK_OBJECT_HANDLE)pKey->keyp, dsaTemplate, 6);
9013089Swyllys 			if (rv != CKR_OK) {
9023089Swyllys 				SET_ERROR(kmfh, rv);
9033089Swyllys 				return (KMF_ERR_BAD_PARAMETER);
9043089Swyllys 			}
9053089Swyllys 			Prime.Length = dsaTemplate[2].ulValueLen;
9063089Swyllys 			Prime.Data = malloc(Prime.Length);
9073089Swyllys 			if (Prime.Data == NULL) {
9083089Swyllys 				return (KMF_ERR_MEMORY);
9093089Swyllys 			}
9103089Swyllys 
9113089Swyllys 			Subprime.Length = dsaTemplate[3].ulValueLen;
9123089Swyllys 			Subprime.Data = malloc(Subprime.Length);
9133089Swyllys 			if (Subprime.Data == NULL) {
9143089Swyllys 				free(Prime.Data);
9153089Swyllys 				return (KMF_ERR_MEMORY);
9163089Swyllys 			}
9173089Swyllys 
9183089Swyllys 			Base.Length = dsaTemplate[4].ulValueLen;
9193089Swyllys 			Base.Data = malloc(Base.Length);
9203089Swyllys 			if (Base.Data == NULL) {
9213089Swyllys 				free(Prime.Data);
9223089Swyllys 				free(Subprime.Data);
9233089Swyllys 				return (KMF_ERR_MEMORY);
9243089Swyllys 			}
9253089Swyllys 
9263089Swyllys 			Value.Length = dsaTemplate[5].ulValueLen;
9273089Swyllys 			Value.Data = malloc(Value.Length);
9283089Swyllys 			if (Value.Data == NULL) {
9293089Swyllys 				free(Prime.Data);
9303089Swyllys 				free(Subprime.Data);
9313089Swyllys 				free(Base.Data);
9323089Swyllys 				return (KMF_ERR_MEMORY);
9333089Swyllys 			}
9343089Swyllys 			SETATTR(dsaTemplate, 2, CKA_PRIME, Prime.Data,
9355051Swyllys 			    Prime.Length);
9363089Swyllys 			SETATTR(dsaTemplate, 3, CKA_SUBPRIME, Subprime.Data,
9375051Swyllys 			    Subprime.Length);
9383089Swyllys 			SETATTR(dsaTemplate, 4, CKA_BASE, Base.Data,
9395051Swyllys 			    Base.Length);
9403089Swyllys 			SETATTR(dsaTemplate, 5, CKA_VALUE, Value.Data,
9415051Swyllys 			    Value.Length);
9423089Swyllys 
9433089Swyllys 			/* Now get the values */
9443089Swyllys 			rv = C_GetAttributeValue(kmfh->pk11handle,
9455051Swyllys 			    (CK_OBJECT_HANDLE)pKey->keyp, dsaTemplate, 6);
9463089Swyllys 			if (rv != CKR_OK) {
9473089Swyllys 				free(Prime.Data);
9483089Swyllys 				free(Subprime.Data);
9493089Swyllys 				free(Base.Data);
9503089Swyllys 				free(Value.Data);
9513089Swyllys 				SET_ERROR(kmfh, rv);
9523089Swyllys 				return (KMF_ERR_BAD_PARAMETER);
9533089Swyllys 			}
9543089Swyllys 			/*
9553089Swyllys 			 * This is the KEY algorithm, not the
9563089Swyllys 			 * signature algorithm.
9573089Swyllys 			 */
9585051Swyllys 			Algorithm = x509_algid_to_algoid(KMF_ALGID_DSA);
9593089Swyllys 
9603089Swyllys 			/* Encode the DSA Algorithm Parameters */
9613089Swyllys 			if ((asn1 = kmfder_alloc()) == NULL) {
9623089Swyllys 				free(Prime.Data);
9633089Swyllys 				free(Subprime.Data);
9643089Swyllys 				free(Base.Data);
9653089Swyllys 				free(Value.Data);
9663089Swyllys 				return (KMF_ERR_MEMORY);
9673089Swyllys 			}
9683089Swyllys 
9695051Swyllys 			if (kmfber_printf(asn1, "{III}", Prime.Data,
9705051Swyllys 			    Prime.Length, Subprime.Data, Subprime.Length,
9715051Swyllys 			    Base.Data, Base.Length) == -1) {
9723089Swyllys 
9733089Swyllys 				kmfber_free(asn1, 1);
9743089Swyllys 				free(Prime.Data);
9753089Swyllys 				free(Subprime.Data);
9763089Swyllys 				free(Base.Data);
9773089Swyllys 				free(Value.Data);
9783089Swyllys 				return (KMF_ERR_ENCODING);
9793089Swyllys 			}
9803089Swyllys 			if (kmfber_flatten(asn1, &PubKeyParams) == -1) {
9813089Swyllys 				kmfber_free(asn1, 1);
9823089Swyllys 				free(Prime.Data);
9833089Swyllys 				free(Subprime.Data);
9843089Swyllys 				free(Base.Data);
9853089Swyllys 				free(Value.Data);
9863089Swyllys 				return (KMF_ERR_ENCODING);
9873089Swyllys 			}
9883089Swyllys 			kmfber_free(asn1, 1);
9893089Swyllys 			free(Prime.Data);
9903089Swyllys 			free(Subprime.Data);
9913089Swyllys 			free(Base.Data);
9923089Swyllys 
9933089Swyllys 			/* Encode the DSA Key Value */
9943089Swyllys 			if ((asn1 = kmfder_alloc()) == NULL) {
9953089Swyllys 				free(Value.Data);
9963089Swyllys 				return (KMF_ERR_MEMORY);
9973089Swyllys 			}
9983089Swyllys 
9993089Swyllys 			if (kmfber_printf(asn1, "I",
10005051Swyllys 			    Value.Data, Value.Length) == -1) {
10013089Swyllys 				kmfber_free(asn1, 1);
10023089Swyllys 				free(Value.Data);
10033089Swyllys 				return (KMF_ERR_ENCODING);
10043089Swyllys 			}
10053089Swyllys 			if (kmfber_flatten(asn1, &EncodedKey) == -1) {
10063089Swyllys 				kmfber_free(asn1, 1);
10073089Swyllys 				free(Value.Data);
10083089Swyllys 				return (KMF_ERR_ENCODING);
10093089Swyllys 			}
10103089Swyllys 			kmfber_free(asn1, 1);
10113089Swyllys 			free(Value.Data);
10123089Swyllys 			break;
101311973Swyllys.ingersoll@sun.com 		case KMF_ECDSA:
101411973Swyllys.ingersoll@sun.com 			/* The EC_PARAMS are the PubKey algorithm parameters */
101511973Swyllys.ingersoll@sun.com 			PubKeyParams = calloc(1, sizeof (BerValue));
101611973Swyllys.ingersoll@sun.com 			if (PubKeyParams == NULL)
101711973Swyllys.ingersoll@sun.com 				return (KMF_ERR_MEMORY);
101811973Swyllys.ingersoll@sun.com 			EncodedKey = calloc(1, sizeof (BerValue));
101911973Swyllys.ingersoll@sun.com 			if (EncodedKey == NULL) {
102011973Swyllys.ingersoll@sun.com 				free(PubKeyParams);
102111973Swyllys.ingersoll@sun.com 				return (KMF_ERR_MEMORY);
102211973Swyllys.ingersoll@sun.com 			}
102311973Swyllys.ingersoll@sun.com 			SETATTR(ecdsaTemplate, 0, CKA_EC_PARAMS,
102411973Swyllys.ingersoll@sun.com 			    &ec_params, sizeof (ec_params));
102511973Swyllys.ingersoll@sun.com 			SETATTR(ecdsaTemplate, 1, CKA_EC_POINT,
102611973Swyllys.ingersoll@sun.com 			    &ec_point, sizeof (ec_point));
102711973Swyllys.ingersoll@sun.com 
102811973Swyllys.ingersoll@sun.com 			/* Get the length of the fields */
102911973Swyllys.ingersoll@sun.com 			rv = C_GetAttributeValue(kmfh->pk11handle,
103011973Swyllys.ingersoll@sun.com 			    (CK_OBJECT_HANDLE)pKey->keyp,
103111973Swyllys.ingersoll@sun.com 			    ecdsaTemplate, 2);
103211973Swyllys.ingersoll@sun.com 			if (rv != CKR_OK) {
103311973Swyllys.ingersoll@sun.com 				SET_ERROR(kmfh, rv);
103411973Swyllys.ingersoll@sun.com 				return (KMF_ERR_BAD_PARAMETER);
103511973Swyllys.ingersoll@sun.com 			}
103611973Swyllys.ingersoll@sun.com 			/* The params are to be used as algorithm parameters */
103711973Swyllys.ingersoll@sun.com 			PubKeyParams->bv_val = (char *)ec_params;
103811973Swyllys.ingersoll@sun.com 			PubKeyParams->bv_len = ecdsaTemplate[0].ulValueLen;
103911973Swyllys.ingersoll@sun.com 			/*
104011973Swyllys.ingersoll@sun.com 			 * The EC_POINT is to be used as the subject pub key.
104111973Swyllys.ingersoll@sun.com 			 */
104211973Swyllys.ingersoll@sun.com 			EncodedKey->bv_val = (char *)ec_point;
104311973Swyllys.ingersoll@sun.com 			EncodedKey->bv_len = ecdsaTemplate[1].ulValueLen;
104411973Swyllys.ingersoll@sun.com 
104511973Swyllys.ingersoll@sun.com 			/* Use the EC_PUBLIC_KEY OID */
104611973Swyllys.ingersoll@sun.com 			Algorithm = (KMF_OID *)&KMFOID_EC_PUBLIC_KEY;
104711973Swyllys.ingersoll@sun.com 			break;
10483089Swyllys 		default:
10493089Swyllys 			return (KMF_ERR_BAD_PARAMETER);
10503089Swyllys 	}
10513089Swyllys 
10523089Swyllys 	/* Now, build an SPKI structure for the final encoding step */
10533089Swyllys 	spki.algorithm.algorithm = *Algorithm;
10543089Swyllys 	if (PubKeyParams != NULL) {
10553089Swyllys 		spki.algorithm.parameters.Data =
10565051Swyllys 		    (uchar_t *)PubKeyParams->bv_val;
10573089Swyllys 		spki.algorithm.parameters.Length = PubKeyParams->bv_len;
10583089Swyllys 	} else {
10593089Swyllys 		spki.algorithm.parameters.Data = NULL;
10603089Swyllys 		spki.algorithm.parameters.Length = 0;
10613089Swyllys 	}
10623089Swyllys 
10633089Swyllys 	if (EncodedKey != NULL) {
10643089Swyllys 		spki.subjectPublicKey.Data = (uchar_t *)EncodedKey->bv_val;
10653089Swyllys 		spki.subjectPublicKey.Length = EncodedKey->bv_len;
10663089Swyllys 	} else {
10673089Swyllys 		spki.subjectPublicKey.Data = NULL;
10683089Swyllys 		spki.subjectPublicKey.Length = 0;
10693089Swyllys 	}
10703089Swyllys 
10713089Swyllys 	/* Finally, encode the entire SPKI record */
10723089Swyllys 	ret = DerEncodeSPKI(&spki, eData);
10733089Swyllys 
10743089Swyllys cleanup:
10753089Swyllys 	if (EncodedKey) {
107611973Swyllys.ingersoll@sun.com 		if (pKey->keyalg != KMF_ECDSA)
107711973Swyllys.ingersoll@sun.com 			free(EncodedKey->bv_val);
10783089Swyllys 		free(EncodedKey);
10793089Swyllys 	}
10803089Swyllys 
10813089Swyllys 	if (PubKeyParams) {
108211973Swyllys.ingersoll@sun.com 		if (pKey->keyalg != KMF_ECDSA)
108311973Swyllys.ingersoll@sun.com 			free(PubKeyParams->bv_val);
10843089Swyllys 		free(PubKeyParams);
10853089Swyllys 	}
10863089Swyllys 
10873089Swyllys 	return (ret);
10883089Swyllys }
10893089Swyllys 
10903089Swyllys static KMF_RETURN
CreateCertObject(KMF_HANDLE_T handle,char * label,KMF_DATA * pcert)10913089Swyllys CreateCertObject(KMF_HANDLE_T handle, char *label, KMF_DATA *pcert)
10923089Swyllys {
10933089Swyllys 	KMF_RETURN rv = 0;
10943089Swyllys 	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
10953089Swyllys 
10963089Swyllys 	KMF_X509_CERTIFICATE *signed_cert_ptr = NULL;
10973089Swyllys 	KMF_DATA data;
10983089Swyllys 	KMF_DATA Id;
10993089Swyllys 
11003089Swyllys 	CK_RV ckrv;
11013089Swyllys 	CK_ULONG subject_len, issuer_len, serno_len;
11023408Swyllys 	CK_BYTE *subject, *issuer, *serial, nullserno;
11033089Swyllys 	CK_BBOOL true = TRUE;
11043089Swyllys 	CK_CERTIFICATE_TYPE certtype = CKC_X_509;
11053089Swyllys 	CK_OBJECT_CLASS certClass = CKO_CERTIFICATE;
11063089Swyllys 	CK_ATTRIBUTE x509templ[11];
11073089Swyllys 	CK_OBJECT_HANDLE hCert = NULL;
11083089Swyllys 	int i;
11093089Swyllys 
11105051Swyllys 	if (kmfh == NULL)
11113089Swyllys 		return (KMF_ERR_INTERNAL); /* should not happen */
11123089Swyllys 
11133089Swyllys 	if (kmfh->pk11handle == CK_INVALID_HANDLE)
11143089Swyllys 		return (KMF_ERR_INTERNAL); /* should not happen */
11153089Swyllys 
11163089Swyllys 	if (pcert == NULL || pcert->Data == NULL || pcert->Length == 0)
11173089Swyllys 		return (KMF_ERR_INTERNAL);  /* should not happen */
11183089Swyllys 
11193089Swyllys 	/*
11203089Swyllys 	 * The data *must* be a DER encoded X.509 certificate.
11213089Swyllys 	 * Convert it to a CSSM cert and then parse the fields so
11223089Swyllys 	 * the PKCS#11 attributes can be filled in correctly.
11233089Swyllys 	 */
11243089Swyllys 	rv = DerDecodeSignedCertificate((const KMF_DATA *)pcert,
11255051Swyllys 	    &signed_cert_ptr);
11263089Swyllys 	if (rv != KMF_OK) {
11273089Swyllys 		return (KMF_ERR_ENCODING);
11283089Swyllys 	}
11293089Swyllys 
11303089Swyllys 	/*
11313089Swyllys 	 * Encode fields into PKCS#11 attributes.
11323089Swyllys 	 */
11333089Swyllys 
11343089Swyllys 	/* Get the subject name */
11353089Swyllys 	rv = DerEncodeName(&signed_cert_ptr->certificate.subject, &data);
11363089Swyllys 	if (rv == KMF_OK) {
11373089Swyllys 		subject = data.Data;
11383089Swyllys 		subject_len = data.Length;
11393089Swyllys 	} else {
11403089Swyllys 		rv = KMF_ERR_ENCODING;
11413089Swyllys 		goto cleanup;
11423089Swyllys 	}
11433089Swyllys 
11443089Swyllys 	/* Encode the issuer */
11453089Swyllys 	rv = DerEncodeName(&signed_cert_ptr->certificate.issuer, &data);
11463089Swyllys 	if (rv == KMF_OK) {
11473089Swyllys 		issuer = data.Data;
11483089Swyllys 		issuer_len = data.Length;
11493089Swyllys 	} else {
11503089Swyllys 		rv = KMF_ERR_ENCODING;
11513089Swyllys 		goto cleanup;
11523089Swyllys 	}
11533089Swyllys 
11543089Swyllys 	/* Encode serial number */
11553089Swyllys 	if (signed_cert_ptr->certificate.serialNumber.len > 0 &&
11563089Swyllys 	    signed_cert_ptr->certificate.serialNumber.val != NULL) {
11573089Swyllys 		serial = signed_cert_ptr->certificate.serialNumber.val;
11583089Swyllys 		serno_len = signed_cert_ptr->certificate.serialNumber.len;
11593089Swyllys 	} else {
11603408Swyllys 		/*
11613408Swyllys 		 * RFC3280 says to gracefully handle certs with serial numbers
11623408Swyllys 		 * of 0.
11633408Swyllys 		 */
11643408Swyllys 		nullserno = '\0';
11653408Swyllys 		serial  = &nullserno;
11663408Swyllys 		serno_len = 1;
11673089Swyllys 	}
11683089Swyllys 
11693089Swyllys 	/* Generate an ID from the SPKI data */
11703089Swyllys 	rv = GetIDFromSPKI(&signed_cert_ptr->certificate.subjectPublicKeyInfo,
11715051Swyllys 	    &Id);
11723089Swyllys 
11733089Swyllys 	if (rv != KMF_OK) {
11743089Swyllys 		goto cleanup;
11753089Swyllys 	}
11763089Swyllys 
11773089Swyllys 	i = 0;
11785051Swyllys 	SETATTR(x509templ, i, CKA_CLASS, &certClass, sizeof (certClass)); i++;
11793089Swyllys 	SETATTR(x509templ, i, CKA_CERTIFICATE_TYPE, &certtype,
11805051Swyllys 	    sizeof (certtype));
11815051Swyllys 	i++;
11823089Swyllys 	SETATTR(x509templ, i, CKA_TOKEN, &true, sizeof (true)); i++;
11833089Swyllys 	SETATTR(x509templ, i, CKA_SUBJECT, subject, subject_len); i++;
11843089Swyllys 	SETATTR(x509templ, i, CKA_ISSUER, issuer, issuer_len); i++;
11853089Swyllys 	SETATTR(x509templ, i, CKA_SERIAL_NUMBER, serial, serno_len); i++;
11863089Swyllys 	SETATTR(x509templ, i, CKA_VALUE, pcert->Data, pcert->Length); i++;
11873089Swyllys 	SETATTR(x509templ, i, CKA_ID, Id.Data, Id.Length); i++;
11883089Swyllys 	if (label != NULL && strlen(label)) {
11895051Swyllys 		SETATTR(x509templ, i, CKA_LABEL, label, strlen(label));	i++;
11903089Swyllys 	}
11913089Swyllys 	/*
11923089Swyllys 	 * The cert object handle is actually "leaked" here.  If the app
11933089Swyllys 	 * really wants to clean up the data space, it will have to call
11943089Swyllys 	 * KMF_DeleteCert and specify the softtoken keystore.
11953089Swyllys 	 */
11963089Swyllys 	ckrv = C_CreateObject(kmfh->pk11handle, x509templ, i, &hCert);
11973089Swyllys 	if (ckrv != CKR_OK) {
11986354Swyllys 		/* Report authentication failures to the caller */
11996354Swyllys 		if (ckrv == CKR_USER_NOT_LOGGED_IN ||
12006354Swyllys 		    ckrv == CKR_PIN_INCORRECT ||
12016354Swyllys 		    ckrv == CKR_PIN_INVALID ||
12026354Swyllys 		    ckrv == CKR_PIN_EXPIRED ||
12036354Swyllys 		    ckrv == CKR_PIN_LOCKED ||
12046354Swyllys 		    ckrv == CKR_SESSION_READ_ONLY)
12056354Swyllys 			rv = KMF_ERR_AUTH_FAILED;
12066354Swyllys 		else
12076354Swyllys 			rv = KMF_ERR_INTERNAL;
12086354Swyllys 		SET_ERROR(kmfh, ckrv);
12093089Swyllys 	}
12103089Swyllys 	free(subject);
12113089Swyllys 	free(issuer);
12123089Swyllys 
12133089Swyllys cleanup:
12143089Swyllys 	if (Id.Data != NULL)
12153089Swyllys 		free(Id.Data);
12163089Swyllys 
12173089Swyllys 	if (signed_cert_ptr) {
12185051Swyllys 		kmf_free_signed_cert(signed_cert_ptr);
12193089Swyllys 		free(signed_cert_ptr);
12203089Swyllys 	}
12213089Swyllys 	return (rv);
12223089Swyllys }
12233089Swyllys 
12243089Swyllys 
12253089Swyllys KMF_RETURN
KMFPK11_StoreCert(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)12265051Swyllys KMFPK11_StoreCert(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
12273089Swyllys {
12283089Swyllys 	KMF_RETURN rv = 0;
12293089Swyllys 	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
12305051Swyllys 	KMF_DATA *cert = NULL;
12316354Swyllys 	KMF_CREDENTIAL *cred = NULL;
12325051Swyllys 	char *label = NULL;
12335051Swyllys 
12345051Swyllys 	if (kmfh == NULL)
12355051Swyllys 		return (KMF_ERR_UNINITIALIZED);
12363089Swyllys 
12373089Swyllys 	if (kmfh->pk11handle == CK_INVALID_HANDLE)
12383089Swyllys 		return (KMF_ERR_NO_TOKEN_SELECTED);
12393089Swyllys 
12405051Swyllys 	cert = kmf_get_attr_ptr(KMF_CERT_DATA_ATTR, attrlist, numattr);
12415051Swyllys 	if (cert == NULL || cert->Data == NULL || cert->Length == 0)
12423089Swyllys 		return (KMF_ERR_BAD_PARAMETER);
12433089Swyllys 
12445051Swyllys 	/* label attribute is optional */
12455051Swyllys 	label = kmf_get_attr_ptr(KMF_CERT_LABEL_ATTR, attrlist, numattr);
12465051Swyllys 
12476354Swyllys 	cred = kmf_get_attr_ptr(KMF_CREDENTIAL_ATTR, attrlist, numattr);
12486354Swyllys 	if (cred != NULL) {
12496354Swyllys 		rv = pk11_authenticate(handle, cred);
12506354Swyllys 		if (rv != KMF_OK)
12516354Swyllys 			return (rv);
12526354Swyllys 	}
12536354Swyllys 
12545051Swyllys 	rv = CreateCertObject(handle, label, cert);
12553089Swyllys 	return (rv);
12563089Swyllys }
12573089Swyllys 
12583089Swyllys KMF_RETURN
KMFPK11_ImportCert(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)12595051Swyllys KMFPK11_ImportCert(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
12603089Swyllys {
12613089Swyllys 	KMF_RETURN rv = 0;
12623089Swyllys 	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
12635051Swyllys 	char *certfile = NULL;
12645051Swyllys 	char *label = NULL;
12653089Swyllys 	KMF_ENCODE_FORMAT format;
12666354Swyllys 	KMF_CREDENTIAL *cred = NULL;
12673089Swyllys 	KMF_DATA  cert1 = { NULL, 0};
12683089Swyllys 	KMF_DATA  cert2 = { NULL, 0};
12693089Swyllys 
12705051Swyllys 	if (kmfh == NULL)
12715051Swyllys 		return (KMF_ERR_UNINITIALIZED);
12723089Swyllys 
12733089Swyllys 	if (kmfh->pk11handle == CK_INVALID_HANDLE)
12743089Swyllys 		return (KMF_ERR_NO_TOKEN_SELECTED);
12753089Swyllys 
12765051Swyllys 	/*
12775051Swyllys 	 * Get the input cert filename attribute, check if it is a valid
12785051Swyllys 	 * certificate and auto-detect the file format of it.
12795051Swyllys 	 */
12805051Swyllys 	certfile = kmf_get_attr_ptr(KMF_CERT_FILENAME_ATTR, attrlist, numattr);
12815051Swyllys 	if (certfile == NULL)
12823089Swyllys 		return (KMF_ERR_BAD_PARAMETER);
12835051Swyllys 
12845051Swyllys 	rv = kmf_is_cert_file(handle, certfile, &format);
12853089Swyllys 	if (rv != KMF_OK)
12863089Swyllys 		return (rv);
12873089Swyllys 
12883089Swyllys 	/* Read in the CERT file */
12895051Swyllys 	rv = kmf_read_input_file(handle, certfile, &cert1);
12903089Swyllys 	if (rv != KMF_OK) {
12913089Swyllys 		return (rv);
12923089Swyllys 	}
12933089Swyllys 
12945051Swyllys 	/* The label attribute is optional */
12955051Swyllys 	label = kmf_get_attr_ptr(KMF_CERT_LABEL_ATTR, attrlist, numattr);
12965051Swyllys 
12973089Swyllys 	/*
12983089Swyllys 	 * If the input certificate is in PEM format, we need to convert
12993089Swyllys 	 * it to DER first.
13003089Swyllys 	 */
13013089Swyllys 	if (format == KMF_FORMAT_PEM) {
13023089Swyllys 		int derlen;
13035051Swyllys 		rv = kmf_pem_to_der(cert1.Data, cert1.Length,
13043089Swyllys 		    &cert2.Data, &derlen);
13053089Swyllys 		if (rv != KMF_OK) {
13063089Swyllys 			goto out;
13073089Swyllys 		}
13083089Swyllys 		cert2.Length = (size_t)derlen;
13093089Swyllys 	}
13103089Swyllys 
13116354Swyllys 	cred = kmf_get_attr_ptr(KMF_CREDENTIAL_ATTR, attrlist, numattr);
13126354Swyllys 	if (cred != NULL) {
13136354Swyllys 		rv = pk11_authenticate(handle, cred);
13146354Swyllys 		if (rv != KMF_OK)
13156354Swyllys 			return (rv);
13166354Swyllys 	}
13176354Swyllys 
13185051Swyllys 	rv = CreateCertObject(handle, label,
13193089Swyllys 	    format == KMF_FORMAT_ASN1 ? &cert1 : &cert2);
13203089Swyllys 
13213089Swyllys out:
13223089Swyllys 	if (cert1.Data != NULL) {
13233089Swyllys 		free(cert1.Data);
13243089Swyllys 	}
13253089Swyllys 
13263089Swyllys 	if (cert2.Data != NULL) {
13273089Swyllys 		free(cert2.Data);
13283089Swyllys 	}
13293089Swyllys 
13303089Swyllys 	return (rv);
13313089Swyllys }
13323089Swyllys 
13333089Swyllys KMF_RETURN
KMFPK11_DeleteCert(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)13345051Swyllys KMFPK11_DeleteCert(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
13353089Swyllys {
13363089Swyllys 	KMF_RETURN rv = 0;
13373089Swyllys 	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
13383089Swyllys 	OBJLIST *objlist;
13393089Swyllys 	uint32_t numObjects = 0;
13405051Swyllys 	char *certlabel = NULL;
13415051Swyllys 	char *issuer = NULL;
13425051Swyllys 	char *subject = NULL;
13435051Swyllys 	KMF_BIGINT *serial = NULL;
13445051Swyllys 	KMF_CERT_VALIDITY validity;
13455051Swyllys 	boolean_t private;
13465051Swyllys 
13475051Swyllys 	if (kmfh == NULL)
13483089Swyllys 		return (KMF_ERR_UNINITIALIZED); /* Plugin Not Initialized */
13493089Swyllys 
13503089Swyllys 	if (kmfh->pk11handle == CK_INVALID_HANDLE)
13513089Swyllys 		return (KMF_ERR_NO_TOKEN_SELECTED);
13523089Swyllys 
13535051Swyllys 
13545051Swyllys 	/* Get the search criteria attributes. They are all optional. */
13555051Swyllys 	certlabel = kmf_get_attr_ptr(KMF_CERT_LABEL_ATTR, attrlist, numattr);
13565051Swyllys 	issuer = kmf_get_attr_ptr(KMF_ISSUER_NAME_ATTR, attrlist, numattr);
13575051Swyllys 	subject = kmf_get_attr_ptr(KMF_SUBJECT_NAME_ATTR, attrlist, numattr);
13585051Swyllys 	serial = kmf_get_attr_ptr(KMF_BIGINT_ATTR, attrlist, numattr);
13595051Swyllys 
13605051Swyllys 	rv = kmf_get_attr(KMF_CERT_VALIDITY_ATTR, attrlist, numattr,
13615051Swyllys 	    &validity, NULL);
13625051Swyllys 	if (rv != KMF_OK) {
13635051Swyllys 		validity = KMF_ALL_CERTS;
13645051Swyllys 		rv = KMF_OK;
13655051Swyllys 	}
13665051Swyllys 
13675051Swyllys 	rv = kmf_get_attr(KMF_PRIVATE_BOOL_ATTR, attrlist, numattr,
13685051Swyllys 	    (void *)&private, NULL);
13695051Swyllys 	if (rv != KMF_OK) {
13705051Swyllys 		private = B_FALSE;
13715051Swyllys 		rv = KMF_OK;
13725051Swyllys 	}
13733089Swyllys 
13743089Swyllys 	/*
13755051Swyllys 	 * Start searching for certificates that match the criteria and
13765051Swyllys 	 * delete them.
13773089Swyllys 	 */
13783089Swyllys 	objlist = NULL;
13795051Swyllys 	rv = search_certs(handle, certlabel, issuer, subject, serial,
13805051Swyllys 	    private, validity, &objlist, &numObjects);
13813089Swyllys 
13823089Swyllys 	if (rv == KMF_OK && objlist != NULL) {
13833089Swyllys 		OBJLIST *node = objlist;
13843089Swyllys 
13853089Swyllys 		while (node != NULL) {
13863089Swyllys 			CK_RV ckrv;
13875051Swyllys 			ckrv = C_DestroyObject(kmfh->pk11handle, node->handle);
13883089Swyllys 			if (ckrv != CKR_OK) {
13893089Swyllys 				SET_ERROR(kmfh, ckrv);
13903089Swyllys 				rv = KMF_ERR_INTERNAL;
13913089Swyllys 				break;
13923089Swyllys 			}
13933089Swyllys 			node = node->next;
13943089Swyllys 		}
13953089Swyllys 		free_objlist(objlist);
13963089Swyllys 	}
13973089Swyllys 
13983089Swyllys 	if (rv == KMF_OK && numObjects == 0)
13993089Swyllys 		rv = KMF_ERR_CERT_NOT_FOUND;
14003089Swyllys 
14013089Swyllys out:
14023089Swyllys 	return (rv);
14033089Swyllys }
14043089Swyllys 
140511973Swyllys.ingersoll@sun.com static CK_RV
gendsa_keypair(KMF_HANDLE * kmfh,boolean_t storekey,CK_OBJECT_HANDLE * pubKey,CK_OBJECT_HANDLE * priKey)140611973Swyllys.ingersoll@sun.com gendsa_keypair(KMF_HANDLE *kmfh, boolean_t storekey,
140711973Swyllys.ingersoll@sun.com 	CK_OBJECT_HANDLE *pubKey,
140811973Swyllys.ingersoll@sun.com 	CK_OBJECT_HANDLE *priKey)
14093089Swyllys {
141011973Swyllys.ingersoll@sun.com 	CK_RV ckrv = CKR_OK;
141111973Swyllys.ingersoll@sun.com 	CK_SESSION_HANDLE hSession = kmfh->pk11handle;
141211973Swyllys.ingersoll@sun.com 	static CK_ULONG	dsaKeyType = CKK_DSA;
141311973Swyllys.ingersoll@sun.com 	static CK_BBOOL	true = TRUE;
141411973Swyllys.ingersoll@sun.com 	static CK_BBOOL	false = FALSE;
14153089Swyllys 	static CK_OBJECT_CLASS	priClass = CKO_PRIVATE_KEY;
14163089Swyllys 	static CK_OBJECT_CLASS	pubClass = CKO_PUBLIC_KEY;
14173089Swyllys 
14183089Swyllys 	static CK_BYTE ckDsaPrime[128] = {
14193089Swyllys 	0xb2, 0x6b, 0xc3, 0xfb, 0xe3, 0x26, 0xf4, 0xc2,
14203089Swyllys 	0xcf, 0xdd, 0xf9, 0xae, 0x3e, 0x39, 0x7f, 0x9c,
14213089Swyllys 	0xa7, 0x73, 0xc3, 0x00, 0xa3, 0x50, 0x67, 0xc3,
14223089Swyllys 	0xab, 0x49, 0x2c, 0xea, 0x59, 0x10, 0xa4, 0xbc,
14233089Swyllys 	0x09, 0x94, 0xa9, 0x05, 0x3b, 0x0d, 0x35, 0x3c,
14243089Swyllys 	0x55, 0x52, 0x47, 0xf0, 0xe3, 0x72, 0x5b, 0xe8,
14253089Swyllys 	0x72, 0xa0, 0x71, 0x1c, 0x23, 0x4f, 0x6d, 0xe8,
14263089Swyllys 	0xac, 0xe5, 0x21, 0x1b, 0xc0, 0xd8, 0x42, 0xd3,
14273089Swyllys 	0x87, 0xae, 0x83, 0x5e, 0x52, 0x7e, 0x46, 0x09,
14283089Swyllys 	0xb5, 0xc7, 0x3d, 0xd6, 0x00, 0xf5, 0xf2, 0x9c,
14293089Swyllys 	0x84, 0x30, 0x81, 0x7e, 0x7b, 0x30, 0x5b, 0xd5,
14303089Swyllys 	0xab, 0xd0, 0x2f, 0x21, 0xb3, 0xd8, 0xed, 0xdb,
14313089Swyllys 	0x97, 0x77, 0xe4, 0x7e, 0x6c, 0xcc, 0xb9, 0x6b,
14323089Swyllys 	0xdd, 0xaa, 0x96, 0x04, 0xe7, 0xd4, 0x55, 0x11,
14333089Swyllys 	0x53, 0xab, 0xba, 0x95, 0x9a, 0xa2, 0x8c, 0x27,
14343089Swyllys 	0xd9, 0xcf, 0xad, 0xf3, 0xcf, 0x3a, 0x0c, 0x4b};
14353089Swyllys 
14363089Swyllys 	static CK_BYTE ckDsaSubPrime[20] = {
14373089Swyllys 	0xa4, 0x5f, 0x2a, 0x27, 0x09, 0x49, 0xb6, 0xfe,
14383089Swyllys 	0x73, 0xeb, 0x95, 0x7d, 0x00, 0xf3, 0x42, 0xfc,
14393089Swyllys 	0x78, 0x47, 0xb0, 0xd5};
14403089Swyllys 
14413089Swyllys 	static CK_BYTE ckDsaBase[128] = {
14423089Swyllys 	0x5c, 0x57, 0x16, 0x49, 0xef, 0xc8, 0xfb, 0x4b,
14433089Swyllys 	0xee, 0x07, 0x45, 0x3b, 0x6a, 0x1d, 0xf3, 0xe5,
14443089Swyllys 	0xeb, 0xee, 0xad, 0x11, 0x13, 0xe3, 0x52, 0xe3,
14453089Swyllys 	0x0d, 0xc0, 0x21, 0x25, 0xfa, 0xf0, 0x93, 0x1c,
14463089Swyllys 	0x53, 0x4d, 0xdc, 0x0d, 0x76, 0xd2, 0xfe, 0xc2,
14473089Swyllys 	0xd7, 0x72, 0x64, 0x69, 0x53, 0x3d, 0x33, 0xbd,
14483089Swyllys 	0xe1, 0x34, 0xf2, 0x5a, 0x67, 0x83, 0xe0, 0xd3,
14493089Swyllys 	0x1c, 0xd6, 0x41, 0x4d, 0x16, 0xe8, 0x6c, 0x5a,
14503089Swyllys 	0x07, 0x95, 0x21, 0x9a, 0xa3, 0xc4, 0xb9, 0x05,
14513089Swyllys 	0x9d, 0x11, 0xcb, 0xc8, 0xc4, 0x9d, 0x00, 0x1a,
14523089Swyllys 	0xf4, 0x85, 0x2a, 0xa9, 0x20, 0x3c, 0xba, 0x67,
14533089Swyllys 	0xe5, 0xed, 0x31, 0xb2, 0x11, 0xfb, 0x1f, 0x73,
14543089Swyllys 	0xec, 0x61, 0x29, 0xad, 0xc7, 0x68, 0xb2, 0x3f,
14553089Swyllys 	0x38, 0xea, 0xd9, 0x87, 0x83, 0x9e, 0x7e, 0x19,
14563089Swyllys 	0x18, 0xdd, 0xc2, 0xc3, 0x5b, 0x16, 0x6d, 0xce,
14573089Swyllys 	0xcf, 0x88, 0x91, 0x07, 0xe0, 0x2b, 0xa8, 0x54 };
14583089Swyllys 
14593089Swyllys 	static CK_ATTRIBUTE ckDsaPubKeyTemplate[] = {
14603089Swyllys 	{ CKA_CLASS, &pubClass, sizeof (pubClass) },
14613089Swyllys 	{ CKA_KEY_TYPE, &dsaKeyType, sizeof (dsaKeyType) },
146211973Swyllys.ingersoll@sun.com 	{ CKA_TOKEN, &true, sizeof (true)},
14633089Swyllys 	{ CKA_PRIVATE, &false, sizeof (false)},
14643089Swyllys 	{ CKA_PRIME, &ckDsaPrime, sizeof (ckDsaPrime) },
14653089Swyllys 	{ CKA_SUBPRIME, &ckDsaSubPrime, sizeof (ckDsaSubPrime)},
14663089Swyllys 	{ CKA_BASE, &ckDsaBase, sizeof (ckDsaBase) },
14673089Swyllys 	{ CKA_VERIFY, &true, sizeof (true) },
14683089Swyllys };
14693089Swyllys 
14703089Swyllys #define	NUMBER_DSA_PUB_TEMPLATES (sizeof (ckDsaPubKeyTemplate) / \
14713089Swyllys 					sizeof (CK_ATTRIBUTE))
14723089Swyllys #define	MAX_DSA_PUB_TEMPLATES (sizeof (ckDsaPubKeyTemplate) / \
14733089Swyllys 				    sizeof (CK_ATTRIBUTE))
14743089Swyllys 
14753089Swyllys 	static CK_ATTRIBUTE ckDsaPriKeyTemplate[] = {
14763089Swyllys 	{CKA_CLASS, &priClass, sizeof (priClass)},
14773089Swyllys 	{CKA_KEY_TYPE, &dsaKeyType, sizeof (dsaKeyType)},
147811973Swyllys.ingersoll@sun.com 	{CKA_TOKEN, &true, sizeof (true)},
14793089Swyllys 	{CKA_PRIVATE, &true, sizeof (true)},
14803089Swyllys 	{CKA_SIGN, &true, sizeof (true)},
14813089Swyllys 	};
14823089Swyllys 
14833089Swyllys #define	NUMBER_DSA_PRI_TEMPLATES (sizeof (ckDsaPriKeyTemplate) / \
14843089Swyllys 					sizeof (CK_ATTRIBUTE))
14853089Swyllys #define	MAX_DSA_PRI_TEMPLATES (sizeof (ckDsaPriKeyTemplate) / \
14863089Swyllys 				sizeof (CK_ATTRIBUTE))
148711973Swyllys.ingersoll@sun.com 	CK_MECHANISM keyGenMech = {CKM_DSA_KEY_PAIR_GEN, NULL, 0};
148811973Swyllys.ingersoll@sun.com 
148911973Swyllys.ingersoll@sun.com 	SETATTR(ckDsaPriKeyTemplate, 2, CKA_TOKEN,
149011973Swyllys.ingersoll@sun.com 	    (storekey ? &true : &false), sizeof (CK_BBOOL));
149111973Swyllys.ingersoll@sun.com 
149211973Swyllys.ingersoll@sun.com 	ckrv = C_GenerateKeyPair(hSession, &keyGenMech,
149311973Swyllys.ingersoll@sun.com 	    ckDsaPubKeyTemplate,
149411973Swyllys.ingersoll@sun.com 	    (sizeof (ckDsaPubKeyTemplate)/sizeof (CK_ATTRIBUTE)),
149511973Swyllys.ingersoll@sun.com 	    ckDsaPriKeyTemplate,
149611973Swyllys.ingersoll@sun.com 	    (sizeof (ckDsaPriKeyTemplate)/sizeof (CK_ATTRIBUTE)),
149711973Swyllys.ingersoll@sun.com 	    pubKey, priKey);
149811973Swyllys.ingersoll@sun.com 	if (ckrv != CKR_OK) {
149911973Swyllys.ingersoll@sun.com 		SET_ERROR(kmfh, ckrv);
150011973Swyllys.ingersoll@sun.com 		return (KMF_ERR_KEYGEN_FAILED);
150111973Swyllys.ingersoll@sun.com 	}
150211973Swyllys.ingersoll@sun.com 
150311973Swyllys.ingersoll@sun.com 	return (ckrv);
150411973Swyllys.ingersoll@sun.com }
150511973Swyllys.ingersoll@sun.com 
150611973Swyllys.ingersoll@sun.com static CK_RV
genrsa_keypair(KMF_HANDLE * kmfh,CK_ULONG modulusBits,boolean_t storekey,KMF_BIGINT * rsaexp,CK_OBJECT_HANDLE * pubKey,CK_OBJECT_HANDLE * priKey)150711973Swyllys.ingersoll@sun.com genrsa_keypair(KMF_HANDLE *kmfh, CK_ULONG modulusBits,
150811973Swyllys.ingersoll@sun.com 	boolean_t storekey, KMF_BIGINT *rsaexp,
150911973Swyllys.ingersoll@sun.com 	CK_OBJECT_HANDLE *pubKey,
151011973Swyllys.ingersoll@sun.com 	CK_OBJECT_HANDLE *priKey)
151111973Swyllys.ingersoll@sun.com {
151211973Swyllys.ingersoll@sun.com 	CK_RV ckrv = CKR_OK;
151311973Swyllys.ingersoll@sun.com 	CK_SESSION_HANDLE hSession = kmfh->pk11handle;
151411973Swyllys.ingersoll@sun.com 	CK_ATTRIBUTE rsaPubKeyTemplate[16];
151511973Swyllys.ingersoll@sun.com 	CK_ATTRIBUTE rsaPriKeyTemplate[16];
151611973Swyllys.ingersoll@sun.com 	CK_MECHANISM keyGenMech = {CKM_RSA_PKCS_KEY_PAIR_GEN, NULL, 0};
151711973Swyllys.ingersoll@sun.com 	int numpubattr = 0, numpriattr = 0;
151811973Swyllys.ingersoll@sun.com 	static CK_BYTE	PubExpo[3] = {0x01, 0x00, 0x01};
151911973Swyllys.ingersoll@sun.com 	static CK_BBOOL	true = TRUE;
152011973Swyllys.ingersoll@sun.com 	static CK_BBOOL	false = FALSE;
152111973Swyllys.ingersoll@sun.com 
152211973Swyllys.ingersoll@sun.com 	SETATTR(rsaPubKeyTemplate, numpubattr, CKA_TOKEN,
152311973Swyllys.ingersoll@sun.com 	    (storekey ? &true : &false), sizeof (CK_BBOOL));
152411973Swyllys.ingersoll@sun.com 	numpubattr++;
152511973Swyllys.ingersoll@sun.com 
152611973Swyllys.ingersoll@sun.com 	SETATTR(rsaPubKeyTemplate, numpubattr, CKA_MODULUS_BITS,
152711973Swyllys.ingersoll@sun.com 	    &modulusBits, sizeof (modulusBits));
152811973Swyllys.ingersoll@sun.com 	numpubattr++;
152911973Swyllys.ingersoll@sun.com 
153011973Swyllys.ingersoll@sun.com 	if (rsaexp != NULL && (rsaexp->len > 0 && rsaexp->val != NULL)) {
153111973Swyllys.ingersoll@sun.com 		SETATTR(rsaPubKeyTemplate, numpubattr,
153211973Swyllys.ingersoll@sun.com 		    CKA_PUBLIC_EXPONENT,
153311973Swyllys.ingersoll@sun.com 		    rsaexp->val, rsaexp->len);
153411973Swyllys.ingersoll@sun.com 		numpubattr++;
153511973Swyllys.ingersoll@sun.com 	} else {
153611973Swyllys.ingersoll@sun.com 		SETATTR(rsaPubKeyTemplate, numpubattr,
153711973Swyllys.ingersoll@sun.com 		    CKA_PUBLIC_EXPONENT, &PubExpo, sizeof (PubExpo));
153811973Swyllys.ingersoll@sun.com 		numpubattr++;
153911973Swyllys.ingersoll@sun.com 	}
154011973Swyllys.ingersoll@sun.com 	SETATTR(rsaPubKeyTemplate, numpubattr, CKA_ENCRYPT,
154111973Swyllys.ingersoll@sun.com 	    &true, sizeof (true));
154211973Swyllys.ingersoll@sun.com 	numpubattr++;
154311973Swyllys.ingersoll@sun.com 	SETATTR(rsaPubKeyTemplate, numpubattr, CKA_VERIFY,
154411973Swyllys.ingersoll@sun.com 	    &true, sizeof (true));
154511973Swyllys.ingersoll@sun.com 	numpubattr++;
154611973Swyllys.ingersoll@sun.com 	SETATTR(rsaPubKeyTemplate, numpubattr, CKA_WRAP,
154711973Swyllys.ingersoll@sun.com 	    &true, sizeof (true));
154811973Swyllys.ingersoll@sun.com 	numpubattr++;
154911973Swyllys.ingersoll@sun.com 
155011973Swyllys.ingersoll@sun.com 	SETATTR(rsaPriKeyTemplate, numpriattr, CKA_TOKEN,
155111973Swyllys.ingersoll@sun.com 	    (storekey ? &true : &false), sizeof (CK_BBOOL));
155211973Swyllys.ingersoll@sun.com 	numpriattr++;
155311973Swyllys.ingersoll@sun.com 	SETATTR(rsaPriKeyTemplate, numpriattr, CKA_PRIVATE, &true,
155411973Swyllys.ingersoll@sun.com 	    sizeof (true));
155511973Swyllys.ingersoll@sun.com 	numpriattr++;
155611973Swyllys.ingersoll@sun.com 	SETATTR(rsaPriKeyTemplate, numpriattr, CKA_DECRYPT, &true,
155711973Swyllys.ingersoll@sun.com 	    sizeof (true));
155811973Swyllys.ingersoll@sun.com 	numpriattr++;
155911973Swyllys.ingersoll@sun.com 	SETATTR(rsaPriKeyTemplate, numpriattr, CKA_SIGN, &true,
156011973Swyllys.ingersoll@sun.com 	    sizeof (true));
156111973Swyllys.ingersoll@sun.com 	numpriattr++;
156211973Swyllys.ingersoll@sun.com 	SETATTR(rsaPriKeyTemplate, numpriattr, CKA_UNWRAP, &true,
156311973Swyllys.ingersoll@sun.com 	    sizeof (true));
156411973Swyllys.ingersoll@sun.com 	numpriattr++;
156511973Swyllys.ingersoll@sun.com 
156611973Swyllys.ingersoll@sun.com 	ckrv = C_GenerateKeyPair(hSession, &keyGenMech,
156711973Swyllys.ingersoll@sun.com 	    rsaPubKeyTemplate, numpubattr,
156811973Swyllys.ingersoll@sun.com 	    rsaPriKeyTemplate, numpriattr,
156911973Swyllys.ingersoll@sun.com 	    pubKey, priKey);
157011973Swyllys.ingersoll@sun.com 	if (ckrv != CKR_OK) {
157111973Swyllys.ingersoll@sun.com 		SET_ERROR(kmfh, ckrv);
157211973Swyllys.ingersoll@sun.com 		return (ckrv);
157311973Swyllys.ingersoll@sun.com 	}
157411973Swyllys.ingersoll@sun.com 
157511973Swyllys.ingersoll@sun.com 	return (ckrv);
157611973Swyllys.ingersoll@sun.com }
157711973Swyllys.ingersoll@sun.com 
157811973Swyllys.ingersoll@sun.com static CK_RV
genecc_keypair(KMF_HANDLE * kmfh,boolean_t ontoken,KMF_OID * curveoid,CK_OBJECT_HANDLE * pubKey,CK_OBJECT_HANDLE * priKey)157911973Swyllys.ingersoll@sun.com genecc_keypair(KMF_HANDLE *kmfh,
158011973Swyllys.ingersoll@sun.com 	boolean_t ontoken,
158111973Swyllys.ingersoll@sun.com 	KMF_OID *curveoid,
158211973Swyllys.ingersoll@sun.com 	CK_OBJECT_HANDLE *pubKey,
158311973Swyllys.ingersoll@sun.com 	CK_OBJECT_HANDLE *priKey)
158411973Swyllys.ingersoll@sun.com {
158511973Swyllys.ingersoll@sun.com 	CK_RV ckrv;
158611973Swyllys.ingersoll@sun.com 	CK_SESSION_HANDLE hSession = kmfh->pk11handle;
158711973Swyllys.ingersoll@sun.com 	CK_MECHANISM keyGenMech = {CKM_EC_KEY_PAIR_GEN, NULL, 0};
158811973Swyllys.ingersoll@sun.com 	const ulong_t publicKey = CKO_PUBLIC_KEY;
158911973Swyllys.ingersoll@sun.com 	const ulong_t privateKey = CKO_PRIVATE_KEY;
159011973Swyllys.ingersoll@sun.com 	const ulong_t keytype = CKK_EC;
159111973Swyllys.ingersoll@sun.com 	static CK_BBOOL	true = TRUE;
159211973Swyllys.ingersoll@sun.com 	static CK_BBOOL	false = FALSE;
159311973Swyllys.ingersoll@sun.com 	CK_ATTRIBUTE public_template[6];
159411973Swyllys.ingersoll@sun.com 	CK_ATTRIBUTE private_template[6];
159511973Swyllys.ingersoll@sun.com 	int numpubattr, numpriattr;
159611973Swyllys.ingersoll@sun.com 
159711973Swyllys.ingersoll@sun.com 	numpubattr = 0;
159811973Swyllys.ingersoll@sun.com 	SETATTR(public_template, numpubattr, CKA_CLASS,
159911973Swyllys.ingersoll@sun.com 	    &publicKey, sizeof (publicKey));
160011973Swyllys.ingersoll@sun.com 	numpubattr++;
160111973Swyllys.ingersoll@sun.com 	SETATTR(public_template, numpubattr, CKA_KEY_TYPE,
160211973Swyllys.ingersoll@sun.com 	    &keytype, sizeof (keytype));
160311973Swyllys.ingersoll@sun.com 	numpubattr++;
160411973Swyllys.ingersoll@sun.com 	SETATTR(public_template, numpubattr, CKA_EC_PARAMS,
160511973Swyllys.ingersoll@sun.com 	    curveoid->Data, curveoid->Length);
160611973Swyllys.ingersoll@sun.com 	numpubattr++;
160711973Swyllys.ingersoll@sun.com 	SETATTR(public_template, numpubattr, CKA_TOKEN,
160811973Swyllys.ingersoll@sun.com 	    ontoken ? &true : &false, sizeof (true));
160911973Swyllys.ingersoll@sun.com 	numpubattr++;
161011973Swyllys.ingersoll@sun.com 	SETATTR(public_template, numpubattr, CKA_VERIFY,
161111973Swyllys.ingersoll@sun.com 	    &true, sizeof (true));
161211973Swyllys.ingersoll@sun.com 	numpubattr++;
161311973Swyllys.ingersoll@sun.com 	SETATTR(public_template, numpubattr, CKA_PRIVATE,
161411973Swyllys.ingersoll@sun.com 	    &false, sizeof (false));
161511973Swyllys.ingersoll@sun.com 	numpubattr++;
161611973Swyllys.ingersoll@sun.com 
161711973Swyllys.ingersoll@sun.com 	numpriattr = 0;
161811973Swyllys.ingersoll@sun.com 	SETATTR(private_template, numpriattr, CKA_CLASS,
161911973Swyllys.ingersoll@sun.com 	    &privateKey, sizeof (privateKey));
162011973Swyllys.ingersoll@sun.com 	numpriattr++;
162111973Swyllys.ingersoll@sun.com 	SETATTR(private_template, numpriattr, CKA_KEY_TYPE,
162211973Swyllys.ingersoll@sun.com 	    &keytype, sizeof (keytype));
162311973Swyllys.ingersoll@sun.com 	numpriattr++;
162411973Swyllys.ingersoll@sun.com 	SETATTR(private_template, numpriattr, CKA_TOKEN,
162511973Swyllys.ingersoll@sun.com 	    ontoken ? &true : &false, sizeof (true));
162611973Swyllys.ingersoll@sun.com 	numpriattr++;
162711973Swyllys.ingersoll@sun.com 	SETATTR(private_template, numpriattr, CKA_PRIVATE,
162811973Swyllys.ingersoll@sun.com 	    &true, sizeof (true));
162911973Swyllys.ingersoll@sun.com 	numpriattr++;
163011973Swyllys.ingersoll@sun.com 	SETATTR(private_template, numpriattr, CKA_SIGN,
163111973Swyllys.ingersoll@sun.com 	    &true, sizeof (true));
163211973Swyllys.ingersoll@sun.com 	numpriattr++;
163311973Swyllys.ingersoll@sun.com 	SETATTR(private_template, numpriattr, CKA_DERIVE,
163411973Swyllys.ingersoll@sun.com 	    &true, sizeof (true));
163511973Swyllys.ingersoll@sun.com 	numpriattr++;
163611973Swyllys.ingersoll@sun.com 
163711973Swyllys.ingersoll@sun.com 	ckrv = C_GenerateKeyPair(hSession, &keyGenMech,
163811973Swyllys.ingersoll@sun.com 	    public_template, numpubattr,
163911973Swyllys.ingersoll@sun.com 	    private_template, numpriattr,
164011973Swyllys.ingersoll@sun.com 	    pubKey, priKey);
164111973Swyllys.ingersoll@sun.com 	if (ckrv != CKR_OK) {
164211973Swyllys.ingersoll@sun.com 		SET_ERROR(kmfh, ckrv);
164311973Swyllys.ingersoll@sun.com 		return (ckrv);
164411973Swyllys.ingersoll@sun.com 	}
164511973Swyllys.ingersoll@sun.com 
164611973Swyllys.ingersoll@sun.com 	return (ckrv);
164711973Swyllys.ingersoll@sun.com }
164811973Swyllys.ingersoll@sun.com 
164911973Swyllys.ingersoll@sun.com KMF_RETURN
KMFPK11_CreateKeypair(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attlist)165011973Swyllys.ingersoll@sun.com KMFPK11_CreateKeypair(KMF_HANDLE_T handle,
165111973Swyllys.ingersoll@sun.com 	int numattr,
165211973Swyllys.ingersoll@sun.com 	KMF_ATTRIBUTE *attlist)
165311973Swyllys.ingersoll@sun.com {
165411973Swyllys.ingersoll@sun.com 	KMF_RETURN rv = KMF_OK;
165511973Swyllys.ingersoll@sun.com 	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
165611973Swyllys.ingersoll@sun.com 	KMF_DATA IDInput, IDOutput;
165711973Swyllys.ingersoll@sun.com 	KMF_CREDENTIAL *cred;
165811973Swyllys.ingersoll@sun.com 	KMF_KEY_ALG keytype = KMF_RSA;
165911973Swyllys.ingersoll@sun.com 	KMF_KEY_HANDLE *pubkey, *privkey;
166011973Swyllys.ingersoll@sun.com 
166111973Swyllys.ingersoll@sun.com 	CK_RV			ckrv = 0;
166211973Swyllys.ingersoll@sun.com 	CK_SESSION_HANDLE	hSession = kmfh->pk11handle;
166311973Swyllys.ingersoll@sun.com 	CK_ATTRIBUTE labelattr[1];
166411973Swyllys.ingersoll@sun.com 	CK_ATTRIBUTE idattr[1];
166511973Swyllys.ingersoll@sun.com 	CK_OBJECT_HANDLE pubKey, priKey;
166611973Swyllys.ingersoll@sun.com 
166711973Swyllys.ingersoll@sun.com 	char IDHashData[SHA1_HASH_LENGTH];
166811973Swyllys.ingersoll@sun.com 	static CK_ULONG	modulusBits = 1024;
166911973Swyllys.ingersoll@sun.com 	uint32_t	modulusBits_size = sizeof (CK_ULONG);
167011973Swyllys.ingersoll@sun.com 	SHA1_CTX ctx;
167111973Swyllys.ingersoll@sun.com 	boolean_t storekey = TRUE;
167211973Swyllys.ingersoll@sun.com 	char *keylabel = NULL;
16733089Swyllys 
16745051Swyllys 	if (kmfh == NULL)
16753089Swyllys 		return (KMF_ERR_UNINITIALIZED); /* Plugin Not Initialized */
16763089Swyllys 
16773089Swyllys 	if (kmfh->pk11handle == CK_INVALID_HANDLE)
16783089Swyllys 		return (KMF_ERR_NO_TOKEN_SELECTED);
16793089Swyllys 
16805051Swyllys 	/* "storekey" is optional. Default is TRUE */
16815051Swyllys 	(void) kmf_get_attr(KMF_STOREKEY_BOOL_ATTR, attlist, numattr,
16825051Swyllys 	    &storekey, NULL);
16835051Swyllys 
16845051Swyllys 	cred = kmf_get_attr_ptr(KMF_CREDENTIAL_ATTR, attlist, numattr);
16855051Swyllys 	if (cred == NULL)
16863089Swyllys 		return (KMF_ERR_BAD_PARAMETER);
16873089Swyllys 
16885051Swyllys 	rv = pk11_authenticate(handle, cred);
16895051Swyllys 	if (rv != KMF_OK)
16903089Swyllys 		return (rv);
16915051Swyllys 
16925051Swyllys 	/* keytype is optional.  KMF_RSA is default */
16935051Swyllys 	(void) kmf_get_attr(KMF_KEYALG_ATTR, attlist, numattr,
16945051Swyllys 	    (void *)&keytype, NULL);
16955051Swyllys 
16965051Swyllys 	pubkey = kmf_get_attr_ptr(KMF_PUBKEY_HANDLE_ATTR, attlist, numattr);
16975051Swyllys 	if (pubkey == NULL)
16985051Swyllys 		return (KMF_ERR_BAD_PARAMETER);
16995051Swyllys 
17005051Swyllys 	privkey = kmf_get_attr_ptr(KMF_PRIVKEY_HANDLE_ATTR, attlist, numattr);
17015051Swyllys 	if (privkey == NULL)
17025051Swyllys 		return (KMF_ERR_BAD_PARAMETER);
17035051Swyllys 
17045051Swyllys 	(void) memset(pubkey, 0, sizeof (KMF_KEY_HANDLE));
17055051Swyllys 	(void) memset(privkey, 0, sizeof (KMF_KEY_HANDLE));
17065051Swyllys 	if (keytype == KMF_RSA) {
170711973Swyllys.ingersoll@sun.com 		CK_BYTE *modulus = NULL;
17086354Swyllys 		CK_ULONG modulusLength = 0;
170911973Swyllys.ingersoll@sun.com 		KMF_BIGINT *rsaexp = NULL;
17103089Swyllys 		CK_ATTRIBUTE modattr[1];
17115051Swyllys 
17125051Swyllys 		rv = kmf_get_attr(KMF_KEYLENGTH_ATTR, attlist, numattr,
17135051Swyllys 		    &modulusBits, &modulusBits_size);
17145051Swyllys 		if (rv == KMF_ERR_ATTR_NOT_FOUND)
17155051Swyllys 			/* Default modulusBits = 1024 */
17165051Swyllys 			rv = KMF_OK;
17175051Swyllys 		if (rv != KMF_OK)
17185051Swyllys 			return (KMF_ERR_BAD_PARAMETER);
17195051Swyllys 
172011973Swyllys.ingersoll@sun.com 		rsaexp = kmf_get_attr_ptr(KMF_RSAEXP_ATTR, attlist, numattr);
172111973Swyllys.ingersoll@sun.com 
172211973Swyllys.ingersoll@sun.com 		/* Generate the RSA keypair */
172311973Swyllys.ingersoll@sun.com 		ckrv = genrsa_keypair(kmfh, modulusBits, storekey,
172411973Swyllys.ingersoll@sun.com 		    rsaexp, &pubKey, &priKey);
172511973Swyllys.ingersoll@sun.com 
172611973Swyllys.ingersoll@sun.com 		if (ckrv != CKR_OK)
172711973Swyllys.ingersoll@sun.com 			return (KMF_ERR_BAD_PARAMETER);
17283089Swyllys 
17295051Swyllys 		privkey->kstype = KMF_KEYSTORE_PK11TOKEN;
17305051Swyllys 		privkey->keyalg = KMF_RSA;
17315051Swyllys 		privkey->keyclass = KMF_ASYM_PRI;
17325051Swyllys 		privkey->keyp = (void *)priKey;
17335051Swyllys 
17345051Swyllys 		pubkey->kstype = KMF_KEYSTORE_PK11TOKEN;
17355051Swyllys 		pubkey->keyalg = KMF_RSA;
17365051Swyllys 		pubkey->keyclass = KMF_ASYM_PUB;
17375051Swyllys 		pubkey->keyp = (void *)pubKey;
17383089Swyllys 
17396354Swyllys 		SETATTR(modattr, 0, CKA_MODULUS, NULL, modulusLength);
17403089Swyllys 		/* Get the Modulus field to use as input for creating the ID */
17416354Swyllys 		ckrv = C_GetAttributeValue(kmfh->pk11handle,
17425051Swyllys 		    (CK_OBJECT_HANDLE)pubKey, modattr, 1);
17436354Swyllys 		if (ckrv != CKR_OK) {
17443089Swyllys 			SET_ERROR(kmfh, ckrv);
17453089Swyllys 			return (KMF_ERR_BAD_PARAMETER);
17463089Swyllys 		}
17473089Swyllys 
17483089Swyllys 		modulusLength = modattr[0].ulValueLen;
17493089Swyllys 		modulus = malloc(modulusLength);
17503089Swyllys 		if (modulus == NULL)
17513089Swyllys 			return (KMF_ERR_MEMORY);
17523089Swyllys 
17533089Swyllys 		modattr[0].pValue = modulus;
17546354Swyllys 		ckrv = C_GetAttributeValue(kmfh->pk11handle,
17555051Swyllys 		    (CK_OBJECT_HANDLE)pubKey, modattr, 1);
17566354Swyllys 		if (ckrv != CKR_OK) {
17573089Swyllys 			SET_ERROR(kmfh, ckrv);
17583089Swyllys 			free(modulus);
17593089Swyllys 			return (KMF_ERR_BAD_PARAMETER);
17603089Swyllys 		}
17613089Swyllys 
17623089Swyllys 		IDInput.Data = modulus;
17633089Swyllys 		IDInput.Length = modulusLength;
17643089Swyllys 
17655051Swyllys 	} else if (keytype == KMF_DSA) {
17663089Swyllys 		CK_BYTE *keyvalue;
17673089Swyllys 		CK_ULONG valueLen;
17683089Swyllys 		CK_ATTRIBUTE valattr[1];
17693089Swyllys 
177011973Swyllys.ingersoll@sun.com 		/* Generate the DSA keypair */
177111973Swyllys.ingersoll@sun.com 		ckrv = gendsa_keypair(kmfh, storekey, &pubKey, &priKey);
177211973Swyllys.ingersoll@sun.com 		if (ckrv != CKR_OK)
177311973Swyllys.ingersoll@sun.com 			return (KMF_ERR_BAD_PARAMETER);
17743089Swyllys 
17755051Swyllys 		privkey->kstype = KMF_KEYSTORE_PK11TOKEN;
17765051Swyllys 		privkey->keyalg = KMF_DSA;
17775051Swyllys 		privkey->keyclass = KMF_ASYM_PRI;
17785051Swyllys 		privkey->keyp = (void *)priKey;
17795051Swyllys 
17805051Swyllys 		pubkey->kstype = KMF_KEYSTORE_PK11TOKEN;
17815051Swyllys 		pubkey->keyalg = KMF_DSA;
17825051Swyllys 		pubkey->keyclass = KMF_ASYM_PUB;
17835051Swyllys 		pubkey->keyp = (void *)pubKey;
17845051Swyllys 
17853089Swyllys 		/* Get the Public Value to use as input for creating the ID */
178611973Swyllys.ingersoll@sun.com 		SETATTR(valattr, 0, CKA_VALUE, NULL, &valueLen);
178711973Swyllys.ingersoll@sun.com 
178811973Swyllys.ingersoll@sun.com 		ckrv = C_GetAttributeValue(hSession,
178911973Swyllys.ingersoll@sun.com 		    (CK_OBJECT_HANDLE)pubKey, valattr, 1);
179011973Swyllys.ingersoll@sun.com 		if (ckrv != CKR_OK) {
179111973Swyllys.ingersoll@sun.com 			SET_ERROR(kmfh, ckrv);
179211973Swyllys.ingersoll@sun.com 			return (KMF_ERR_BAD_PARAMETER);
179311973Swyllys.ingersoll@sun.com 		}
179411973Swyllys.ingersoll@sun.com 
179511973Swyllys.ingersoll@sun.com 		valueLen = valattr[0].ulValueLen;
179611973Swyllys.ingersoll@sun.com 		keyvalue = malloc(valueLen);
179711973Swyllys.ingersoll@sun.com 		if (keyvalue == NULL)
179811973Swyllys.ingersoll@sun.com 			return (KMF_ERR_MEMORY);
179911973Swyllys.ingersoll@sun.com 
180011973Swyllys.ingersoll@sun.com 		valattr[0].pValue = keyvalue;
180111973Swyllys.ingersoll@sun.com 		ckrv = C_GetAttributeValue(hSession,
180211973Swyllys.ingersoll@sun.com 		    (CK_OBJECT_HANDLE)pubKey, valattr, 1);
180311973Swyllys.ingersoll@sun.com 		if (ckrv != CKR_OK) {
180411973Swyllys.ingersoll@sun.com 			SET_ERROR(kmfh, ckrv);
180511973Swyllys.ingersoll@sun.com 			free(keyvalue);
180611973Swyllys.ingersoll@sun.com 			return (KMF_ERR_BAD_PARAMETER);
180711973Swyllys.ingersoll@sun.com 		}
180811973Swyllys.ingersoll@sun.com 
180911973Swyllys.ingersoll@sun.com 		IDInput.Data = keyvalue;
181011973Swyllys.ingersoll@sun.com 		IDInput.Length = valueLen;
181111973Swyllys.ingersoll@sun.com 	} else if (keytype == KMF_ECDSA) {
181211973Swyllys.ingersoll@sun.com 		CK_BYTE *keyvalue;
181311973Swyllys.ingersoll@sun.com 		CK_ULONG valueLen;
181411973Swyllys.ingersoll@sun.com 		CK_ATTRIBUTE valattr[1];
181511973Swyllys.ingersoll@sun.com 		KMF_OID *eccoid = kmf_get_attr_ptr(KMF_ECC_CURVE_OID_ATTR,
181611973Swyllys.ingersoll@sun.com 		    attlist, numattr);
181711973Swyllys.ingersoll@sun.com 
181811973Swyllys.ingersoll@sun.com 		if (eccoid == NULL)
181911973Swyllys.ingersoll@sun.com 			return (KMF_ERR_BAD_PARAMETER);
182011973Swyllys.ingersoll@sun.com 
182111973Swyllys.ingersoll@sun.com 		ckrv = genecc_keypair(kmfh, storekey, eccoid,
182211973Swyllys.ingersoll@sun.com 		    &pubKey, &priKey);
182311973Swyllys.ingersoll@sun.com 		if (ckrv != CKR_OK)
182411973Swyllys.ingersoll@sun.com 			return (KMF_ERR_BAD_PARAMETER);
182511973Swyllys.ingersoll@sun.com 
182611973Swyllys.ingersoll@sun.com 		privkey->kstype = KMF_KEYSTORE_PK11TOKEN;
182711973Swyllys.ingersoll@sun.com 		privkey->keyalg = KMF_ECDSA;
182811973Swyllys.ingersoll@sun.com 		privkey->keyclass = KMF_ASYM_PRI;
182911973Swyllys.ingersoll@sun.com 		privkey->keyp = (void *)priKey;
183011973Swyllys.ingersoll@sun.com 
183111973Swyllys.ingersoll@sun.com 		pubkey->kstype = KMF_KEYSTORE_PK11TOKEN;
183211973Swyllys.ingersoll@sun.com 		pubkey->keyalg = KMF_ECDSA;
183311973Swyllys.ingersoll@sun.com 		pubkey->keyclass = KMF_ASYM_PUB;
183411973Swyllys.ingersoll@sun.com 		pubkey->keyp = (void *)pubKey;
183511973Swyllys.ingersoll@sun.com 
183611973Swyllys.ingersoll@sun.com 		/* Get the EC_POINT to use as input for creating the ID */
183711973Swyllys.ingersoll@sun.com 		SETATTR(valattr, 0, CKA_EC_POINT, NULL, &valueLen);
183811973Swyllys.ingersoll@sun.com 
18396354Swyllys 		ckrv = C_GetAttributeValue(hSession,
18405051Swyllys 		    (CK_OBJECT_HANDLE)pubKey, valattr, 1);
18416354Swyllys 		if (ckrv != CKR_OK) {
18423089Swyllys 			SET_ERROR(kmfh, ckrv);
18433089Swyllys 			return (KMF_ERR_BAD_PARAMETER);
18443089Swyllys 		}
18453089Swyllys 
18463089Swyllys 		valueLen = valattr[0].ulValueLen;
18473089Swyllys 		keyvalue = malloc(valueLen);
18483089Swyllys 		if (keyvalue == NULL)
18493089Swyllys 			return (KMF_ERR_MEMORY);
18503089Swyllys 
18513089Swyllys 		valattr[0].pValue = keyvalue;
18526354Swyllys 		ckrv = C_GetAttributeValue(hSession,
18535051Swyllys 		    (CK_OBJECT_HANDLE)pubKey, valattr, 1);
18546354Swyllys 		if (ckrv != CKR_OK) {
18553089Swyllys 			SET_ERROR(kmfh, ckrv);
18563089Swyllys 			free(keyvalue);
18573089Swyllys 			return (KMF_ERR_BAD_PARAMETER);
18583089Swyllys 		}
18593089Swyllys 
18603089Swyllys 		IDInput.Data = keyvalue;
18613089Swyllys 		IDInput.Length = valueLen;
18623089Swyllys 	} else {
18633089Swyllys 		return (KMF_ERR_BAD_PARAMETER);
18643089Swyllys 	}
18653089Swyllys 
18665051Swyllys 	keylabel = kmf_get_attr_ptr(KMF_KEYLABEL_ATTR, attlist, numattr);
18675051Swyllys 	if (keylabel != NULL && strlen(keylabel)) {
18685051Swyllys 		SETATTR(labelattr, 0, CKA_LABEL, keylabel, strlen(keylabel));
18693089Swyllys 
18703089Swyllys 		/* Set the CKA_LABEL if one was indicated */
18713089Swyllys 		if ((ckrv = C_SetAttributeValue(hSession, pubKey,
18725051Swyllys 		    labelattr, 1)) != CKR_OK) {
18733089Swyllys 			SET_ERROR(kmfh, ckrv);
18743089Swyllys 			rv = KMF_ERR_INTERNAL;
18753089Swyllys 			goto cleanup;
18763089Swyllys 		}
18775051Swyllys 		pubkey->keylabel = (char *)strdup(keylabel);
18785051Swyllys 		if (pubkey->keylabel == NULL) {
18795051Swyllys 			rv = KMF_ERR_MEMORY;
18805051Swyllys 			goto cleanup;
18813089Swyllys 		}
18823089Swyllys 		if ((ckrv = C_SetAttributeValue(hSession, priKey,
18835051Swyllys 		    labelattr, 1)) != CKR_OK) {
18843089Swyllys 			SET_ERROR(kmfh, ckrv);
18853089Swyllys 			rv = KMF_ERR_INTERNAL;
18863089Swyllys 			goto cleanup;
18873089Swyllys 		}
18885051Swyllys 		privkey->keylabel = (char *)strdup(keylabel);
18895051Swyllys 		if (privkey->keylabel == NULL) {
18905051Swyllys 			rv = KMF_ERR_MEMORY;
18915051Swyllys 			goto cleanup;
18923089Swyllys 		}
18935051Swyllys 	} else {
18945051Swyllys 		rv = KMF_OK;
18953089Swyllys 	}
18963089Swyllys 
18973089Swyllys 	/* Now, assign a CKA_ID value so it can be searched */
18983089Swyllys 	/* ID_Input was assigned above in the RSA or DSA keygen section */
18993089Swyllys 	IDOutput.Data = (uchar_t *)IDHashData;
19003089Swyllys 	IDOutput.Length = sizeof (IDHashData);
19013089Swyllys 
19023825Swyllys 	SHA1Init(&ctx);
19033825Swyllys 	SHA1Update(&ctx, IDInput.Data, IDInput.Length);
19043825Swyllys 	SHA1Final(IDOutput.Data, &ctx);
19053825Swyllys 
19063825Swyllys 	IDOutput.Length = SHA1_DIGEST_LENGTH;
19073825Swyllys 
19083089Swyllys 	free(IDInput.Data);
19093089Swyllys 
19103089Swyllys 	if (rv != CKR_OK) {
19113089Swyllys 		goto cleanup;
19123089Swyllys 	}
19133089Swyllys 	SETATTR(idattr, 0, CKA_ID, IDOutput.Data, IDOutput.Length);
19143089Swyllys 	if ((ckrv = C_SetAttributeValue(hSession, pubKey,
19155051Swyllys 	    idattr, 1)) != CKR_OK) {
19163089Swyllys 		SET_ERROR(kmfh, ckrv);
19173089Swyllys 		rv = KMF_ERR_INTERNAL;
19183089Swyllys 		goto cleanup;
19193089Swyllys 	}
19203089Swyllys 	if ((ckrv = C_SetAttributeValue(hSession, priKey,
19215051Swyllys 	    idattr, 1)) != CKR_OK) {
19223089Swyllys 		SET_ERROR(kmfh, ckrv);
19233089Swyllys 		rv = KMF_ERR_INTERNAL;
19243089Swyllys 		goto cleanup;
19253089Swyllys 	}
19263089Swyllys 
19273089Swyllys cleanup:
19283089Swyllys 	if (rv != KMF_OK) {
19293089Swyllys 		if (pubKey != CK_INVALID_HANDLE)
19303089Swyllys 			(void) C_DestroyObject(hSession, pubKey);
19313089Swyllys 		if (priKey != CK_INVALID_HANDLE)
19323089Swyllys 			(void) C_DestroyObject(hSession, priKey);
19335051Swyllys 
19345051Swyllys 		if (privkey->keylabel)
19355051Swyllys 			free(privkey->keylabel);
19365051Swyllys 		if (pubkey->keylabel)
19375051Swyllys 			free(pubkey->keylabel);
19383089Swyllys 	}
19393089Swyllys 	return (rv);
19403089Swyllys }
19413089Swyllys 
19423089Swyllys KMF_RETURN
KMFPK11_DeleteKey(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)19435051Swyllys KMFPK11_DeleteKey(KMF_HANDLE_T handle,
19445051Swyllys 	int numattr, KMF_ATTRIBUTE *attrlist)
19453089Swyllys {
19463089Swyllys 	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
19473089Swyllys 	CK_RV ckrv = CKR_OK;
19483089Swyllys 	KMF_RETURN rv = KMF_OK;
19495051Swyllys 	KMF_KEY_HANDLE *key;
19505051Swyllys 	KMF_CREDENTIAL cred;
19515051Swyllys 	boolean_t destroy = B_TRUE;
19525051Swyllys 
19535051Swyllys 	if (kmfh == NULL)
19543089Swyllys 		return (KMF_ERR_UNINITIALIZED); /* Plugin Not Initialized */
19553089Swyllys 
19563089Swyllys 	if (kmfh->pk11handle == CK_INVALID_HANDLE)
19573089Swyllys 		return (KMF_ERR_NO_TOKEN_SELECTED);
19583089Swyllys 
19595051Swyllys 	key = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, numattr);
19603089Swyllys 	if (key == NULL || key->keyp == NULL)
19613089Swyllys 		return (KMF_ERR_BAD_PARAMETER);
19623089Swyllys 
19633089Swyllys 	if (key->keyclass != KMF_ASYM_PUB &&
19645051Swyllys 	    key->keyclass != KMF_ASYM_PRI &&
19655051Swyllys 	    key->keyclass != KMF_SYMMETRIC)
19663089Swyllys 		return (KMF_ERR_BAD_KEY_CLASS);
19673089Swyllys 
19685051Swyllys 	/* "destroy" is optional. Default is TRUE */
19695051Swyllys 	(void) kmf_get_attr(KMF_DESTROY_BOOL_ATTR, attrlist, numattr,
19705051Swyllys 	    (void *)&destroy, NULL);
19715051Swyllys 
19723089Swyllys 	if (destroy) {
19735051Swyllys 		rv = kmf_get_attr(KMF_CREDENTIAL_ATTR, attrlist, numattr,
19745051Swyllys 		    (void *)&cred, NULL);
19755051Swyllys 		if (rv != KMF_OK)
19765051Swyllys 			return (KMF_ERR_BAD_PARAMETER);
19775051Swyllys 
19785051Swyllys 		rv = pk11_authenticate(handle, &cred);
19793089Swyllys 		if (rv != KMF_OK) {
19803089Swyllys 			return (rv);
19813089Swyllys 		}
19823089Swyllys 	}
19833089Swyllys 
19843089Swyllys 	if (!key->israw && destroy)
19853089Swyllys 		ckrv = C_DestroyObject(kmfh->pk11handle,
19865051Swyllys 		    (CK_OBJECT_HANDLE)key->keyp);
19873089Swyllys 
19883089Swyllys 	if (ckrv != CKR_OK) {
19893089Swyllys 		SET_ERROR(kmfh, ckrv);
19903089Swyllys 		/* Report authentication failures to the caller */
19915051Swyllys 		if (ckrv == CKR_PIN_EXPIRED || ckrv == CKR_SESSION_READ_ONLY)
19923089Swyllys 			rv = KMF_ERR_AUTH_FAILED;
19933089Swyllys 		else
19943089Swyllys 			rv = KMF_ERR_INTERNAL;
19953089Swyllys 	}
19963089Swyllys 	return (rv);
19973089Swyllys }
19983089Swyllys 
19993089Swyllys KMF_RETURN
KMFPK11_SignData(KMF_HANDLE_T handle,KMF_KEY_HANDLE * keyp,KMF_OID * algOID,KMF_DATA * tobesigned,KMF_DATA * output)20003089Swyllys KMFPK11_SignData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *keyp,
20013089Swyllys 	KMF_OID *algOID,
20023089Swyllys 	KMF_DATA *tobesigned,
20033089Swyllys 	KMF_DATA *output)
20043089Swyllys {
200511973Swyllys.ingersoll@sun.com 	KMF_RETURN		rv = KMF_OK;
20063089Swyllys 	CK_RV			ckrv;
20073089Swyllys 	KMF_HANDLE		*kmfh = (KMF_HANDLE *)handle;
20083089Swyllys 	CK_SESSION_HANDLE	hSession = kmfh->pk11handle;
20093089Swyllys 	CK_MECHANISM		mechanism;
201011973Swyllys.ingersoll@sun.com 	CK_MECHANISM_TYPE	mechtype, hashmech;
201111973Swyllys.ingersoll@sun.com 	CK_KEY_TYPE		keytype;
20125051Swyllys 	KMF_ALGORITHM_INDEX	AlgId;
201311973Swyllys.ingersoll@sun.com 	KMF_DATA		hashData = {NULL, 0};
201411973Swyllys.ingersoll@sun.com 	uchar_t			digest[1024];
201511973Swyllys.ingersoll@sun.com 	CK_ATTRIBUTE		subprime = { CKA_SUBPRIME, NULL, 0 };
20165051Swyllys 
20175051Swyllys 	if (kmfh == NULL)
20183089Swyllys 		return (KMF_ERR_UNINITIALIZED); /* Plugin Not Initialized */
20193089Swyllys 
20203089Swyllys 	if (kmfh->pk11handle == CK_INVALID_HANDLE)
20213089Swyllys 		return (KMF_ERR_NO_TOKEN_SELECTED);
20223089Swyllys 
20233089Swyllys 	if (keyp == NULL || algOID == NULL ||
20243089Swyllys 	    tobesigned == NULL || output == NULL)
20253089Swyllys 		return (KMF_ERR_BAD_PARAMETER);
20263089Swyllys 
20273089Swyllys 	/* These functions are available to the plugin from libkmf */
20285051Swyllys 	AlgId = x509_algoid_to_algid(algOID);
20293089Swyllys 	if (AlgId == KMF_ALGID_NONE)
20303089Swyllys 		return (KMF_ERR_BAD_PARAMETER);
20313089Swyllys 
203211973Swyllys.ingersoll@sun.com 	/* Get the PKCS11 signing key type and mechtype */
203311973Swyllys.ingersoll@sun.com 	if (get_pk11_data(AlgId, &keytype, &mechtype, &hashmech, 0))
20343089Swyllys 		return (KMF_ERR_BAD_PARAMETER);
20353089Swyllys 
203611973Swyllys.ingersoll@sun.com 	(void) memset(digest, 0, sizeof (digest));
203711973Swyllys.ingersoll@sun.com 	hashData.Data = digest;
203811973Swyllys.ingersoll@sun.com 	hashData.Length = sizeof (digest);
203911973Swyllys.ingersoll@sun.com 	rv = PKCS_DigestData(handle, hSession, hashmech, tobesigned, &hashData,
204011973Swyllys.ingersoll@sun.com 	    (mechtype == CKM_RSA_PKCS));
204111973Swyllys.ingersoll@sun.com 	if (rv)
204211973Swyllys.ingersoll@sun.com 		return (rv);
204311973Swyllys.ingersoll@sun.com 
204411973Swyllys.ingersoll@sun.com 	if (mechtype == CKM_DSA && hashmech == CKM_SHA256) {
204511973Swyllys.ingersoll@sun.com 		/*
204611973Swyllys.ingersoll@sun.com 		 * FIPS 186-3 says that when signing with DSA
204711973Swyllys.ingersoll@sun.com 		 * the hash must be truncated to the size of the
204811973Swyllys.ingersoll@sun.com 		 * subprime.
204911973Swyllys.ingersoll@sun.com 		 */
205011973Swyllys.ingersoll@sun.com 		ckrv = C_GetAttributeValue(hSession,
205111973Swyllys.ingersoll@sun.com 		    (CK_OBJECT_HANDLE)keyp->keyp,
205211973Swyllys.ingersoll@sun.com 		    &subprime, 1);
205311973Swyllys.ingersoll@sun.com 		if (ckrv != CKR_OK)  {
205411973Swyllys.ingersoll@sun.com 			SET_ERROR(kmfh, ckrv);
205511973Swyllys.ingersoll@sun.com 			return (KMF_ERR_INTERNAL);
205611973Swyllys.ingersoll@sun.com 		}
205711973Swyllys.ingersoll@sun.com 		hashData.Length = subprime.ulValueLen;
205811973Swyllys.ingersoll@sun.com 	}
205911973Swyllys.ingersoll@sun.com 
206011973Swyllys.ingersoll@sun.com 	/* the mechtype from the 'get_pk11_info' refers to the signing */
206111973Swyllys.ingersoll@sun.com 	mechanism.mechanism = mechtype;
20623089Swyllys 	mechanism.pParameter = NULL;
20633089Swyllys 	mechanism.ulParameterLen = 0;
20643089Swyllys 
20653089Swyllys 	ckrv = C_SignInit(hSession, &mechanism, (CK_OBJECT_HANDLE)keyp->keyp);
20663089Swyllys 	if (ckrv != CKR_OK) {
20673089Swyllys 		SET_ERROR(kmfh, ckrv);
20683089Swyllys 		return (KMF_ERR_INTERNAL);
20693089Swyllys 	}
20703089Swyllys 
207111973Swyllys.ingersoll@sun.com 	ckrv = C_Sign(hSession,	hashData.Data, hashData.Length,
20725051Swyllys 	    output->Data, (CK_ULONG *)&output->Length);
20733089Swyllys 
20743089Swyllys 	if (ckrv != CKR_OK) {
20753089Swyllys 		SET_ERROR(kmfh, ckrv);
20763089Swyllys 		return (KMF_ERR_INTERNAL);
20773089Swyllys 	}
20783089Swyllys 
20793089Swyllys 	return (KMF_OK);
20803089Swyllys }
20813089Swyllys 
20823089Swyllys KMF_RETURN
KMFPK11_GetErrorString(KMF_HANDLE_T handle,char ** msgstr)20833089Swyllys KMFPK11_GetErrorString(KMF_HANDLE_T handle, char **msgstr)
20843089Swyllys {
20853089Swyllys 	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
20863089Swyllys 
20873089Swyllys 	*msgstr = NULL;
20883089Swyllys 	if (kmfh->lasterr.errcode != 0) {
20893089Swyllys 		char *e = pkcs11_strerror(kmfh->lasterr.errcode);
20903089Swyllys 		if (e == NULL || (*msgstr = (char *)strdup(e)) == NULL) {
20913089Swyllys 			return (KMF_ERR_MEMORY);
20923089Swyllys 		}
20933089Swyllys 	}
20943089Swyllys 
20953089Swyllys 	return (KMF_OK);
20963089Swyllys }
20973089Swyllys 
20983089Swyllys static CK_RV
getObjectKeytype(KMF_HANDLE_T handle,CK_OBJECT_HANDLE obj,CK_ULONG * keytype)20993089Swyllys getObjectKeytype(KMF_HANDLE_T handle, CK_OBJECT_HANDLE obj,
21003089Swyllys 	CK_ULONG *keytype)
21013089Swyllys {
21023089Swyllys 	CK_RV rv = CKR_OK;
21033089Swyllys 	CK_ATTRIBUTE templ;
21043089Swyllys 	CK_ULONG len = sizeof (CK_ULONG);
21053089Swyllys 	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
21063089Swyllys 
21073089Swyllys 	templ.type = CKA_KEY_TYPE;
21083089Swyllys 	templ.pValue = keytype;
21093089Swyllys 	templ.ulValueLen = len;
21103089Swyllys 
21113089Swyllys 	rv = C_GetAttributeValue(kmfh->pk11handle, obj, &templ, 1);
21123089Swyllys 
21133089Swyllys 	return (rv);
21143089Swyllys 
21153089Swyllys }
21165128Swyllys 
21173089Swyllys static CK_RV
getObjectLabel(KMF_HANDLE_T handle,CK_OBJECT_HANDLE obj,char ** outlabel)21183089Swyllys getObjectLabel(KMF_HANDLE_T handle, CK_OBJECT_HANDLE obj,
21193089Swyllys 	char **outlabel)
21203089Swyllys {
21213089Swyllys 	CK_RV rv = CKR_OK;
21223089Swyllys 	CK_ATTRIBUTE templ;
21233089Swyllys 	char	Label[BUFSIZ];
21243089Swyllys 	CK_ULONG len = sizeof (Label);
21253089Swyllys 	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
21263089Swyllys 
21273089Swyllys 	(void) memset(Label, 0, len);
21283089Swyllys 	templ.type = CKA_LABEL;
21293089Swyllys 	templ.pValue = Label;
21303089Swyllys 	templ.ulValueLen = len;
21313089Swyllys 
21323089Swyllys 	rv = C_GetAttributeValue(kmfh->pk11handle, obj, &templ, 1);
21333089Swyllys 	if (rv == CKR_OK) {
21343089Swyllys 		*outlabel = (char *)strdup(Label);
21353089Swyllys 	} else {
21363089Swyllys 		*outlabel = NULL;
21373089Swyllys 	}
21383089Swyllys 	return (rv);
21393089Swyllys }
21403089Swyllys 
21415128Swyllys static CK_RV
getObjectKeyclass(KMF_HANDLE_T handle,CK_OBJECT_HANDLE obj,KMF_KEY_CLASS * keyclass)21425128Swyllys getObjectKeyclass(KMF_HANDLE_T handle, CK_OBJECT_HANDLE obj,
21435128Swyllys 	KMF_KEY_CLASS *keyclass)
21445128Swyllys {
21455128Swyllys 	CK_RV rv = CKR_OK;
21465128Swyllys 	CK_ATTRIBUTE templ;
21475128Swyllys 	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
21485128Swyllys 	CK_OBJECT_CLASS class;
21495128Swyllys 
21505128Swyllys 	templ.type = CKA_CLASS;
21515128Swyllys 	templ.pValue = &class;
21525128Swyllys 	templ.ulValueLen = sizeof (CK_OBJECT_CLASS);
21535128Swyllys 
21545128Swyllys 	rv = C_GetAttributeValue(kmfh->pk11handle, obj, &templ, 1);
21555128Swyllys 	if (rv == CKR_OK) {
21565128Swyllys 		if (class == CKO_PUBLIC_KEY) {
21575128Swyllys 			*keyclass = KMF_ASYM_PUB;
21585128Swyllys 		} else if (class == CKO_PRIVATE_KEY) {
21595128Swyllys 			*keyclass = KMF_ASYM_PRI;
21605128Swyllys 		} else if (class == CKO_SECRET_KEY) {
21615128Swyllys 			*keyclass = KMF_SYMMETRIC;
21625128Swyllys 		}
21635128Swyllys 	} else {
21645128Swyllys 		*keyclass = KMF_KEYCLASS_NONE;
21655128Swyllys 	}
21665128Swyllys 	return (rv);
21675128Swyllys }
21685051Swyllys 
21693089Swyllys KMF_RETURN
KMFPK11_FindPrikeyByCert(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)21705051Swyllys KMFPK11_FindPrikeyByCert(KMF_HANDLE_T handle, int numattr,
21715051Swyllys     KMF_ATTRIBUTE *attrlist)
21723089Swyllys {
21733089Swyllys 	KMF_X509_SPKI *pubkey;
21743089Swyllys 	KMF_X509_CERTIFICATE *SignerCert = NULL;
21753089Swyllys 	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
21763089Swyllys 	KMF_RETURN rv = KMF_OK;
21773089Swyllys 	CK_RV ckrv = CKR_OK;
21783089Swyllys 	CK_ATTRIBUTE templ[4];
21793089Swyllys 	CK_OBJECT_HANDLE pri_obj = CK_INVALID_HANDLE;
21803089Swyllys 	CK_ULONG obj_count;
2181*12234Swyllys.ingersoll@sun.com 	CK_OBJECT_CLASS objClass = CKO_PRIVATE_KEY;
21823089Swyllys 	CK_BBOOL true = TRUE;
21833089Swyllys 	KMF_DATA Id = { NULL, 0 };
21845051Swyllys 	KMF_KEY_HANDLE *key = NULL;
21855051Swyllys 	KMF_DATA *cert = NULL;
21865051Swyllys 	KMF_CREDENTIAL cred;
21875051Swyllys 	KMF_ENCODE_FORMAT format = KMF_FORMAT_UNDEF;
21885051Swyllys 	CK_ULONG keytype;
21895051Swyllys 
21905051Swyllys 	/* Get the key handle */
21915051Swyllys 	key = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, numattr);
21925051Swyllys 	if (key == NULL)
21935051Swyllys 		return (KMF_ERR_BAD_PARAMETER);
21945051Swyllys 
21955051Swyllys 	/* Get the optional encoded format */
21965051Swyllys 	(void) kmf_get_attr(KMF_ENCODE_FORMAT_ATTR, attrlist, numattr,
21975051Swyllys 	    (void *)&format, NULL);
21983089Swyllys 
21993089Swyllys 	/* Decode the signer cert so we can get the SPKI data */
22005051Swyllys 	cert = kmf_get_attr_ptr(KMF_CERT_DATA_ATTR, attrlist, numattr);
22015051Swyllys 	if (cert == NULL || cert->Data == NULL)
22025051Swyllys 		return (KMF_ERR_BAD_PARAMETER);
22035051Swyllys 
22045051Swyllys 	if ((rv = DerDecodeSignedCertificate(cert,
22053089Swyllys 	    &SignerCert)) != KMF_OK)
22063089Swyllys 		return (rv);
22073089Swyllys 
22083089Swyllys 	/* Get the public key info from the signer certificate */
22093089Swyllys 	pubkey = &SignerCert->certificate.subjectPublicKeyInfo;
22103089Swyllys 
22113089Swyllys 	/* Generate an ID from the SPKI data */
22123089Swyllys 	rv = GetIDFromSPKI(pubkey, &Id);
22133089Swyllys 	if (rv != KMF_OK) {
22143089Swyllys 		goto errout;
22153089Swyllys 	}
22163089Swyllys 
22175051Swyllys 	/* Get the credential and login */
22185051Swyllys 	rv = kmf_get_attr(KMF_CREDENTIAL_ATTR, attrlist, numattr,
22195051Swyllys 	    (void *)&cred, NULL);
22205051Swyllys 	if (rv != KMF_OK)
22215051Swyllys 		return (KMF_ERR_BAD_PARAMETER);
22225051Swyllys 
22235051Swyllys 	rv = pk11_authenticate(handle, &cred);
22245051Swyllys 	if (rv != KMF_OK) {
22255051Swyllys 		return (rv);
22265051Swyllys 	}
22275051Swyllys 
22285051Swyllys 	/* Start searching */
2229*12234Swyllys.ingersoll@sun.com 	SETATTR(templ, 0, CKA_CLASS, &objClass, sizeof (objClass));
22303089Swyllys 	SETATTR(templ, 1, CKA_TOKEN, &true, sizeof (true));
22313089Swyllys 	SETATTR(templ, 2, CKA_PRIVATE, &true, sizeof (true));
22323089Swyllys 	SETATTR(templ, 3, CKA_ID, Id.Data, Id.Length);
22333089Swyllys 
22343089Swyllys 	if ((ckrv = C_FindObjectsInit(kmfh->pk11handle, templ, 4)) != CKR_OK) {
22353089Swyllys 		SET_ERROR(kmfh, ckrv);
22363089Swyllys 		rv = KMF_ERR_INTERNAL;
22373089Swyllys 		goto errout;
22383089Swyllys 	}
22393089Swyllys 
22406354Swyllys 	if ((ckrv = C_FindObjects(kmfh->pk11handle, &pri_obj, 1,
22413089Swyllys 	    &obj_count)) != CKR_OK) {
22423089Swyllys 		SET_ERROR(kmfh, ckrv);
22433089Swyllys 		rv = KMF_ERR_INTERNAL;
22443089Swyllys 		goto errout;
22453089Swyllys 	}
22463089Swyllys 
22473089Swyllys 	if (obj_count == 0) {
22483089Swyllys 		SET_ERROR(kmfh, ckrv);
2249*12234Swyllys.ingersoll@sun.com 		rv = KMF_ERR_KEY_NOT_FOUND;
22503089Swyllys 		goto errout;
22513089Swyllys 	}
22523089Swyllys 
22533089Swyllys 	key->kstype = KMF_KEYSTORE_PK11TOKEN;
22543089Swyllys 	key->keyclass = KMF_ASYM_PRI;
22553089Swyllys 	key->keyp = (void *)pri_obj;
22565051Swyllys 	key->israw = FALSE;
22573089Swyllys 
22583089Swyllys 	(void) C_FindObjectsFinal(kmfh->pk11handle);
22593089Swyllys 
22603089Swyllys 	ckrv = getObjectLabel(handle, (CK_OBJECT_HANDLE)key->keyp,
22615051Swyllys 	    &key->keylabel);
22623089Swyllys 	if (ckrv != CKR_OK) {
22633089Swyllys 		SET_ERROR(handle, ckrv);
22643089Swyllys 		rv = KMF_ERR_INTERNAL;
22653089Swyllys 	} else {
22663089Swyllys 		rv = KMF_OK;
22673089Swyllys 	}
22683089Swyllys 
22695051Swyllys 	/*
22705051Swyllys 	 * The key->keyalg value is needed if we need to convert the key
22715051Swyllys 	 * to raw key.  However, the key->keyalg value will not be set if
22725051Swyllys 	 * this function is not called thru the kmf_find_prikey_by_cert()
22735051Swyllys 	 * framework function. To be safe, we will get the keytype from
22745051Swyllys 	 * the key object and set key->keyalg value here.
22755051Swyllys 	 */
22765051Swyllys 	ckrv = getObjectKeytype(handle, (CK_OBJECT_HANDLE)key->keyp,
22775051Swyllys 	    &keytype);
22785051Swyllys 	if (ckrv != CKR_OK) {
22795051Swyllys 		SET_ERROR(handle, ckrv);
22805051Swyllys 		rv = KMF_ERR_INTERNAL;
22815051Swyllys 	} else {
22825051Swyllys 		rv = KMF_OK;
22835051Swyllys 	}
22845051Swyllys 
22855051Swyllys 	if (keytype == CKK_RSA)
22865051Swyllys 		key->keyalg = KMF_RSA;
22875051Swyllys 	else if (keytype == CKK_DSA)
22885051Swyllys 		key->keyalg = KMF_DSA;
228911973Swyllys.ingersoll@sun.com 	else if (keytype == CKK_EC)
229011973Swyllys.ingersoll@sun.com 		key->keyalg = KMF_ECDSA;
22915051Swyllys 	else {
22925051Swyllys 		/* For asymmetric keys, we only support RSA and DSA */
22935051Swyllys 		rv = KMF_ERR_KEY_NOT_FOUND;
22945051Swyllys 		goto errout;
22955051Swyllys 	}
22965051Swyllys 
22975051Swyllys 	if (rv == KMF_OK && format == KMF_FORMAT_RAWKEY) {
22983089Swyllys 		KMF_RAW_KEY_DATA *rkey = NULL;
22993089Swyllys 		rv = keyObj2RawKey(handle, key, &rkey);
23003089Swyllys 		if (rv == KMF_OK) {
23013089Swyllys 			key->keyp = rkey;
23023089Swyllys 			key->israw = TRUE;
23033089Swyllys 		}
23043089Swyllys 	}
23053089Swyllys 
23063089Swyllys errout:
23073089Swyllys 	if (Id.Data != NULL)
23083089Swyllys 		free(Id.Data);
23093089Swyllys 
23103089Swyllys 	if (SignerCert != NULL) {
23115051Swyllys 		kmf_free_signed_cert(SignerCert);
23123089Swyllys 		free(SignerCert);
23133089Swyllys 	}
23143089Swyllys 	return (rv);
23153089Swyllys }
23163089Swyllys 
23173089Swyllys KMF_RETURN
KMFPK11_DecryptData(KMF_HANDLE_T handle,KMF_KEY_HANDLE * key,KMF_OID * algOID,KMF_DATA * ciphertext,KMF_DATA * output)23183089Swyllys KMFPK11_DecryptData(KMF_HANDLE_T handle, KMF_KEY_HANDLE *key,
23193089Swyllys 	KMF_OID *algOID, KMF_DATA *ciphertext,
23203089Swyllys 	KMF_DATA *output)
23213089Swyllys {
23223089Swyllys 	CK_RV			ckrv;
23233089Swyllys 	KMF_HANDLE		*kmfh = (KMF_HANDLE *)handle;
23243089Swyllys 	CK_SESSION_HANDLE	hSession = kmfh->pk11handle;
23253089Swyllys 	CK_MECHANISM		mechanism;
232611973Swyllys.ingersoll@sun.com 	CK_MECHANISM_TYPE	mechtype;
232711973Swyllys.ingersoll@sun.com 	CK_KEY_TYPE		keytype;
23283089Swyllys 	KMF_ALGORITHM_INDEX	AlgId;
23293089Swyllys 	CK_ULONG out_len = 0, block_len = 0, total_decrypted = 0;
23303089Swyllys 	uint8_t *in_data, *out_data;
23313089Swyllys 	int i, blocks;
23323089Swyllys 	CK_ATTRIBUTE ckTemplate[1];
23333089Swyllys 
23345051Swyllys 	if (kmfh == NULL)
23353089Swyllys 		return (KMF_ERR_UNINITIALIZED); /* Plugin Not Initialized */
23363089Swyllys 
23373089Swyllys 	if (kmfh->pk11handle == CK_INVALID_HANDLE)
23383089Swyllys 		return (KMF_ERR_NO_TOKEN_SELECTED);
23393089Swyllys 
23403089Swyllys 	if (key == NULL || algOID == NULL ||
23413089Swyllys 	    ciphertext == NULL || output == NULL)
23423089Swyllys 		return (KMF_ERR_BAD_PARAMETER);
23433089Swyllys 
23445051Swyllys 	AlgId = x509_algoid_to_algid(algOID);
23453089Swyllys 	if (AlgId == KMF_ALGID_NONE)
23463089Swyllys 		return (KMF_ERR_BAD_PARAMETER);
23473089Swyllys 
23483089Swyllys 	/* Map the Algorithm ID to a PKCS#11 mechanism */
234911973Swyllys.ingersoll@sun.com 	if (get_pk11_data(AlgId, &keytype, &mechtype, NULL, 0))
23503089Swyllys 		return (KMF_ERR_BAD_PARAMETER);
23513089Swyllys 
235211973Swyllys.ingersoll@sun.com 	mechanism.mechanism = mechtype;
23533089Swyllys 	mechanism.pParameter = NULL;
23543089Swyllys 	mechanism.ulParameterLen = 0;
23553089Swyllys 
23563089Swyllys 	SETATTR(ckTemplate, 0, CKA_MODULUS, (CK_BYTE *)NULL,
23573089Swyllys 	    sizeof (CK_ULONG));
23583089Swyllys 
23593089Swyllys 	/* Get the modulus length */
23603089Swyllys 	ckrv = C_GetAttributeValue(hSession,
23613089Swyllys 	    (CK_OBJECT_HANDLE)key->keyp, ckTemplate, 1);
23623089Swyllys 
23633089Swyllys 	if (ckrv != CKR_OK)  {
23643089Swyllys 		SET_ERROR(kmfh, ckrv);
23653089Swyllys 		return (KMF_ERR_INTERNAL);
23663089Swyllys 	}
23673089Swyllys 
23683089Swyllys 	block_len = ckTemplate[0].ulValueLen;
23693089Swyllys 
23703089Swyllys 	/* Compute the number of times to do single-part decryption */
23713089Swyllys 	blocks = ciphertext->Length/block_len;
23723089Swyllys 
23733089Swyllys 	out_data = output->Data;
23743089Swyllys 	in_data = ciphertext->Data;
23753089Swyllys 	out_len = block_len - 11;
23763089Swyllys 
23773089Swyllys 	for (i = 0; i < blocks; i++) {
23783089Swyllys 		ckrv = C_DecryptInit(hSession, &mechanism,
23795051Swyllys 		    (CK_OBJECT_HANDLE)key->keyp);
23803089Swyllys 
23813089Swyllys 		if (ckrv != CKR_OK) {
23823089Swyllys 			SET_ERROR(kmfh, ckrv);
23833089Swyllys 			return (KMF_ERR_INTERNAL);
23843089Swyllys 		}
23853089Swyllys 
23863089Swyllys 		ckrv = C_Decrypt(hSession, in_data, block_len,
23873089Swyllys 		    out_data, (CK_ULONG *)&out_len);
23883089Swyllys 
23893089Swyllys 		if (ckrv != CKR_OK) {
23903089Swyllys 			SET_ERROR(kmfh, ckrv);
23913089Swyllys 			return (KMF_ERR_INTERNAL);
23923089Swyllys 		}
23933089Swyllys 
23943089Swyllys 		out_data += out_len;
23953089Swyllys 		total_decrypted += out_len;
23963089Swyllys 		in_data += block_len;
23973089Swyllys 
23983089Swyllys 	}
23993089Swyllys 
24003089Swyllys 	output->Length = total_decrypted;
24013089Swyllys 	return (KMF_OK);
24023089Swyllys }
24033089Swyllys 
24043089Swyllys static void
attr2bigint(CK_ATTRIBUTE_PTR attr,KMF_BIGINT * big)24053089Swyllys attr2bigint(CK_ATTRIBUTE_PTR attr, KMF_BIGINT *big)
24063089Swyllys {
24073089Swyllys 	big->val = attr->pValue;
24083089Swyllys 	big->len = attr->ulValueLen;
24093089Swyllys }
24103089Swyllys 
24115637Swyllys static KMF_RETURN
get_bigint_attr(CK_SESSION_HANDLE sess,CK_OBJECT_HANDLE obj,CK_ATTRIBUTE_TYPE attrtype,KMF_BIGINT * bigint)24125637Swyllys get_bigint_attr(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj,
24135637Swyllys 	CK_ATTRIBUTE_TYPE attrtype, KMF_BIGINT *bigint)
24145637Swyllys {
24155637Swyllys 	CK_RV ckrv;
24165637Swyllys 	CK_ATTRIBUTE attr;
24175637Swyllys 
24185637Swyllys 	attr.type = attrtype;
24195637Swyllys 	attr.pValue = NULL;
24205637Swyllys 	attr.ulValueLen = 0;
24215637Swyllys 
24225637Swyllys 	if ((ckrv = C_GetAttributeValue(sess, obj,
24235637Swyllys 	    &attr, 1)) != CKR_OK) {
24245637Swyllys 		/* Mask this error so the caller can continue */
24255637Swyllys 		if (ckrv == CKR_ATTRIBUTE_TYPE_INVALID)
24265637Swyllys 			return (KMF_OK);
24275637Swyllys 		else
24285637Swyllys 			return (KMF_ERR_INTERNAL);
24295637Swyllys 	}
24305637Swyllys 	if (attr.ulValueLen > 0 && bigint != NULL) {
24315637Swyllys 		attr.pValue = malloc(attr.ulValueLen);
24325637Swyllys 		if (attr.pValue == NULL)
24335637Swyllys 			return (KMF_ERR_MEMORY);
24345637Swyllys 
24355637Swyllys 		if ((ckrv = C_GetAttributeValue(sess, obj,
24365637Swyllys 		    &attr, 1)) != CKR_OK)
24375637Swyllys 		if (ckrv != CKR_OK) {
24385637Swyllys 			free(attr.pValue);
24395637Swyllys 			return (KMF_ERR_INTERNAL);
24405637Swyllys 		}
24415637Swyllys 
24425637Swyllys 		bigint->val = attr.pValue;
24435637Swyllys 		bigint->len = attr.ulValueLen;
24445637Swyllys 	}
24455637Swyllys 	return (KMF_OK);
24465637Swyllys }
24473089Swyllys 
24483089Swyllys static KMF_RETURN
get_raw_rsa(KMF_HANDLE * kmfh,CK_OBJECT_HANDLE obj,KMF_RAW_RSA_KEY * rawrsa)24493089Swyllys get_raw_rsa(KMF_HANDLE *kmfh, CK_OBJECT_HANDLE obj, KMF_RAW_RSA_KEY *rawrsa)
24503089Swyllys {
24513089Swyllys 	KMF_RETURN rv = KMF_OK;
24523408Swyllys 	CK_RV ckrv;
24533089Swyllys 	CK_SESSION_HANDLE sess = kmfh->pk11handle;
24545637Swyllys 	CK_ATTRIBUTE rsa_pri_attrs[2] = {
24553089Swyllys 		{ CKA_MODULUS, NULL, 0 },
24565637Swyllys 		{ CKA_PUBLIC_EXPONENT, NULL, 0 }
24575637Swyllys 	};
24585051Swyllys 	CK_ULONG count = sizeof (rsa_pri_attrs) / sizeof (CK_ATTRIBUTE);
24595051Swyllys 	int i;
24603089Swyllys 
24615637Swyllys 	if (rawrsa == NULL)
24625637Swyllys 		return (KMF_ERR_BAD_PARAMETER);
24635637Swyllys 
24645637Swyllys 	(void) memset(rawrsa, 0, sizeof (KMF_RAW_RSA_KEY));
24653408Swyllys 	if ((ckrv = C_GetAttributeValue(sess, obj,
24665051Swyllys 	    rsa_pri_attrs, count)) != CKR_OK) {
24673408Swyllys 		SET_ERROR(kmfh, ckrv);
24683408Swyllys 		/* Tell the caller know why the key data cannot be retrieved. */
24693408Swyllys 		if (ckrv == CKR_ATTRIBUTE_SENSITIVE)
24703408Swyllys 			return (KMF_ERR_SENSITIVE_KEY);
24713408Swyllys 		else if (ckrv == CKR_KEY_UNEXTRACTABLE)
24723408Swyllys 			return (KMF_ERR_UNEXTRACTABLE_KEY);
24733408Swyllys 		else
24743408Swyllys 			return (KMF_ERR_INTERNAL);
24753089Swyllys 	}
24763089Swyllys 
24773089Swyllys 	/* Allocate memory for each attribute. */
24783089Swyllys 	for (i = 0; i < count; i++) {
24793089Swyllys 		if (rsa_pri_attrs[i].ulValueLen == (CK_ULONG)-1 ||
24803089Swyllys 		    rsa_pri_attrs[i].ulValueLen == 0) {
24813089Swyllys 			rsa_pri_attrs[i].ulValueLen = 0;
24823089Swyllys 			continue;
24833089Swyllys 		}
24843089Swyllys 		if ((rsa_pri_attrs[i].pValue =
24853089Swyllys 		    malloc(rsa_pri_attrs[i].ulValueLen)) == NULL) {
24863089Swyllys 			rv = KMF_ERR_MEMORY;
24873089Swyllys 			goto end;
24883089Swyllys 		}
24893089Swyllys 	}
24903089Swyllys 	/* Now that we have space, really get the attributes */
24916354Swyllys 	if ((ckrv = C_GetAttributeValue(sess, obj,
24925051Swyllys 	    rsa_pri_attrs, count)) != CKR_OK) {
24936354Swyllys 		SET_ERROR(kmfh, ckrv);
24943089Swyllys 		rv = KMF_ERR_INTERNAL;
24953089Swyllys 		goto end;
24963089Swyllys 	}
24973089Swyllys 	i = 0;
24983089Swyllys 	attr2bigint(&(rsa_pri_attrs[i++]), &rawrsa->mod);
24993089Swyllys 	attr2bigint(&(rsa_pri_attrs[i++]), &rawrsa->pubexp);
25003089Swyllys 
25015637Swyllys 	/* Now get the optional parameters */
25025637Swyllys 	rv = get_bigint_attr(sess, obj, CKA_PRIVATE_EXPONENT, &rawrsa->priexp);
25035637Swyllys 	if (rv != KMF_OK)
25045637Swyllys 		goto end;
25055637Swyllys 	rv = get_bigint_attr(sess, obj, CKA_PRIME_1, &rawrsa->prime1);
25065637Swyllys 	if (rv != KMF_OK)
25075637Swyllys 		goto end;
25085637Swyllys 	rv = get_bigint_attr(sess, obj, CKA_PRIME_2, &rawrsa->prime2);
25095637Swyllys 	if (rv != KMF_OK)
25105637Swyllys 		goto end;
25115637Swyllys 	rv = get_bigint_attr(sess, obj, CKA_EXPONENT_1, &rawrsa->exp1);
25125637Swyllys 	if (rv != KMF_OK)
25135637Swyllys 		goto end;
25145637Swyllys 	rv = get_bigint_attr(sess, obj, CKA_EXPONENT_2, &rawrsa->exp2);
25155637Swyllys 	if (rv != KMF_OK)
25165637Swyllys 		goto end;
25175637Swyllys 	rv = get_bigint_attr(sess, obj, CKA_COEFFICIENT, &rawrsa->coef);
25185637Swyllys 	if (rv != KMF_OK)
25195637Swyllys 		goto end;
25203089Swyllys 
25213089Swyllys end:
25223089Swyllys 	if (rv != KMF_OK) {
25233089Swyllys 		for (i = 0; i < count; i++) {
25243089Swyllys 			if (rsa_pri_attrs[i].pValue != NULL)
25253089Swyllys 				free(rsa_pri_attrs[i].pValue);
25263089Swyllys 		}
25275637Swyllys 		if (rawrsa->priexp.val)
25285637Swyllys 			free(rawrsa->priexp.val);
25295637Swyllys 		if (rawrsa->prime1.val)
25305637Swyllys 			free(rawrsa->prime1.val);
25315637Swyllys 		if (rawrsa->prime2.val)
25325637Swyllys 			free(rawrsa->prime2.val);
25335637Swyllys 		if (rawrsa->exp1.val)
25345637Swyllys 			free(rawrsa->exp1.val);
25355637Swyllys 		if (rawrsa->exp2.val)
25365637Swyllys 			free(rawrsa->exp2.val);
25375637Swyllys 		if (rawrsa->coef.val)
25385637Swyllys 			free(rawrsa->coef.val);
25393089Swyllys 		(void) memset(rawrsa, 0, sizeof (KMF_RAW_RSA_KEY));
25403089Swyllys 	}
25413089Swyllys 	return (rv);
25423089Swyllys }
25433089Swyllys 
25446557Sfr41279 #define	DSA_PRIME_BUFSIZE	CHARLEN2BIGNUMLEN(1024)	/* 8192 bits */
25456557Sfr41279 #define	DSA_PRIVATE_BUFSIZE	BIG_CHUNKS_FOR_160BITS	/* 160 bits */
25465051Swyllys 
25475051Swyllys /*
25485051Swyllys  * This function calculates the pubkey value from the prime,
25495051Swyllys  * base and private key values of a DSA key.
25505051Swyllys  */
25515051Swyllys static KMF_RETURN
compute_dsa_pubvalue(KMF_RAW_DSA_KEY * rawdsa)25525051Swyllys compute_dsa_pubvalue(KMF_RAW_DSA_KEY *rawdsa)
25535051Swyllys {
25545051Swyllys 	KMF_RETURN rv = KMF_OK;
25555051Swyllys 	BIGNUM p, g, x, y;
25565051Swyllys 	BIG_ERR_CODE err;
25575051Swyllys 	uchar_t *pubvalue;
25585051Swyllys 	uint32_t pubvalue_len;
25595051Swyllys 
25605051Swyllys 	if ((err = big_init1(&p, DSA_PRIME_BUFSIZE, NULL, 0)) != BIG_OK) {
25615051Swyllys 		rv = KMF_ERR_MEMORY;
25625051Swyllys 		return (rv);
25635051Swyllys 	}
25645051Swyllys 	bytestring2bignum(&p, rawdsa->prime.val, rawdsa->prime.len);
25655051Swyllys 
25665051Swyllys 	if ((err = big_init1(&g, DSA_PRIME_BUFSIZE, NULL, 0)) != BIG_OK) {
25675051Swyllys 		rv = KMF_ERR_MEMORY;
25685051Swyllys 		goto ret1;
25695051Swyllys 	}
25705051Swyllys 	bytestring2bignum(&g, rawdsa->base.val, rawdsa->base.len);
25715051Swyllys 
25725051Swyllys 	if ((err = big_init1(&x, DSA_PRIVATE_BUFSIZE, NULL, 0)) != BIG_OK) {
25735051Swyllys 		rv = KMF_ERR_MEMORY;
25745051Swyllys 		goto ret2;
25755051Swyllys 	}
25765051Swyllys 	bytestring2bignum(&x, rawdsa->value.val, rawdsa->value.len);
25775051Swyllys 
25785051Swyllys 	if ((err = big_init1(&y, DSA_PRIME_BUFSIZE, NULL, 0)) != BIG_OK) {
25795051Swyllys 		rv = KMF_ERR_MEMORY;
25805051Swyllys 		goto ret3;
25815051Swyllys 	}
25825051Swyllys 
25835051Swyllys 	err = big_modexp(&y, &g, &x, &p, NULL);
25845051Swyllys 	if (err != BIG_OK) {
25855051Swyllys 		rv = KMF_ERR_INTERNAL;
25865051Swyllys 		goto ret3;
25875051Swyllys 	}
25885051Swyllys 
25895051Swyllys 	pubvalue_len = y.len * (int)sizeof (uint32_t);
25905051Swyllys 	if ((pubvalue = malloc(pubvalue_len)) == NULL) {
25915051Swyllys 		rv = KMF_ERR_MEMORY;
25925051Swyllys 		goto ret4;
25935051Swyllys 	}
25945051Swyllys 	bignum2bytestring(pubvalue, &y, pubvalue_len);
25955051Swyllys 
25965051Swyllys 	rawdsa->pubvalue.val = pubvalue;
25975051Swyllys 	rawdsa->pubvalue.len = pubvalue_len;
25985051Swyllys 
25995051Swyllys ret4:
26005051Swyllys 	big_finish(&y);
26015051Swyllys ret3:
26025051Swyllys 	big_finish(&x);
26035051Swyllys ret2:
26045051Swyllys 	big_finish(&g);
26055051Swyllys ret1:
26065051Swyllys 	big_finish(&p);
26075051Swyllys 	return (rv);
26085051Swyllys }
26095051Swyllys 
261011973Swyllys.ingersoll@sun.com static KMF_RETURN
get_raw_ec(KMF_HANDLE * kmfh,CK_OBJECT_HANDLE obj,KMF_RAW_EC_KEY * rawec)261111973Swyllys.ingersoll@sun.com get_raw_ec(KMF_HANDLE *kmfh, CK_OBJECT_HANDLE obj, KMF_RAW_EC_KEY *rawec)
261211973Swyllys.ingersoll@sun.com {
261311973Swyllys.ingersoll@sun.com 	KMF_RETURN rv = KMF_OK;
261411973Swyllys.ingersoll@sun.com 	CK_RV ckrv;
261511973Swyllys.ingersoll@sun.com 	CK_SESSION_HANDLE sess = kmfh->pk11handle;
261611973Swyllys.ingersoll@sun.com 	CK_ATTRIBUTE	ec_attrs[2] = {
261711973Swyllys.ingersoll@sun.com 		{ CKA_EC_PARAMS, NULL, 0},
261811973Swyllys.ingersoll@sun.com 		{ CKA_VALUE, NULL, 0}
261911973Swyllys.ingersoll@sun.com 	};
262011973Swyllys.ingersoll@sun.com 	CK_ULONG	count = sizeof (ec_attrs) / sizeof (CK_ATTRIBUTE);
262111973Swyllys.ingersoll@sun.com 	int		i;
262211973Swyllys.ingersoll@sun.com 
262311973Swyllys.ingersoll@sun.com 	if ((ckrv = C_GetAttributeValue(sess, obj,
262411973Swyllys.ingersoll@sun.com 	    ec_attrs, 2)) != CKR_OK) {
262511973Swyllys.ingersoll@sun.com 		SET_ERROR(kmfh, ckrv);
262611973Swyllys.ingersoll@sun.com 
262711973Swyllys.ingersoll@sun.com 		/* Tell the caller know why the key data cannot be retrieved. */
262811973Swyllys.ingersoll@sun.com 		if (ckrv == CKR_ATTRIBUTE_SENSITIVE)
262911973Swyllys.ingersoll@sun.com 			return (KMF_ERR_SENSITIVE_KEY);
263011973Swyllys.ingersoll@sun.com 		else if (ckrv == CKR_KEY_UNEXTRACTABLE)
263111973Swyllys.ingersoll@sun.com 			return (KMF_ERR_UNEXTRACTABLE_KEY);
263211973Swyllys.ingersoll@sun.com 		return (KMF_ERR_INTERNAL);
263311973Swyllys.ingersoll@sun.com 	}
263411973Swyllys.ingersoll@sun.com 	for (i = 0; i < count; i++) {
263511973Swyllys.ingersoll@sun.com 		if (ec_attrs[i].ulValueLen == (CK_ULONG)-1 ||
263611973Swyllys.ingersoll@sun.com 		    ec_attrs[i].ulValueLen == 0) {
263711973Swyllys.ingersoll@sun.com 			ec_attrs[i].ulValueLen = 0;
263811973Swyllys.ingersoll@sun.com 			continue;
263911973Swyllys.ingersoll@sun.com 		}
264011973Swyllys.ingersoll@sun.com 		if ((ec_attrs[i].pValue =
264111973Swyllys.ingersoll@sun.com 		    malloc(ec_attrs[i].ulValueLen)) == NULL) {
264211973Swyllys.ingersoll@sun.com 			rv = KMF_ERR_MEMORY;
264311973Swyllys.ingersoll@sun.com 			goto end;
264411973Swyllys.ingersoll@sun.com 		}
264511973Swyllys.ingersoll@sun.com 	}
264611973Swyllys.ingersoll@sun.com 	if ((ckrv = C_GetAttributeValue(sess, obj,
264711973Swyllys.ingersoll@sun.com 	    ec_attrs, count)) != CKR_OK) {
264811973Swyllys.ingersoll@sun.com 		SET_ERROR(kmfh, ckrv);
264911973Swyllys.ingersoll@sun.com 		rv = KMF_ERR_INTERNAL;
265011973Swyllys.ingersoll@sun.com 		goto end;
265111973Swyllys.ingersoll@sun.com 	}
265211973Swyllys.ingersoll@sun.com 
265311973Swyllys.ingersoll@sun.com 	rawec->params.Data = ec_attrs[0].pValue;
265411973Swyllys.ingersoll@sun.com 	rawec->params.Length = ec_attrs[0].ulValueLen;
265511973Swyllys.ingersoll@sun.com 	rawec->value.val = ec_attrs[1].pValue;
265611973Swyllys.ingersoll@sun.com 	rawec->value.len = ec_attrs[1].ulValueLen;
265711973Swyllys.ingersoll@sun.com 
265811973Swyllys.ingersoll@sun.com end:
265911973Swyllys.ingersoll@sun.com 	if (rv != KMF_OK) {
266011973Swyllys.ingersoll@sun.com 		for (i = 0; i < count; i++) {
266111973Swyllys.ingersoll@sun.com 			if (ec_attrs[i].pValue != NULL)
266211973Swyllys.ingersoll@sun.com 				free(ec_attrs[i].pValue);
266311973Swyllys.ingersoll@sun.com 		}
266411973Swyllys.ingersoll@sun.com 		(void) memset(rawec, 0, sizeof (KMF_RAW_EC_KEY));
266511973Swyllys.ingersoll@sun.com 	}
266611973Swyllys.ingersoll@sun.com 	return (rv);
266711973Swyllys.ingersoll@sun.com }
26685051Swyllys 
26693089Swyllys static KMF_RETURN
get_raw_dsa(KMF_HANDLE * kmfh,CK_OBJECT_HANDLE obj,KMF_RAW_DSA_KEY * rawdsa)26703089Swyllys get_raw_dsa(KMF_HANDLE *kmfh, CK_OBJECT_HANDLE obj, KMF_RAW_DSA_KEY *rawdsa)
26713089Swyllys {
26723089Swyllys 	KMF_RETURN rv = KMF_OK;
26735051Swyllys 	CK_RV ckrv;
26743089Swyllys 	CK_SESSION_HANDLE sess = kmfh->pk11handle;
26753089Swyllys 	CK_ATTRIBUTE	dsa_pri_attrs[8] = {
26763089Swyllys 		{ CKA_PRIME, NULL, 0 },
26773089Swyllys 		{ CKA_SUBPRIME, NULL, 0 },
26783089Swyllys 		{ CKA_BASE, NULL, 0 },
26793089Swyllys 		{ CKA_VALUE, NULL, 0 }
26803089Swyllys 	};
26813089Swyllys 	CK_ULONG	count = sizeof (dsa_pri_attrs) / sizeof (CK_ATTRIBUTE);
26823089Swyllys 	int		i;
26833089Swyllys 
26845051Swyllys 	if ((ckrv = C_GetAttributeValue(sess, obj,
26855051Swyllys 	    dsa_pri_attrs, count)) != CKR_OK) {
26865051Swyllys 		SET_ERROR(kmfh, ckrv);
26875051Swyllys 
26885051Swyllys 		/* Tell the caller know why the key data cannot be retrieved. */
26895051Swyllys 		if (ckrv == CKR_ATTRIBUTE_SENSITIVE)
26905051Swyllys 			return (KMF_ERR_SENSITIVE_KEY);
26915051Swyllys 		else if (ckrv == CKR_KEY_UNEXTRACTABLE)
26925051Swyllys 			return (KMF_ERR_UNEXTRACTABLE_KEY);
26933089Swyllys 		return (KMF_ERR_INTERNAL);
26943089Swyllys 	}
26953089Swyllys 
26963089Swyllys 	/* Allocate memory for each attribute. */
26973089Swyllys 	for (i = 0; i < count; i++) {
26983089Swyllys 		if (dsa_pri_attrs[i].ulValueLen == (CK_ULONG)-1 ||
26993089Swyllys 		    dsa_pri_attrs[i].ulValueLen == 0) {
27003089Swyllys 			dsa_pri_attrs[i].ulValueLen = 0;
27013089Swyllys 			continue;
27023089Swyllys 		}
27033089Swyllys 		if ((dsa_pri_attrs[i].pValue =
27043089Swyllys 		    malloc(dsa_pri_attrs[i].ulValueLen)) == NULL) {
27053089Swyllys 			rv = KMF_ERR_MEMORY;
27063089Swyllys 			goto end;
27073089Swyllys 		}
27083089Swyllys 	}
27096354Swyllys 	if ((ckrv = C_GetAttributeValue(sess, obj,
27105051Swyllys 	    dsa_pri_attrs, count)) != CKR_OK) {
27116354Swyllys 		SET_ERROR(kmfh, ckrv);
27123089Swyllys 		rv = KMF_ERR_INTERNAL;
27133089Swyllys 		goto end;
27143089Swyllys 	}
27153089Swyllys 
27163089Swyllys 	/* Fill in all the temp variables.  They are all required. */
27173089Swyllys 	i = 0;
27183089Swyllys 	attr2bigint(&(dsa_pri_attrs[i++]), &rawdsa->prime);
27193089Swyllys 	attr2bigint(&(dsa_pri_attrs[i++]), &rawdsa->subprime);
27203089Swyllys 	attr2bigint(&(dsa_pri_attrs[i++]), &rawdsa->base);
27213089Swyllys 	attr2bigint(&(dsa_pri_attrs[i++]), &rawdsa->value);
27223089Swyllys 
27235051Swyllys 	/* Compute the public key value and store it */
27245051Swyllys 	rv = compute_dsa_pubvalue(rawdsa);
27255051Swyllys 
27263089Swyllys end:
27273089Swyllys 	if (rv != KMF_OK) {
27283089Swyllys 		for (i = 0; i < count; i++) {
27293089Swyllys 			if (dsa_pri_attrs[i].pValue != NULL)
27303089Swyllys 				free(dsa_pri_attrs[i].pValue);
27313089Swyllys 		}
27323089Swyllys 		(void) memset(rawdsa, 0, sizeof (KMF_RAW_DSA_KEY));
27333089Swyllys 	}
27343089Swyllys 	return (rv);
27353089Swyllys }
27363089Swyllys 
27373089Swyllys static KMF_RETURN
get_raw_sym(KMF_HANDLE * kmfh,CK_OBJECT_HANDLE obj,KMF_RAW_SYM_KEY * rawsym)27383089Swyllys get_raw_sym(KMF_HANDLE *kmfh, CK_OBJECT_HANDLE obj, KMF_RAW_SYM_KEY *rawsym)
27393089Swyllys {
27403089Swyllys 	KMF_RETURN rv = KMF_OK;
27413089Swyllys 	CK_RV	ckrv;
27423089Swyllys 	CK_SESSION_HANDLE sess = kmfh->pk11handle;
27433089Swyllys 	CK_ATTRIBUTE	sym_attr[1];
27443089Swyllys 	CK_ULONG	value_len = 0;
27453089Swyllys 
27463089Swyllys 	/* find the key length first */
27473089Swyllys 	sym_attr[0].type = CKA_VALUE;
27483089Swyllys 	sym_attr[0].pValue = NULL;
27493089Swyllys 	sym_attr[0].ulValueLen = value_len;
27503089Swyllys 	if ((ckrv = C_GetAttributeValue(sess, obj, sym_attr, 1)) != CKR_OK) {
27515051Swyllys 		rawsym->keydata.val = NULL;
27525051Swyllys 		rawsym->keydata.len = 0;
27533089Swyllys 		if (ckrv == CKR_ATTRIBUTE_SENSITIVE) {
27545051Swyllys 			return (KMF_ERR_SENSITIVE_KEY);
27555051Swyllys 		} else if (ckrv == CKR_KEY_UNEXTRACTABLE) {
27565051Swyllys 			return (KMF_ERR_UNEXTRACTABLE_KEY);
27575051Swyllys 		} else {
27585051Swyllys 			SET_ERROR(kmfh, ckrv);
27595051Swyllys 			return (KMF_ERR_INTERNAL);
27603089Swyllys 		}
27613089Swyllys 	}
27623089Swyllys 
27633089Swyllys 	/* Allocate memory for pValue */
27643089Swyllys 	sym_attr[0].pValue = malloc(sym_attr[0].ulValueLen);
27653089Swyllys 	if (sym_attr[0].pValue == NULL) {
27663089Swyllys 		return (KMF_ERR_MEMORY);
27673089Swyllys 	}
27683089Swyllys 
27693089Swyllys 	/* get the key data */
27706354Swyllys 	if ((ckrv = C_GetAttributeValue(sess, obj, sym_attr, 1)) != CKR_OK) {
27716354Swyllys 		SET_ERROR(kmfh, ckrv);
27723089Swyllys 		free(sym_attr[0].pValue);
27733089Swyllys 		return (KMF_ERR_INTERNAL);
27743089Swyllys 	}
27753089Swyllys 
27763089Swyllys 	rawsym->keydata.val = sym_attr[0].pValue;
27773089Swyllys 	rawsym->keydata.len = sym_attr[0].ulValueLen;
27783089Swyllys 	return (rv);
27793089Swyllys }
27803089Swyllys 
27813089Swyllys static KMF_RETURN
keyObj2RawKey(KMF_HANDLE_T handle,KMF_KEY_HANDLE * inkey,KMF_RAW_KEY_DATA ** outkey)27823089Swyllys keyObj2RawKey(KMF_HANDLE_T handle, KMF_KEY_HANDLE *inkey,
27833089Swyllys 	KMF_RAW_KEY_DATA **outkey)
27843089Swyllys {
27853089Swyllys 	KMF_RETURN rv = KMF_OK;
27863089Swyllys 	KMF_RAW_KEY_DATA *rkey;
27873089Swyllys 	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
27883089Swyllys 
27893089Swyllys 	rkey = malloc(sizeof (KMF_RAW_KEY_DATA));
27903089Swyllys 	if (rkey == NULL)
27913089Swyllys 		return (KMF_ERR_MEMORY);
27923089Swyllys 
27933089Swyllys 	(void) memset(rkey, 0, sizeof (KMF_RAW_KEY_DATA));
27943089Swyllys 
27953089Swyllys 	rkey->keytype = inkey->keyalg;
27963089Swyllys 
27973089Swyllys 	if (inkey->keyalg == KMF_RSA) {
27983089Swyllys 		rv = get_raw_rsa(kmfh, (CK_OBJECT_HANDLE)inkey->keyp,
27995051Swyllys 		    &rkey->rawdata.rsa);
28003089Swyllys 	} else if (inkey->keyalg == KMF_DSA) {
28013089Swyllys 		rv = get_raw_dsa(kmfh, (CK_OBJECT_HANDLE)inkey->keyp,
28025051Swyllys 		    &rkey->rawdata.dsa);
28033089Swyllys 	} else if (inkey->keyalg == KMF_AES ||
28043089Swyllys 	    inkey->keyalg == KMF_RC4 ||
28053089Swyllys 	    inkey->keyalg == KMF_DES ||
28063812Shylee 	    inkey->keyalg == KMF_DES3 ||
28073812Shylee 	    inkey->keyalg == KMF_GENERIC_SECRET) {
28083089Swyllys 		rv = get_raw_sym(kmfh, (CK_OBJECT_HANDLE)inkey->keyp,
28093089Swyllys 		    &rkey->rawdata.sym);
28105051Swyllys 		/*
28115051Swyllys 		 * If sensitive or non-extractable, mark them as such
28125051Swyllys 		 * but return "OK" status so the keys get counted
28135051Swyllys 		 * when doing FindKey operations.
28145051Swyllys 		 */
28155051Swyllys 		if (rv == KMF_ERR_SENSITIVE_KEY) {
28165051Swyllys 			rkey->sensitive = B_TRUE;
28175051Swyllys 			rv = KMF_OK;
28185051Swyllys 		} else if (rv == KMF_ERR_UNEXTRACTABLE_KEY) {
28195051Swyllys 			rkey->not_extractable = B_TRUE;
28205051Swyllys 			rv = KMF_OK;
28215051Swyllys 		}
282211973Swyllys.ingersoll@sun.com 	} else if (inkey->keyalg == KMF_ECDSA) {
282311973Swyllys.ingersoll@sun.com 		rv = get_raw_ec(kmfh, (CK_OBJECT_HANDLE)inkey->keyp,
282411973Swyllys.ingersoll@sun.com 		    &rkey->rawdata.ec);
28253089Swyllys 	} else {
28263089Swyllys 		rv = KMF_ERR_BAD_PARAMETER;
28273089Swyllys 	}
28283089Swyllys 
28293089Swyllys 	if (rv == KMF_OK) {
28303089Swyllys 		*outkey = rkey;
28313089Swyllys 	} else if (rkey != NULL) {
28323089Swyllys 		free(rkey);
28333089Swyllys 		*outkey = NULL;
28343089Swyllys 	}
28353089Swyllys 
28363089Swyllys 	return (rv);
28373089Swyllys }
28383089Swyllys 
28393089Swyllys 
28403089Swyllys static KMF_RETURN
kmf2pk11keytype(KMF_KEY_ALG keyalg,CK_KEY_TYPE * type)28413089Swyllys kmf2pk11keytype(KMF_KEY_ALG keyalg, CK_KEY_TYPE *type)
28423089Swyllys {
28433089Swyllys 	switch (keyalg) {
28443089Swyllys 	case KMF_RSA:
28453089Swyllys 		*type = CKK_RSA;
28463089Swyllys 		break;
28473089Swyllys 	case KMF_DSA:
28483089Swyllys 		*type = CKK_DSA;
28493089Swyllys 		break;
285011973Swyllys.ingersoll@sun.com 	case KMF_ECDSA:
285111973Swyllys.ingersoll@sun.com 		*type = CKK_EC;
285211973Swyllys.ingersoll@sun.com 		break;
28533089Swyllys 	case KMF_AES:
28543089Swyllys 		*type = CKK_AES;
28553089Swyllys 		break;
28563089Swyllys 	case KMF_RC4:
28573089Swyllys 		*type = CKK_RC4;
28583089Swyllys 		break;
28593089Swyllys 	case KMF_DES:
28603089Swyllys 		*type = CKK_DES;
28613089Swyllys 		break;
28623089Swyllys 	case KMF_DES3:
28633089Swyllys 		*type = CKK_DES3;
28643089Swyllys 		break;
28653812Shylee 	case KMF_GENERIC_SECRET:
28663812Shylee 		*type = CKK_GENERIC_SECRET;
28673812Shylee 		break;
28683089Swyllys 	default:
28693089Swyllys 		return (KMF_ERR_BAD_KEY_TYPE);
28703089Swyllys 	}
28713089Swyllys 
28723089Swyllys 	return (KMF_OK);
28733089Swyllys }
28743089Swyllys 
28753089Swyllys static int
IDStringToData(char * idstr,KMF_DATA * iddata)28763089Swyllys IDStringToData(char *idstr, KMF_DATA *iddata)
28773089Swyllys {
28783089Swyllys 	int len, i;
28793089Swyllys 	char *iddup, *byte;
28803089Swyllys 	uint_t lvalue;
28813089Swyllys 
28823089Swyllys 	if (idstr == NULL || !strlen(idstr))
28833089Swyllys 		return (-1);
28843089Swyllys 
28853089Swyllys 	iddup = (char *)strdup(idstr);
28863089Swyllys 	if (iddup == NULL)
28873089Swyllys 		return (KMF_ERR_MEMORY);
28883089Swyllys 
28893089Swyllys 	len = strlen(iddup) / 3  + 1;
28903089Swyllys 	iddata->Data = malloc(len);
28913089Swyllys 	if (iddata->Data == NULL)
28923089Swyllys 		return (KMF_ERR_MEMORY);
28933089Swyllys 	(void) memset(iddata->Data, 0, len);
28943089Swyllys 	iddata->Length = len;
28953089Swyllys 
28963089Swyllys 	byte = strtok(iddup, ":");
28973089Swyllys 	if (byte == NULL) {
28983089Swyllys 		free(iddup);
28993089Swyllys 		free(iddata->Data);
29003089Swyllys 		iddata->Data = NULL;
29013089Swyllys 		iddata->Length = 0;
29023089Swyllys 		return (-1);
29033089Swyllys 	}
29043089Swyllys 
29053089Swyllys 	i = 0;
29063089Swyllys 	do {
29073089Swyllys 		(void) sscanf(byte, "%x", &lvalue);
29083089Swyllys 		iddata->Data[i++] = (uchar_t)(lvalue & 0x000000FF);
29093089Swyllys 		byte = strtok(NULL, ":");
29103089Swyllys 	} while (byte != NULL && i < len);
29113089Swyllys 
29123089Swyllys 	iddata->Length = i;
29133089Swyllys 	free(iddup);
29143089Swyllys 	return (0);
29153089Swyllys }
29163089Swyllys 
29173089Swyllys KMF_RETURN
KMFPK11_FindKey(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)29185051Swyllys KMFPK11_FindKey(KMF_HANDLE_T handle,
29195051Swyllys 	int numattr, KMF_ATTRIBUTE *attrlist)
29203089Swyllys {
29213089Swyllys 	KMF_RETURN rv = KMF_OK;
29223089Swyllys 	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
29233089Swyllys 	uint32_t want_keys, i;
29243089Swyllys 	CK_RV ckrv;
29253089Swyllys 	CK_ATTRIBUTE pTmpl[10];
29263089Swyllys 	CK_OBJECT_CLASS class;
29273089Swyllys 	CK_BBOOL true = TRUE;
29283089Swyllys 	CK_ULONG alg;
29295637Swyllys 	boolean_t is_token = B_TRUE, is_private = B_FALSE;
29305051Swyllys 	KMF_KEY_HANDLE *keys;
29315051Swyllys 	uint32_t *numkeys;
29326051Swyllys 	KMF_CREDENTIAL *cred = NULL;
29335051Swyllys 	KMF_KEY_CLASS keyclass = KMF_KEYCLASS_NONE;
29345051Swyllys 	char *findLabel, *idstr;
29355051Swyllys 	KMF_KEY_ALG keytype = KMF_KEYALG_NONE;
29365051Swyllys 	KMF_ENCODE_FORMAT format;
29375051Swyllys 
29385051Swyllys 	if (kmfh == NULL)
29393089Swyllys 		return (KMF_ERR_UNINITIALIZED); /* Plugin Not Initialized */
29403089Swyllys 
29413089Swyllys 	if (kmfh->pk11handle == CK_INVALID_HANDLE)
29423089Swyllys 		return (KMF_ERR_NO_TOKEN_SELECTED);
29433089Swyllys 
29445051Swyllys 	numkeys = kmf_get_attr_ptr(KMF_COUNT_ATTR, attrlist, numattr);
29455051Swyllys 	if (numkeys == NULL)
29463089Swyllys 		return (KMF_ERR_BAD_PARAMETER);
29473089Swyllys 
29485051Swyllys 	if (*numkeys > 0)
29493089Swyllys 		want_keys = *numkeys;
29503089Swyllys 	else
29513089Swyllys 		want_keys = MAXINT; /* count them all */
29523089Swyllys 
29535051Swyllys 	/* keyclass is optional */
29545051Swyllys 	(void) kmf_get_attr(KMF_KEYCLASS_ATTR, attrlist, numattr,
29555051Swyllys 	    (void *)&keyclass, NULL);
29565051Swyllys 
29575051Swyllys 	if (keyclass == KMF_ASYM_PUB) {
29583089Swyllys 		class = CKO_PUBLIC_KEY;
29595051Swyllys 	} else if (keyclass == KMF_ASYM_PRI) {
29603089Swyllys 		class = CKO_PRIVATE_KEY;
29615051Swyllys 	} else if (keyclass == KMF_SYMMETRIC) {
29623089Swyllys 		class = CKO_SECRET_KEY;
29633089Swyllys 	}
29643089Swyllys 
29655051Swyllys 	rv = kmf_get_attr(KMF_TOKEN_BOOL_ATTR, attrlist, numattr,
29665051Swyllys 	    (void *)&is_token, NULL);
29675051Swyllys 	if (rv != KMF_OK)
29685051Swyllys 		return (rv);
29695051Swyllys 
29703089Swyllys 	i = 0;
29715051Swyllys 	if (is_token) {
29725051Swyllys 		SETATTR(pTmpl, i, CKA_TOKEN, &true, sizeof (true));
29735051Swyllys 		i++;
29745051Swyllys 	}
29755051Swyllys 
29765051Swyllys 	if (keyclass != KMF_KEYCLASS_NONE) {
29775051Swyllys 		SETATTR(pTmpl, i, CKA_CLASS, &class, sizeof (class));
29783089Swyllys 		i++;
29793089Swyllys 	}
29803089Swyllys 
29815051Swyllys 	findLabel = kmf_get_attr_ptr(KMF_KEYLABEL_ATTR, attrlist, numattr);
29825051Swyllys 
29835051Swyllys 	if (findLabel != NULL && strlen(findLabel)) {
29845051Swyllys 		SETATTR(pTmpl, i, CKA_LABEL, findLabel, strlen(findLabel));
29855051Swyllys 		i++;
29865051Swyllys 	}
29875051Swyllys 	/* keytype is optional */
29885051Swyllys 	(void) kmf_get_attr(KMF_KEYALG_ATTR, attrlist, numattr,
29895051Swyllys 	    (void *)&keytype, NULL);
29905051Swyllys 
29915051Swyllys 	if (keytype != 0) {
29925051Swyllys 		rv = kmf2pk11keytype(keytype, &alg);
29933089Swyllys 		if (rv != KMF_OK) {
29943089Swyllys 			return (KMF_ERR_BAD_KEY_TYPE);
29953089Swyllys 		}
29965051Swyllys 		SETATTR(pTmpl, i, CKA_KEY_TYPE, &alg, sizeof (alg));
29973089Swyllys 		i++;
29983089Swyllys 	}
29993089Swyllys 
30005051Swyllys 	idstr = kmf_get_attr_ptr(KMF_IDSTR_ATTR, attrlist, numattr);
30015051Swyllys 
30025051Swyllys 	if (idstr != NULL) {
30033089Swyllys 		KMF_DATA iddata = { NULL, 0 };
30043089Swyllys 
30053089Swyllys 		/*
30063089Swyllys 		 * ID String parameter is assumed to be of form:
30073089Swyllys 		 * XX:XX:XX:XX:XX ... :XX
30083089Swyllys 		 * where XX is a hex number.
30093089Swyllys 		 *
30103089Swyllys 		 * We must convert this back to binary in order to
30113089Swyllys 		 * use it in a search.
30123089Swyllys 		 */
30135051Swyllys 		rv = IDStringToData(idstr, &iddata);
30143089Swyllys 		if (rv == KMF_OK) {
30155051Swyllys 			SETATTR(pTmpl, i, CKA_ID, iddata.Data, iddata.Length);
30163089Swyllys 			i++;
30173089Swyllys 		} else {
30183089Swyllys 			return (rv);
30193089Swyllys 		}
30203089Swyllys 	}
30213089Swyllys 
30225051Swyllys 	/* is_private is optional */
30235051Swyllys 	(void) kmf_get_attr(KMF_PRIVATE_BOOL_ATTR, attrlist, numattr,
30245051Swyllys 	    (void *)&is_private, NULL);
30255051Swyllys 
30265051Swyllys 	if (is_private) {
30275051Swyllys 		SETATTR(pTmpl, i, CKA_PRIVATE, &true, sizeof (true));
30283089Swyllys 		i++;
30293089Swyllys 	}
30303089Swyllys 
30313408Swyllys 	/*
30323408Swyllys 	 * Authenticate if the object is a token object,
30333408Swyllys 	 * a private or secred key, or if the user passed in credentials.
30343408Swyllys 	 */
30356051Swyllys 	cred = kmf_get_attr_ptr(KMF_CREDENTIAL_ATTR, attrlist, numattr);
30366354Swyllys 	if (cred != NULL) {
30376051Swyllys 		rv = pk11_authenticate(handle, cred);
30386051Swyllys 		if (rv != KMF_OK)
30396051Swyllys 			return (rv);
30403089Swyllys 	}
30413089Swyllys 
30425051Swyllys 	keys = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, numattr);
30435051Swyllys 	/* it is okay to have "keys" contains NULL */
30445051Swyllys 
30453089Swyllys 	ckrv = C_FindObjectsInit(kmfh->pk11handle, pTmpl, i);
30463089Swyllys 	if (ckrv == CKR_OK) {
30473089Swyllys 		CK_ULONG obj_count, n = 0;
30483089Swyllys 		while (ckrv == CKR_OK && n < want_keys) {
30493089Swyllys 			CK_OBJECT_HANDLE hObj;
30503089Swyllys 
30513089Swyllys 			ckrv = C_FindObjects(kmfh->pk11handle, &hObj,
30525051Swyllys 			    1, &obj_count);
30533089Swyllys 			if (ckrv == CKR_OK && obj_count == 1) {
30543089Swyllys 				if (keys != NULL) {
30553089Swyllys 					CK_ULONG keytype;
30563089Swyllys 					keys[n].kstype = KMF_KEYSTORE_PK11TOKEN;
30573089Swyllys 					keys[n].israw = FALSE;
30583089Swyllys 					keys[n].keyp = (void *)hObj;
30593089Swyllys 
30603089Swyllys 					ckrv = getObjectKeytype(handle,
30615051Swyllys 					    (CK_OBJECT_HANDLE)keys[n].keyp,
30625051Swyllys 					    &keytype);
30633089Swyllys 					if (ckrv != CKR_OK)
30643089Swyllys 						goto end;
30653089Swyllys 
30663089Swyllys 					ckrv = getObjectLabel(handle,
30675051Swyllys 					    (CK_OBJECT_HANDLE)keys[n].keyp,
30685051Swyllys 					    &(keys[n].keylabel));
30693089Swyllys 					if (ckrv != CKR_OK)
30703089Swyllys 						goto end;
30713089Swyllys 
30725128Swyllys 					if (keyclass == KMF_KEYCLASS_NONE) {
30735128Swyllys 						ckrv = getObjectKeyclass(handle,
30745128Swyllys 						    (CK_OBJECT_HANDLE)
30755128Swyllys 						    keys[n].keyp,
30765128Swyllys 						    &(keys[n].keyclass));
30775128Swyllys 						if (ckrv != CKR_OK)
30785128Swyllys 							goto end;
30795128Swyllys 					} else {
30805128Swyllys 						keys[n].keyclass = keyclass;
30815128Swyllys 					}
30825051Swyllys 					if (keytype == CKK_RSA) {
30833089Swyllys 						keys[n].keyalg = KMF_RSA;
30845051Swyllys 					} else if (keytype == CKK_DSA) {
30853089Swyllys 						keys[n].keyalg = KMF_DSA;
308611973Swyllys.ingersoll@sun.com 					} else if (keytype == CKK_EC) {
308711973Swyllys.ingersoll@sun.com 						keys[n].keyalg = KMF_ECDSA;
30885051Swyllys 					} else if (keytype == CKK_AES) {
30893089Swyllys 						keys[n].keyalg = KMF_AES;
30905051Swyllys 						keys[n].keyclass =
30915051Swyllys 						    KMF_SYMMETRIC;
30925051Swyllys 					} else if (keytype == CKK_RC4) {
30933089Swyllys 						keys[n].keyalg = KMF_RC4;
30945051Swyllys 						keys[n].keyclass =
30955051Swyllys 						    KMF_SYMMETRIC;
30965051Swyllys 					} else if (keytype == CKK_DES) {
30973089Swyllys 						keys[n].keyalg = KMF_DES;
30985051Swyllys 						keys[n].keyclass =
30995051Swyllys 						    KMF_SYMMETRIC;
31005051Swyllys 					} else if (keytype == CKK_DES3) {
31013089Swyllys 						keys[n].keyalg = KMF_DES3;
31025051Swyllys 						keys[n].keyclass =
31035051Swyllys 						    KMF_SYMMETRIC;
31045051Swyllys 					} else if (keytype ==
31055051Swyllys 					    CKK_GENERIC_SECRET) {
31063812Shylee 						keys[n].keyalg =
31073812Shylee 						    KMF_GENERIC_SECRET;
31085051Swyllys 						keys[n].keyclass =
31095051Swyllys 						    KMF_SYMMETRIC;
31105051Swyllys 					}
31113089Swyllys 
31123089Swyllys 				}
31133089Swyllys 				n++;
31143089Swyllys 			} else {
31153089Swyllys 				break;
31163089Swyllys 			}
31173089Swyllys 		}
31183089Swyllys 		ckrv = C_FindObjectsFinal(kmfh->pk11handle);
31193089Swyllys 
31203089Swyllys 		/* "numkeys" indicates the number that were actually found */
31213089Swyllys 		*numkeys = n;
31223089Swyllys 	}
31235051Swyllys 
31243408Swyllys 	if (ckrv == KMF_OK && keys != NULL && (*numkeys) > 0) {
31255051Swyllys 		if ((rv = kmf_get_attr(KMF_ENCODE_FORMAT_ATTR, attrlist,
31265051Swyllys 		    numattr, (void *)&format, NULL)) == KMF_OK) {
31275051Swyllys 			if (format == KMF_FORMAT_RAWKEY ||
31285051Swyllys 			    format == KMF_FORMAT_PEM) {
31295051Swyllys 				/* Convert keys to "rawkey" format */
31305051Swyllys 				for (i = 0; i < (*numkeys); i++) {
31315051Swyllys 					KMF_RAW_KEY_DATA *rkey = NULL;
31325051Swyllys 					rv = keyObj2RawKey(handle, &keys[i],
31335051Swyllys 					    &rkey);
31345051Swyllys 					if (rv == KMF_OK) {
31355051Swyllys 						keys[i].keyp = rkey;
31365051Swyllys 						keys[i].israw = TRUE;
31375051Swyllys 					} else {
31385051Swyllys 						break;
31395051Swyllys 					}
31403408Swyllys 				}
31413089Swyllys 			}
31425051Swyllys 		} else {
31435051Swyllys 			rv = KMF_OK; /* format is optional */
31443089Swyllys 		}
31453089Swyllys 	}
31465051Swyllys 
31473089Swyllys end:
31483089Swyllys 	if (ckrv != CKR_OK) {
31493089Swyllys 		SET_ERROR(kmfh, ckrv);
31503089Swyllys 		/* Report authentication failures to the caller */
31513089Swyllys 		if (ckrv == CKR_USER_NOT_LOGGED_IN ||
31523089Swyllys 		    ckrv == CKR_PIN_INCORRECT ||
31533089Swyllys 		    ckrv == CKR_PIN_INVALID ||
31543089Swyllys 		    ckrv == CKR_PIN_EXPIRED ||
31553089Swyllys 		    ckrv == CKR_PIN_LOCKED ||
31563089Swyllys 		    ckrv == CKR_SESSION_READ_ONLY)
31573089Swyllys 			rv = KMF_ERR_AUTH_FAILED;
31583089Swyllys 		else
31593089Swyllys 			rv = KMF_ERR_INTERNAL;
31603089Swyllys 	} else if ((*numkeys) == 0) {
31613089Swyllys 		rv = KMF_ERR_KEY_NOT_FOUND;
31623089Swyllys 	}
31633089Swyllys 
31643089Swyllys 	return (rv);
31653089Swyllys }
31663089Swyllys 
31673089Swyllys static char *
convertDate(char * fulldate)31683089Swyllys convertDate(char *fulldate)
31693089Swyllys {
31703089Swyllys 	struct tm tms;
31713089Swyllys 	char newtime[9];
31723089Swyllys 
31733089Swyllys 	(void) strptime(fulldate, "%b %d %T %Y %Z", &tms);
31743089Swyllys 
31753089Swyllys 	if (tms.tm_year < 69)
31763089Swyllys 		tms.tm_year += 100;
31773089Swyllys 
31783089Swyllys 	(void) strftime(newtime, sizeof (newtime), "m%d", &tms);
31793089Swyllys 
31803089Swyllys 	newtime[8] = 0;
31813089Swyllys 
31823089Swyllys 	/* memory returned must be freed by the caller */
31833089Swyllys 	return ((char *)strdup(newtime));
31843089Swyllys }
31853089Swyllys 
31865051Swyllys static KMF_RETURN
store_raw_key(KMF_HANDLE_T handle,KMF_ATTRIBUTE * attrlist,int numattr,KMF_RAW_KEY_DATA * rawkey)31875051Swyllys store_raw_key(KMF_HANDLE_T handle,
31885051Swyllys 	KMF_ATTRIBUTE *attrlist, int numattr,
31893089Swyllys 	KMF_RAW_KEY_DATA *rawkey)
31903089Swyllys {
31913089Swyllys 	KMF_RETURN rv = KMF_OK;
31923089Swyllys 	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
31933089Swyllys 	int i;
31943089Swyllys 	CK_RV		ckrv = CKR_OK;
31953089Swyllys 	CK_ATTRIBUTE	templ[32];
31963089Swyllys 	CK_OBJECT_HANDLE keyobj;
31973089Swyllys 	CK_KEY_TYPE	keytype;
31983089Swyllys 	CK_OBJECT_CLASS oClass = CKO_PRIVATE_KEY;
31993089Swyllys 	CK_BBOOL	cktrue = TRUE;
32003089Swyllys 	CK_DATE		startdate, enddate;
32013089Swyllys 	KMF_DATA	id = {NULL, 0};
32023089Swyllys 	KMF_DATA	subject = {NULL, 0};
32033089Swyllys 	KMF_X509EXT_KEY_USAGE kuext;
32043089Swyllys 	KMF_X509_CERTIFICATE *x509 = NULL;
32055051Swyllys 	CK_BBOOL	kufound = B_FALSE;
32065051Swyllys 	KMF_DATA	*cert = NULL;
32073089Swyllys 	char		*notbefore = NULL, *start = NULL;
32083089Swyllys 	char		*notafter = NULL, *end = NULL;
32095051Swyllys 	char		*keylabel = NULL;
32106354Swyllys 	KMF_CREDENTIAL	*cred = NULL;
32115051Swyllys 
32125051Swyllys 	if (kmfh == NULL)
32133089Swyllys 		return (KMF_ERR_UNINITIALIZED); /* Plugin Not Initialized */
32143089Swyllys 
32153089Swyllys 	if (kmfh->pk11handle == CK_INVALID_HANDLE)
32163089Swyllys 		return (KMF_ERR_NO_TOKEN_SELECTED);
32173089Swyllys 
32183089Swyllys 	if (rawkey->keytype == KMF_RSA)
32193089Swyllys 		keytype = CKK_RSA;
32203089Swyllys 	else if (rawkey->keytype == KMF_DSA)
32213089Swyllys 		keytype = CKK_DSA;
322211973Swyllys.ingersoll@sun.com 	else if (rawkey->keytype == KMF_ECDSA)
322311973Swyllys.ingersoll@sun.com 		keytype = CKK_EC;
32243089Swyllys 	else
32253089Swyllys 		return (KMF_ERR_BAD_PARAMETER);
32263089Swyllys 
32276354Swyllys 	cred = kmf_get_attr_ptr(KMF_CREDENTIAL_ATTR, attrlist, numattr);
32286354Swyllys 	if (cred != NULL) {
32296354Swyllys 		rv = pk11_authenticate(handle, cred);
32306354Swyllys 		if (rv != KMF_OK)
32316354Swyllys 			return (rv);
32326354Swyllys 	}
32336354Swyllys 
32345051Swyllys 	keylabel = kmf_get_attr_ptr(KMF_KEYLABEL_ATTR, attrlist, numattr);
32355536Swyllys 	/*
32365536Swyllys 	 * If the caller did not specify a label, see if the raw key
32375536Swyllys 	 * came with one (possible if it came from a PKCS#12 file).
32385536Swyllys 	 */
32395536Swyllys 	if (keylabel == NULL) {
32405536Swyllys 		keylabel = rawkey->label;
32415536Swyllys 	}
32423089Swyllys 
32433089Swyllys 	i = 0;
32443089Swyllys 	SETATTR(templ, i, CKA_CLASS, &oClass, sizeof (CK_OBJECT_CLASS)); i++;
32453089Swyllys 	SETATTR(templ, i, CKA_KEY_TYPE, &keytype, sizeof (keytype)); i++;
32463089Swyllys 	SETATTR(templ, i, CKA_TOKEN, &cktrue, sizeof (cktrue)); i++;
32473089Swyllys 	SETATTR(templ, i, CKA_PRIVATE, &cktrue, sizeof (cktrue)); i++;
324811973Swyllys.ingersoll@sun.com 	if (keytype != CKK_EC)
324911973Swyllys.ingersoll@sun.com 		SETATTR(templ, i, CKA_DECRYPT, &cktrue, sizeof (cktrue)); i++;
32503089Swyllys 
32515051Swyllys 	cert = kmf_get_attr_ptr(KMF_CERT_DATA_ATTR, attrlist, numattr);
32525051Swyllys 	if (cert != NULL) {
32535051Swyllys 		id.Data = NULL;
32545051Swyllys 		id.Length = 0;
32555051Swyllys 		rv = kmf_get_cert_id_data(cert, &id);
32565051Swyllys 		if (rv != KMF_OK) {
32575051Swyllys 			goto cleanup;
32585051Swyllys 		}
32595051Swyllys 
32605051Swyllys 		rv = DerDecodeSignedCertificate((const KMF_DATA *)cert, &x509);
32615051Swyllys 		if (rv != KMF_OK) {
32625051Swyllys 			goto cleanup;
32635051Swyllys 		}
32645051Swyllys 
32655051Swyllys 		rv = DerEncodeName(&x509->certificate.subject, &subject);
32665051Swyllys 		if (rv != KMF_OK) {
32675051Swyllys 			goto cleanup;
32685051Swyllys 		}
32695051Swyllys 		SETATTR(templ, i, CKA_SUBJECT, subject.Data, subject.Length);
32705051Swyllys 		i++;
32715051Swyllys 
32725051Swyllys 		rv = kmf_get_cert_start_date_str(handle, cert, &notbefore);
32735051Swyllys 		if (rv != KMF_OK) {
32745051Swyllys 			goto cleanup;
32755051Swyllys 		}
32765051Swyllys 		start = convertDate(notbefore);
32775536Swyllys 		free(notbefore);
32785051Swyllys 
32795051Swyllys 		rv = kmf_get_cert_end_date_str(handle, cert, &notafter);
32805051Swyllys 		if (rv != KMF_OK) {
32815051Swyllys 			goto cleanup;
32825051Swyllys 		}
32835051Swyllys 		end = convertDate(notafter);
32845536Swyllys 		free(notafter);
32855051Swyllys 		if (id.Data != NULL && id.Data != NULL && id.Length > 0) {
32865051Swyllys 			SETATTR(templ, i, CKA_ID, id.Data, id.Length);
32875051Swyllys 			i++;
32885051Swyllys 		}
32895051Swyllys 		if (start != NULL) {
32905051Swyllys 			/*
32915051Swyllys 			 * This makes some potentially dangerous assumptions:
32925051Swyllys 			 *  1. that the startdate in the parameter block is
32935051Swyllys 			 * properly formatted as YYYYMMDD
32945051Swyllys 			 *  2. That the CK_DATE structure is always the same.
32955051Swyllys 			 */
32965051Swyllys 			(void) memcpy(&startdate, start, sizeof (CK_DATE));
32975051Swyllys 			SETATTR(templ, i, CKA_START_DATE, &startdate,
32985051Swyllys 			    sizeof (startdate));
32995051Swyllys 			i++;
33005051Swyllys 		}
33015051Swyllys 		if (end != NULL) {
33025051Swyllys 			(void) memcpy(&enddate, end, sizeof (CK_DATE));
33035051Swyllys 			SETATTR(templ, i, CKA_END_DATE, &enddate,
33045051Swyllys 			    sizeof (enddate));
33055051Swyllys 			i++;
33065051Swyllys 		}
33075051Swyllys 
33085051Swyllys 		if ((rv = kmf_get_cert_ku(cert, &kuext)) != KMF_OK &&
33095051Swyllys 		    rv != KMF_ERR_EXTENSION_NOT_FOUND)
33105051Swyllys 			goto cleanup;
33115051Swyllys 
33125051Swyllys 		kufound = (rv == KMF_OK);
33135051Swyllys 		rv = KMF_OK; /* reset if we got KMF_ERR_EXTENSION_NOT_FOUND */
33145051Swyllys 	}
33155051Swyllys 
33163089Swyllys 	/*
33173089Swyllys 	 * Only set the KeyUsage stuff if the KU extension was present.
33183089Swyllys 	 */
33193089Swyllys 	if (kufound) {
33203089Swyllys 		CK_BBOOL	condition;
33213089Swyllys 
33223089Swyllys 		condition = (kuext.KeyUsageBits & KMF_keyEncipherment) ?
33235051Swyllys 		    B_TRUE : B_FALSE;
33245051Swyllys 		SETATTR(templ, i, CKA_UNWRAP, &condition, sizeof (CK_BBOOL));
33255051Swyllys 		i++;
33263089Swyllys 		condition = (kuext.KeyUsageBits & KMF_dataEncipherment) ?
33275051Swyllys 		    B_TRUE : B_FALSE;
33285051Swyllys 		SETATTR(templ, i, CKA_DECRYPT, &condition, sizeof (CK_BBOOL));
33295051Swyllys 		i++;
33303089Swyllys 		condition = (kuext.KeyUsageBits & KMF_digitalSignature) ?
33315051Swyllys 		    B_TRUE : B_FALSE;
33325051Swyllys 		SETATTR(templ, i, CKA_SIGN, &condition,	sizeof (CK_BBOOL));
33335051Swyllys 		i++;
33343089Swyllys 		condition = (kuext.KeyUsageBits & KMF_digitalSignature) ?
33355051Swyllys 		    B_TRUE : B_FALSE;
33363089Swyllys 		SETATTR(templ, i, CKA_SIGN_RECOVER, &condition,
33375051Swyllys 		    sizeof (CK_BBOOL));
33383089Swyllys 		i++;
33395051Swyllys 
33403089Swyllys 	}
33415051Swyllys 
33425051Swyllys 	if (keylabel != NULL) {
33435051Swyllys 		SETATTR(templ, i, CKA_LABEL, keylabel, strlen(keylabel));
33443089Swyllys 		i++;
33453089Swyllys 	}
33465536Swyllys 	if (id.Data == NULL && rawkey->id.Data != NULL) {
33475536Swyllys 		SETATTR(templ, i, CKA_ID, rawkey->id.Data,
33485536Swyllys 		    rawkey->id.Length);
33495536Swyllys 		i++;
33505536Swyllys 	}
33513089Swyllys 	if (keytype == CKK_RSA) {
33523089Swyllys 		SETATTR(templ, i, CKA_MODULUS,
33535051Swyllys 		    rawkey->rawdata.rsa.mod.val,
33545051Swyllys 		    rawkey->rawdata.rsa.mod.len);
33553089Swyllys 		i++;
33563089Swyllys 		SETATTR(templ, i, CKA_PUBLIC_EXPONENT,
33575051Swyllys 		    rawkey->rawdata.rsa.pubexp.val,
33585051Swyllys 		    rawkey->rawdata.rsa.pubexp.len);
33593089Swyllys 		i++;
33603089Swyllys 		if (rawkey->rawdata.rsa.priexp.val != NULL) {
33613089Swyllys 			SETATTR(templ, i, CKA_PRIVATE_EXPONENT,
33625051Swyllys 			    rawkey->rawdata.rsa.priexp.val,
33635051Swyllys 			    rawkey->rawdata.rsa.priexp.len);
33643089Swyllys 			i++;
33653089Swyllys 		}
33663089Swyllys 		if (rawkey->rawdata.rsa.prime1.val != NULL) {
33673089Swyllys 			SETATTR(templ, i, CKA_PRIME_1,
33685051Swyllys 			    rawkey->rawdata.rsa.prime1.val,
33695051Swyllys 			    rawkey->rawdata.rsa.prime1.len);
33703089Swyllys 			i++;
33713089Swyllys 		}
33723089Swyllys 		if (rawkey->rawdata.rsa.prime2.val != NULL) {
33733089Swyllys 			SETATTR(templ, i, CKA_PRIME_2,
33745051Swyllys 			    rawkey->rawdata.rsa.prime2.val,
33755051Swyllys 			    rawkey->rawdata.rsa.prime2.len);
33763089Swyllys 			i++;
33773089Swyllys 		}
33783089Swyllys 		if (rawkey->rawdata.rsa.exp1.val != NULL) {
33793089Swyllys 			SETATTR(templ, i, CKA_EXPONENT_1,
33805051Swyllys 			    rawkey->rawdata.rsa.exp1.val,
33815051Swyllys 			    rawkey->rawdata.rsa.exp1.len);
33823089Swyllys 			i++;
33833089Swyllys 		}
33843089Swyllys 		if (rawkey->rawdata.rsa.exp2.val != NULL) {
33853089Swyllys 			SETATTR(templ, i, CKA_EXPONENT_2,
33865051Swyllys 			    rawkey->rawdata.rsa.exp2.val,
33875051Swyllys 			    rawkey->rawdata.rsa.exp2.len);
33883089Swyllys 			i++;
33893089Swyllys 		}
33903089Swyllys 		if (rawkey->rawdata.rsa.coef.val != NULL) {
33913089Swyllys 			SETATTR(templ, i, CKA_COEFFICIENT,
33925051Swyllys 			    rawkey->rawdata.rsa.coef.val,
33935051Swyllys 			    rawkey->rawdata.rsa.coef.len);
33943089Swyllys 			i++;
33953089Swyllys 		}
339611973Swyllys.ingersoll@sun.com 	} else if (keytype == CKK_DSA) {
33973089Swyllys 		SETATTR(templ, i, CKA_PRIME,
33985051Swyllys 		    rawkey->rawdata.dsa.prime.val,
33995051Swyllys 		    rawkey->rawdata.dsa.prime.len);
34003089Swyllys 		i++;
34013089Swyllys 		SETATTR(templ, i, CKA_SUBPRIME,
34025051Swyllys 		    rawkey->rawdata.dsa.subprime.val,
34035051Swyllys 		    rawkey->rawdata.dsa.subprime.len);
34043089Swyllys 		i++;
34053089Swyllys 		SETATTR(templ, i, CKA_BASE,
34065051Swyllys 		    rawkey->rawdata.dsa.base.val,
34075051Swyllys 		    rawkey->rawdata.dsa.base.len);
34083089Swyllys 		i++;
34093089Swyllys 		SETATTR(templ, i, CKA_VALUE,
34105051Swyllys 		    rawkey->rawdata.dsa.value.val,
34115051Swyllys 		    rawkey->rawdata.dsa.value.len);
34123089Swyllys 		i++;
341311973Swyllys.ingersoll@sun.com 	} else if (keytype == CKK_EC) {
341411973Swyllys.ingersoll@sun.com 		SETATTR(templ, i, CKA_SIGN, &cktrue, sizeof (cktrue));
341511973Swyllys.ingersoll@sun.com 		i++;
341611973Swyllys.ingersoll@sun.com 		SETATTR(templ, i, CKA_DERIVE, &cktrue, sizeof (cktrue));
341711973Swyllys.ingersoll@sun.com 		i++;
341811973Swyllys.ingersoll@sun.com 		SETATTR(templ, i, CKA_VALUE,
341911973Swyllys.ingersoll@sun.com 		    rawkey->rawdata.ec.value.val,
342011973Swyllys.ingersoll@sun.com 		    rawkey->rawdata.ec.value.len);
342111973Swyllys.ingersoll@sun.com 		i++;
342211973Swyllys.ingersoll@sun.com 		SETATTR(templ, i, CKA_EC_PARAMS,
342311973Swyllys.ingersoll@sun.com 		    rawkey->rawdata.ec.params.Data,
342411973Swyllys.ingersoll@sun.com 		    rawkey->rawdata.ec.params.Length);
342511973Swyllys.ingersoll@sun.com 		i++;
34263089Swyllys 	}
34273089Swyllys 
34283089Swyllys 	ckrv = C_CreateObject(kmfh->pk11handle, templ, i, &keyobj);
34293089Swyllys 	if (ckrv != CKR_OK) {
34303089Swyllys 		SET_ERROR(kmfh, ckrv);
34313089Swyllys 
34323089Swyllys 		/* Report authentication failures to the caller */
34333089Swyllys 		if (ckrv == CKR_USER_NOT_LOGGED_IN ||
34343089Swyllys 		    ckrv == CKR_PIN_INCORRECT ||
34353089Swyllys 		    ckrv == CKR_PIN_INVALID ||
34363089Swyllys 		    ckrv == CKR_PIN_EXPIRED ||
34373089Swyllys 		    ckrv == CKR_PIN_LOCKED ||
34383089Swyllys 		    ckrv == CKR_SESSION_READ_ONLY)
34393089Swyllys 			rv = KMF_ERR_AUTH_FAILED;
34403089Swyllys 		else
34413089Swyllys 			rv = KMF_ERR_INTERNAL;
34423089Swyllys 	}
34433089Swyllys cleanup:
34445536Swyllys 	if (start != NULL)
34455536Swyllys 		free(start);
34465536Swyllys 	if (end != NULL)
34475536Swyllys 		free(end);
34485051Swyllys 	kmf_free_data(&id);
34495051Swyllys 	kmf_free_data(&subject);
34505051Swyllys 	kmf_free_signed_cert(x509);
34513089Swyllys 	free(x509);
34523089Swyllys 
34533089Swyllys 	return (rv);
34543089Swyllys }
34553089Swyllys 
34563089Swyllys KMF_RETURN
KMFPK11_CreateSymKey(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)34575051Swyllys KMFPK11_CreateSymKey(KMF_HANDLE_T handle,
34585051Swyllys     int numattr, KMF_ATTRIBUTE *attrlist)
34593089Swyllys {
34603089Swyllys 	KMF_RETURN		rv = KMF_OK;
34613089Swyllys 	KMF_HANDLE		*kmfh = (KMF_HANDLE *)handle;
34623089Swyllys 	CK_RV			ckrv;
34633089Swyllys 	CK_SESSION_HANDLE	hSession = kmfh->pk11handle;
34643089Swyllys 	CK_OBJECT_HANDLE	keyhandle;
34653089Swyllys 	CK_MECHANISM		keyGenMech;
34663089Swyllys 	CK_OBJECT_CLASS		class = CKO_SECRET_KEY;
34673089Swyllys 	CK_ULONG		secKeyType;
34683089Swyllys 	CK_ULONG		secKeyLen;	/* for RC4 and AES */
34693089Swyllys 	CK_BBOOL		true = TRUE;
34703089Swyllys 	CK_BBOOL		false = FALSE;
34713089Swyllys 	CK_ATTRIBUTE		templ[15];
34725051Swyllys 	CK_BYTE			*keydata = NULL;
34735051Swyllys 	int			i = 0;
34745051Swyllys 	KMF_KEY_HANDLE		*symkey;
34755051Swyllys 	KMF_KEY_ALG		keytype;
34765051Swyllys 	uint32_t		keylen = 0;
34775051Swyllys 	uint32_t		attrkeylen = 0;
34785051Swyllys 	uint32_t		keylen_size = sizeof (uint32_t);
34795051Swyllys 	char			*keylabel = NULL;
34806051Swyllys 	KMF_CREDENTIAL		*cred = NULL;
34815051Swyllys 	uint32_t		is_sensitive = B_FALSE;
34825051Swyllys 	uint32_t		is_not_extractable = B_FALSE;
34833089Swyllys 
34843089Swyllys 	if (kmfh == NULL)
34853089Swyllys 		return (KMF_ERR_UNINITIALIZED);
34863089Swyllys 
34873089Swyllys 	if (kmfh->pk11handle == CK_INVALID_HANDLE)
34883089Swyllys 		return (KMF_ERR_NO_TOKEN_SELECTED);
34893089Swyllys 
34905051Swyllys 	symkey = kmf_get_attr_ptr(KMF_KEY_HANDLE_ATTR, attrlist, numattr);
34915051Swyllys 	if (symkey == NULL)
34925051Swyllys 		return (KMF_ERR_BAD_PARAMETER);
34935051Swyllys 
34945051Swyllys 	rv = kmf_get_attr(KMF_KEYALG_ATTR, attrlist, numattr,
34955051Swyllys 	    (void *)&keytype, NULL);
34965051Swyllys 	if (rv != KMF_OK)
34975051Swyllys 		return (KMF_ERR_BAD_PARAMETER);
34985051Swyllys 
34995051Swyllys 	keylabel = kmf_get_attr_ptr(KMF_KEYLABEL_ATTR, attrlist, numattr);
35005051Swyllys 	if (keylabel == NULL)
35013089Swyllys 		return (KMF_ERR_BAD_PARAMETER);
35025051Swyllys 
35035051Swyllys 	rv = kmf_get_attr(KMF_SENSITIVE_BOOL_ATTR, attrlist, numattr,
35045051Swyllys 	    (void *)&is_sensitive, NULL);
35055051Swyllys 	if (rv != KMF_OK)
35065051Swyllys 		return (KMF_ERR_BAD_PARAMETER);
35075051Swyllys 
35085051Swyllys 	rv = kmf_get_attr(KMF_NON_EXTRACTABLE_BOOL_ATTR, attrlist, numattr,
35095051Swyllys 	    (void *)&is_not_extractable, NULL);
35105051Swyllys 	if (rv != KMF_OK)
35115051Swyllys 		return (KMF_ERR_BAD_PARAMETER);
35125051Swyllys 
35133812Shylee 	/*
35143812Shylee 	 * For AES, RC4, DES and 3DES, call C_GenerateKey() to create a key.
35153812Shylee 	 *
35163812Shylee 	 * For a generic secret key, because it may not be supported in
35173812Shylee 	 * C_GenerateKey() for some PKCS11 providers, we will handle it
35183812Shylee 	 * differently.
35193812Shylee 	 */
35205051Swyllys 	if (keytype == KMF_GENERIC_SECRET) {
35215051Swyllys 		rv = create_generic_secret_key(handle, numattr,
35225051Swyllys 		    attrlist, &keyhandle);
35233812Shylee 		if (rv != KMF_OK)
35243812Shylee 			goto out;
35253812Shylee 		else
35263812Shylee 			goto setup;
35273812Shylee 	}
35283812Shylee 
35295051Swyllys 	rv = kmf_get_attr(KMF_KEY_DATA_ATTR, attrlist, numattr,
35305051Swyllys 	    NULL, &attrkeylen);
35315051Swyllys 	if (rv == KMF_OK && attrkeylen > 0) {
35325051Swyllys 		keydata = kmf_get_attr_ptr(KMF_KEY_DATA_ATTR, attrlist,
35335051Swyllys 		    numattr);
35345051Swyllys 	} else {
35355051Swyllys 		keydata = NULL;
35365051Swyllys 		attrkeylen = 0;
35375051Swyllys 		rv = KMF_OK;
35385051Swyllys 	}
35395051Swyllys 	if (keydata != NULL) {
35405051Swyllys 		if (keytype == KMF_DES && attrkeylen != 8) {
35415051Swyllys 			rv = KMF_ERR_BAD_KEY_SIZE;
35425051Swyllys 			goto out;
35435051Swyllys 		}
35445051Swyllys 		if (keytype == KMF_DES3 && attrkeylen != 24) {
35455051Swyllys 			rv = KMF_ERR_BAD_KEY_SIZE;
35465051Swyllys 			goto out;
35475051Swyllys 		}
35485051Swyllys 		/*
35495051Swyllys 		 * This may override what the user gave on the
35505051Swyllys 		 * command line.
35515051Swyllys 		 */
35525051Swyllys 		keylen = attrkeylen * 8; /* bytes to bits */
35535051Swyllys 	} else {
35545051Swyllys 		/*
35555051Swyllys 		 * If keydata was not given, key length must be
35565051Swyllys 		 * provided.
35575051Swyllys 		 */
35585051Swyllys 		rv = kmf_get_attr(KMF_KEYLENGTH_ATTR, attrlist, numattr,
35595051Swyllys 		    &keylen, &keylen_size);
35605051Swyllys 		if (rv == KMF_ERR_ATTR_NOT_FOUND &&
35615051Swyllys 		    (keytype == KMF_DES || keytype == KMF_DES3))
35625051Swyllys 			/* keylength is not required for DES and 3DES */
35635051Swyllys 			rv = KMF_OK;
35645051Swyllys 		if (rv != KMF_OK)
35655051Swyllys 			return (KMF_ERR_BAD_PARAMETER);
35665051Swyllys 	}
35675051Swyllys 
35685051Swyllys 	if ((keylen % 8) != 0) {
35695051Swyllys 		return (KMF_ERR_BAD_KEY_SIZE);
35705051Swyllys 	}
35715051Swyllys 	secKeyLen = keylen / 8;  /* in bytes for RC4/AES */
35725051Swyllys 
35735051Swyllys 	/*
35745051Swyllys 	 * Only set CKA_VALUE_LEN if the key data was not given and
35755051Swyllys 	 * we are creating an RC4 or AES key.
35765051Swyllys 	 */
35775051Swyllys 	if (keydata == NULL &&
35785051Swyllys 	    (keytype == KMF_AES || keytype == KMF_RC4)) {
35795051Swyllys 		SETATTR(templ, i, CKA_VALUE_LEN, &secKeyLen,
35805051Swyllys 		    sizeof (secKeyLen));
35815051Swyllys 		i++;
35825051Swyllys 	}
35835051Swyllys 
35843812Shylee 	/* Other keytypes */
35853089Swyllys 	keyGenMech.pParameter = NULL_PTR;
35863089Swyllys 	keyGenMech.ulParameterLen = 0;
35875051Swyllys 	switch (keytype) {
35885051Swyllys 		case KMF_AES:
35895051Swyllys 			keyGenMech.mechanism = CKM_AES_KEY_GEN;
35905051Swyllys 			secKeyType = CKK_AES;
35915051Swyllys 			break;
35925051Swyllys 		case KMF_RC4:
35935051Swyllys 			keyGenMech.mechanism = CKM_RC4_KEY_GEN;
35945051Swyllys 			secKeyType = CKK_RC4;
35955051Swyllys 			break;
35965051Swyllys 		case KMF_DES:
35975051Swyllys 			keyGenMech.mechanism = CKM_DES_KEY_GEN;
35985051Swyllys 			secKeyType = CKK_DES;
35995051Swyllys 			break;
36005051Swyllys 		case KMF_DES3:
36015051Swyllys 			keyGenMech.mechanism = CKM_DES3_KEY_GEN;
36025051Swyllys 			secKeyType = CKK_DES3;
36035051Swyllys 			break;
36045051Swyllys 		default:
36055051Swyllys 			return (KMF_ERR_BAD_KEY_TYPE);
36063089Swyllys 	}
36075051Swyllys 	if (keydata != NULL) {
36085051Swyllys 		SETATTR(templ, i, CKA_VALUE, keydata, secKeyLen);
36095051Swyllys 		i++;
36105051Swyllys 	}
36113089Swyllys 	SETATTR(templ, i, CKA_CLASS, &class, sizeof (class));
36123089Swyllys 	i++;
36133089Swyllys 	SETATTR(templ, i, CKA_KEY_TYPE, &secKeyType, sizeof (secKeyType));
36143089Swyllys 	i++;
36153089Swyllys 
36165051Swyllys 	if (keylabel != NULL) {
36175051Swyllys 		SETATTR(templ, i, CKA_LABEL, keylabel, strlen(keylabel));
36183089Swyllys 		i++;
36193089Swyllys 	}
36203089Swyllys 
36215051Swyllys 	if (is_sensitive == B_TRUE) {
36223089Swyllys 		SETATTR(templ, i, CKA_SENSITIVE, &true, sizeof (true));
36233089Swyllys 	} else {
36243089Swyllys 		SETATTR(templ, i, CKA_SENSITIVE, &false, sizeof (false));
36253089Swyllys 	}
36263089Swyllys 	i++;
36273089Swyllys 
36285051Swyllys 	if (is_not_extractable == B_TRUE) {
36293089Swyllys 		SETATTR(templ, i, CKA_EXTRACTABLE, &false, sizeof (false));
36303089Swyllys 	} else {
36313089Swyllys 		SETATTR(templ, i, CKA_EXTRACTABLE, &true, sizeof (true));
36323089Swyllys 	}
36333089Swyllys 	i++;
36343089Swyllys 
36353089Swyllys 	SETATTR(templ, i, CKA_TOKEN, &true, sizeof (true));
36363089Swyllys 	i++;
36373089Swyllys 	SETATTR(templ, i, CKA_PRIVATE, &true, sizeof (true));
36383089Swyllys 	i++;
36393089Swyllys 	SETATTR(templ, i, CKA_ENCRYPT, &true, sizeof (true));
36403089Swyllys 	i++;
36413089Swyllys 	SETATTR(templ, i, CKA_DECRYPT, &true, sizeof (true));
36423089Swyllys 	i++;
36433089Swyllys 	SETATTR(templ, i, CKA_SIGN, &true, sizeof (true));
36443089Swyllys 	i++;
36453089Swyllys 	SETATTR(templ, i, CKA_VERIFY, &true, sizeof (true));
36463089Swyllys 	i++;
36473089Swyllys 
36486051Swyllys 	cred = kmf_get_attr_ptr(KMF_CREDENTIAL_ATTR, attrlist, numattr);
36496051Swyllys 	if (cred == NULL)
36505051Swyllys 		return (KMF_ERR_BAD_PARAMETER);
36515051Swyllys 
36526051Swyllys 	rv = pk11_authenticate(handle, cred);
36533089Swyllys 	if (rv != KMF_OK) {
36543089Swyllys 		return (rv);
36553089Swyllys 	}
36563089Swyllys 
36575051Swyllys 	/* If the key data was given, use C_CreateObject */
36585051Swyllys 	if (keydata != NULL) {
36595051Swyllys 		ckrv = C_CreateObject(hSession, templ, i, &keyhandle);
36605051Swyllys 	} else {
36615051Swyllys 		ckrv = C_GenerateKey(hSession, &keyGenMech, templ, i,
36625051Swyllys 		    &keyhandle);
36635051Swyllys 	}
36643089Swyllys 	if (ckrv != CKR_OK) {
36656354Swyllys 		if (ckrv == CKR_USER_NOT_LOGGED_IN ||
36666354Swyllys 		    ckrv == CKR_PIN_INCORRECT ||
36676354Swyllys 		    ckrv == CKR_PIN_INVALID ||
36686354Swyllys 		    ckrv == CKR_PIN_EXPIRED ||
36696354Swyllys 		    ckrv == CKR_PIN_LOCKED ||
36706354Swyllys 		    ckrv == CKR_SESSION_READ_ONLY)
36716354Swyllys 			rv = KMF_ERR_AUTH_FAILED;
36726354Swyllys 		else
36736354Swyllys 			rv = KMF_ERR_KEYGEN_FAILED;
36743089Swyllys 		SET_ERROR(kmfh, ckrv);
36753089Swyllys 		goto out;
36763089Swyllys 	}
36773089Swyllys 
36783812Shylee setup:
36793089Swyllys 	symkey->kstype = KMF_KEYSTORE_PK11TOKEN;
36805051Swyllys 	symkey->keyalg = keytype;
36813089Swyllys 	symkey->keyclass = KMF_SYMMETRIC;
36823089Swyllys 	symkey->israw = FALSE;
36833089Swyllys 	symkey->keyp = (void *)keyhandle;
36843089Swyllys 
36853089Swyllys out:
36863089Swyllys 	return (rv);
36873089Swyllys }
36883089Swyllys 
36893089Swyllys KMF_RETURN
KMFPK11_GetSymKeyValue(KMF_HANDLE_T handle,KMF_KEY_HANDLE * symkey,KMF_RAW_SYM_KEY * rkey)36903089Swyllys KMFPK11_GetSymKeyValue(KMF_HANDLE_T handle, KMF_KEY_HANDLE *symkey,
36913089Swyllys     KMF_RAW_SYM_KEY *rkey)
36923089Swyllys {
36933089Swyllys 	KMF_RETURN		rv = KMF_OK;
36943089Swyllys 	KMF_HANDLE		*kmfh = (KMF_HANDLE *)handle;
36953089Swyllys 
36963089Swyllys 	if (kmfh == NULL)
36973089Swyllys 		return (KMF_ERR_UNINITIALIZED);
36983089Swyllys 
36993089Swyllys 	if (kmfh->pk11handle == CK_INVALID_HANDLE)
37003089Swyllys 		return (KMF_ERR_NO_TOKEN_SELECTED);
37013089Swyllys 
37023089Swyllys 	if (symkey == NULL || rkey == NULL)
37033089Swyllys 		return (KMF_ERR_BAD_PARAMETER);
37043089Swyllys 	else if (symkey->keyclass != KMF_SYMMETRIC)
37053089Swyllys 		return (KMF_ERR_BAD_KEY_CLASS);
37063089Swyllys 
37075051Swyllys 	/*
37085051Swyllys 	 * If the key is already in "raw" format, copy the data
37095051Swyllys 	 * to the new record if possible.
37105051Swyllys 	 */
37113089Swyllys 	if (symkey->israw) {
37123089Swyllys 		KMF_RAW_KEY_DATA *rawkey = (KMF_RAW_KEY_DATA *)symkey->keyp;
37133089Swyllys 
37145051Swyllys 		if (rawkey == NULL)
37155051Swyllys 			return (KMF_ERR_BAD_KEYHANDLE);
37165051Swyllys 		if (rawkey->sensitive)
37175051Swyllys 			return (KMF_ERR_SENSITIVE_KEY);
37185051Swyllys 		if (rawkey->not_extractable)
37195051Swyllys 			return (KMF_ERR_UNEXTRACTABLE_KEY);
37205051Swyllys 
37215051Swyllys 		if (rawkey->rawdata.sym.keydata.val == NULL ||
37223089Swyllys 		    rawkey->rawdata.sym.keydata.len == 0)
37235051Swyllys 			return (KMF_ERR_GETKEYVALUE_FAILED);
37243089Swyllys 
37253089Swyllys 		rkey->keydata.len = rawkey->rawdata.sym.keydata.len;
37263089Swyllys 		if ((rkey->keydata.val = malloc(rkey->keydata.len)) == NULL)
37273089Swyllys 			return (KMF_ERR_MEMORY);
37283089Swyllys 		(void) memcpy(rkey->keydata.val,
37295051Swyllys 		    rawkey->rawdata.sym.keydata.val, rkey->keydata.len);
37303089Swyllys 	} else {
37313089Swyllys 		rv = get_raw_sym(kmfh, (CK_OBJECT_HANDLE)symkey->keyp, rkey);
37323089Swyllys 	}
37333089Swyllys 
37343089Swyllys 	return (rv);
37353089Swyllys }
37363089Swyllys 
37373089Swyllys KMF_RETURN
KMFPK11_SetTokenPin(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)37385051Swyllys KMFPK11_SetTokenPin(KMF_HANDLE_T handle,
37395051Swyllys 	int numattr, KMF_ATTRIBUTE *attrlist)
37403089Swyllys {
37413089Swyllys 	KMF_RETURN	ret = KMF_OK;
37423089Swyllys 	CK_RV		rv = CKR_OK;
37433089Swyllys 	KMF_HANDLE	*kmfh = (KMF_HANDLE *)handle;
37443089Swyllys 	CK_SESSION_HANDLE	session = NULL;
37456051Swyllys 	KMF_CREDENTIAL	*oldcred;
37466051Swyllys 	KMF_CREDENTIAL	*newcred;
37475051Swyllys 	CK_SLOT_ID	slotid;
37489126SWyllys.Ingersoll@Sun.COM 	CK_USER_TYPE	user = CKU_USER;
37495051Swyllys 
37505051Swyllys 	if (handle == NULL || attrlist == NULL || numattr == 0)
37515051Swyllys 		return (KMF_ERR_BAD_PARAMETER);
37525051Swyllys 
37536051Swyllys 	oldcred = kmf_get_attr_ptr(KMF_CREDENTIAL_ATTR, attrlist, numattr);
37546051Swyllys 	if (oldcred == NULL)
37555051Swyllys 		return (KMF_ERR_BAD_PARAMETER);
37565051Swyllys 
37576051Swyllys 	newcred = kmf_get_attr_ptr(KMF_NEWPIN_ATTR, attrlist, numattr);
37586051Swyllys 	if (newcred == NULL)
37593089Swyllys 		return (KMF_ERR_BAD_PARAMETER);
37603089Swyllys 
37615051Swyllys 	rv = kmf_get_attr(KMF_SLOT_ID_ATTR, attrlist, numattr,
37625051Swyllys 	    (void *)&slotid, NULL);
37635051Swyllys 	if (rv != KMF_OK) {
37645051Swyllys 		char *tokenlabel = NULL;
37655051Swyllys 		/*
37665051Swyllys 		 * If a slot wasn't given, the user must pass
37675051Swyllys 		 * a token label so we can find the slot here.
37685051Swyllys 		 */
37696051Swyllys 		tokenlabel = kmf_get_attr_ptr(KMF_TOKEN_LABEL_ATTR, attrlist,
37706051Swyllys 		    numattr);
37716051Swyllys 		if (tokenlabel == NULL)
37726051Swyllys 			return (KMF_ERR_BAD_PARAMETER);
37735051Swyllys 
37745051Swyllys 		rv = kmf_pk11_token_lookup(handle, tokenlabel, &slotid);
37755051Swyllys 		if (rv != KMF_OK)
37765051Swyllys 			return (rv);
37775051Swyllys 	}
37789126SWyllys.Ingersoll@Sun.COM 	rv = kmf_get_attr(KMF_PK11_USER_TYPE_ATTR, attrlist, numattr,
37799126SWyllys.Ingersoll@Sun.COM 	    (void *)&user, NULL);
37809126SWyllys.Ingersoll@Sun.COM 	if (rv != CKR_OK)
37819126SWyllys.Ingersoll@Sun.COM 		user = CKU_USER;
37825051Swyllys 
37835051Swyllys 	rv = C_OpenSession(slotid, CKF_SERIAL_SESSION | CKF_RW_SESSION,
37845051Swyllys 	    NULL, NULL, &session);
37853089Swyllys 	if (rv != CKR_OK) {
37863089Swyllys 		SET_ERROR(kmfh, rv);
37873089Swyllys 		ret = KMF_ERR_UNINITIALIZED;
37883089Swyllys 		goto end;
37893089Swyllys 	}
37903089Swyllys 
37919126SWyllys.Ingersoll@Sun.COM 	rv = C_Login(session, user, (CK_BYTE *)oldcred->cred,
37929126SWyllys.Ingersoll@Sun.COM 	    oldcred->credlen);
37939126SWyllys.Ingersoll@Sun.COM 	if (rv != CKR_OK) {
37949126SWyllys.Ingersoll@Sun.COM 		SET_ERROR(kmfh, rv);
37959126SWyllys.Ingersoll@Sun.COM 		if (rv == CKR_PIN_INCORRECT ||
37969126SWyllys.Ingersoll@Sun.COM 		    rv == CKR_PIN_INVALID ||
37979126SWyllys.Ingersoll@Sun.COM 		    rv == CKR_PIN_EXPIRED ||
37989126SWyllys.Ingersoll@Sun.COM 		    rv == CKR_PIN_LOCKED)
37999126SWyllys.Ingersoll@Sun.COM 			ret = KMF_ERR_AUTH_FAILED;
38009126SWyllys.Ingersoll@Sun.COM 		else
38019126SWyllys.Ingersoll@Sun.COM 			ret = KMF_ERR_INTERNAL;
38029126SWyllys.Ingersoll@Sun.COM 
38039126SWyllys.Ingersoll@Sun.COM 		goto end;
38049126SWyllys.Ingersoll@Sun.COM 	}
38059126SWyllys.Ingersoll@Sun.COM 
38063089Swyllys 	rv = C_SetPIN(session,
38076051Swyllys 	    (CK_BYTE *)oldcred->cred, oldcred->credlen,
38086051Swyllys 	    (CK_BYTE *)newcred->cred, newcred->credlen);
38093089Swyllys 
38103089Swyllys 	if (rv != CKR_OK) {
38113089Swyllys 		SET_ERROR(kmfh, rv);
38123089Swyllys 		if (rv == CKR_PIN_INCORRECT ||
38133089Swyllys 		    rv == CKR_PIN_INVALID ||
38143089Swyllys 		    rv == CKR_PIN_EXPIRED ||
38153089Swyllys 		    rv == CKR_PIN_LOCKED)
38163089Swyllys 			ret = KMF_ERR_AUTH_FAILED;
38173089Swyllys 		else
38183089Swyllys 			ret = KMF_ERR_INTERNAL;
38193089Swyllys 	}
38203089Swyllys end:
38213089Swyllys 	if (session != NULL)
38223089Swyllys 		(void) C_CloseSession(session);
38233089Swyllys 	return (ret);
38243089Swyllys }
38253754Swyllys 
38263754Swyllys static KMF_RETURN
create_generic_secret_key(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist,CK_OBJECT_HANDLE * key)38273812Shylee create_generic_secret_key(KMF_HANDLE_T handle,
38285051Swyllys 	int numattr, KMF_ATTRIBUTE *attrlist, CK_OBJECT_HANDLE *key)
38293812Shylee {
38303812Shylee 	KMF_RETURN		rv = KMF_OK;
38313812Shylee 	KMF_HANDLE		*kmfh = (KMF_HANDLE *)handle;
38323812Shylee 	CK_RV			ckrv;
38333812Shylee 	CK_SESSION_HANDLE	hSession = kmfh->pk11handle;
38343812Shylee 	CK_OBJECT_CLASS		class = CKO_SECRET_KEY;
38353812Shylee 	CK_ULONG		secKeyType = CKK_GENERIC_SECRET;
38363812Shylee 	CK_ULONG		secKeyLen;
38373812Shylee 	CK_BBOOL		true = TRUE;
38383812Shylee 	CK_BBOOL		false = FALSE;
38393812Shylee 	CK_ATTRIBUTE		templ[15];
38403812Shylee 	int			i;
38413812Shylee 	int			random_fd = -1;
38423812Shylee 	int			nread;
38435051Swyllys 	int			freebuf = 0;
38443812Shylee 	char			*buf = NULL;
38455051Swyllys 	uint32_t		keylen = 0, attrkeylen = 0;
38465051Swyllys 	char			*keylabel = NULL;
38475051Swyllys 	KMF_CREDENTIAL		*cred;
38485051Swyllys 	uint32_t is_sensitive, is_not_extractable;
38495051Swyllys 
38505051Swyllys 	keylabel = kmf_get_attr_ptr(KMF_KEYLABEL_ATTR, attrlist, numattr);
38515051Swyllys 	if (keylabel == NULL)
38525051Swyllys 		return (KMF_ERR_BAD_PARAMETER);
38535051Swyllys 
38545051Swyllys 	cred = kmf_get_attr_ptr(KMF_CREDENTIAL_ATTR, attrlist, numattr);
38555051Swyllys 	if (cred == NULL)
38565051Swyllys 		return (KMF_ERR_BAD_PARAMETER);
38575051Swyllys 
38585051Swyllys 	rv = kmf_get_attr(KMF_SENSITIVE_BOOL_ATTR, attrlist, numattr,
38595051Swyllys 	    (void *)&is_sensitive, NULL);
38605051Swyllys 	if (rv != KMF_OK)
38615051Swyllys 		return (KMF_ERR_BAD_PARAMETER);
38625051Swyllys 
38635051Swyllys 	rv = kmf_get_attr(KMF_NON_EXTRACTABLE_BOOL_ATTR, attrlist, numattr,
38645051Swyllys 	    (void *)&is_not_extractable, NULL);
38655051Swyllys 	if (rv != KMF_OK)
38665051Swyllys 		return (KMF_ERR_BAD_PARAMETER);
38675051Swyllys 
38685051Swyllys 	rv = kmf_get_attr(KMF_KEY_DATA_ATTR, attrlist, numattr,
38695051Swyllys 	    NULL, &attrkeylen);
38705051Swyllys 	if (rv == KMF_OK && attrkeylen > 0) {
38715051Swyllys 		buf = kmf_get_attr_ptr(KMF_KEY_DATA_ATTR, attrlist,
38725051Swyllys 		    numattr);
38735051Swyllys 		secKeyLen = attrkeylen;
38743812Shylee 	} else {
38755051Swyllys 		buf = NULL;
38765051Swyllys 		rv = KMF_OK;
38773812Shylee 	}
38785051Swyllys 	if (buf == NULL) {
38795051Swyllys 		/*
38805051Swyllys 		 * If the key data was not given, key length must
38815051Swyllys 		 * be provided.
38825051Swyllys 		 */
38835051Swyllys 		rv = kmf_get_attr(KMF_KEYLENGTH_ATTR, attrlist, numattr,
38845051Swyllys 		    &keylen, NULL);
38855051Swyllys 		if (rv != KMF_OK)
38865051Swyllys 			return (KMF_ERR_BAD_PARAMETER);
38875051Swyllys 
38885051Swyllys 		/*
38895051Swyllys 		 * Check the key size.
38905051Swyllys 		 */
38915051Swyllys 		if ((keylen % 8) != 0) {
38925051Swyllys 			return (KMF_ERR_BAD_KEY_SIZE);
38935051Swyllys 		} else {
38945051Swyllys 			secKeyLen = keylen/8;  /* in bytes */
38955051Swyllys 		}
38965051Swyllys 
38975051Swyllys 		/*
38985051Swyllys 		 * Generate a random number with the key size first.
38995051Swyllys 		 */
39005051Swyllys 		buf = malloc(secKeyLen);
39015051Swyllys 		if (buf == NULL)
39025051Swyllys 			return (KMF_ERR_MEMORY);
39035051Swyllys 
39045051Swyllys 		freebuf = 1;
39055051Swyllys 		while ((random_fd = open(DEV_RANDOM, O_RDONLY)) < 0) {
39065051Swyllys 			if (errno != EINTR)
39075051Swyllys 				break;
39085051Swyllys 		}
39095051Swyllys 
39105051Swyllys 		if (random_fd < 0) {
39115051Swyllys 			rv = KMF_ERR_KEYGEN_FAILED;
39125051Swyllys 			goto out;
39135051Swyllys 		}
39145051Swyllys 
39155051Swyllys 		nread = read(random_fd, buf, secKeyLen);
39165051Swyllys 		if (nread <= 0 || nread != secKeyLen) {
39175051Swyllys 			rv = KMF_ERR_KEYGEN_FAILED;
39185051Swyllys 			goto out;
39195051Swyllys 		}
39203812Shylee 	}
39213812Shylee 
39223812Shylee 	/*
39233812Shylee 	 * Authenticate into the token and call C_CreateObject to generate
39243812Shylee 	 * a generic secret token key.
39253812Shylee 	 */
39265051Swyllys 	rv = pk11_authenticate(handle, cred);
39273812Shylee 	if (rv != KMF_OK) {
39283812Shylee 		goto out;
39293812Shylee 	}
39303812Shylee 
39313812Shylee 	i = 0;
39323812Shylee 	SETATTR(templ, i, CKA_CLASS, &class, sizeof (class));
39333812Shylee 	i++;
39343812Shylee 	SETATTR(templ, i, CKA_KEY_TYPE, &secKeyType, sizeof (secKeyType));
39353812Shylee 	i++;
39363812Shylee 	SETATTR(templ, i, CKA_VALUE, buf, secKeyLen);
39373812Shylee 	i++;
39383812Shylee 
39395051Swyllys 	if (keylabel != NULL) {
39405051Swyllys 		SETATTR(templ, i, CKA_LABEL, keylabel, strlen(keylabel));
39413812Shylee 		i++;
39423812Shylee 	}
39433812Shylee 
39445051Swyllys 	if (is_sensitive == B_TRUE) {
39453812Shylee 		SETATTR(templ, i, CKA_SENSITIVE, &true, sizeof (true));
39463812Shylee 	} else {
39473812Shylee 		SETATTR(templ, i, CKA_SENSITIVE, &false, sizeof (false));
39483812Shylee 	}
39493812Shylee 	i++;
39503812Shylee 
39515051Swyllys 	if (is_not_extractable == B_TRUE) {
39523812Shylee 		SETATTR(templ, i, CKA_EXTRACTABLE, &false, sizeof (false));
39533812Shylee 	} else {
39543812Shylee 		SETATTR(templ, i, CKA_EXTRACTABLE, &true, sizeof (true));
39553812Shylee 	}
39563812Shylee 	i++;
39573812Shylee 
39583812Shylee 	SETATTR(templ, i, CKA_TOKEN, &true, sizeof (true));
39593812Shylee 	i++;
39603812Shylee 	SETATTR(templ, i, CKA_PRIVATE, &true, sizeof (true));
39613812Shylee 	i++;
39623812Shylee 	SETATTR(templ, i, CKA_SIGN, &true, sizeof (true));
39633812Shylee 	i++;
39643812Shylee 
39653812Shylee 	ckrv = C_CreateObject(hSession, templ, i, key);
39663812Shylee 	if (ckrv != CKR_OK) {
39676354Swyllys 		if (ckrv == CKR_USER_NOT_LOGGED_IN ||
39686354Swyllys 		    ckrv == CKR_PIN_INCORRECT ||
39696354Swyllys 		    ckrv == CKR_PIN_INVALID ||
39706354Swyllys 		    ckrv == CKR_PIN_EXPIRED ||
39716354Swyllys 		    ckrv == CKR_PIN_LOCKED ||
39726354Swyllys 		    ckrv == CKR_SESSION_READ_ONLY)
39736354Swyllys 			rv = KMF_ERR_AUTH_FAILED;
39746354Swyllys 		else
39756354Swyllys 			rv = KMF_ERR_KEYGEN_FAILED;
39763812Shylee 		SET_ERROR(kmfh, ckrv);
39773812Shylee 	}
39783812Shylee 
39793812Shylee out:
39805051Swyllys 	if (buf != NULL && freebuf)
39813812Shylee 		free(buf);
39823812Shylee 
39833812Shylee 	if (random_fd != -1)
39843812Shylee 		(void) close(random_fd);
39853812Shylee 
39863812Shylee 	return (rv);
39873812Shylee }
39885051Swyllys 
39895051Swyllys KMF_RETURN
KMFPK11_StoreKey(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attlist)39905051Swyllys KMFPK11_StoreKey(KMF_HANDLE_T handle,
39915051Swyllys 	int numattr,
39925051Swyllys 	KMF_ATTRIBUTE *attlist)
39935051Swyllys {
39945051Swyllys 	KMF_RETURN rv = KMF_OK;
39955051Swyllys 	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
39965051Swyllys 	KMF_CREDENTIAL cred = {NULL, 0};
39975051Swyllys 	KMF_KEY_HANDLE *key;
39985814Swyllys 	KMF_RAW_KEY_DATA *rawkey = NULL;
39995051Swyllys 	CK_BBOOL btrue = TRUE;
40005051Swyllys 	CK_ATTRIBUTE tokenattr[1];
40015051Swyllys 	CK_OBJECT_HANDLE newobj;
40025051Swyllys 	CK_RV ckrv;
40035051Swyllys 
40045051Swyllys 	if (kmfh == NULL)
40055051Swyllys 		return (KMF_ERR_UNINITIALIZED);
40065051Swyllys 
40075051Swyllys 	if (kmfh->pk11handle == CK_INVALID_HANDLE)
40085051Swyllys 		return (KMF_ERR_NO_TOKEN_SELECTED);
40095051Swyllys 
40105051Swyllys 	rv = kmf_get_attr(KMF_CREDENTIAL_ATTR, attlist, numattr,
40115051Swyllys 	    (void *)&cred, NULL);
40125051Swyllys 	if (rv != KMF_OK)
40135051Swyllys 		return (KMF_ERR_BAD_PARAMETER);
40145051Swyllys 
40155051Swyllys 	rv = pk11_authenticate(handle, &cred);
40165051Swyllys 	if (rv != KMF_OK)
40175051Swyllys 		return (rv);
40185051Swyllys 
40195051Swyllys 	key = kmf_get_attr_ptr(KMF_PUBKEY_HANDLE_ATTR, attlist, numattr);
40205051Swyllys 	if (key == NULL) {
40215051Swyllys 		key = kmf_get_attr_ptr(KMF_PRIVKEY_HANDLE_ATTR, attlist,
40225051Swyllys 		    numattr);
40235051Swyllys 		if (key == NULL)
40245051Swyllys 			rawkey = kmf_get_attr_ptr(KMF_RAW_KEY_ATTR, attlist,
40255051Swyllys 			    numattr);
40265051Swyllys 	}
40275051Swyllys 	if (key == NULL && rawkey == NULL)
40285051Swyllys 		return (KMF_ERR_ATTR_NOT_FOUND);
40295051Swyllys 
40305051Swyllys 	if (rawkey != NULL) {
40315051Swyllys 		rv = store_raw_key(handle, attlist, numattr, rawkey);
40325051Swyllys 	} else if (key && key->kstype == KMF_KEYSTORE_PK11TOKEN) {
40335051Swyllys 
40345051Swyllys 		SETATTR(tokenattr, 0, CKA_TOKEN, &btrue, sizeof (btrue));
40355051Swyllys 		/* Copy the key object to the token */
40365051Swyllys 		ckrv = C_CopyObject(kmfh->pk11handle,
40375051Swyllys 		    (CK_OBJECT_HANDLE)key->keyp, tokenattr, 1, &newobj);
40385051Swyllys 		if (ckrv != CKR_OK)  {
40395051Swyllys 			SET_ERROR(kmfh, ckrv);
40405051Swyllys 			return (KMF_ERR_INTERNAL);
40415051Swyllys 		}
40425051Swyllys 
40435051Swyllys 		/* Replace the object handle with the new token-based one */
40445051Swyllys 		ckrv = C_DestroyObject(kmfh->pk11handle,
40455051Swyllys 		    (CK_OBJECT_HANDLE)key->keyp);
40465051Swyllys 		if (ckrv != CKR_OK)  {
40475051Swyllys 			SET_ERROR(kmfh, ckrv);
40485051Swyllys 			return (KMF_ERR_INTERNAL);
40495051Swyllys 		}
40505051Swyllys 		key->keyp = (void *)newobj;
40515051Swyllys 	} else {
40525051Swyllys 		rv = KMF_ERR_BAD_PARAMETER;
40535051Swyllys 	}
40545051Swyllys 
40555051Swyllys 	return (rv);
40565051Swyllys }
40575051Swyllys 
40585051Swyllys 
40595051Swyllys KMF_RETURN
KMFPK11_ExportPK12(KMF_HANDLE_T handle,int numattr,KMF_ATTRIBUTE * attrlist)40605051Swyllys KMFPK11_ExportPK12(KMF_HANDLE_T handle, int numattr, KMF_ATTRIBUTE *attrlist)
40615051Swyllys {
40625051Swyllys 	KMF_RETURN rv = KMF_OK;
40635051Swyllys 	KMF_HANDLE *kmfh = (KMF_HANDLE *)handle;
40645051Swyllys 	KMF_CREDENTIAL *cred = NULL;
40655051Swyllys 	KMF_CREDENTIAL *p12cred = NULL;
40665051Swyllys 	char *filename = NULL;
40675051Swyllys 	KMF_X509_DER_CERT *certlist = NULL;
40685051Swyllys 	KMF_KEY_HANDLE *keylist = NULL;
40695051Swyllys 	uint32_t numcerts;
40705051Swyllys 	uint32_t numkeys;
40715051Swyllys 	char *certlabel = NULL;
40725051Swyllys 	char *issuer = NULL;
40735051Swyllys 	char *subject = NULL;
40745051Swyllys 	KMF_BIGINT *serial = NULL;
40755051Swyllys 	KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_PK11TOKEN;
40765051Swyllys 	KMF_ATTRIBUTE fc_attrlist[16];
40775051Swyllys 	int i;
40785051Swyllys 
40795051Swyllys 	if (kmfh == NULL)
40805051Swyllys 		return (KMF_ERR_UNINITIALIZED); /* Plugin Not Initialized */
40815051Swyllys 
40825051Swyllys 	if (kmfh->pk11handle == CK_INVALID_HANDLE)
40835051Swyllys 		return (KMF_ERR_NO_TOKEN_SELECTED);
40845051Swyllys 
40855051Swyllys 	/* First get the required attributes */
40865051Swyllys 	cred =  kmf_get_attr_ptr(KMF_CREDENTIAL_ATTR, attrlist, numattr);
40875051Swyllys 	if (cred == NULL)
40885051Swyllys 		return (KMF_ERR_BAD_PARAMETER);
40895051Swyllys 
40905051Swyllys 	p12cred =  kmf_get_attr_ptr(KMF_PK12CRED_ATTR, attrlist, numattr);
40915051Swyllys 	if (p12cred == NULL)
40925051Swyllys 		return (KMF_ERR_BAD_PARAMETER);
40935051Swyllys 
40945051Swyllys 	filename = kmf_get_attr_ptr(KMF_OUTPUT_FILENAME_ATTR, attrlist,
40955051Swyllys 	    numattr);
40965051Swyllys 	if (filename == NULL)
40975051Swyllys 		return (KMF_ERR_BAD_PARAMETER);
40985051Swyllys 
40995051Swyllys 	/* Find all the certificates that match the searching criteria */
41005051Swyllys 	i = 0;
41015051Swyllys 	kmf_set_attr_at_index(fc_attrlist, i,
41025051Swyllys 	    KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype));
41035051Swyllys 	i++;
41045051Swyllys 
41055051Swyllys 	kmf_set_attr_at_index(fc_attrlist, i,
41065051Swyllys 	    KMF_COUNT_ATTR, &numcerts, sizeof (uint32_t));
41075051Swyllys 	i++;
41085051Swyllys 
41095051Swyllys 	certlabel = kmf_get_attr_ptr(KMF_CERT_LABEL_ATTR, attrlist, numattr);
41105051Swyllys 	if (certlabel != NULL) {
41115051Swyllys 		kmf_set_attr_at_index(fc_attrlist, i,
41125051Swyllys 		    KMF_CERT_LABEL_ATTR, certlabel, strlen(certlabel));
41135051Swyllys 		i++;
41145051Swyllys 	}
41155051Swyllys 
41165051Swyllys 	issuer = kmf_get_attr_ptr(KMF_ISSUER_NAME_ATTR, attrlist, numattr);
41175051Swyllys 	if (issuer != NULL) {
41185051Swyllys 		kmf_set_attr_at_index(fc_attrlist, i,
41195051Swyllys 		    KMF_ISSUER_NAME_ATTR, issuer, strlen(issuer));
41205051Swyllys 		i++;
41215051Swyllys 	}
41225051Swyllys 
41235051Swyllys 	subject = kmf_get_attr_ptr(KMF_SUBJECT_NAME_ATTR, attrlist, numattr);
41245051Swyllys 	if (subject != NULL) {
41255051Swyllys 		kmf_set_attr_at_index(fc_attrlist, i,
41265051Swyllys 		    KMF_SUBJECT_NAME_ATTR, subject, strlen(subject));
41275051Swyllys 		i++;
41285051Swyllys 	}
41295051Swyllys 
41305051Swyllys 	serial = kmf_get_attr_ptr(KMF_BIGINT_ATTR, attrlist, numattr);
41315051Swyllys 	if (serial != NULL) {
41325051Swyllys 		kmf_set_attr_at_index(fc_attrlist, i,
41335051Swyllys 		    KMF_BIGINT_ATTR, serial, sizeof (KMF_BIGINT));
41345051Swyllys 		i++;
41355051Swyllys 	}
41365051Swyllys 
41375051Swyllys 	rv = KMFPK11_FindCert(handle, i, fc_attrlist);
41385051Swyllys 
41395051Swyllys 	if (rv == KMF_OK && numcerts > 0) {
41405051Swyllys 		certlist = (KMF_X509_DER_CERT *)malloc(numcerts *
41415051Swyllys 		    sizeof (KMF_X509_DER_CERT));
41425051Swyllys 		if (certlist == NULL)
41435051Swyllys 			return (KMF_ERR_MEMORY);
41445051Swyllys 
41455051Swyllys 		(void) memset(certlist, 0, numcerts *
41465051Swyllys 		    sizeof (KMF_X509_DER_CERT));
41475051Swyllys 
41485051Swyllys 		kmf_set_attr_at_index(fc_attrlist, i, KMF_X509_DER_CERT_ATTR,
41495051Swyllys 		    certlist, sizeof (KMF_X509_DER_CERT));
41505051Swyllys 		i++;
41515051Swyllys 
41525051Swyllys 		rv = kmf_find_cert(handle, i, fc_attrlist);
41535051Swyllys 		if (rv != KMF_OK) {
41545051Swyllys 			free(certlist);
41555051Swyllys 			return (rv);
41565051Swyllys 		}
41575051Swyllys 	} else {
41585051Swyllys 		return (rv);
41595051Swyllys 	}
41605051Swyllys 
41615051Swyllys 	/* For each certificate, find the matching private key */
41625051Swyllys 	numkeys = 0;
41635051Swyllys 	for (i = 0; i < numcerts; i++) {
41645051Swyllys 		KMF_ATTRIBUTE fk_attrlist[16];
41655051Swyllys 		int j = 0;
41665051Swyllys 		KMF_KEY_HANDLE newkey;
41675051Swyllys 		KMF_ENCODE_FORMAT format = KMF_FORMAT_RAWKEY;
41685051Swyllys 
41695051Swyllys 		kmf_set_attr_at_index(fk_attrlist, j,
41705051Swyllys 		    KMF_KEYSTORE_TYPE_ATTR, &kstype, sizeof (kstype));
41715051Swyllys 		j++;
41725051Swyllys 
41735051Swyllys 		kmf_set_attr_at_index(fk_attrlist, j,
41745051Swyllys 		    KMF_ENCODE_FORMAT_ATTR, &format, sizeof (format));
41755051Swyllys 		j++;
41765051Swyllys 
41775051Swyllys 		kmf_set_attr_at_index(fk_attrlist, j,
41785051Swyllys 		    KMF_CREDENTIAL_ATTR, cred, sizeof (KMF_CREDENTIAL));
41795051Swyllys 		j++;
41805051Swyllys 
41815051Swyllys 		kmf_set_attr_at_index(fk_attrlist, j,
41825051Swyllys 		    KMF_CERT_DATA_ATTR, &certlist[i].certificate,
41835051Swyllys 		    sizeof (KMF_DATA));
41845051Swyllys 		j++;
41855051Swyllys 
41865051Swyllys 		kmf_set_attr_at_index(fk_attrlist, j,
41875051Swyllys 		    KMF_KEY_HANDLE_ATTR, &newkey, sizeof (KMF_KEY_HANDLE));
41885051Swyllys 		j++;
41895051Swyllys 
41905051Swyllys 		rv = KMFPK11_FindPrikeyByCert(handle, j, fk_attrlist);
41915051Swyllys 		if (rv == KMF_OK) {
41925051Swyllys 			numkeys++;
41935051Swyllys 			keylist = realloc(keylist,
41945051Swyllys 			    numkeys * sizeof (KMF_KEY_HANDLE));
41955051Swyllys 			if (keylist == NULL) {
41965051Swyllys 				rv = KMF_ERR_MEMORY;
41975051Swyllys 				goto out;
41985051Swyllys 			}
41995051Swyllys 			keylist[numkeys - 1] = newkey;
42005051Swyllys 		} else if (rv == KMF_ERR_KEY_NOT_FOUND) {
42015051Swyllys 			/* it is OK if a key is not found */
42025051Swyllys 			rv = KMF_OK;
42035051Swyllys 		}
42045051Swyllys 	}
42055051Swyllys 
42065051Swyllys 	if (rv != KMF_OK)
42075051Swyllys 		goto out;
42085051Swyllys 
42095051Swyllys 	rv = kmf_build_pk12(handle, numcerts, certlist, numkeys, keylist,
42105051Swyllys 	    p12cred, filename);
42115051Swyllys 
42125051Swyllys out:
42135051Swyllys 	if (certlist != NULL) {
42145051Swyllys 		for (i = 0; i < numcerts; i++)
42155051Swyllys 			kmf_free_kmf_cert(handle, &certlist[i]);
42165051Swyllys 		free(certlist);
42175051Swyllys 	}
42185051Swyllys 	if (keylist != NULL) {
42195051Swyllys 		for (i = 0; i < numkeys; i++)
42205051Swyllys 			kmf_free_kmf_key(handle, &keylist[i]);
42215051Swyllys 		free(keylist);
42225051Swyllys 	}
42235051Swyllys 
42245051Swyllys 	return (rv);
42255051Swyllys }
4226