xref: /onnv-gate/usr/src/lib/pkcs11/pkcs11_kms/common/kmsObjectUtil.c (revision 12720:3db6e0082404)
1*12720SWyllys.Ingersoll@Sun.COM /*
2*12720SWyllys.Ingersoll@Sun.COM  * CDDL HEADER START
3*12720SWyllys.Ingersoll@Sun.COM  *
4*12720SWyllys.Ingersoll@Sun.COM  * The contents of this file are subject to the terms of the
5*12720SWyllys.Ingersoll@Sun.COM  * Common Development and Distribution License (the "License").
6*12720SWyllys.Ingersoll@Sun.COM  * You may not use this file except in compliance with the License.
7*12720SWyllys.Ingersoll@Sun.COM  *
8*12720SWyllys.Ingersoll@Sun.COM  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*12720SWyllys.Ingersoll@Sun.COM  * or http://www.opensolaris.org/os/licensing.
10*12720SWyllys.Ingersoll@Sun.COM  * See the License for the specific language governing permissions
11*12720SWyllys.Ingersoll@Sun.COM  * and limitations under the License.
12*12720SWyllys.Ingersoll@Sun.COM  *
13*12720SWyllys.Ingersoll@Sun.COM  * When distributing Covered Code, include this CDDL HEADER in each
14*12720SWyllys.Ingersoll@Sun.COM  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*12720SWyllys.Ingersoll@Sun.COM  * If applicable, add the following below this CDDL HEADER, with the
16*12720SWyllys.Ingersoll@Sun.COM  * fields enclosed by brackets "[]" replaced with your own identifying
17*12720SWyllys.Ingersoll@Sun.COM  * information: Portions Copyright [yyyy] [name of copyright owner]
18*12720SWyllys.Ingersoll@Sun.COM  *
19*12720SWyllys.Ingersoll@Sun.COM  * CDDL HEADER END
20*12720SWyllys.Ingersoll@Sun.COM  */
21*12720SWyllys.Ingersoll@Sun.COM /*
22*12720SWyllys.Ingersoll@Sun.COM  * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
23*12720SWyllys.Ingersoll@Sun.COM  */
24*12720SWyllys.Ingersoll@Sun.COM 
25*12720SWyllys.Ingersoll@Sun.COM #include <stdio.h>
26*12720SWyllys.Ingersoll@Sun.COM #include <stdlib.h>
27*12720SWyllys.Ingersoll@Sun.COM #include <strings.h>
28*12720SWyllys.Ingersoll@Sun.COM #include <errno.h>
29*12720SWyllys.Ingersoll@Sun.COM #include <security/cryptoki.h>
30*12720SWyllys.Ingersoll@Sun.COM #include <cryptoutil.h>
31*12720SWyllys.Ingersoll@Sun.COM 
32*12720SWyllys.Ingersoll@Sun.COM #include "kmsGlobal.h"
33*12720SWyllys.Ingersoll@Sun.COM #include "kmsObject.h"
34*12720SWyllys.Ingersoll@Sun.COM #include "kmsSession.h"
35*12720SWyllys.Ingersoll@Sun.COM #include "kmsSlot.h"
36*12720SWyllys.Ingersoll@Sun.COM #include "kmsKeystoreUtil.h"
37*12720SWyllys.Ingersoll@Sun.COM 
38*12720SWyllys.Ingersoll@Sun.COM kms_object_t *
kms_new_object()39*12720SWyllys.Ingersoll@Sun.COM kms_new_object()
40*12720SWyllys.Ingersoll@Sun.COM {
41*12720SWyllys.Ingersoll@Sun.COM 	kms_object_t *obj;
42*12720SWyllys.Ingersoll@Sun.COM 
43*12720SWyllys.Ingersoll@Sun.COM 	obj = calloc(1, sizeof (kms_object_t));
44*12720SWyllys.Ingersoll@Sun.COM 	if (obj == NULL)
45*12720SWyllys.Ingersoll@Sun.COM 		return (NULL);
46*12720SWyllys.Ingersoll@Sun.COM 
47*12720SWyllys.Ingersoll@Sun.COM 	(void) pthread_cond_init(&obj->obj_free_cond, NULL);
48*12720SWyllys.Ingersoll@Sun.COM 	(void) pthread_mutex_init(&obj->object_mutex, NULL);
49*12720SWyllys.Ingersoll@Sun.COM 	obj->magic_marker = KMSTOKEN_OBJECT_MAGIC;
50*12720SWyllys.Ingersoll@Sun.COM 
51*12720SWyllys.Ingersoll@Sun.COM 	return (obj);
52*12720SWyllys.Ingersoll@Sun.COM }
53*12720SWyllys.Ingersoll@Sun.COM 
54*12720SWyllys.Ingersoll@Sun.COM /*
55*12720SWyllys.Ingersoll@Sun.COM  * Add an object to the session's object list.
56*12720SWyllys.Ingersoll@Sun.COM  *
57*12720SWyllys.Ingersoll@Sun.COM  * This function will acquire the lock on the session, and release
58*12720SWyllys.Ingersoll@Sun.COM  * that lock after adding the object to the session's object list.
59*12720SWyllys.Ingersoll@Sun.COM  */
60*12720SWyllys.Ingersoll@Sun.COM void
kms_add_object_to_session(kms_object_t * objp,kms_session_t * sp)61*12720SWyllys.Ingersoll@Sun.COM kms_add_object_to_session(kms_object_t *objp, kms_session_t *sp)
62*12720SWyllys.Ingersoll@Sun.COM {
63*12720SWyllys.Ingersoll@Sun.COM 	/* Acquire the session lock. */
64*12720SWyllys.Ingersoll@Sun.COM 	(void) pthread_mutex_lock(&sp->session_mutex);
65*12720SWyllys.Ingersoll@Sun.COM 
66*12720SWyllys.Ingersoll@Sun.COM 	/* Insert the new object in front of session's object list. */
67*12720SWyllys.Ingersoll@Sun.COM 	if (sp->object_list == NULL) {
68*12720SWyllys.Ingersoll@Sun.COM 		sp->object_list = objp;
69*12720SWyllys.Ingersoll@Sun.COM 		objp->next = NULL;
70*12720SWyllys.Ingersoll@Sun.COM 		objp->prev = NULL;
71*12720SWyllys.Ingersoll@Sun.COM 	} else {
72*12720SWyllys.Ingersoll@Sun.COM 		sp->object_list->prev = objp;
73*12720SWyllys.Ingersoll@Sun.COM 		objp->next = sp->object_list;
74*12720SWyllys.Ingersoll@Sun.COM 		objp->prev = NULL;
75*12720SWyllys.Ingersoll@Sun.COM 		sp->object_list = objp;
76*12720SWyllys.Ingersoll@Sun.COM 	}
77*12720SWyllys.Ingersoll@Sun.COM 
78*12720SWyllys.Ingersoll@Sun.COM 	/* Release the session lock. */
79*12720SWyllys.Ingersoll@Sun.COM 	(void) pthread_mutex_unlock(&sp->session_mutex);
80*12720SWyllys.Ingersoll@Sun.COM }
81*12720SWyllys.Ingersoll@Sun.COM 
82*12720SWyllys.Ingersoll@Sun.COM /*
83*12720SWyllys.Ingersoll@Sun.COM  * Clean up and release the storage allocated to the object.
84*12720SWyllys.Ingersoll@Sun.COM  *
85*12720SWyllys.Ingersoll@Sun.COM  * The function is called either with the object lock being held
86*12720SWyllys.Ingersoll@Sun.COM  * (by caller kms_delete_object()), or there is no object lock
87*12720SWyllys.Ingersoll@Sun.COM  * yet (by kms_build_XXX_object() during creating an object).
88*12720SWyllys.Ingersoll@Sun.COM  */
89*12720SWyllys.Ingersoll@Sun.COM void
kms_cleanup_object(kms_object_t * objp)90*12720SWyllys.Ingersoll@Sun.COM kms_cleanup_object(kms_object_t *objp)
91*12720SWyllys.Ingersoll@Sun.COM {
92*12720SWyllys.Ingersoll@Sun.COM 	/*
93*12720SWyllys.Ingersoll@Sun.COM 	 * Free the storage allocated to a secret key object.
94*12720SWyllys.Ingersoll@Sun.COM 	 */
95*12720SWyllys.Ingersoll@Sun.COM 	if (objp->class == CKO_SECRET_KEY) {
96*12720SWyllys.Ingersoll@Sun.COM 		if (OBJ_SEC(objp) != NULL && OBJ_SEC_VALUE(objp) != NULL) {
97*12720SWyllys.Ingersoll@Sun.COM 			bzero(OBJ_SEC_VALUE(objp), OBJ_SEC_VALUE_LEN(objp));
98*12720SWyllys.Ingersoll@Sun.COM 			free(OBJ_SEC_VALUE(objp));
99*12720SWyllys.Ingersoll@Sun.COM 			OBJ_SEC_VALUE(objp) = NULL;
100*12720SWyllys.Ingersoll@Sun.COM 			OBJ_SEC_VALUE_LEN(objp) = 0;
101*12720SWyllys.Ingersoll@Sun.COM 		}
102*12720SWyllys.Ingersoll@Sun.COM 		if (OBJ_SEC(objp) != NULL)
103*12720SWyllys.Ingersoll@Sun.COM 			free(OBJ_SEC(objp));
104*12720SWyllys.Ingersoll@Sun.COM 
105*12720SWyllys.Ingersoll@Sun.COM 		OBJ_SEC(objp) = NULL;
106*12720SWyllys.Ingersoll@Sun.COM 	}
107*12720SWyllys.Ingersoll@Sun.COM 
108*12720SWyllys.Ingersoll@Sun.COM 	/*
109*12720SWyllys.Ingersoll@Sun.COM 	 * Free the storage allocated to the extra attribute list.
110*12720SWyllys.Ingersoll@Sun.COM 	 */
111*12720SWyllys.Ingersoll@Sun.COM 	kms_cleanup_extra_attr(objp);
112*12720SWyllys.Ingersoll@Sun.COM }
113*12720SWyllys.Ingersoll@Sun.COM 
114*12720SWyllys.Ingersoll@Sun.COM void
kms_free_object(kms_object_t * obj)115*12720SWyllys.Ingersoll@Sun.COM kms_free_object(kms_object_t *obj)
116*12720SWyllys.Ingersoll@Sun.COM {
117*12720SWyllys.Ingersoll@Sun.COM 	(void) pthread_cond_destroy(&obj->obj_free_cond);
118*12720SWyllys.Ingersoll@Sun.COM 	(void) pthread_mutex_destroy(&obj->object_mutex);
119*12720SWyllys.Ingersoll@Sun.COM 
120*12720SWyllys.Ingersoll@Sun.COM 	kms_cleanup_object(obj);
121*12720SWyllys.Ingersoll@Sun.COM 
122*12720SWyllys.Ingersoll@Sun.COM 	free(obj);
123*12720SWyllys.Ingersoll@Sun.COM }
124*12720SWyllys.Ingersoll@Sun.COM 
125*12720SWyllys.Ingersoll@Sun.COM /*
126*12720SWyllys.Ingersoll@Sun.COM  * Create a new object. Copy the attributes that can be modified
127*12720SWyllys.Ingersoll@Sun.COM  * (in the boolean attribute mask field and extra attribute list)
128*12720SWyllys.Ingersoll@Sun.COM  * from the old object to the new object.
129*12720SWyllys.Ingersoll@Sun.COM  *
130*12720SWyllys.Ingersoll@Sun.COM  * The caller of this function holds the lock on the old object.
131*12720SWyllys.Ingersoll@Sun.COM  */
132*12720SWyllys.Ingersoll@Sun.COM CK_RV
kms_copy_object(kms_object_t * old_object,kms_object_t ** new_object,boolean_t copy_everything,kms_session_t * sp)133*12720SWyllys.Ingersoll@Sun.COM kms_copy_object(kms_object_t *old_object, kms_object_t **new_object,
134*12720SWyllys.Ingersoll@Sun.COM     boolean_t copy_everything, kms_session_t *sp)
135*12720SWyllys.Ingersoll@Sun.COM {
136*12720SWyllys.Ingersoll@Sun.COM 	CK_RV rv = CKR_OK;
137*12720SWyllys.Ingersoll@Sun.COM 	kms_object_t *new_objp = NULL;
138*12720SWyllys.Ingersoll@Sun.COM 	CK_ATTRIBUTE_INFO_PTR attrp;
139*12720SWyllys.Ingersoll@Sun.COM 
140*12720SWyllys.Ingersoll@Sun.COM 	/* Allocate new object. */
141*12720SWyllys.Ingersoll@Sun.COM 	new_objp = kms_new_object();
142*12720SWyllys.Ingersoll@Sun.COM 	if (new_objp == NULL)
143*12720SWyllys.Ingersoll@Sun.COM 		return (CKR_HOST_MEMORY);
144*12720SWyllys.Ingersoll@Sun.COM 
145*12720SWyllys.Ingersoll@Sun.COM 	new_objp->class = old_object->class;
146*12720SWyllys.Ingersoll@Sun.COM 	new_objp->bool_attr_mask = old_object->bool_attr_mask;
147*12720SWyllys.Ingersoll@Sun.COM 
148*12720SWyllys.Ingersoll@Sun.COM 	attrp = old_object->extra_attrlistp;
149*12720SWyllys.Ingersoll@Sun.COM 	while (attrp) {
150*12720SWyllys.Ingersoll@Sun.COM 		/*
151*12720SWyllys.Ingersoll@Sun.COM 		 * Copy the attribute_info struct from the old
152*12720SWyllys.Ingersoll@Sun.COM 		 * object to a new attribute_info struct, and add
153*12720SWyllys.Ingersoll@Sun.COM 		 * that new struct to the extra attribute list
154*12720SWyllys.Ingersoll@Sun.COM 		 * of the new object.
155*12720SWyllys.Ingersoll@Sun.COM 		 */
156*12720SWyllys.Ingersoll@Sun.COM 		rv = kms_copy_extra_attr(attrp, new_objp);
157*12720SWyllys.Ingersoll@Sun.COM 		if (rv != CKR_OK) {
158*12720SWyllys.Ingersoll@Sun.COM 			kms_free_object(new_objp);
159*12720SWyllys.Ingersoll@Sun.COM 			return (rv);
160*12720SWyllys.Ingersoll@Sun.COM 		}
161*12720SWyllys.Ingersoll@Sun.COM 		attrp = attrp->next;
162*12720SWyllys.Ingersoll@Sun.COM 	}
163*12720SWyllys.Ingersoll@Sun.COM 
164*12720SWyllys.Ingersoll@Sun.COM 	*new_object = new_objp;
165*12720SWyllys.Ingersoll@Sun.COM 
166*12720SWyllys.Ingersoll@Sun.COM 	if (!copy_everything) {
167*12720SWyllys.Ingersoll@Sun.COM 		/* done with copying all information that can be modified */
168*12720SWyllys.Ingersoll@Sun.COM 		return (CKR_OK);
169*12720SWyllys.Ingersoll@Sun.COM 	}
170*12720SWyllys.Ingersoll@Sun.COM 
171*12720SWyllys.Ingersoll@Sun.COM 	/*
172*12720SWyllys.Ingersoll@Sun.COM 	 * Copy the rest of the object.
173*12720SWyllys.Ingersoll@Sun.COM 	 * Certain fields that are not appropriate for coping will be
174*12720SWyllys.Ingersoll@Sun.COM 	 * initialized.
175*12720SWyllys.Ingersoll@Sun.COM 	 */
176*12720SWyllys.Ingersoll@Sun.COM 	new_objp->key_type = old_object->key_type;
177*12720SWyllys.Ingersoll@Sun.COM 	new_objp->magic_marker = old_object->magic_marker;
178*12720SWyllys.Ingersoll@Sun.COM 	new_objp->mechanism = old_object->mechanism;
179*12720SWyllys.Ingersoll@Sun.COM 	new_objp->session_handle = (CK_SESSION_HANDLE)sp;
180*12720SWyllys.Ingersoll@Sun.COM 
181*12720SWyllys.Ingersoll@Sun.COM 	/* copy key related information */
182*12720SWyllys.Ingersoll@Sun.COM 	switch (new_objp->class) {
183*12720SWyllys.Ingersoll@Sun.COM 		case CKO_SECRET_KEY:
184*12720SWyllys.Ingersoll@Sun.COM 			rv = kms_copy_secret_key_attr(OBJ_SEC(old_object),
185*12720SWyllys.Ingersoll@Sun.COM 			    &(OBJ_SEC(new_objp)));
186*12720SWyllys.Ingersoll@Sun.COM 			break;
187*12720SWyllys.Ingersoll@Sun.COM 		default:
188*12720SWyllys.Ingersoll@Sun.COM 			/* should never be this case */
189*12720SWyllys.Ingersoll@Sun.COM 			break;
190*12720SWyllys.Ingersoll@Sun.COM 	}
191*12720SWyllys.Ingersoll@Sun.COM 	if (rv != CKR_OK) {
192*12720SWyllys.Ingersoll@Sun.COM 		kms_free_object(new_objp);
193*12720SWyllys.Ingersoll@Sun.COM 		*new_object = NULL;
194*12720SWyllys.Ingersoll@Sun.COM 	}
195*12720SWyllys.Ingersoll@Sun.COM 	return (rv);
196*12720SWyllys.Ingersoll@Sun.COM }
197*12720SWyllys.Ingersoll@Sun.COM 
198*12720SWyllys.Ingersoll@Sun.COM /*
199*12720SWyllys.Ingersoll@Sun.COM  * Copy the attributes (in the boolean attribute mask field and
200*12720SWyllys.Ingersoll@Sun.COM  * extra attribute list) from the new object back to the original
201*12720SWyllys.Ingersoll@Sun.COM  * object. Also, clean up and release all the storage in the extra
202*12720SWyllys.Ingersoll@Sun.COM  * attribute list of the original object.
203*12720SWyllys.Ingersoll@Sun.COM  *
204*12720SWyllys.Ingersoll@Sun.COM  * The caller of this function holds the lock on the old object.
205*12720SWyllys.Ingersoll@Sun.COM  */
206*12720SWyllys.Ingersoll@Sun.COM void
kms_merge_object(kms_object_t * old_object,kms_object_t * new_object)207*12720SWyllys.Ingersoll@Sun.COM kms_merge_object(kms_object_t *old_object, kms_object_t *new_object)
208*12720SWyllys.Ingersoll@Sun.COM {
209*12720SWyllys.Ingersoll@Sun.COM 	old_object->bool_attr_mask = new_object->bool_attr_mask;
210*12720SWyllys.Ingersoll@Sun.COM 	kms_cleanup_extra_attr(old_object);
211*12720SWyllys.Ingersoll@Sun.COM 	old_object->extra_attrlistp = new_object->extra_attrlistp;
212*12720SWyllys.Ingersoll@Sun.COM }
213*12720SWyllys.Ingersoll@Sun.COM 
214*12720SWyllys.Ingersoll@Sun.COM /*
215*12720SWyllys.Ingersoll@Sun.COM  * Create a new object struct.  If it is a session object, add the object to
216*12720SWyllys.Ingersoll@Sun.COM  * the session's object list.  If it is a token object, add it to the slot's
217*12720SWyllys.Ingersoll@Sun.COM  * token object list.  The caller does not hold the slot lock.
218*12720SWyllys.Ingersoll@Sun.COM  */
219*12720SWyllys.Ingersoll@Sun.COM CK_RV
kms_add_object(CK_ATTRIBUTE_PTR pTemplate,CK_ULONG ulCount,CK_ULONG * objecthandle_p,kms_session_t * sp)220*12720SWyllys.Ingersoll@Sun.COM kms_add_object(CK_ATTRIBUTE_PTR pTemplate,  CK_ULONG ulCount,
221*12720SWyllys.Ingersoll@Sun.COM 	CK_ULONG *objecthandle_p, kms_session_t *sp)
222*12720SWyllys.Ingersoll@Sun.COM {
223*12720SWyllys.Ingersoll@Sun.COM 	CK_RV rv = CKR_OK;
224*12720SWyllys.Ingersoll@Sun.COM 	kms_object_t *new_objp = NULL;
225*12720SWyllys.Ingersoll@Sun.COM 	kms_slot_t	*pslot;
226*12720SWyllys.Ingersoll@Sun.COM 	CK_ATTRIBUTE	pritmpl;
227*12720SWyllys.Ingersoll@Sun.COM 	CK_BBOOL	is_pri_obj, is_token_obj;
228*12720SWyllys.Ingersoll@Sun.COM 
229*12720SWyllys.Ingersoll@Sun.COM 	new_objp = kms_new_object();
230*12720SWyllys.Ingersoll@Sun.COM 	if (new_objp == NULL)
231*12720SWyllys.Ingersoll@Sun.COM 		return (CKR_HOST_MEMORY);
232*12720SWyllys.Ingersoll@Sun.COM 
233*12720SWyllys.Ingersoll@Sun.COM 	rv = kms_build_object(pTemplate, ulCount, new_objp);
234*12720SWyllys.Ingersoll@Sun.COM 	if (rv != CKR_OK)
235*12720SWyllys.Ingersoll@Sun.COM 		goto fail_cleanup;
236*12720SWyllys.Ingersoll@Sun.COM 
237*12720SWyllys.Ingersoll@Sun.COM 	/* Cannot create a token object with a READ-ONLY session */
238*12720SWyllys.Ingersoll@Sun.COM 	pritmpl.type = CKA_TOKEN;
239*12720SWyllys.Ingersoll@Sun.COM 	pritmpl.pValue = &is_token_obj;
240*12720SWyllys.Ingersoll@Sun.COM 	pritmpl.ulValueLen = sizeof (is_token_obj);
241*12720SWyllys.Ingersoll@Sun.COM 	rv = kms_get_attribute(new_objp, &pritmpl);
242*12720SWyllys.Ingersoll@Sun.COM 	if (rv != CKR_OK)
243*12720SWyllys.Ingersoll@Sun.COM 		goto fail_cleanup;
244*12720SWyllys.Ingersoll@Sun.COM 
245*12720SWyllys.Ingersoll@Sun.COM 	if (is_token_obj && sp->ses_RO) {
246*12720SWyllys.Ingersoll@Sun.COM 		rv = CKR_SESSION_READ_ONLY;
247*12720SWyllys.Ingersoll@Sun.COM 		goto fail_cleanup;
248*12720SWyllys.Ingersoll@Sun.COM 	}
249*12720SWyllys.Ingersoll@Sun.COM 
250*12720SWyllys.Ingersoll@Sun.COM 	/*
251*12720SWyllys.Ingersoll@Sun.COM 	 * If the KMS supports object creation, create the object
252*12720SWyllys.Ingersoll@Sun.COM 	 * in the KMS.  Otherwise, create the object in the library.
253*12720SWyllys.Ingersoll@Sun.COM 	 */
254*12720SWyllys.Ingersoll@Sun.COM 
255*12720SWyllys.Ingersoll@Sun.COM 	/* Get the CKA_PRIVATE value of this object. */
256*12720SWyllys.Ingersoll@Sun.COM 	pritmpl.type = CKA_PRIVATE;
257*12720SWyllys.Ingersoll@Sun.COM 	pritmpl.pValue = &is_pri_obj;
258*12720SWyllys.Ingersoll@Sun.COM 	pritmpl.ulValueLen = sizeof (is_pri_obj);
259*12720SWyllys.Ingersoll@Sun.COM 
260*12720SWyllys.Ingersoll@Sun.COM 	rv = kms_get_attribute(new_objp, &pritmpl);
261*12720SWyllys.Ingersoll@Sun.COM 	if (rv != CKR_OK) {
262*12720SWyllys.Ingersoll@Sun.COM 		goto fail_cleanup;
263*12720SWyllys.Ingersoll@Sun.COM 	}
264*12720SWyllys.Ingersoll@Sun.COM 
265*12720SWyllys.Ingersoll@Sun.COM 	/* Set the PRIVATE_BOOL_ON and TOKEN_BOOL_ON attributes */
266*12720SWyllys.Ingersoll@Sun.COM 	if (is_pri_obj)
267*12720SWyllys.Ingersoll@Sun.COM 		new_objp->bool_attr_mask |= PRIVATE_BOOL_ON;
268*12720SWyllys.Ingersoll@Sun.COM 	else
269*12720SWyllys.Ingersoll@Sun.COM 		new_objp->bool_attr_mask &= ~PRIVATE_BOOL_ON;
270*12720SWyllys.Ingersoll@Sun.COM 
271*12720SWyllys.Ingersoll@Sun.COM 	if (is_token_obj)
272*12720SWyllys.Ingersoll@Sun.COM 		new_objp->bool_attr_mask |= TOKEN_BOOL_ON;
273*12720SWyllys.Ingersoll@Sun.COM 	else
274*12720SWyllys.Ingersoll@Sun.COM 		new_objp->bool_attr_mask &= ~TOKEN_BOOL_ON;
275*12720SWyllys.Ingersoll@Sun.COM 
276*12720SWyllys.Ingersoll@Sun.COM 	new_objp->session_handle = (CK_SESSION_HANDLE)sp;
277*12720SWyllys.Ingersoll@Sun.COM 
278*12720SWyllys.Ingersoll@Sun.COM 	if (is_token_obj) {
279*12720SWyllys.Ingersoll@Sun.COM 		/* Add the new object to the slot's token object list. */
280*12720SWyllys.Ingersoll@Sun.COM 		pslot = get_slotinfo();
281*12720SWyllys.Ingersoll@Sun.COM 		kms_add_token_object_to_slot(new_objp, pslot);
282*12720SWyllys.Ingersoll@Sun.COM 	} else {
283*12720SWyllys.Ingersoll@Sun.COM 		/* Add the new object to the session's object list. */
284*12720SWyllys.Ingersoll@Sun.COM 		kms_add_object_to_session(new_objp, sp);
285*12720SWyllys.Ingersoll@Sun.COM 	}
286*12720SWyllys.Ingersoll@Sun.COM 
287*12720SWyllys.Ingersoll@Sun.COM 	/* Type casting the address of an object struct to an object handle. */
288*12720SWyllys.Ingersoll@Sun.COM 	if (rv == CKR_OK)
289*12720SWyllys.Ingersoll@Sun.COM 		*objecthandle_p = (CK_ULONG)new_objp;
290*12720SWyllys.Ingersoll@Sun.COM 
291*12720SWyllys.Ingersoll@Sun.COM fail_cleanup:
292*12720SWyllys.Ingersoll@Sun.COM 	if (rv != CKR_OK) {
293*12720SWyllys.Ingersoll@Sun.COM 		kms_free_object(new_objp);
294*12720SWyllys.Ingersoll@Sun.COM 	}
295*12720SWyllys.Ingersoll@Sun.COM 	return (rv);
296*12720SWyllys.Ingersoll@Sun.COM }
297*12720SWyllys.Ingersoll@Sun.COM 
298*12720SWyllys.Ingersoll@Sun.COM /*
299*12720SWyllys.Ingersoll@Sun.COM  * Remove an object from the session's object list.
300*12720SWyllys.Ingersoll@Sun.COM  *
301*12720SWyllys.Ingersoll@Sun.COM  * The caller of this function holds the session lock.
302*12720SWyllys.Ingersoll@Sun.COM  */
303*12720SWyllys.Ingersoll@Sun.COM CK_RV
kms_remove_object_from_session(kms_object_t * objp,kms_session_t * sp)304*12720SWyllys.Ingersoll@Sun.COM kms_remove_object_from_session(kms_object_t *objp, kms_session_t *sp)
305*12720SWyllys.Ingersoll@Sun.COM {
306*12720SWyllys.Ingersoll@Sun.COM 	kms_object_t *tmp_objp;
307*12720SWyllys.Ingersoll@Sun.COM 	boolean_t found = B_FALSE;
308*12720SWyllys.Ingersoll@Sun.COM 
309*12720SWyllys.Ingersoll@Sun.COM 	/*
310*12720SWyllys.Ingersoll@Sun.COM 	 * Remove the object from the session's object list.
311*12720SWyllys.Ingersoll@Sun.COM 	 */
312*12720SWyllys.Ingersoll@Sun.COM 	if ((sp == NULL) ||
313*12720SWyllys.Ingersoll@Sun.COM 	    (sp->magic_marker != KMSTOKEN_SESSION_MAGIC)) {
314*12720SWyllys.Ingersoll@Sun.COM 		return (CKR_SESSION_HANDLE_INVALID);
315*12720SWyllys.Ingersoll@Sun.COM 	}
316*12720SWyllys.Ingersoll@Sun.COM 
317*12720SWyllys.Ingersoll@Sun.COM 	if ((sp->object_list == NULL) || (objp == NULL) ||
318*12720SWyllys.Ingersoll@Sun.COM 	    (objp->magic_marker != KMSTOKEN_OBJECT_MAGIC)) {
319*12720SWyllys.Ingersoll@Sun.COM 		return (CKR_OBJECT_HANDLE_INVALID);
320*12720SWyllys.Ingersoll@Sun.COM 	}
321*12720SWyllys.Ingersoll@Sun.COM 
322*12720SWyllys.Ingersoll@Sun.COM 	tmp_objp = sp->object_list;
323*12720SWyllys.Ingersoll@Sun.COM 	while (tmp_objp) {
324*12720SWyllys.Ingersoll@Sun.COM 		if (tmp_objp == objp) {
325*12720SWyllys.Ingersoll@Sun.COM 			found = B_TRUE;
326*12720SWyllys.Ingersoll@Sun.COM 			break;
327*12720SWyllys.Ingersoll@Sun.COM 		}
328*12720SWyllys.Ingersoll@Sun.COM 		tmp_objp = tmp_objp->next;
329*12720SWyllys.Ingersoll@Sun.COM 	}
330*12720SWyllys.Ingersoll@Sun.COM 	if (!found)
331*12720SWyllys.Ingersoll@Sun.COM 		return (CKR_OBJECT_HANDLE_INVALID);
332*12720SWyllys.Ingersoll@Sun.COM 
333*12720SWyllys.Ingersoll@Sun.COM 	if (sp->object_list == objp) {
334*12720SWyllys.Ingersoll@Sun.COM 		/* Object is the first one in the list. */
335*12720SWyllys.Ingersoll@Sun.COM 		if (objp->next) {
336*12720SWyllys.Ingersoll@Sun.COM 			sp->object_list = objp->next;
337*12720SWyllys.Ingersoll@Sun.COM 			objp->next->prev = NULL;
338*12720SWyllys.Ingersoll@Sun.COM 		} else {
339*12720SWyllys.Ingersoll@Sun.COM 			/* Object is the only one in the list. */
340*12720SWyllys.Ingersoll@Sun.COM 			sp->object_list = NULL;
341*12720SWyllys.Ingersoll@Sun.COM 		}
342*12720SWyllys.Ingersoll@Sun.COM 	} else {
343*12720SWyllys.Ingersoll@Sun.COM 		/* Object is not the first one in the list. */
344*12720SWyllys.Ingersoll@Sun.COM 		if (objp->next) {
345*12720SWyllys.Ingersoll@Sun.COM 			/* Object is in the middle of the list. */
346*12720SWyllys.Ingersoll@Sun.COM 			objp->prev->next = objp->next;
347*12720SWyllys.Ingersoll@Sun.COM 			objp->next->prev = objp->prev;
348*12720SWyllys.Ingersoll@Sun.COM 		} else {
349*12720SWyllys.Ingersoll@Sun.COM 			/* Object is the last one in the list. */
350*12720SWyllys.Ingersoll@Sun.COM 			objp->prev->next = NULL;
351*12720SWyllys.Ingersoll@Sun.COM 		}
352*12720SWyllys.Ingersoll@Sun.COM 	}
353*12720SWyllys.Ingersoll@Sun.COM 	return (CKR_OK);
354*12720SWyllys.Ingersoll@Sun.COM }
355*12720SWyllys.Ingersoll@Sun.COM 
356*12720SWyllys.Ingersoll@Sun.COM /*
357*12720SWyllys.Ingersoll@Sun.COM  * This function adds the to-be-freed session object to a linked list.
358*12720SWyllys.Ingersoll@Sun.COM  * When the number of objects queued in the linked list reaches the
359*12720SWyllys.Ingersoll@Sun.COM  * maximum threshold MAX_OBJ_TO_BE_FREED, it will free the first
360*12720SWyllys.Ingersoll@Sun.COM  * object (FIFO) in the list.
361*12720SWyllys.Ingersoll@Sun.COM  */
362*12720SWyllys.Ingersoll@Sun.COM void
kms_object_delay_free(kms_object_t * objp)363*12720SWyllys.Ingersoll@Sun.COM kms_object_delay_free(kms_object_t *objp)
364*12720SWyllys.Ingersoll@Sun.COM {
365*12720SWyllys.Ingersoll@Sun.COM 	kms_object_t *tmp;
366*12720SWyllys.Ingersoll@Sun.COM 
367*12720SWyllys.Ingersoll@Sun.COM 	(void) pthread_mutex_lock(&obj_delay_freed.obj_to_be_free_mutex);
368*12720SWyllys.Ingersoll@Sun.COM 
369*12720SWyllys.Ingersoll@Sun.COM 	/* Add the newly deleted object at the end of the list */
370*12720SWyllys.Ingersoll@Sun.COM 	objp->next = NULL;
371*12720SWyllys.Ingersoll@Sun.COM 	if (obj_delay_freed.first == NULL) {
372*12720SWyllys.Ingersoll@Sun.COM 		obj_delay_freed.last = objp;
373*12720SWyllys.Ingersoll@Sun.COM 		obj_delay_freed.first = objp;
374*12720SWyllys.Ingersoll@Sun.COM 	} else {
375*12720SWyllys.Ingersoll@Sun.COM 		obj_delay_freed.last->next = objp;
376*12720SWyllys.Ingersoll@Sun.COM 		obj_delay_freed.last = objp;
377*12720SWyllys.Ingersoll@Sun.COM 	}
378*12720SWyllys.Ingersoll@Sun.COM 
379*12720SWyllys.Ingersoll@Sun.COM 	if (++obj_delay_freed.count >= MAX_OBJ_TO_BE_FREED) {
380*12720SWyllys.Ingersoll@Sun.COM 		/*
381*12720SWyllys.Ingersoll@Sun.COM 		 * Free the first object in the list only if
382*12720SWyllys.Ingersoll@Sun.COM 		 * the total count reaches maximum threshold.
383*12720SWyllys.Ingersoll@Sun.COM 		 */
384*12720SWyllys.Ingersoll@Sun.COM 		obj_delay_freed.count--;
385*12720SWyllys.Ingersoll@Sun.COM 		tmp = obj_delay_freed.first->next;
386*12720SWyllys.Ingersoll@Sun.COM 		kms_free_object(obj_delay_freed.first);
387*12720SWyllys.Ingersoll@Sun.COM 		obj_delay_freed.first = tmp;
388*12720SWyllys.Ingersoll@Sun.COM 	}
389*12720SWyllys.Ingersoll@Sun.COM 	(void) pthread_mutex_unlock(&obj_delay_freed.obj_to_be_free_mutex);
390*12720SWyllys.Ingersoll@Sun.COM }
391*12720SWyllys.Ingersoll@Sun.COM 
392*12720SWyllys.Ingersoll@Sun.COM static void
kms_delete_object_cleanup(kms_object_t * objp,boolean_t force)393*12720SWyllys.Ingersoll@Sun.COM kms_delete_object_cleanup(kms_object_t *objp, boolean_t force)
394*12720SWyllys.Ingersoll@Sun.COM {
395*12720SWyllys.Ingersoll@Sun.COM 	/* Acquire the lock on the object. */
396*12720SWyllys.Ingersoll@Sun.COM 	(void) pthread_mutex_lock(&objp->object_mutex);
397*12720SWyllys.Ingersoll@Sun.COM 
398*12720SWyllys.Ingersoll@Sun.COM 	/*
399*12720SWyllys.Ingersoll@Sun.COM 	 * Make sure another thread hasn't freed the object.
400*12720SWyllys.Ingersoll@Sun.COM 	 */
401*12720SWyllys.Ingersoll@Sun.COM 	if (objp->magic_marker != KMSTOKEN_OBJECT_MAGIC) {
402*12720SWyllys.Ingersoll@Sun.COM 		(void) pthread_mutex_unlock(&objp->object_mutex);
403*12720SWyllys.Ingersoll@Sun.COM 		return;
404*12720SWyllys.Ingersoll@Sun.COM 	}
405*12720SWyllys.Ingersoll@Sun.COM 
406*12720SWyllys.Ingersoll@Sun.COM 	/*
407*12720SWyllys.Ingersoll@Sun.COM 	 * The deletion of an object must be blocked when the object
408*12720SWyllys.Ingersoll@Sun.COM 	 * reference count is not zero. This means if any object related
409*12720SWyllys.Ingersoll@Sun.COM 	 * operation starts prior to the delete object operation gets in,
410*12720SWyllys.Ingersoll@Sun.COM 	 * the object deleting thread must wait for the non-deleting
411*12720SWyllys.Ingersoll@Sun.COM 	 * operation to be completed before it can proceed the delete
412*12720SWyllys.Ingersoll@Sun.COM 	 * operation.
413*12720SWyllys.Ingersoll@Sun.COM 	 *
414*12720SWyllys.Ingersoll@Sun.COM 	 * Unless we are being forced to shut everything down, this only
415*12720SWyllys.Ingersoll@Sun.COM 	 * happens if the library's _fini() is running not if someone
416*12720SWyllys.Ingersoll@Sun.COM 	 * explicitly called C_Finalize().
417*12720SWyllys.Ingersoll@Sun.COM 	 */
418*12720SWyllys.Ingersoll@Sun.COM 	if (force) {
419*12720SWyllys.Ingersoll@Sun.COM 		objp->obj_refcnt = 0;
420*12720SWyllys.Ingersoll@Sun.COM 	}
421*12720SWyllys.Ingersoll@Sun.COM 
422*12720SWyllys.Ingersoll@Sun.COM 	while (objp->obj_refcnt != 0) {
423*12720SWyllys.Ingersoll@Sun.COM 		/*
424*12720SWyllys.Ingersoll@Sun.COM 		 * We set the OBJECT_REFCNT_WAITING flag before we put
425*12720SWyllys.Ingersoll@Sun.COM 		 * this deleting thread in a wait state, so other non-deleting
426*12720SWyllys.Ingersoll@Sun.COM 		 * operation thread will signal to wake it up only when
427*12720SWyllys.Ingersoll@Sun.COM 		 * the object reference count becomes zero and this flag
428*12720SWyllys.Ingersoll@Sun.COM 		 * is set.
429*12720SWyllys.Ingersoll@Sun.COM 		 */
430*12720SWyllys.Ingersoll@Sun.COM 		objp->obj_delete_sync |= OBJECT_REFCNT_WAITING;
431*12720SWyllys.Ingersoll@Sun.COM 		(void) pthread_cond_wait(&objp->obj_free_cond,
432*12720SWyllys.Ingersoll@Sun.COM 		    &objp->object_mutex);
433*12720SWyllys.Ingersoll@Sun.COM 	}
434*12720SWyllys.Ingersoll@Sun.COM 
435*12720SWyllys.Ingersoll@Sun.COM 	objp->obj_delete_sync &= ~OBJECT_REFCNT_WAITING;
436*12720SWyllys.Ingersoll@Sun.COM 
437*12720SWyllys.Ingersoll@Sun.COM 	/* Mark object as no longer valid. */
438*12720SWyllys.Ingersoll@Sun.COM 	objp->magic_marker = 0;
439*12720SWyllys.Ingersoll@Sun.COM 	kms_cleanup_object(objp);
440*12720SWyllys.Ingersoll@Sun.COM 
441*12720SWyllys.Ingersoll@Sun.COM 	objp->obj_delete_sync &= ~OBJECT_IS_DELETING;
442*12720SWyllys.Ingersoll@Sun.COM 	(void) pthread_mutex_unlock(&objp->object_mutex);
443*12720SWyllys.Ingersoll@Sun.COM 
444*12720SWyllys.Ingersoll@Sun.COM 	if (objp->bool_attr_mask & TOKEN_BOOL_ON)
445*12720SWyllys.Ingersoll@Sun.COM 		free(objp);
446*12720SWyllys.Ingersoll@Sun.COM 	else
447*12720SWyllys.Ingersoll@Sun.COM 		kms_object_delay_free(objp);
448*12720SWyllys.Ingersoll@Sun.COM }
449*12720SWyllys.Ingersoll@Sun.COM 
450*12720SWyllys.Ingersoll@Sun.COM /*
451*12720SWyllys.Ingersoll@Sun.COM  * Delete a session object:
452*12720SWyllys.Ingersoll@Sun.COM  * - Remove the object from the session's object list.
453*12720SWyllys.Ingersoll@Sun.COM  * - Release the storage allocated to the object.
454*12720SWyllys.Ingersoll@Sun.COM  *
455*12720SWyllys.Ingersoll@Sun.COM  * The boolean argument ses_lock_held is used to indicate that whether
456*12720SWyllys.Ingersoll@Sun.COM  * the caller holds the session lock or not.
457*12720SWyllys.Ingersoll@Sun.COM  * - When called by kms_delete_all_objects_in_session() or
458*12720SWyllys.Ingersoll@Sun.COM  *   kms_delete_pri_objects_in_slot() -- ses_lock_held = TRUE.
459*12720SWyllys.Ingersoll@Sun.COM  *
460*12720SWyllys.Ingersoll@Sun.COM  * The boolean argument wrapper_only is used to indicate that whether
461*12720SWyllys.Ingersoll@Sun.COM  * the caller only wants to clean up the object wrapper from the library and
462*12720SWyllys.Ingersoll@Sun.COM  * needs not to make an call to KMS.
463*12720SWyllys.Ingersoll@Sun.COM  * - This argument only applies to the object created in the provider level.
464*12720SWyllys.Ingersoll@Sun.COM  * - When called by kms_cleanup_pri_objects_in_slot(), wrapper_only is TRUE.
465*12720SWyllys.Ingersoll@Sun.COM  * - When called by C_DestroyObject(), wrapper_only is FALSE.
466*12720SWyllys.Ingersoll@Sun.COM  * - When called by kms_delete_all_objects_in_session(), the value of
467*12720SWyllys.Ingersoll@Sun.COM  *   wrapper_only depends on its caller.
468*12720SWyllys.Ingersoll@Sun.COM  */
469*12720SWyllys.Ingersoll@Sun.COM CK_RV
kms_delete_object(kms_session_t * sp,kms_object_t * objp,boolean_t ses_lock_held,boolean_t wrapper_only)470*12720SWyllys.Ingersoll@Sun.COM kms_delete_object(kms_session_t *sp, kms_object_t *objp,
471*12720SWyllys.Ingersoll@Sun.COM     boolean_t ses_lock_held, boolean_t wrapper_only)
472*12720SWyllys.Ingersoll@Sun.COM {
473*12720SWyllys.Ingersoll@Sun.COM 	CK_RV rv = CKR_OK;
474*12720SWyllys.Ingersoll@Sun.COM 
475*12720SWyllys.Ingersoll@Sun.COM 	/*
476*12720SWyllys.Ingersoll@Sun.COM 	 * Check to see if the caller holds the lock on the session.
477*12720SWyllys.Ingersoll@Sun.COM 	 * If not, we need to acquire that lock in order to proceed.
478*12720SWyllys.Ingersoll@Sun.COM 	 */
479*12720SWyllys.Ingersoll@Sun.COM 	if (!ses_lock_held) {
480*12720SWyllys.Ingersoll@Sun.COM 		/* Acquire the session lock. */
481*12720SWyllys.Ingersoll@Sun.COM 		(void) pthread_mutex_lock(&sp->session_mutex);
482*12720SWyllys.Ingersoll@Sun.COM 	}
483*12720SWyllys.Ingersoll@Sun.COM 
484*12720SWyllys.Ingersoll@Sun.COM 	/* Remove the object from the session's object list first. */
485*12720SWyllys.Ingersoll@Sun.COM 	if ((rv = kms_remove_object_from_session(objp, sp))) {
486*12720SWyllys.Ingersoll@Sun.COM 		if (!ses_lock_held)
487*12720SWyllys.Ingersoll@Sun.COM 			(void) pthread_mutex_unlock(&sp->session_mutex);
488*12720SWyllys.Ingersoll@Sun.COM 		return (rv);
489*12720SWyllys.Ingersoll@Sun.COM 	}
490*12720SWyllys.Ingersoll@Sun.COM 
491*12720SWyllys.Ingersoll@Sun.COM 	if (!wrapper_only)
492*12720SWyllys.Ingersoll@Sun.COM 		(void) pthread_mutex_unlock(&sp->session_mutex);
493*12720SWyllys.Ingersoll@Sun.COM 
494*12720SWyllys.Ingersoll@Sun.COM 	kms_delete_object_cleanup(objp, wrapper_only);
495*12720SWyllys.Ingersoll@Sun.COM 
496*12720SWyllys.Ingersoll@Sun.COM 	return (rv);
497*12720SWyllys.Ingersoll@Sun.COM }
498*12720SWyllys.Ingersoll@Sun.COM 
499*12720SWyllys.Ingersoll@Sun.COM /*
500*12720SWyllys.Ingersoll@Sun.COM  * Delete all the objects in a session. The caller holds the lock
501*12720SWyllys.Ingersoll@Sun.COM  * on the session.   If the wrapper_only argument is TRUE, the caller only
502*12720SWyllys.Ingersoll@Sun.COM  * want to clean up object wrappers in the library.
503*12720SWyllys.Ingersoll@Sun.COM  */
504*12720SWyllys.Ingersoll@Sun.COM void
kms_delete_all_objects_in_session(kms_session_t * sp,boolean_t wrapper_only)505*12720SWyllys.Ingersoll@Sun.COM kms_delete_all_objects_in_session(kms_session_t *sp,
506*12720SWyllys.Ingersoll@Sun.COM     boolean_t wrapper_only)
507*12720SWyllys.Ingersoll@Sun.COM {
508*12720SWyllys.Ingersoll@Sun.COM 	kms_object_t *objp = sp->object_list;
509*12720SWyllys.Ingersoll@Sun.COM 	kms_object_t *objp1;
510*12720SWyllys.Ingersoll@Sun.COM 
511*12720SWyllys.Ingersoll@Sun.COM 	/* Delete all the objects in the session. */
512*12720SWyllys.Ingersoll@Sun.COM 	while (objp) {
513*12720SWyllys.Ingersoll@Sun.COM 		objp1 = objp->next;
514*12720SWyllys.Ingersoll@Sun.COM 		(void) kms_delete_object(sp, objp, B_TRUE,
515*12720SWyllys.Ingersoll@Sun.COM 		    wrapper_only);
516*12720SWyllys.Ingersoll@Sun.COM 
517*12720SWyllys.Ingersoll@Sun.COM 		objp = objp1;
518*12720SWyllys.Ingersoll@Sun.COM 	}
519*12720SWyllys.Ingersoll@Sun.COM }
520*12720SWyllys.Ingersoll@Sun.COM 
521*12720SWyllys.Ingersoll@Sun.COM static CK_RV
add_to_search_result(kms_object_t * obj,find_context_t * fcontext,CK_ULONG * num_result_alloc)522*12720SWyllys.Ingersoll@Sun.COM add_to_search_result(kms_object_t *obj, find_context_t *fcontext,
523*12720SWyllys.Ingersoll@Sun.COM     CK_ULONG *num_result_alloc)
524*12720SWyllys.Ingersoll@Sun.COM {
525*12720SWyllys.Ingersoll@Sun.COM 	/*
526*12720SWyllys.Ingersoll@Sun.COM 	 * allocate space for storing results if the currently
527*12720SWyllys.Ingersoll@Sun.COM 	 * allocated space is not enough
528*12720SWyllys.Ingersoll@Sun.COM 	 */
529*12720SWyllys.Ingersoll@Sun.COM 	if (*num_result_alloc <= fcontext->num_results) {
530*12720SWyllys.Ingersoll@Sun.COM 		fcontext->objs_found = realloc(fcontext->objs_found,
531*12720SWyllys.Ingersoll@Sun.COM 		    sizeof (kms_object_t *) * (*num_result_alloc + BUFSIZ));
532*12720SWyllys.Ingersoll@Sun.COM 		if (fcontext->objs_found == NULL) {
533*12720SWyllys.Ingersoll@Sun.COM 			return (CKR_HOST_MEMORY);
534*12720SWyllys.Ingersoll@Sun.COM 		}
535*12720SWyllys.Ingersoll@Sun.COM 		*num_result_alloc += BUFSIZ;
536*12720SWyllys.Ingersoll@Sun.COM 	}
537*12720SWyllys.Ingersoll@Sun.COM 
538*12720SWyllys.Ingersoll@Sun.COM 	(fcontext->objs_found)[(fcontext->num_results)++] = obj;
539*12720SWyllys.Ingersoll@Sun.COM 	return (CKR_OK);
540*12720SWyllys.Ingersoll@Sun.COM }
541*12720SWyllys.Ingersoll@Sun.COM 
542*12720SWyllys.Ingersoll@Sun.COM static CK_RV
search_for_objects(kms_session_t * sp,CK_ATTRIBUTE_PTR pTemplate,CK_ULONG ulCount,find_context_t * fcontext)543*12720SWyllys.Ingersoll@Sun.COM search_for_objects(kms_session_t *sp, CK_ATTRIBUTE_PTR pTemplate,
544*12720SWyllys.Ingersoll@Sun.COM     CK_ULONG ulCount, find_context_t *fcontext)
545*12720SWyllys.Ingersoll@Sun.COM {
546*12720SWyllys.Ingersoll@Sun.COM 	kms_session_t *session_p;
547*12720SWyllys.Ingersoll@Sun.COM 	kms_object_t *obj;
548*12720SWyllys.Ingersoll@Sun.COM 	CK_OBJECT_CLASS pclasses[6]; /* classes attrs possibly exist */
549*12720SWyllys.Ingersoll@Sun.COM 	CK_ULONG num_pclasses;	/* number of possible classes */
550*12720SWyllys.Ingersoll@Sun.COM 	CK_ULONG num_result_alloc = 0; /* spaces allocated for results */
551*12720SWyllys.Ingersoll@Sun.COM 	CK_RV rv = CKR_OK;
552*12720SWyllys.Ingersoll@Sun.COM 	kms_slot_t	*pslot = NULL;
553*12720SWyllys.Ingersoll@Sun.COM 	boolean_t token_specified = B_FALSE;
554*12720SWyllys.Ingersoll@Sun.COM 	boolean_t token_flag_val = B_FALSE;
555*12720SWyllys.Ingersoll@Sun.COM 	int i;
556*12720SWyllys.Ingersoll@Sun.COM 
557*12720SWyllys.Ingersoll@Sun.COM 	if (ulCount > 0) {
558*12720SWyllys.Ingersoll@Sun.COM 		/* there are some search requirement */
559*12720SWyllys.Ingersoll@Sun.COM 		kms_process_find_attr(pclasses, &num_pclasses,
560*12720SWyllys.Ingersoll@Sun.COM 		    pTemplate, ulCount);
561*12720SWyllys.Ingersoll@Sun.COM 	}
562*12720SWyllys.Ingersoll@Sun.COM 
563*12720SWyllys.Ingersoll@Sun.COM 	/*
564*12720SWyllys.Ingersoll@Sun.COM 	 * look through template and see if it explicitly specifies
565*12720SWyllys.Ingersoll@Sun.COM 	 * whether we need to look for token objects or not
566*12720SWyllys.Ingersoll@Sun.COM 	 */
567*12720SWyllys.Ingersoll@Sun.COM 	for (i = 0; i < ulCount; i++) {
568*12720SWyllys.Ingersoll@Sun.COM 		if (pTemplate[i].type == CKA_TOKEN) {
569*12720SWyllys.Ingersoll@Sun.COM 			token_specified = B_TRUE;
570*12720SWyllys.Ingersoll@Sun.COM 			token_flag_val = *((CK_BBOOL *)pTemplate[i].pValue);
571*12720SWyllys.Ingersoll@Sun.COM 			break;
572*12720SWyllys.Ingersoll@Sun.COM 		}
573*12720SWyllys.Ingersoll@Sun.COM 	}
574*12720SWyllys.Ingersoll@Sun.COM 
575*12720SWyllys.Ingersoll@Sun.COM 	pslot = get_slotinfo();
576*12720SWyllys.Ingersoll@Sun.COM 
577*12720SWyllys.Ingersoll@Sun.COM 	/* Acquire the slot lock */
578*12720SWyllys.Ingersoll@Sun.COM 	if (token_flag_val || !token_specified) {
579*12720SWyllys.Ingersoll@Sun.COM 		(void) pthread_mutex_lock(&pslot->sl_mutex);
580*12720SWyllys.Ingersoll@Sun.COM 		/*
581*12720SWyllys.Ingersoll@Sun.COM 		 * Make sure the object list is current.
582*12720SWyllys.Ingersoll@Sun.COM 		 */
583*12720SWyllys.Ingersoll@Sun.COM 		rv = KMS_RefreshObjectList(sp, pslot);
584*12720SWyllys.Ingersoll@Sun.COM 		if (rv != CKR_OK) {
585*12720SWyllys.Ingersoll@Sun.COM 			(void) pthread_mutex_unlock(&pslot->sl_mutex);
586*12720SWyllys.Ingersoll@Sun.COM 			return (rv);
587*12720SWyllys.Ingersoll@Sun.COM 		}
588*12720SWyllys.Ingersoll@Sun.COM 
589*12720SWyllys.Ingersoll@Sun.COM 		obj = pslot->sl_tobj_list;
590*12720SWyllys.Ingersoll@Sun.COM 		while (obj) {
591*12720SWyllys.Ingersoll@Sun.COM 			(void) pthread_mutex_lock(&obj->object_mutex);
592*12720SWyllys.Ingersoll@Sun.COM 			if (((token_specified) && (ulCount > 1)) ||
593*12720SWyllys.Ingersoll@Sun.COM 			    ((!token_specified) && (ulCount > 0))) {
594*12720SWyllys.Ingersoll@Sun.COM 				if (kms_find_match_attrs(obj, pclasses,
595*12720SWyllys.Ingersoll@Sun.COM 				    num_pclasses, pTemplate, ulCount)) {
596*12720SWyllys.Ingersoll@Sun.COM 					rv = add_to_search_result(
597*12720SWyllys.Ingersoll@Sun.COM 					    obj, fcontext, &num_result_alloc);
598*12720SWyllys.Ingersoll@Sun.COM 				}
599*12720SWyllys.Ingersoll@Sun.COM 			} else {
600*12720SWyllys.Ingersoll@Sun.COM 				/* no search criteria, just record the object */
601*12720SWyllys.Ingersoll@Sun.COM 				rv = add_to_search_result(obj, fcontext,
602*12720SWyllys.Ingersoll@Sun.COM 				    &num_result_alloc);
603*12720SWyllys.Ingersoll@Sun.COM 			}
604*12720SWyllys.Ingersoll@Sun.COM 			(void) pthread_mutex_unlock(&obj->object_mutex);
605*12720SWyllys.Ingersoll@Sun.COM 			if (rv != CKR_OK) {
606*12720SWyllys.Ingersoll@Sun.COM 				goto cleanup;
607*12720SWyllys.Ingersoll@Sun.COM 			}
608*12720SWyllys.Ingersoll@Sun.COM 			obj = obj->next;
609*12720SWyllys.Ingersoll@Sun.COM 		}
610*12720SWyllys.Ingersoll@Sun.COM 		(void) pthread_mutex_unlock(&pslot->sl_mutex);
611*12720SWyllys.Ingersoll@Sun.COM 	}
612*12720SWyllys.Ingersoll@Sun.COM 
613*12720SWyllys.Ingersoll@Sun.COM 	if (token_flag_val) {
614*12720SWyllys.Ingersoll@Sun.COM 		return (rv);
615*12720SWyllys.Ingersoll@Sun.COM 	}
616*12720SWyllys.Ingersoll@Sun.COM 
617*12720SWyllys.Ingersoll@Sun.COM 	/*
618*12720SWyllys.Ingersoll@Sun.COM 	 * Go through all objects in each session.
619*12720SWyllys.Ingersoll@Sun.COM 	 * Acquire individual session lock for the session
620*12720SWyllys.Ingersoll@Sun.COM 	 * we are searching.
621*12720SWyllys.Ingersoll@Sun.COM 	 */
622*12720SWyllys.Ingersoll@Sun.COM 	session_p = pslot->sl_sess_list;
623*12720SWyllys.Ingersoll@Sun.COM 	while (session_p) {
624*12720SWyllys.Ingersoll@Sun.COM 		(void) pthread_mutex_lock(&session_p->session_mutex);
625*12720SWyllys.Ingersoll@Sun.COM 		obj = session_p->object_list;
626*12720SWyllys.Ingersoll@Sun.COM 		while (obj) {
627*12720SWyllys.Ingersoll@Sun.COM 			(void) pthread_mutex_lock(&obj->object_mutex);
628*12720SWyllys.Ingersoll@Sun.COM 			if (ulCount > 0) {
629*12720SWyllys.Ingersoll@Sun.COM 				if (kms_find_match_attrs(obj, pclasses,
630*12720SWyllys.Ingersoll@Sun.COM 				    num_pclasses, pTemplate, ulCount)) {
631*12720SWyllys.Ingersoll@Sun.COM 					rv = add_to_search_result(
632*12720SWyllys.Ingersoll@Sun.COM 					    obj, fcontext, &num_result_alloc);
633*12720SWyllys.Ingersoll@Sun.COM 				}
634*12720SWyllys.Ingersoll@Sun.COM 			} else {
635*12720SWyllys.Ingersoll@Sun.COM 				/* no search criteria, just record the object */
636*12720SWyllys.Ingersoll@Sun.COM 				rv = add_to_search_result(obj, fcontext,
637*12720SWyllys.Ingersoll@Sun.COM 				    &num_result_alloc);
638*12720SWyllys.Ingersoll@Sun.COM 			}
639*12720SWyllys.Ingersoll@Sun.COM 			(void) pthread_mutex_unlock(&obj->object_mutex);
640*12720SWyllys.Ingersoll@Sun.COM 			if (rv != CKR_OK) {
641*12720SWyllys.Ingersoll@Sun.COM 				(void) pthread_mutex_unlock(
642*12720SWyllys.Ingersoll@Sun.COM 				    &session_p->session_mutex);
643*12720SWyllys.Ingersoll@Sun.COM 				goto cleanup;
644*12720SWyllys.Ingersoll@Sun.COM 			}
645*12720SWyllys.Ingersoll@Sun.COM 			obj = obj->next;
646*12720SWyllys.Ingersoll@Sun.COM 		}
647*12720SWyllys.Ingersoll@Sun.COM 		(void) pthread_mutex_unlock(&session_p->session_mutex);
648*12720SWyllys.Ingersoll@Sun.COM 		session_p = session_p->next;
649*12720SWyllys.Ingersoll@Sun.COM 	}
650*12720SWyllys.Ingersoll@Sun.COM 
651*12720SWyllys.Ingersoll@Sun.COM cleanup:
652*12720SWyllys.Ingersoll@Sun.COM 	/* Release the slot lock */
653*12720SWyllys.Ingersoll@Sun.COM 	(void) pthread_mutex_unlock(&pslot->sl_mutex);
654*12720SWyllys.Ingersoll@Sun.COM 	return (rv);
655*12720SWyllys.Ingersoll@Sun.COM }
656*12720SWyllys.Ingersoll@Sun.COM 
657*12720SWyllys.Ingersoll@Sun.COM /*
658*12720SWyllys.Ingersoll@Sun.COM  * Initialize the context for C_FindObjects() calls
659*12720SWyllys.Ingersoll@Sun.COM  */
660*12720SWyllys.Ingersoll@Sun.COM CK_RV
kms_find_objects_init(kms_session_t * sp,CK_ATTRIBUTE_PTR pTemplate,CK_ULONG ulCount)661*12720SWyllys.Ingersoll@Sun.COM kms_find_objects_init(kms_session_t *sp, CK_ATTRIBUTE_PTR pTemplate,
662*12720SWyllys.Ingersoll@Sun.COM     CK_ULONG ulCount)
663*12720SWyllys.Ingersoll@Sun.COM {
664*12720SWyllys.Ingersoll@Sun.COM 	CK_RV rv = CKR_OK;
665*12720SWyllys.Ingersoll@Sun.COM 	CK_OBJECT_CLASS class; /* for kms_validate_attr(). Value unused */
666*12720SWyllys.Ingersoll@Sun.COM 	find_context_t *fcontext;
667*12720SWyllys.Ingersoll@Sun.COM 
668*12720SWyllys.Ingersoll@Sun.COM 	if (ulCount) {
669*12720SWyllys.Ingersoll@Sun.COM 		rv = kms_validate_attr(pTemplate, ulCount, &class);
670*12720SWyllys.Ingersoll@Sun.COM 		/* Make sure all attributes in template are valid */
671*12720SWyllys.Ingersoll@Sun.COM 		if (rv != CKR_OK) {
672*12720SWyllys.Ingersoll@Sun.COM 			return (rv);
673*12720SWyllys.Ingersoll@Sun.COM 		}
674*12720SWyllys.Ingersoll@Sun.COM 	}
675*12720SWyllys.Ingersoll@Sun.COM 
676*12720SWyllys.Ingersoll@Sun.COM 	/* prepare the find context */
677*12720SWyllys.Ingersoll@Sun.COM 	fcontext = calloc(1, sizeof (find_context_t));
678*12720SWyllys.Ingersoll@Sun.COM 	if (fcontext == NULL) {
679*12720SWyllys.Ingersoll@Sun.COM 		return (CKR_HOST_MEMORY);
680*12720SWyllys.Ingersoll@Sun.COM 	}
681*12720SWyllys.Ingersoll@Sun.COM 
682*12720SWyllys.Ingersoll@Sun.COM 	rv = search_for_objects(sp, pTemplate, ulCount, fcontext);
683*12720SWyllys.Ingersoll@Sun.COM 	if (rv != CKR_OK) {
684*12720SWyllys.Ingersoll@Sun.COM 		free(fcontext);
685*12720SWyllys.Ingersoll@Sun.COM 		return (rv);
686*12720SWyllys.Ingersoll@Sun.COM 	}
687*12720SWyllys.Ingersoll@Sun.COM 
688*12720SWyllys.Ingersoll@Sun.COM 	/* store the find_context in the session */
689*12720SWyllys.Ingersoll@Sun.COM 	sp->find_objects.context = (CK_VOID_PTR)fcontext;
690*12720SWyllys.Ingersoll@Sun.COM 
691*12720SWyllys.Ingersoll@Sun.COM 	return (rv);
692*12720SWyllys.Ingersoll@Sun.COM }
693*12720SWyllys.Ingersoll@Sun.COM 
694*12720SWyllys.Ingersoll@Sun.COM void
kms_find_objects_final(kms_session_t * sp)695*12720SWyllys.Ingersoll@Sun.COM kms_find_objects_final(kms_session_t *sp)
696*12720SWyllys.Ingersoll@Sun.COM {
697*12720SWyllys.Ingersoll@Sun.COM 	find_context_t *fcontext;
698*12720SWyllys.Ingersoll@Sun.COM 
699*12720SWyllys.Ingersoll@Sun.COM 	fcontext = sp->find_objects.context;
700*12720SWyllys.Ingersoll@Sun.COM 	sp->find_objects.context = NULL;
701*12720SWyllys.Ingersoll@Sun.COM 	sp->find_objects.flags = 0;
702*12720SWyllys.Ingersoll@Sun.COM 	if (fcontext->objs_found != NULL) {
703*12720SWyllys.Ingersoll@Sun.COM 		free(fcontext->objs_found);
704*12720SWyllys.Ingersoll@Sun.COM 	}
705*12720SWyllys.Ingersoll@Sun.COM 
706*12720SWyllys.Ingersoll@Sun.COM 	free(fcontext);
707*12720SWyllys.Ingersoll@Sun.COM }
708*12720SWyllys.Ingersoll@Sun.COM 
709*12720SWyllys.Ingersoll@Sun.COM CK_RV
kms_find_objects(kms_session_t * sp,CK_OBJECT_HANDLE * obj_found,CK_ULONG max_obj_requested,CK_ULONG * found_obj_count)710*12720SWyllys.Ingersoll@Sun.COM kms_find_objects(kms_session_t *sp, CK_OBJECT_HANDLE *obj_found,
711*12720SWyllys.Ingersoll@Sun.COM     CK_ULONG max_obj_requested, CK_ULONG *found_obj_count)
712*12720SWyllys.Ingersoll@Sun.COM {
713*12720SWyllys.Ingersoll@Sun.COM 	find_context_t *fcontext;
714*12720SWyllys.Ingersoll@Sun.COM 	CK_ULONG num_obj_found = 0;
715*12720SWyllys.Ingersoll@Sun.COM 	CK_ULONG i;
716*12720SWyllys.Ingersoll@Sun.COM 	kms_object_t *obj;
717*12720SWyllys.Ingersoll@Sun.COM 
718*12720SWyllys.Ingersoll@Sun.COM 	fcontext = sp->find_objects.context;
719*12720SWyllys.Ingersoll@Sun.COM 
720*12720SWyllys.Ingersoll@Sun.COM 	for (i = fcontext->next_result_index;
721*12720SWyllys.Ingersoll@Sun.COM 	    ((num_obj_found < max_obj_requested) &&
722*12720SWyllys.Ingersoll@Sun.COM 	    (i < fcontext->num_results));
723*12720SWyllys.Ingersoll@Sun.COM 	    i++) {
724*12720SWyllys.Ingersoll@Sun.COM 		obj = fcontext->objs_found[i];
725*12720SWyllys.Ingersoll@Sun.COM 		if (obj != NULL) {
726*12720SWyllys.Ingersoll@Sun.COM 			(void) pthread_mutex_lock(&obj->object_mutex);
727*12720SWyllys.Ingersoll@Sun.COM 			/* a sanity check to make sure the obj is still valid */
728*12720SWyllys.Ingersoll@Sun.COM 			if (obj->magic_marker == KMSTOKEN_OBJECT_MAGIC) {
729*12720SWyllys.Ingersoll@Sun.COM 				obj_found[num_obj_found] =
730*12720SWyllys.Ingersoll@Sun.COM 				    (CK_OBJECT_HANDLE)obj;
731*12720SWyllys.Ingersoll@Sun.COM 				num_obj_found++;
732*12720SWyllys.Ingersoll@Sun.COM 			}
733*12720SWyllys.Ingersoll@Sun.COM 			(void) pthread_mutex_unlock(&obj->object_mutex);
734*12720SWyllys.Ingersoll@Sun.COM 		}
735*12720SWyllys.Ingersoll@Sun.COM 	}
736*12720SWyllys.Ingersoll@Sun.COM 	fcontext->next_result_index = i;
737*12720SWyllys.Ingersoll@Sun.COM 	*found_obj_count = num_obj_found;
738*12720SWyllys.Ingersoll@Sun.COM 	return (CKR_OK);
739*12720SWyllys.Ingersoll@Sun.COM }
740*12720SWyllys.Ingersoll@Sun.COM 
741*12720SWyllys.Ingersoll@Sun.COM /*
742*12720SWyllys.Ingersoll@Sun.COM  * Add an token object to the token object list in slot.
743*12720SWyllys.Ingersoll@Sun.COM  *
744*12720SWyllys.Ingersoll@Sun.COM  * This function will acquire the lock on the slot, and release
745*12720SWyllys.Ingersoll@Sun.COM  * that lock after adding the object to the slot's token object list.
746*12720SWyllys.Ingersoll@Sun.COM  */
747*12720SWyllys.Ingersoll@Sun.COM void
kms_add_token_object_to_slot(kms_object_t * objp,kms_slot_t * pslot)748*12720SWyllys.Ingersoll@Sun.COM kms_add_token_object_to_slot(kms_object_t *objp, kms_slot_t *pslot)
749*12720SWyllys.Ingersoll@Sun.COM {
750*12720SWyllys.Ingersoll@Sun.COM 	/* Acquire the slot lock. */
751*12720SWyllys.Ingersoll@Sun.COM 	(void) pthread_mutex_lock(&pslot->sl_mutex);
752*12720SWyllys.Ingersoll@Sun.COM 
753*12720SWyllys.Ingersoll@Sun.COM 	/* Insert the new object in front of slot's token object list. */
754*12720SWyllys.Ingersoll@Sun.COM 	if (pslot->sl_tobj_list == NULL) {
755*12720SWyllys.Ingersoll@Sun.COM 		pslot->sl_tobj_list = objp;
756*12720SWyllys.Ingersoll@Sun.COM 		objp->next = NULL;
757*12720SWyllys.Ingersoll@Sun.COM 		objp->prev = NULL;
758*12720SWyllys.Ingersoll@Sun.COM 	} else {
759*12720SWyllys.Ingersoll@Sun.COM 		pslot->sl_tobj_list->prev = objp;
760*12720SWyllys.Ingersoll@Sun.COM 		objp->next = pslot->sl_tobj_list;
761*12720SWyllys.Ingersoll@Sun.COM 		objp->prev = NULL;
762*12720SWyllys.Ingersoll@Sun.COM 		pslot->sl_tobj_list = objp;
763*12720SWyllys.Ingersoll@Sun.COM 	}
764*12720SWyllys.Ingersoll@Sun.COM 
765*12720SWyllys.Ingersoll@Sun.COM 	/* Release the slot lock. */
766*12720SWyllys.Ingersoll@Sun.COM 	(void) pthread_mutex_unlock(&pslot->sl_mutex);
767*12720SWyllys.Ingersoll@Sun.COM }
768*12720SWyllys.Ingersoll@Sun.COM 
769*12720SWyllys.Ingersoll@Sun.COM /*
770*12720SWyllys.Ingersoll@Sun.COM  * Remove an token object from the slot's token object list.
771*12720SWyllys.Ingersoll@Sun.COM  * This routine is called by kms_delete_token_object().
772*12720SWyllys.Ingersoll@Sun.COM  * The caller of this function hold the slot lock.
773*12720SWyllys.Ingersoll@Sun.COM  */
774*12720SWyllys.Ingersoll@Sun.COM void
kms_remove_token_object_from_slot(kms_slot_t * pslot,kms_object_t * objp)775*12720SWyllys.Ingersoll@Sun.COM kms_remove_token_object_from_slot(kms_slot_t *pslot,
776*12720SWyllys.Ingersoll@Sun.COM     kms_object_t *objp)
777*12720SWyllys.Ingersoll@Sun.COM {
778*12720SWyllys.Ingersoll@Sun.COM 
779*12720SWyllys.Ingersoll@Sun.COM 	if (pslot->sl_tobj_list == objp) {
780*12720SWyllys.Ingersoll@Sun.COM 		/* Object is the first one in the list */
781*12720SWyllys.Ingersoll@Sun.COM 		if (objp->next) {
782*12720SWyllys.Ingersoll@Sun.COM 			pslot->sl_tobj_list = objp->next;
783*12720SWyllys.Ingersoll@Sun.COM 			objp->next->prev = NULL;
784*12720SWyllys.Ingersoll@Sun.COM 		} else {
785*12720SWyllys.Ingersoll@Sun.COM 			/* Object is the only one in the list. */
786*12720SWyllys.Ingersoll@Sun.COM 			pslot->sl_tobj_list = NULL;
787*12720SWyllys.Ingersoll@Sun.COM 		}
788*12720SWyllys.Ingersoll@Sun.COM 	} else {
789*12720SWyllys.Ingersoll@Sun.COM 		/* Object is not the first one in the list. */
790*12720SWyllys.Ingersoll@Sun.COM 		if (objp->next) {
791*12720SWyllys.Ingersoll@Sun.COM 			/* Object is in the middle of the list. */
792*12720SWyllys.Ingersoll@Sun.COM 			if (objp->prev)
793*12720SWyllys.Ingersoll@Sun.COM 				objp->prev->next = objp->next;
794*12720SWyllys.Ingersoll@Sun.COM 			objp->next->prev = objp->prev;
795*12720SWyllys.Ingersoll@Sun.COM 		} else if (objp->prev) {
796*12720SWyllys.Ingersoll@Sun.COM 			/* Object is the last one in the list. */
797*12720SWyllys.Ingersoll@Sun.COM 			objp->prev->next = NULL;
798*12720SWyllys.Ingersoll@Sun.COM 		}
799*12720SWyllys.Ingersoll@Sun.COM 	}
800*12720SWyllys.Ingersoll@Sun.COM }
801*12720SWyllys.Ingersoll@Sun.COM 
802*12720SWyllys.Ingersoll@Sun.COM /*
803*12720SWyllys.Ingersoll@Sun.COM  * Delete a token object:
804*12720SWyllys.Ingersoll@Sun.COM  * - Remove the object from the slot's token object list.
805*12720SWyllys.Ingersoll@Sun.COM  * - Release the storage allocated to the object.
806*12720SWyllys.Ingersoll@Sun.COM  *
807*12720SWyllys.Ingersoll@Sun.COM  * The boolean argument slot_lock_held is used to indicate that whether
808*12720SWyllys.Ingersoll@Sun.COM  * the caller holds the slot lock or not. When the caller does not hold
809*12720SWyllys.Ingersoll@Sun.COM  * the slot lock, this function will acquire that lock in order to proceed,
810*12720SWyllys.Ingersoll@Sun.COM  * and also release that lock before returning to caller.
811*12720SWyllys.Ingersoll@Sun.COM  *
812*12720SWyllys.Ingersoll@Sun.COM  * The boolean argument wrapper_only is used to indicate that whether
813*12720SWyllys.Ingersoll@Sun.COM  * the caller only wants to the object wrapper from library.
814*12720SWyllys.Ingersoll@Sun.COM  */
815*12720SWyllys.Ingersoll@Sun.COM CK_RV
kms_delete_token_object(kms_slot_t * pslot,kms_session_t * sp,kms_object_t * objp,boolean_t slot_lock_held,boolean_t wrapper_only)816*12720SWyllys.Ingersoll@Sun.COM kms_delete_token_object(kms_slot_t *pslot, kms_session_t *sp,
817*12720SWyllys.Ingersoll@Sun.COM     kms_object_t *objp, boolean_t slot_lock_held, boolean_t wrapper_only)
818*12720SWyllys.Ingersoll@Sun.COM {
819*12720SWyllys.Ingersoll@Sun.COM 	CK_RV rv = CKR_OK;
820*12720SWyllys.Ingersoll@Sun.COM 
821*12720SWyllys.Ingersoll@Sun.COM 	if (!slot_lock_held) {
822*12720SWyllys.Ingersoll@Sun.COM 		(void) pthread_mutex_lock(&pslot->sl_mutex);
823*12720SWyllys.Ingersoll@Sun.COM 	}
824*12720SWyllys.Ingersoll@Sun.COM 	if (!wrapper_only && objp->class == CKO_SECRET_KEY) {
825*12720SWyllys.Ingersoll@Sun.COM 		/* Delete from KMS */
826*12720SWyllys.Ingersoll@Sun.COM 		rv = KMS_DestroyKey(sp, objp);
827*12720SWyllys.Ingersoll@Sun.COM 	}
828*12720SWyllys.Ingersoll@Sun.COM 
829*12720SWyllys.Ingersoll@Sun.COM 	/* Remove the object from the slot's token object list first. */
830*12720SWyllys.Ingersoll@Sun.COM 	kms_remove_token_object_from_slot(pslot, objp);
831*12720SWyllys.Ingersoll@Sun.COM 
832*12720SWyllys.Ingersoll@Sun.COM 	/* Release the slot lock if the call doesn't hold the lock. */
833*12720SWyllys.Ingersoll@Sun.COM 	if (!slot_lock_held) {
834*12720SWyllys.Ingersoll@Sun.COM 		(void) pthread_mutex_unlock(&pslot->sl_mutex);
835*12720SWyllys.Ingersoll@Sun.COM 	}
836*12720SWyllys.Ingersoll@Sun.COM 
837*12720SWyllys.Ingersoll@Sun.COM 	kms_delete_object_cleanup(objp, wrapper_only);
838*12720SWyllys.Ingersoll@Sun.COM 
839*12720SWyllys.Ingersoll@Sun.COM 	return (rv);
840*12720SWyllys.Ingersoll@Sun.COM }
841*12720SWyllys.Ingersoll@Sun.COM 
842*12720SWyllys.Ingersoll@Sun.COM /*
843*12720SWyllys.Ingersoll@Sun.COM  * Clean up private object wrappers in this slot. The caller holds the slot
844*12720SWyllys.Ingersoll@Sun.COM  * lock.
845*12720SWyllys.Ingersoll@Sun.COM  */
846*12720SWyllys.Ingersoll@Sun.COM void
kms_cleanup_pri_objects_in_slot(kms_slot_t * pslot,kms_session_t * cur_sp)847*12720SWyllys.Ingersoll@Sun.COM kms_cleanup_pri_objects_in_slot(kms_slot_t *pslot,
848*12720SWyllys.Ingersoll@Sun.COM     kms_session_t *cur_sp)
849*12720SWyllys.Ingersoll@Sun.COM {
850*12720SWyllys.Ingersoll@Sun.COM 	kms_session_t *session_p;
851*12720SWyllys.Ingersoll@Sun.COM 	kms_object_t *objp;
852*12720SWyllys.Ingersoll@Sun.COM 	kms_object_t *objp1;
853*12720SWyllys.Ingersoll@Sun.COM 
854*12720SWyllys.Ingersoll@Sun.COM 	/*
855*12720SWyllys.Ingersoll@Sun.COM 	 * Delete every private token object from
856*12720SWyllys.Ingersoll@Sun.COM 	 * the slot token object list.
857*12720SWyllys.Ingersoll@Sun.COM 	 */
858*12720SWyllys.Ingersoll@Sun.COM 	(void) pthread_mutex_lock(&pslot->sl_mutex);
859*12720SWyllys.Ingersoll@Sun.COM 	objp = pslot->sl_tobj_list;
860*12720SWyllys.Ingersoll@Sun.COM 	while (objp) {
861*12720SWyllys.Ingersoll@Sun.COM 		objp1 = objp->next;
862*12720SWyllys.Ingersoll@Sun.COM 		/*
863*12720SWyllys.Ingersoll@Sun.COM 		 * The first TRUE boolean argument indicates that the caller
864*12720SWyllys.Ingersoll@Sun.COM 		 * hold the slot lock.  The second TRUE boolean argument
865*12720SWyllys.Ingersoll@Sun.COM 		 * indicates that the caller just wants to clean up the object
866*12720SWyllys.Ingersoll@Sun.COM 		 * wrapper from the library only.
867*12720SWyllys.Ingersoll@Sun.COM 		 */
868*12720SWyllys.Ingersoll@Sun.COM 		if (objp->bool_attr_mask & PRIVATE_BOOL_ON) {
869*12720SWyllys.Ingersoll@Sun.COM 			(void) kms_delete_token_object(pslot, cur_sp, objp,
870*12720SWyllys.Ingersoll@Sun.COM 			    B_TRUE, B_TRUE);
871*12720SWyllys.Ingersoll@Sun.COM 		}
872*12720SWyllys.Ingersoll@Sun.COM 		objp = objp1;
873*12720SWyllys.Ingersoll@Sun.COM 	}
874*12720SWyllys.Ingersoll@Sun.COM 
875*12720SWyllys.Ingersoll@Sun.COM 	(void) pthread_mutex_unlock(&pslot->sl_mutex);
876*12720SWyllys.Ingersoll@Sun.COM 	/*
877*12720SWyllys.Ingersoll@Sun.COM 	 * Walk through all the sessions in this slot and delete every
878*12720SWyllys.Ingersoll@Sun.COM 	 * private object.
879*12720SWyllys.Ingersoll@Sun.COM 	 */
880*12720SWyllys.Ingersoll@Sun.COM 	session_p = pslot->sl_sess_list;
881*12720SWyllys.Ingersoll@Sun.COM 	while (session_p) {
882*12720SWyllys.Ingersoll@Sun.COM 
883*12720SWyllys.Ingersoll@Sun.COM 		/* Delete all the objects in the session. */
884*12720SWyllys.Ingersoll@Sun.COM 		objp = session_p->object_list;
885*12720SWyllys.Ingersoll@Sun.COM 		while (objp) {
886*12720SWyllys.Ingersoll@Sun.COM 			objp1 = objp->next;
887*12720SWyllys.Ingersoll@Sun.COM 			/*
888*12720SWyllys.Ingersoll@Sun.COM 			 * The FALSE boolean argument indicates that the
889*12720SWyllys.Ingersoll@Sun.COM 			 * caller does not hold the session lock.  The TRUE
890*12720SWyllys.Ingersoll@Sun.COM 			 * boolean argument indicates that the caller just
891*12720SWyllys.Ingersoll@Sun.COM 			 * want to clean upt the object wrapper from the
892*12720SWyllys.Ingersoll@Sun.COM 			 * library only.
893*12720SWyllys.Ingersoll@Sun.COM 			 */
894*12720SWyllys.Ingersoll@Sun.COM 			if (objp->bool_attr_mask & PRIVATE_BOOL_ON) {
895*12720SWyllys.Ingersoll@Sun.COM 				(void) kms_delete_object(session_p,
896*12720SWyllys.Ingersoll@Sun.COM 				    objp, B_FALSE, B_TRUE);
897*12720SWyllys.Ingersoll@Sun.COM 			}
898*12720SWyllys.Ingersoll@Sun.COM 			objp = objp1;
899*12720SWyllys.Ingersoll@Sun.COM 		}
900*12720SWyllys.Ingersoll@Sun.COM 
901*12720SWyllys.Ingersoll@Sun.COM 		session_p = session_p->next;
902*12720SWyllys.Ingersoll@Sun.COM 	}
903*12720SWyllys.Ingersoll@Sun.COM }
904*12720SWyllys.Ingersoll@Sun.COM 
905*12720SWyllys.Ingersoll@Sun.COM /*
906*12720SWyllys.Ingersoll@Sun.COM  * Get the object size in bytes for the objects created in the library.
907*12720SWyllys.Ingersoll@Sun.COM  */
908*12720SWyllys.Ingersoll@Sun.COM CK_RV
kms_get_object_size(kms_object_t * obj,CK_ULONG_PTR pulSize)909*12720SWyllys.Ingersoll@Sun.COM kms_get_object_size(kms_object_t *obj, CK_ULONG_PTR pulSize)
910*12720SWyllys.Ingersoll@Sun.COM {
911*12720SWyllys.Ingersoll@Sun.COM 	CK_RV rv = CKR_OK;
912*12720SWyllys.Ingersoll@Sun.COM 	CK_ULONG obj_size;
913*12720SWyllys.Ingersoll@Sun.COM 
914*12720SWyllys.Ingersoll@Sun.COM 	obj_size = sizeof (kms_object_t);
915*12720SWyllys.Ingersoll@Sun.COM 
916*12720SWyllys.Ingersoll@Sun.COM 	switch (obj->class) {
917*12720SWyllys.Ingersoll@Sun.COM 	case CKO_SECRET_KEY:
918*12720SWyllys.Ingersoll@Sun.COM 		obj_size += OBJ_SEC_VALUE_LEN(obj);
919*12720SWyllys.Ingersoll@Sun.COM 		break;
920*12720SWyllys.Ingersoll@Sun.COM 
921*12720SWyllys.Ingersoll@Sun.COM 	default:
922*12720SWyllys.Ingersoll@Sun.COM 		rv = CKR_OBJECT_HANDLE_INVALID;
923*12720SWyllys.Ingersoll@Sun.COM 	}
924*12720SWyllys.Ingersoll@Sun.COM 
925*12720SWyllys.Ingersoll@Sun.COM 	if (rv == CKR_OK) {
926*12720SWyllys.Ingersoll@Sun.COM 		*pulSize = obj_size;
927*12720SWyllys.Ingersoll@Sun.COM 	}
928*12720SWyllys.Ingersoll@Sun.COM 
929*12720SWyllys.Ingersoll@Sun.COM 	return (rv);
930*12720SWyllys.Ingersoll@Sun.COM }
931