1*99ebb4caSwyllys /*
2*99ebb4caSwyllys  * CDDL HEADER START
3*99ebb4caSwyllys  *
4*99ebb4caSwyllys  * The contents of this file are subject to the terms of the
5*99ebb4caSwyllys  * Common Development and Distribution License (the "License").
6*99ebb4caSwyllys  * You may not use this file except in compliance with the License.
7*99ebb4caSwyllys  *
8*99ebb4caSwyllys  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*99ebb4caSwyllys  * or http://www.opensolaris.org/os/licensing.
10*99ebb4caSwyllys  * See the License for the specific language governing permissions
11*99ebb4caSwyllys  * and limitations under the License.
12*99ebb4caSwyllys  *
13*99ebb4caSwyllys  * When distributing Covered Code, include this CDDL HEADER in each
14*99ebb4caSwyllys  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*99ebb4caSwyllys  * If applicable, add the following below this CDDL HEADER, with the
16*99ebb4caSwyllys  * fields enclosed by brackets "[]" replaced with your own identifying
17*99ebb4caSwyllys  * information: Portions Copyright [yyyy] [name of copyright owner]
18*99ebb4caSwyllys  *
19*99ebb4caSwyllys  * CDDL HEADER END
20*99ebb4caSwyllys  */
21*99ebb4caSwyllys /*
22*99ebb4caSwyllys  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
23*99ebb4caSwyllys  * Use is subject to license terms.
24*99ebb4caSwyllys  *
25*99ebb4caSwyllys  * File: KEYS.C
26*99ebb4caSwyllys  *
27*99ebb4caSwyllys  * Copyright (c) 1995-2000 Intel Corporation. All rights reserved.
28*99ebb4caSwyllys  *
29*99ebb4caSwyllys  */
30*99ebb4caSwyllys 
31*99ebb4caSwyllys #pragma ident	"%Z%%M%	%I%	%E% SMI"
32*99ebb4caSwyllys 
33*99ebb4caSwyllys #include <kmfapiP.h>
34*99ebb4caSwyllys #include <security/cryptoki.h>
35*99ebb4caSwyllys 
36*99ebb4caSwyllys #include <algorithm.h>
37*99ebb4caSwyllys #include <ber_der.h>
38*99ebb4caSwyllys 
39*99ebb4caSwyllys #define	MAX_PUBLIC_KEY_TEMPLATES    (20)
40*99ebb4caSwyllys #define	MAX_PRIVATE_KEY_TEMPLATES   (24)
41*99ebb4caSwyllys #define	MAX_SECRET_KEY_TEMPLATES    (24)
42*99ebb4caSwyllys 
43*99ebb4caSwyllys static KMF_RETURN
44*99ebb4caSwyllys create_pk11_session(CK_SESSION_HANDLE *sessionp, CK_MECHANISM_TYPE wanted_mech,
45*99ebb4caSwyllys 	CK_FLAGS wanted_flags)
46*99ebb4caSwyllys {
47*99ebb4caSwyllys 	CK_RV rv;
48*99ebb4caSwyllys 	KMF_RETURN kmf_rv = KMF_OK;
49*99ebb4caSwyllys 	CK_SLOT_ID_PTR pSlotList;
50*99ebb4caSwyllys 	CK_ULONG pulCount;
51*99ebb4caSwyllys 	CK_MECHANISM_INFO info;
52*99ebb4caSwyllys 	int i;
53*99ebb4caSwyllys 
54*99ebb4caSwyllys 	if (!is_pk11_ready()) {
55*99ebb4caSwyllys 		rv = C_Initialize(NULL);
56*99ebb4caSwyllys 		if ((rv != CKR_OK) &&
57*99ebb4caSwyllys 		    (rv != CKR_CRYPTOKI_ALREADY_INITIALIZED)) {
58*99ebb4caSwyllys 			kmf_rv = KMF_ERR_UNINITIALIZED;
59*99ebb4caSwyllys 			goto out;
60*99ebb4caSwyllys 		}
61*99ebb4caSwyllys 	}
62*99ebb4caSwyllys 
63*99ebb4caSwyllys 	rv = C_GetSlotList(0, NULL, &pulCount);
64*99ebb4caSwyllys 	if (rv != CKR_OK) {
65*99ebb4caSwyllys 		kmf_rv = KMF_ERR_UNINITIALIZED;
66*99ebb4caSwyllys 		goto out;
67*99ebb4caSwyllys 	}
68*99ebb4caSwyllys 
69*99ebb4caSwyllys 	pSlotList = (CK_SLOT_ID_PTR) malloc(pulCount * sizeof (CK_SLOT_ID));
70*99ebb4caSwyllys 	if (pSlotList == NULL) {
71*99ebb4caSwyllys 		kmf_rv = KMF_ERR_MEMORY;
72*99ebb4caSwyllys 		goto out;
73*99ebb4caSwyllys 	}
74*99ebb4caSwyllys 
75*99ebb4caSwyllys 	rv = C_GetSlotList(0, pSlotList, &pulCount);
76*99ebb4caSwyllys 	if (rv != CKR_OK) {
77*99ebb4caSwyllys 		kmf_rv = KMF_ERR_UNINITIALIZED;
78*99ebb4caSwyllys 		goto out;
79*99ebb4caSwyllys 	}
80*99ebb4caSwyllys 
81*99ebb4caSwyllys 	for (i = 0; i < pulCount; i++) {
82*99ebb4caSwyllys 		rv = C_GetMechanismInfo(pSlotList[i], wanted_mech, &info);
83*99ebb4caSwyllys 		if (rv == CKR_OK && (info.flags & wanted_flags))
84*99ebb4caSwyllys 			break;
85*99ebb4caSwyllys 	}
86*99ebb4caSwyllys 	if (i < pulCount) {
87*99ebb4caSwyllys 		rv = C_OpenSession(pSlotList[i], CKF_SERIAL_SESSION,
88*99ebb4caSwyllys 			NULL, NULL, sessionp);
89*99ebb4caSwyllys 
90*99ebb4caSwyllys 		if (rv != CKR_OK) {
91*99ebb4caSwyllys 			kmf_rv = KMF_ERR_UNINITIALIZED;
92*99ebb4caSwyllys 		}
93*99ebb4caSwyllys 	} else {
94*99ebb4caSwyllys 		kmf_rv = KMF_ERR_UNINITIALIZED;
95*99ebb4caSwyllys 	}
96*99ebb4caSwyllys 
97*99ebb4caSwyllys out:
98*99ebb4caSwyllys 	if (pSlotList != NULL)
99*99ebb4caSwyllys 		free(pSlotList);
100*99ebb4caSwyllys 	return (kmf_rv);
101*99ebb4caSwyllys 
102*99ebb4caSwyllys }
103*99ebb4caSwyllys 
104*99ebb4caSwyllys /*
105*99ebb4caSwyllys  * Name: PKCS_AddTemplate
106*99ebb4caSwyllys  *
107*99ebb4caSwyllys  * Description:
108*99ebb4caSwyllys  *  Adds a CK_ATTRIBUTE value to an existing array of CK_ATTRIBUTES. Will
109*99ebb4caSwyllys  *  not expand the array beyond the maximum specified size.
110*99ebb4caSwyllys  *
111*99ebb4caSwyllys  * Returns:
112*99ebb4caSwyllys  *  TRUE - Attribute value succesfully added.
113*99ebb4caSwyllys  *  FALSE - Maximum array size would be exceded.
114*99ebb4caSwyllys  */
115*99ebb4caSwyllys static int
116*99ebb4caSwyllys PKCS_AddTemplate(CK_ATTRIBUTE *pTemplate,
117*99ebb4caSwyllys 	CK_ULONG *ckNumTemplates,
118*99ebb4caSwyllys 	CK_ULONG ckMaxTemplates,
119*99ebb4caSwyllys 	CK_ATTRIBUTE_TYPE ckAttribCode,
120*99ebb4caSwyllys 	CK_BYTE * pckBuffer,
121*99ebb4caSwyllys 	CK_ULONG ckBufferLen)
122*99ebb4caSwyllys {
123*99ebb4caSwyllys 	if (*ckNumTemplates >= ckMaxTemplates) {
124*99ebb4caSwyllys 		return (FALSE);
125*99ebb4caSwyllys 	}
126*99ebb4caSwyllys 
127*99ebb4caSwyllys 	pTemplate[*ckNumTemplates].type = ckAttribCode;
128*99ebb4caSwyllys 	pTemplate[*ckNumTemplates].pValue = pckBuffer;
129*99ebb4caSwyllys 	pTemplate[*ckNumTemplates].ulValueLen = ckBufferLen;
130*99ebb4caSwyllys 	(*ckNumTemplates)++;
131*99ebb4caSwyllys 
132*99ebb4caSwyllys 	return (TRUE);
133*99ebb4caSwyllys }
134*99ebb4caSwyllys 
135*99ebb4caSwyllys /*
136*99ebb4caSwyllys  * Convert an SPKI data record to PKCS#11
137*99ebb4caSwyllys  * public key object.
138*99ebb4caSwyllys  */
139*99ebb4caSwyllys static KMF_RETURN
140*99ebb4caSwyllys PKCS_CreatePublicKey(
141*99ebb4caSwyllys 	const KMF_X509_SPKI *pKey,
142*99ebb4caSwyllys 	CK_SESSION_HANDLE ckSession,
143*99ebb4caSwyllys 	CK_OBJECT_HANDLE *pckPublicKey)
144*99ebb4caSwyllys {
145*99ebb4caSwyllys 	KMF_RETURN mrReturn = KMF_OK;
146*99ebb4caSwyllys 	CK_RV ckRv;
147*99ebb4caSwyllys 
148*99ebb4caSwyllys 	CK_ATTRIBUTE ckTemplate[MAX_PUBLIC_KEY_TEMPLATES];
149*99ebb4caSwyllys 	CK_ULONG ckNumTemplates = 0;
150*99ebb4caSwyllys 
151*99ebb4caSwyllys 	/* Common object attributes */
152*99ebb4caSwyllys 	CK_OBJECT_CLASS ckObjClass = CKO_PUBLIC_KEY;
153*99ebb4caSwyllys 	CK_BBOOL ckToken = 0;
154*99ebb4caSwyllys 	CK_BBOOL ckPrivate = 0;
155*99ebb4caSwyllys 
156*99ebb4caSwyllys 	/* Common key attributes */
157*99ebb4caSwyllys 	CK_KEY_TYPE ckKeyType;
158*99ebb4caSwyllys 	CK_BBOOL ckDerive = CK_FALSE;
159*99ebb4caSwyllys 
160*99ebb4caSwyllys 	/* Common public key attributes */
161*99ebb4caSwyllys 	CK_BBOOL ckEncrypt = 1;
162*99ebb4caSwyllys 	CK_BBOOL ckVerify = 1;
163*99ebb4caSwyllys 
164*99ebb4caSwyllys 	CK_BBOOL ckVerifyRecover = CK_FALSE;
165*99ebb4caSwyllys 	CK_BBOOL ckWrap = CK_FALSE;
166*99ebb4caSwyllys 
167*99ebb4caSwyllys 	/* Key part array */
168*99ebb4caSwyllys 	KMF_DATA KeyParts[KMF_MAX_PUBLIC_KEY_PARTS];
169*99ebb4caSwyllys 	uint32_t i, uNumKeyParts = KMF_MAX_PUBLIC_KEY_PARTS;
170*99ebb4caSwyllys 	KMF_ALGORITHM_INDEX AlgorithmId;
171*99ebb4caSwyllys 
172*99ebb4caSwyllys 	/* Parse the keyblob */
173*99ebb4caSwyllys 	(void) memset(KeyParts, 0, sizeof (KeyParts));
174*99ebb4caSwyllys 
175*99ebb4caSwyllys 	AlgorithmId = X509_AlgorithmOidToAlgId((KMF_OID *)
176*99ebb4caSwyllys 		&pKey->algorithm.algorithm);
177*99ebb4caSwyllys 
178*99ebb4caSwyllys 	mrReturn = ExtractSPKIData(pKey, AlgorithmId, KeyParts, &uNumKeyParts);
179*99ebb4caSwyllys 
180*99ebb4caSwyllys 	if (mrReturn != KMF_OK)
181*99ebb4caSwyllys 		return (mrReturn);
182*99ebb4caSwyllys 
183*99ebb4caSwyllys 	/* Fill in the common object attributes */
184*99ebb4caSwyllys 	if (!PKCS_AddTemplate(ckTemplate,
185*99ebb4caSwyllys 		&ckNumTemplates,
186*99ebb4caSwyllys 		MAX_PUBLIC_KEY_TEMPLATES,
187*99ebb4caSwyllys 		CKA_CLASS,
188*99ebb4caSwyllys 		(CK_BYTE *)&ckObjClass,
189*99ebb4caSwyllys 		sizeof (ckObjClass)) ||
190*99ebb4caSwyllys 		!PKCS_AddTemplate(ckTemplate,
191*99ebb4caSwyllys 			&ckNumTemplates,
192*99ebb4caSwyllys 			MAX_PUBLIC_KEY_TEMPLATES,
193*99ebb4caSwyllys 			CKA_TOKEN,
194*99ebb4caSwyllys 			(CK_BYTE *)&ckToken,
195*99ebb4caSwyllys 			sizeof (ckToken)) ||
196*99ebb4caSwyllys 		!PKCS_AddTemplate(ckTemplate,
197*99ebb4caSwyllys 			&ckNumTemplates,
198*99ebb4caSwyllys 			MAX_PUBLIC_KEY_TEMPLATES,
199*99ebb4caSwyllys 			CKA_PRIVATE,
200*99ebb4caSwyllys 			(CK_BYTE *)&ckPrivate,
201*99ebb4caSwyllys 			sizeof (ckPrivate))) {
202*99ebb4caSwyllys 		mrReturn = KMF_ERR_INTERNAL;
203*99ebb4caSwyllys 		goto cleanup;
204*99ebb4caSwyllys 	}
205*99ebb4caSwyllys 
206*99ebb4caSwyllys 	/* Fill in the common key attributes */
207*99ebb4caSwyllys 	if (!PKCS_ConvertAlgorithmId2PKCSKeyType(AlgorithmId,
208*99ebb4caSwyllys 		&ckKeyType)) {
209*99ebb4caSwyllys 		goto cleanup;
210*99ebb4caSwyllys 	}
211*99ebb4caSwyllys 	if (!PKCS_AddTemplate(ckTemplate,
212*99ebb4caSwyllys 		&ckNumTemplates,
213*99ebb4caSwyllys 		MAX_PUBLIC_KEY_TEMPLATES,
214*99ebb4caSwyllys 		CKA_KEY_TYPE,
215*99ebb4caSwyllys 		(CK_BYTE *)&ckKeyType,
216*99ebb4caSwyllys 		sizeof (ckKeyType)) ||
217*99ebb4caSwyllys 	    !PKCS_AddTemplate(ckTemplate,
218*99ebb4caSwyllys 		&ckNumTemplates,
219*99ebb4caSwyllys 		MAX_PUBLIC_KEY_TEMPLATES,
220*99ebb4caSwyllys 		CKA_DERIVE,
221*99ebb4caSwyllys 		(CK_BYTE *)&ckDerive,
222*99ebb4caSwyllys 		sizeof (ckDerive))) {
223*99ebb4caSwyllys 		mrReturn = KMF_ERR_INTERNAL;
224*99ebb4caSwyllys 		goto cleanup;
225*99ebb4caSwyllys 	}
226*99ebb4caSwyllys 
227*99ebb4caSwyllys 	/* Add common public key attributes */
228*99ebb4caSwyllys 	if (!PKCS_AddTemplate(ckTemplate,
229*99ebb4caSwyllys 		&ckNumTemplates,
230*99ebb4caSwyllys 		MAX_PUBLIC_KEY_TEMPLATES,
231*99ebb4caSwyllys 		CKA_ENCRYPT,
232*99ebb4caSwyllys 		(CK_BYTE *)&ckEncrypt,
233*99ebb4caSwyllys 		sizeof (ckEncrypt)) ||
234*99ebb4caSwyllys 	    !PKCS_AddTemplate(ckTemplate,
235*99ebb4caSwyllys 		&ckNumTemplates,
236*99ebb4caSwyllys 		MAX_PUBLIC_KEY_TEMPLATES,
237*99ebb4caSwyllys 		CKA_VERIFY,
238*99ebb4caSwyllys 		(CK_BYTE *)&ckVerify,
239*99ebb4caSwyllys 		sizeof (ckVerify)) ||
240*99ebb4caSwyllys 	    !PKCS_AddTemplate(ckTemplate,
241*99ebb4caSwyllys 		&ckNumTemplates,
242*99ebb4caSwyllys 		MAX_PUBLIC_KEY_TEMPLATES,
243*99ebb4caSwyllys 		CKA_VERIFY_RECOVER,
244*99ebb4caSwyllys 		(CK_BYTE *)&ckVerifyRecover,
245*99ebb4caSwyllys 		sizeof (ckVerifyRecover)) ||
246*99ebb4caSwyllys 	    !PKCS_AddTemplate(ckTemplate,
247*99ebb4caSwyllys 		&ckNumTemplates,
248*99ebb4caSwyllys 		MAX_PUBLIC_KEY_TEMPLATES,
249*99ebb4caSwyllys 		CKA_WRAP,
250*99ebb4caSwyllys 		(CK_BYTE *)&ckWrap,
251*99ebb4caSwyllys 		sizeof (ckWrap))) {
252*99ebb4caSwyllys 		mrReturn = KMF_ERR_INTERNAL;
253*99ebb4caSwyllys 		goto cleanup;
254*99ebb4caSwyllys 	}
255*99ebb4caSwyllys 
256*99ebb4caSwyllys 	/* Add algorithm specific attributes */
257*99ebb4caSwyllys 	switch (ckKeyType) {
258*99ebb4caSwyllys 	case CKK_RSA:
259*99ebb4caSwyllys 		if (!PKCS_AddTemplate(ckTemplate,
260*99ebb4caSwyllys 			&ckNumTemplates,
261*99ebb4caSwyllys 			MAX_PUBLIC_KEY_TEMPLATES,
262*99ebb4caSwyllys 			CKA_MODULUS,
263*99ebb4caSwyllys 			(CK_BYTE *)KeyParts[KMF_RSA_MODULUS].Data,
264*99ebb4caSwyllys 			(CK_ULONG)KeyParts[KMF_RSA_MODULUS].Length) ||
265*99ebb4caSwyllys 		!PKCS_AddTemplate(ckTemplate,
266*99ebb4caSwyllys 			&ckNumTemplates,
267*99ebb4caSwyllys 			MAX_PUBLIC_KEY_TEMPLATES,
268*99ebb4caSwyllys 			CKA_PUBLIC_EXPONENT,
269*99ebb4caSwyllys 			(CK_BYTE *)KeyParts[KMF_RSA_PUBLIC_EXPONENT].Data,
270*99ebb4caSwyllys 			(CK_ULONG)KeyParts[KMF_RSA_PUBLIC_EXPONENT].Length)) {
271*99ebb4caSwyllys 		mrReturn = KMF_ERR_INTERNAL;
272*99ebb4caSwyllys 		goto cleanup;
273*99ebb4caSwyllys 		}
274*99ebb4caSwyllys 		break;
275*99ebb4caSwyllys 	case CKK_DSA:
276*99ebb4caSwyllys 		if (!PKCS_AddTemplate(ckTemplate,
277*99ebb4caSwyllys 			&ckNumTemplates,
278*99ebb4caSwyllys 			MAX_PUBLIC_KEY_TEMPLATES,
279*99ebb4caSwyllys 			CKA_PRIME,
280*99ebb4caSwyllys 			(CK_BYTE *)KeyParts[KMF_DSA_PRIME].Data,
281*99ebb4caSwyllys 			(CK_ULONG)KeyParts[KMF_DSA_PRIME].Length) ||
282*99ebb4caSwyllys 		!PKCS_AddTemplate(ckTemplate,
283*99ebb4caSwyllys 			&ckNumTemplates,
284*99ebb4caSwyllys 			MAX_PUBLIC_KEY_TEMPLATES,
285*99ebb4caSwyllys 			CKA_SUBPRIME,
286*99ebb4caSwyllys 			(CK_BYTE *)KeyParts[KMF_DSA_SUB_PRIME].Data,
287*99ebb4caSwyllys 			(CK_ULONG)KeyParts[KMF_DSA_SUB_PRIME].Length) ||
288*99ebb4caSwyllys 		!PKCS_AddTemplate(ckTemplate,
289*99ebb4caSwyllys 			&ckNumTemplates,
290*99ebb4caSwyllys 			MAX_PUBLIC_KEY_TEMPLATES,
291*99ebb4caSwyllys 			CKA_BASE,
292*99ebb4caSwyllys 			(CK_BYTE *)KeyParts[KMF_DSA_BASE].Data,
293*99ebb4caSwyllys 			(CK_ULONG)KeyParts[KMF_DSA_BASE].Length) ||
294*99ebb4caSwyllys 		!PKCS_AddTemplate(ckTemplate,
295*99ebb4caSwyllys 			&ckNumTemplates,
296*99ebb4caSwyllys 			MAX_PUBLIC_KEY_TEMPLATES,
297*99ebb4caSwyllys 			CKA_VALUE,
298*99ebb4caSwyllys 			(CK_BYTE *)KeyParts[KMF_DSA_PUBLIC_VALUE].Data,
299*99ebb4caSwyllys 			(CK_ULONG)KeyParts[KMF_DSA_PUBLIC_VALUE].Length)) {
300*99ebb4caSwyllys 		mrReturn = KMF_ERR_INTERNAL;
301*99ebb4caSwyllys 		goto cleanup;
302*99ebb4caSwyllys 		}
303*99ebb4caSwyllys 		break;
304*99ebb4caSwyllys 	default:
305*99ebb4caSwyllys 		mrReturn = KMF_ERR_BAD_PARAMETER;
306*99ebb4caSwyllys 	}
307*99ebb4caSwyllys 
308*99ebb4caSwyllys 	if (mrReturn == KMF_OK) {
309*99ebb4caSwyllys 		/* Instantiate the object */
310*99ebb4caSwyllys 		ckRv = C_CreateObject(ckSession,
311*99ebb4caSwyllys 				ckTemplate,
312*99ebb4caSwyllys 				ckNumTemplates,
313*99ebb4caSwyllys 				pckPublicKey);
314*99ebb4caSwyllys 		if (ckRv != CKR_OK)
315*99ebb4caSwyllys 			mrReturn = KMF_ERR_INTERNAL;
316*99ebb4caSwyllys 	}
317*99ebb4caSwyllys 
318*99ebb4caSwyllys cleanup:
319*99ebb4caSwyllys 	for (i = 0; i < uNumKeyParts; i++) {
320*99ebb4caSwyllys 		KMF_FreeData(&KeyParts[i]);
321*99ebb4caSwyllys 	}
322*99ebb4caSwyllys 
323*99ebb4caSwyllys 	return (mrReturn);
324*99ebb4caSwyllys }
325*99ebb4caSwyllys 
326*99ebb4caSwyllys /*
327*99ebb4caSwyllys  * PKCS_AcquirePublicKeyHandle
328*99ebb4caSwyllys  *
329*99ebb4caSwyllys  *   Given an assymetric key keyblob, attempts to find the appropriate
330*99ebb4caSwyllys  *    public key.
331*99ebb4caSwyllys  *
332*99ebb4caSwyllys  *  Methods of finding the public key:
333*99ebb4caSwyllys  *  - Public Key with data present:
334*99ebb4caSwyllys  *    Parses the key and creates a temporary session object.
335*99ebb4caSwyllys  *  - Public Key with handle:
336*99ebb4caSwyllys  *    The handle is type converted and returned. Validity of the handle is
337*99ebb4caSwyllys  *    not checked.
338*99ebb4caSwyllys  *  - Public Key with label:
339*99ebb4caSwyllys  *    Attempts to find a public key with the corresponding label.
340*99ebb4caSwyllys  */
341*99ebb4caSwyllys static KMF_RETURN
342*99ebb4caSwyllys PKCS_AcquirePublicKeyHandle(CK_SESSION_HANDLE ckSession,
343*99ebb4caSwyllys 	const KMF_X509_SPKI *pKey,
344*99ebb4caSwyllys 	CK_KEY_TYPE ckRequestedKeyType,
345*99ebb4caSwyllys 	CK_OBJECT_HANDLE *pckKeyHandle,
346*99ebb4caSwyllys 	KMF_BOOL *pbTemporary)
347*99ebb4caSwyllys {
348*99ebb4caSwyllys 	KMF_RETURN mrReturn = KMF_OK;
349*99ebb4caSwyllys 
350*99ebb4caSwyllys 
351*99ebb4caSwyllys 	/* Key searching variables */
352*99ebb4caSwyllys 	CK_OBJECT_HANDLE ckKeyHandle;
353*99ebb4caSwyllys 	CK_OBJECT_CLASS ckObjClass;
354*99ebb4caSwyllys 	CK_KEY_TYPE ckKeyType;
355*99ebb4caSwyllys 	CK_ATTRIBUTE ckTemplate[3];
356*99ebb4caSwyllys 	CK_ULONG ckNumTemplates;
357*99ebb4caSwyllys 	static const CK_ULONG ckMaxTemplates = (sizeof (ckTemplate) /
358*99ebb4caSwyllys 		sizeof (CK_ATTRIBUTE));
359*99ebb4caSwyllys 	CK_RV ckRv;
360*99ebb4caSwyllys 
361*99ebb4caSwyllys 	/* Extract the data from the SPKI into individual fields */
362*99ebb4caSwyllys 	mrReturn = PKCS_CreatePublicKey(pKey, ckSession, &ckKeyHandle);
363*99ebb4caSwyllys 	if (mrReturn != KMF_OK)
364*99ebb4caSwyllys 		return (mrReturn);
365*99ebb4caSwyllys 
366*99ebb4caSwyllys 	*pbTemporary = KMF_TRUE;
367*99ebb4caSwyllys 
368*99ebb4caSwyllys 	/* Fetch the key class and algorithm from the object */
369*99ebb4caSwyllys 	ckNumTemplates = 0;
370*99ebb4caSwyllys 	if (!PKCS_AddTemplate(ckTemplate,
371*99ebb4caSwyllys 			&ckNumTemplates,
372*99ebb4caSwyllys 			ckMaxTemplates,
373*99ebb4caSwyllys 			CKA_CLASS,
374*99ebb4caSwyllys 			(CK_BYTE *)&ckObjClass,
375*99ebb4caSwyllys 			sizeof (ckObjClass)) ||
376*99ebb4caSwyllys 		!PKCS_AddTemplate(ckTemplate,
377*99ebb4caSwyllys 			&ckNumTemplates,
378*99ebb4caSwyllys 			ckMaxTemplates,
379*99ebb4caSwyllys 			CKA_KEY_TYPE,
380*99ebb4caSwyllys 			(CK_BYTE *)&ckKeyType,
381*99ebb4caSwyllys 			sizeof (ckKeyType))) {
382*99ebb4caSwyllys 		return (KMF_ERR_INTERNAL);
383*99ebb4caSwyllys 	}
384*99ebb4caSwyllys 	ckRv = C_GetAttributeValue(ckSession,
385*99ebb4caSwyllys 				ckKeyHandle,
386*99ebb4caSwyllys 				ckTemplate,
387*99ebb4caSwyllys 				ckNumTemplates);
388*99ebb4caSwyllys 	if (ckRv != CKR_OK) {
389*99ebb4caSwyllys 		return (ckRv);
390*99ebb4caSwyllys 	}
391*99ebb4caSwyllys 
392*99ebb4caSwyllys 	/* Make sure the results match the expected values */
393*99ebb4caSwyllys 	if ((ckKeyType != ckRequestedKeyType) ||
394*99ebb4caSwyllys 		(ckObjClass != CKO_PUBLIC_KEY)) {
395*99ebb4caSwyllys 		if (*pbTemporary == KMF_TRUE) {
396*99ebb4caSwyllys 			(void) C_DestroyObject(ckSession, ckKeyHandle);
397*99ebb4caSwyllys 		}
398*99ebb4caSwyllys 
399*99ebb4caSwyllys 		return (KMF_ERR_BAD_KEY_FORMAT);
400*99ebb4caSwyllys 	}
401*99ebb4caSwyllys 
402*99ebb4caSwyllys 	/* Set the return values */
403*99ebb4caSwyllys 	*pckKeyHandle = ckKeyHandle;
404*99ebb4caSwyllys 
405*99ebb4caSwyllys 	return (KMF_OK);
406*99ebb4caSwyllys }
407*99ebb4caSwyllys 
408*99ebb4caSwyllys KMF_SIGNATURE_MODE
409*99ebb4caSwyllys PKCS_GetDefaultSignatureMode(KMF_ALGORITHM_INDEX AlgId)
410*99ebb4caSwyllys {
411*99ebb4caSwyllys 	KMF_SIGNATURE_MODE AlgMode;
412*99ebb4caSwyllys 
413*99ebb4caSwyllys 	switch (AlgId) {
414*99ebb4caSwyllys 		case KMF_ALGID_RSA:
415*99ebb4caSwyllys 		case KMF_ALGID_MD5WithRSA:
416*99ebb4caSwyllys 		case KMF_ALGID_MD2WithRSA:
417*99ebb4caSwyllys 		case KMF_ALGID_SHA1WithRSA:
418*99ebb4caSwyllys 			AlgMode = KMF_ALGMODE_PKCS1_EMSA_V15;
419*99ebb4caSwyllys 			break;
420*99ebb4caSwyllys 		default:
421*99ebb4caSwyllys 			AlgMode = KMF_ALGMODE_NONE;
422*99ebb4caSwyllys 			break;
423*99ebb4caSwyllys 	}
424*99ebb4caSwyllys 
425*99ebb4caSwyllys 	return (AlgMode);
426*99ebb4caSwyllys }
427*99ebb4caSwyllys 
428*99ebb4caSwyllys KMF_RETURN
429*99ebb4caSwyllys PKCS_VerifyData(KMF_HANDLE_T kmfh,
430*99ebb4caSwyllys 		KMF_ALGORITHM_INDEX AlgorithmId,
431*99ebb4caSwyllys 		KMF_X509_SPKI *keyp,
432*99ebb4caSwyllys 		KMF_DATA *data,
433*99ebb4caSwyllys 		KMF_DATA *signed_data)
434*99ebb4caSwyllys {
435*99ebb4caSwyllys 	KMF_RETURN rv = KMF_OK;
436*99ebb4caSwyllys 	PKCS_ALGORITHM_MAP *pAlgMap = NULL;
437*99ebb4caSwyllys 	CK_RV ckRv;
438*99ebb4caSwyllys 	CK_MECHANISM ckMechanism;
439*99ebb4caSwyllys 	CK_OBJECT_HANDLE ckKeyHandle;
440*99ebb4caSwyllys 	KMF_BOOL	bTempKey;
441*99ebb4caSwyllys 	CK_SESSION_HANDLE ckSession = 0;
442*99ebb4caSwyllys 
443*99ebb4caSwyllys 	if (AlgorithmId == KMF_ALGID_NONE)
444*99ebb4caSwyllys 		return (KMF_ERR_BAD_ALGORITHM);
445*99ebb4caSwyllys 
446*99ebb4caSwyllys 	pAlgMap = PKCS_GetAlgorithmMap(KMF_ALGCLASS_SIGNATURE,
447*99ebb4caSwyllys 		AlgorithmId, PKCS_GetDefaultSignatureMode(AlgorithmId));
448*99ebb4caSwyllys 
449*99ebb4caSwyllys 	if (!pAlgMap)
450*99ebb4caSwyllys 		return (KMF_ERR_BAD_ALGORITHM);
451*99ebb4caSwyllys 
452*99ebb4caSwyllys 	rv = create_pk11_session(&ckSession, pAlgMap->pkcs_mechanism,
453*99ebb4caSwyllys 		CKF_VERIFY);
454*99ebb4caSwyllys 
455*99ebb4caSwyllys 	if (rv != KMF_OK)
456*99ebb4caSwyllys 		return (rv);
457*99ebb4caSwyllys 
458*99ebb4caSwyllys 	/* Fetch the verifying key */
459*99ebb4caSwyllys 	rv = PKCS_AcquirePublicKeyHandle(ckSession, keyp,
460*99ebb4caSwyllys 		pAlgMap->key_type, &ckKeyHandle, &bTempKey);
461*99ebb4caSwyllys 
462*99ebb4caSwyllys 	if (rv != KMF_OK) {
463*99ebb4caSwyllys 		(void) C_CloseSession(ckSession);
464*99ebb4caSwyllys 		return (rv);
465*99ebb4caSwyllys 	}
466*99ebb4caSwyllys 
467*99ebb4caSwyllys 	ckMechanism.mechanism = pAlgMap->pkcs_mechanism;
468*99ebb4caSwyllys 	ckMechanism.pParameter = NULL;
469*99ebb4caSwyllys 	ckMechanism.ulParameterLen = 0;
470*99ebb4caSwyllys 
471*99ebb4caSwyllys 	ckRv = C_VerifyInit(ckSession, &ckMechanism, ckKeyHandle);
472*99ebb4caSwyllys 	if (ckRv != CKR_OK) {
473*99ebb4caSwyllys 		if (bTempKey)
474*99ebb4caSwyllys 			(void) C_DestroyObject(ckSession, ckKeyHandle);
475*99ebb4caSwyllys 		kmfh->lasterr.kstype = KMF_KEYSTORE_PK11TOKEN;
476*99ebb4caSwyllys 		kmfh->lasterr.errcode = ckRv;
477*99ebb4caSwyllys 		(void) C_CloseSession(ckSession);
478*99ebb4caSwyllys 		return (KMF_ERR_INTERNAL);
479*99ebb4caSwyllys 	}
480*99ebb4caSwyllys 
481*99ebb4caSwyllys 	ckRv = C_Verify(ckSession,
482*99ebb4caSwyllys 		(CK_BYTE *)data->Data,
483*99ebb4caSwyllys 			(CK_ULONG)data->Length,
484*99ebb4caSwyllys 			(CK_BYTE *)signed_data->Data,
485*99ebb4caSwyllys 			(CK_ULONG)signed_data->Length);
486*99ebb4caSwyllys 
487*99ebb4caSwyllys 	if (ckRv != CKR_OK) {
488*99ebb4caSwyllys 		kmfh->lasterr.kstype = KMF_KEYSTORE_PK11TOKEN;
489*99ebb4caSwyllys 		kmfh->lasterr.errcode = ckRv;
490*99ebb4caSwyllys 		rv = KMF_ERR_INTERNAL;
491*99ebb4caSwyllys 	}
492*99ebb4caSwyllys 	if (bTempKey)
493*99ebb4caSwyllys 		(void) C_DestroyObject(ckSession, ckKeyHandle);
494*99ebb4caSwyllys 
495*99ebb4caSwyllys 	(void) C_CloseSession(ckSession);
496*99ebb4caSwyllys 	return (rv);
497*99ebb4caSwyllys 
498*99ebb4caSwyllys }
499*99ebb4caSwyllys 
500*99ebb4caSwyllys KMF_RETURN
501*99ebb4caSwyllys PKCS_EncryptData(KMF_HANDLE_T kmfh,
502*99ebb4caSwyllys 		KMF_ALGORITHM_INDEX AlgorithmId,
503*99ebb4caSwyllys 		KMF_X509_SPKI *keyp,
504*99ebb4caSwyllys 		KMF_DATA *plaintext,
505*99ebb4caSwyllys 		KMF_DATA *ciphertext)
506*99ebb4caSwyllys {
507*99ebb4caSwyllys 	KMF_RETURN rv = KMF_OK;
508*99ebb4caSwyllys 	PKCS_ALGORITHM_MAP *pAlgMap = NULL;
509*99ebb4caSwyllys 	CK_RV ckRv;
510*99ebb4caSwyllys 	CK_MECHANISM ckMechanism;
511*99ebb4caSwyllys 	CK_OBJECT_HANDLE ckKeyHandle;
512*99ebb4caSwyllys 	KMF_BOOL bTempKey;
513*99ebb4caSwyllys 	CK_SESSION_HANDLE ckSession = NULL;
514*99ebb4caSwyllys 	CK_ULONG out_len = 0, in_len = 0, total_encrypted = 0;
515*99ebb4caSwyllys 	uint8_t *in_data, *out_data;
516*99ebb4caSwyllys 	int i, blocks, block_size;
517*99ebb4caSwyllys 	CK_ATTRIBUTE ckTemplate[2];
518*99ebb4caSwyllys 	CK_ULONG ckNumTemplates;
519*99ebb4caSwyllys 	CK_ULONG ckMaxTemplates = (sizeof (ckTemplate) /
520*99ebb4caSwyllys 		sizeof (CK_ATTRIBUTE));
521*99ebb4caSwyllys 
522*99ebb4caSwyllys 	pAlgMap = PKCS_GetAlgorithmMap(KMF_ALGCLASS_SIGNATURE,
523*99ebb4caSwyllys 	    AlgorithmId, PKCS_GetDefaultSignatureMode(AlgorithmId));
524*99ebb4caSwyllys 
525*99ebb4caSwyllys 	if (!pAlgMap)
526*99ebb4caSwyllys 		return (KMF_ERR_BAD_ALGORITHM);
527*99ebb4caSwyllys 
528*99ebb4caSwyllys 	rv = create_pk11_session(&ckSession, pAlgMap->pkcs_mechanism,
529*99ebb4caSwyllys 		CKF_ENCRYPT);
530*99ebb4caSwyllys 
531*99ebb4caSwyllys 	if (rv != KMF_OK)
532*99ebb4caSwyllys 		return (rv);
533*99ebb4caSwyllys 
534*99ebb4caSwyllys 	/* Get the public key used in encryption */
535*99ebb4caSwyllys 	rv = PKCS_AcquirePublicKeyHandle(ckSession, keyp,
536*99ebb4caSwyllys 	    pAlgMap->key_type, &ckKeyHandle, &bTempKey);
537*99ebb4caSwyllys 
538*99ebb4caSwyllys 	if (rv != KMF_OK) {
539*99ebb4caSwyllys 		(void) C_CloseSession(ckSession);
540*99ebb4caSwyllys 		return (rv);
541*99ebb4caSwyllys 	}
542*99ebb4caSwyllys 
543*99ebb4caSwyllys 	/* Get the modulus length */
544*99ebb4caSwyllys 	ckNumTemplates = 0;
545*99ebb4caSwyllys 	if (!PKCS_AddTemplate(ckTemplate,
546*99ebb4caSwyllys 			&ckNumTemplates,
547*99ebb4caSwyllys 			ckMaxTemplates,
548*99ebb4caSwyllys 			CKA_MODULUS,
549*99ebb4caSwyllys 			(CK_BYTE *)NULL,
550*99ebb4caSwyllys 			sizeof (CK_ULONG))) {
551*99ebb4caSwyllys 		if (bTempKey)
552*99ebb4caSwyllys 			(void) C_DestroyObject(ckSession, ckKeyHandle);
553*99ebb4caSwyllys 		(void) C_CloseSession(ckSession);
554*99ebb4caSwyllys 		return (KMF_ERR_INTERNAL);
555*99ebb4caSwyllys 	}
556*99ebb4caSwyllys 
557*99ebb4caSwyllys 	ckRv = C_GetAttributeValue(ckSession,
558*99ebb4caSwyllys 				ckKeyHandle,
559*99ebb4caSwyllys 				ckTemplate,
560*99ebb4caSwyllys 				ckNumTemplates);
561*99ebb4caSwyllys 
562*99ebb4caSwyllys 	if (ckRv != CKR_OK) {
563*99ebb4caSwyllys 		if (bTempKey)
564*99ebb4caSwyllys 			(void) C_DestroyObject(ckSession, ckKeyHandle);
565*99ebb4caSwyllys 		kmfh->lasterr.kstype = KMF_KEYSTORE_PK11TOKEN;
566*99ebb4caSwyllys 		kmfh->lasterr.errcode = ckRv;
567*99ebb4caSwyllys 		(void) C_CloseSession(ckSession);
568*99ebb4caSwyllys 		return (KMF_ERR_INTERNAL);
569*99ebb4caSwyllys 	}
570*99ebb4caSwyllys 	out_len = ckTemplate[0].ulValueLen;
571*99ebb4caSwyllys 
572*99ebb4caSwyllys 	if (out_len > ciphertext->Length) {
573*99ebb4caSwyllys 		if (bTempKey)
574*99ebb4caSwyllys 			(void) C_DestroyObject(ckSession, ckKeyHandle);
575*99ebb4caSwyllys 		(void) C_CloseSession(ckSession);
576*99ebb4caSwyllys 		return (KMF_ERR_BUFFER_SIZE);
577*99ebb4caSwyllys 	}
578*99ebb4caSwyllys 
579*99ebb4caSwyllys 	ckMechanism.mechanism = pAlgMap->pkcs_mechanism;
580*99ebb4caSwyllys 	ckMechanism.pParameter = NULL_PTR;
581*99ebb4caSwyllys 	ckMechanism.ulParameterLen = 0;
582*99ebb4caSwyllys 
583*99ebb4caSwyllys 	/* Compute the fixed input data length for single-part encryption */
584*99ebb4caSwyllys 	block_size = out_len - 11;
585*99ebb4caSwyllys 
586*99ebb4caSwyllys 	in_data = plaintext->Data;
587*99ebb4caSwyllys 	out_data = ciphertext->Data;
588*99ebb4caSwyllys 
589*99ebb4caSwyllys 	blocks = plaintext->Length/block_size;
590*99ebb4caSwyllys 
591*99ebb4caSwyllys 	for (i = 0; i < blocks; i++) {
592*99ebb4caSwyllys 		ckRv = C_EncryptInit(ckSession, &ckMechanism, ckKeyHandle);
593*99ebb4caSwyllys 		if (ckRv != CKR_OK) {
594*99ebb4caSwyllys 			if (bTempKey)
595*99ebb4caSwyllys 				(void) C_DestroyObject(ckSession, ckKeyHandle);
596*99ebb4caSwyllys 			kmfh->lasterr.kstype = KMF_KEYSTORE_PK11TOKEN;
597*99ebb4caSwyllys 			kmfh->lasterr.errcode = ckRv;
598*99ebb4caSwyllys 			(void) C_CloseSession(ckSession);
599*99ebb4caSwyllys 			return (KMF_ERR_INTERNAL);
600*99ebb4caSwyllys 		}
601*99ebb4caSwyllys 		ckRv = C_Encrypt(ckSession, (CK_BYTE_PTR)in_data, block_size,
602*99ebb4caSwyllys 		    (CK_BYTE_PTR)out_data, &out_len);
603*99ebb4caSwyllys 
604*99ebb4caSwyllys 		if (ckRv != CKR_OK) {
605*99ebb4caSwyllys 			if (bTempKey)
606*99ebb4caSwyllys 				(void) C_DestroyObject(ckSession, ckKeyHandle);
607*99ebb4caSwyllys 			kmfh->lasterr.kstype = KMF_KEYSTORE_PK11TOKEN;
608*99ebb4caSwyllys 			kmfh->lasterr.errcode = ckRv;
609*99ebb4caSwyllys 			(void) C_CloseSession(ckSession);
610*99ebb4caSwyllys 			return (KMF_ERR_INTERNAL);
611*99ebb4caSwyllys 		}
612*99ebb4caSwyllys 
613*99ebb4caSwyllys 		out_data += out_len;
614*99ebb4caSwyllys 		total_encrypted += out_len;
615*99ebb4caSwyllys 		in_data += block_size;
616*99ebb4caSwyllys 	}
617*99ebb4caSwyllys 
618*99ebb4caSwyllys 	if (plaintext->Length % block_size) {
619*99ebb4caSwyllys 		/* Encrypt the remaining data */
620*99ebb4caSwyllys 		ckRv = C_EncryptInit(ckSession, &ckMechanism, ckKeyHandle);
621*99ebb4caSwyllys 		if (ckRv != CKR_OK) {
622*99ebb4caSwyllys 			if (bTempKey)
623*99ebb4caSwyllys 				(void) C_DestroyObject(ckSession, ckKeyHandle);
624*99ebb4caSwyllys 			kmfh->lasterr.kstype = KMF_KEYSTORE_PK11TOKEN;
625*99ebb4caSwyllys 			kmfh->lasterr.errcode = ckRv;
626*99ebb4caSwyllys 			(void) C_CloseSession(ckSession);
627*99ebb4caSwyllys 			return (KMF_ERR_INTERNAL);
628*99ebb4caSwyllys 		}
629*99ebb4caSwyllys 
630*99ebb4caSwyllys 		in_len = plaintext->Length % block_size;
631*99ebb4caSwyllys 		ckRv = C_Encrypt(ckSession, (CK_BYTE_PTR)in_data, in_len,
632*99ebb4caSwyllys 		    (CK_BYTE_PTR)out_data, &out_len);
633*99ebb4caSwyllys 
634*99ebb4caSwyllys 		if (ckRv != CKR_OK) {
635*99ebb4caSwyllys 			if (bTempKey)
636*99ebb4caSwyllys 				(void) C_DestroyObject(ckSession, ckKeyHandle);
637*99ebb4caSwyllys 			kmfh->lasterr.kstype = KMF_KEYSTORE_PK11TOKEN;
638*99ebb4caSwyllys 			kmfh->lasterr.errcode = ckRv;
639*99ebb4caSwyllys 			(void) C_CloseSession(ckSession);
640*99ebb4caSwyllys 			return (KMF_ERR_INTERNAL);
641*99ebb4caSwyllys 		}
642*99ebb4caSwyllys 
643*99ebb4caSwyllys 		out_data += out_len;
644*99ebb4caSwyllys 		total_encrypted += out_len;
645*99ebb4caSwyllys 		in_data += in_len;
646*99ebb4caSwyllys 	}
647*99ebb4caSwyllys 
648*99ebb4caSwyllys 	ciphertext->Length = total_encrypted;
649*99ebb4caSwyllys 
650*99ebb4caSwyllys 	if (bTempKey)
651*99ebb4caSwyllys 		(void) C_DestroyObject(ckSession, ckKeyHandle);
652*99ebb4caSwyllys 
653*99ebb4caSwyllys 	(void) C_CloseSession(ckSession);
654*99ebb4caSwyllys 	return (rv);
655*99ebb4caSwyllys 
656*99ebb4caSwyllys }
657*99ebb4caSwyllys 
658*99ebb4caSwyllys CK_RV
659*99ebb4caSwyllys DigestData(CK_SESSION_HANDLE hSession,
660*99ebb4caSwyllys 	KMF_DATA *IDInput, KMF_DATA *IDOutput)
661*99ebb4caSwyllys {
662*99ebb4caSwyllys 	CK_RV rv = KMF_OK;
663*99ebb4caSwyllys 	CK_MECHANISM mechanism = {CKM_SHA_1, NULL, 0};
664*99ebb4caSwyllys 
665*99ebb4caSwyllys 	rv = C_DigestInit(hSession, &mechanism);
666*99ebb4caSwyllys 	if (rv != CKR_OK)
667*99ebb4caSwyllys 		return (rv);
668*99ebb4caSwyllys 
669*99ebb4caSwyllys 	rv = C_Digest(hSession,
670*99ebb4caSwyllys 			IDInput->Data, IDInput->Length,
671*99ebb4caSwyllys 			IDOutput->Data, (CK_ULONG *)&IDOutput->Length);
672*99ebb4caSwyllys 
673*99ebb4caSwyllys 	return (rv);
674*99ebb4caSwyllys }
675*99ebb4caSwyllys 
676*99ebb4caSwyllys KMF_RETURN
677*99ebb4caSwyllys GetIDFromSPKI(KMF_X509_SPKI *spki,
678*99ebb4caSwyllys 	KMF_DATA *ID)
679*99ebb4caSwyllys {
680*99ebb4caSwyllys 	KMF_RETURN rv = KMF_OK;
681*99ebb4caSwyllys 	KMF_DATA KeyParts[KMF_MAX_PUBLIC_KEY_PARTS];
682*99ebb4caSwyllys 	uint32_t uNumKeyParts = KMF_MAX_PUBLIC_KEY_PARTS;
683*99ebb4caSwyllys 	KMF_ALGORITHM_INDEX algId;
684*99ebb4caSwyllys 	CK_SESSION_HANDLE hSession = NULL;
685*99ebb4caSwyllys 	int i;
686*99ebb4caSwyllys 
687*99ebb4caSwyllys 	if (ID == NULL || spki == NULL)
688*99ebb4caSwyllys 		return (KMF_ERR_BAD_PARAMETER);
689*99ebb4caSwyllys 
690*99ebb4caSwyllys 	ID->Data = (uchar_t *)malloc(SHA1_HASH_LENGTH);
691*99ebb4caSwyllys 	if (ID->Data == NULL)
692*99ebb4caSwyllys 		return (KMF_ERR_MEMORY);
693*99ebb4caSwyllys 
694*99ebb4caSwyllys 	ID->Length = SHA1_HASH_LENGTH;
695*99ebb4caSwyllys 
696*99ebb4caSwyllys 	algId = X509_AlgorithmOidToAlgId(&spki->algorithm.algorithm);
697*99ebb4caSwyllys 
698*99ebb4caSwyllys 	rv = ExtractSPKIData(spki, algId, KeyParts, &uNumKeyParts);
699*99ebb4caSwyllys 	if (rv != KMF_OK)
700*99ebb4caSwyllys 		return (rv);
701*99ebb4caSwyllys 
702*99ebb4caSwyllys 	rv = create_pk11_session(&hSession, CKM_SHA_1, CKF_DIGEST);
703*99ebb4caSwyllys 
704*99ebb4caSwyllys 	if (rv != KMF_OK)
705*99ebb4caSwyllys 		return (rv);
706*99ebb4caSwyllys 
707*99ebb4caSwyllys 	/* Check the KEY algorithm */
708*99ebb4caSwyllys 	if (algId == KMF_ALGID_RSA) {
709*99ebb4caSwyllys 		rv = DigestData(hSession,
710*99ebb4caSwyllys 				&KeyParts[KMF_RSA_MODULUS],
711*99ebb4caSwyllys 				ID);
712*99ebb4caSwyllys 	} else if (algId == KMF_ALGID_DSA) {
713*99ebb4caSwyllys 		rv = DigestData(hSession,
714*99ebb4caSwyllys 				&KeyParts[KMF_DSA_PUBLIC_VALUE],
715*99ebb4caSwyllys 				ID);
716*99ebb4caSwyllys 	} else {
717*99ebb4caSwyllys 		/* We only support RSA and DSA keys for now */
718*99ebb4caSwyllys 		rv = KMF_ERR_BAD_ALGORITHM;
719*99ebb4caSwyllys 	}
720*99ebb4caSwyllys 
721*99ebb4caSwyllys 
722*99ebb4caSwyllys 	for (i = 0; i < uNumKeyParts; i++) {
723*99ebb4caSwyllys 		if (KeyParts[i].Data != NULL)
724*99ebb4caSwyllys 			free(KeyParts[i].Data);
725*99ebb4caSwyllys 	}
726*99ebb4caSwyllys 
727*99ebb4caSwyllys 	if (rv != KMF_OK && ID->Data != NULL) {
728*99ebb4caSwyllys 		free(ID->Data);
729*99ebb4caSwyllys 		ID->Data = NULL;
730*99ebb4caSwyllys 		ID->Length = 0;
731*99ebb4caSwyllys 	}
732*99ebb4caSwyllys 
733*99ebb4caSwyllys 	(void) C_CloseSession(hSession);
734*99ebb4caSwyllys 	return (rv);
735*99ebb4caSwyllys }
736