xref: /onnv-gate/usr/src/lib/pkcs11/pkcs11_kms/common/kmsObject.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 /*
23*12720SWyllys.Ingersoll@Sun.COM  * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
24*12720SWyllys.Ingersoll@Sun.COM  */
25*12720SWyllys.Ingersoll@Sun.COM 
26*12720SWyllys.Ingersoll@Sun.COM 
27*12720SWyllys.Ingersoll@Sun.COM #include <pthread.h>
28*12720SWyllys.Ingersoll@Sun.COM #include <stdlib.h>
29*12720SWyllys.Ingersoll@Sun.COM #include <errno.h>
30*12720SWyllys.Ingersoll@Sun.COM #include <errno.h>
31*12720SWyllys.Ingersoll@Sun.COM #include <string.h>
32*12720SWyllys.Ingersoll@Sun.COM #include <security/cryptoki.h>
33*12720SWyllys.Ingersoll@Sun.COM #include "kmsGlobal.h"
34*12720SWyllys.Ingersoll@Sun.COM #include "kmsObject.h"
35*12720SWyllys.Ingersoll@Sun.COM #include "kmsSession.h"
36*12720SWyllys.Ingersoll@Sun.COM 
37*12720SWyllys.Ingersoll@Sun.COM CK_RV
C_CreateObject(CK_SESSION_HANDLE hSession,CK_ATTRIBUTE_PTR pTemplate,CK_ULONG ulCount,CK_OBJECT_HANDLE_PTR phObject)38*12720SWyllys.Ingersoll@Sun.COM C_CreateObject(CK_SESSION_HANDLE hSession,
39*12720SWyllys.Ingersoll@Sun.COM     CK_ATTRIBUTE_PTR pTemplate,
40*12720SWyllys.Ingersoll@Sun.COM     CK_ULONG ulCount,
41*12720SWyllys.Ingersoll@Sun.COM     CK_OBJECT_HANDLE_PTR phObject)
42*12720SWyllys.Ingersoll@Sun.COM {
43*12720SWyllys.Ingersoll@Sun.COM 
44*12720SWyllys.Ingersoll@Sun.COM 	CK_RV rv;
45*12720SWyllys.Ingersoll@Sun.COM 	kms_session_t *session_p;
46*12720SWyllys.Ingersoll@Sun.COM 	boolean_t ses_lock_held = B_FALSE;
47*12720SWyllys.Ingersoll@Sun.COM 
48*12720SWyllys.Ingersoll@Sun.COM 	if (!kms_initialized)
49*12720SWyllys.Ingersoll@Sun.COM 		return (CKR_CRYPTOKI_NOT_INITIALIZED);
50*12720SWyllys.Ingersoll@Sun.COM 
51*12720SWyllys.Ingersoll@Sun.COM 	if ((pTemplate == NULL) || (ulCount == 0) ||
52*12720SWyllys.Ingersoll@Sun.COM 	    (phObject == NULL)) {
53*12720SWyllys.Ingersoll@Sun.COM 		return (CKR_ARGUMENTS_BAD);
54*12720SWyllys.Ingersoll@Sun.COM 	}
55*12720SWyllys.Ingersoll@Sun.COM 
56*12720SWyllys.Ingersoll@Sun.COM 	/*
57*12720SWyllys.Ingersoll@Sun.COM 	 * Obtain the session pointer. Also, increment the session
58*12720SWyllys.Ingersoll@Sun.COM 	 * reference count.
59*12720SWyllys.Ingersoll@Sun.COM 	 */
60*12720SWyllys.Ingersoll@Sun.COM 	rv = handle2session(hSession, &session_p);
61*12720SWyllys.Ingersoll@Sun.COM 	if (rv != CKR_OK)
62*12720SWyllys.Ingersoll@Sun.COM 		return (rv);
63*12720SWyllys.Ingersoll@Sun.COM 
64*12720SWyllys.Ingersoll@Sun.COM 	/* Create a new object. */
65*12720SWyllys.Ingersoll@Sun.COM 	rv = kms_add_object(pTemplate, ulCount, phObject, session_p);
66*12720SWyllys.Ingersoll@Sun.COM 
67*12720SWyllys.Ingersoll@Sun.COM 	/*
68*12720SWyllys.Ingersoll@Sun.COM 	 * Decrement the session reference count.
69*12720SWyllys.Ingersoll@Sun.COM 	 * We do not hold the session lock.
70*12720SWyllys.Ingersoll@Sun.COM 	 */
71*12720SWyllys.Ingersoll@Sun.COM 	REFRELE(session_p, ses_lock_held);
72*12720SWyllys.Ingersoll@Sun.COM 
73*12720SWyllys.Ingersoll@Sun.COM 	return (rv);
74*12720SWyllys.Ingersoll@Sun.COM }
75*12720SWyllys.Ingersoll@Sun.COM 
76*12720SWyllys.Ingersoll@Sun.COM CK_RV
C_CopyObject(CK_SESSION_HANDLE hSession,CK_OBJECT_HANDLE hObject,CK_ATTRIBUTE_PTR pTemplate,CK_ULONG ulCount,CK_OBJECT_HANDLE_PTR phNewObject)77*12720SWyllys.Ingersoll@Sun.COM C_CopyObject(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject,
78*12720SWyllys.Ingersoll@Sun.COM     CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount,
79*12720SWyllys.Ingersoll@Sun.COM     CK_OBJECT_HANDLE_PTR phNewObject)
80*12720SWyllys.Ingersoll@Sun.COM {
81*12720SWyllys.Ingersoll@Sun.COM 
82*12720SWyllys.Ingersoll@Sun.COM 	CK_RV rv;
83*12720SWyllys.Ingersoll@Sun.COM 	kms_session_t *session_p;
84*12720SWyllys.Ingersoll@Sun.COM 	boolean_t ses_lock_held = B_FALSE;
85*12720SWyllys.Ingersoll@Sun.COM 	kms_object_t *old_object;
86*12720SWyllys.Ingersoll@Sun.COM 	kms_object_t *new_object = NULL;
87*12720SWyllys.Ingersoll@Sun.COM 	int i;
88*12720SWyllys.Ingersoll@Sun.COM 
89*12720SWyllys.Ingersoll@Sun.COM 	if (!kms_initialized)
90*12720SWyllys.Ingersoll@Sun.COM 		return (CKR_CRYPTOKI_NOT_INITIALIZED);
91*12720SWyllys.Ingersoll@Sun.COM 
92*12720SWyllys.Ingersoll@Sun.COM 	/* Check arguments */
93*12720SWyllys.Ingersoll@Sun.COM 	if (((ulCount > 0) && (pTemplate == NULL)) ||
94*12720SWyllys.Ingersoll@Sun.COM 	    (phNewObject == NULL)) {
95*12720SWyllys.Ingersoll@Sun.COM 		return (CKR_ARGUMENTS_BAD);
96*12720SWyllys.Ingersoll@Sun.COM 	}
97*12720SWyllys.Ingersoll@Sun.COM 
98*12720SWyllys.Ingersoll@Sun.COM 	/*
99*12720SWyllys.Ingersoll@Sun.COM 	 * Obtain the session pointer. Also, increment the session
100*12720SWyllys.Ingersoll@Sun.COM 	 * reference count.
101*12720SWyllys.Ingersoll@Sun.COM 	 */
102*12720SWyllys.Ingersoll@Sun.COM 	rv = handle2session(hSession, &session_p);
103*12720SWyllys.Ingersoll@Sun.COM 	if (rv != CKR_OK)
104*12720SWyllys.Ingersoll@Sun.COM 		return (rv);
105*12720SWyllys.Ingersoll@Sun.COM 
106*12720SWyllys.Ingersoll@Sun.COM 	/* Obtain the object pointer. */
107*12720SWyllys.Ingersoll@Sun.COM 	HANDLE2OBJECT(hObject, old_object, rv);
108*12720SWyllys.Ingersoll@Sun.COM 	if (rv != CKR_OK) {
109*12720SWyllys.Ingersoll@Sun.COM 		/*
110*12720SWyllys.Ingersoll@Sun.COM 		 * Decrement the session reference count.
111*12720SWyllys.Ingersoll@Sun.COM 		 * We do not hold the session lock.
112*12720SWyllys.Ingersoll@Sun.COM 		 */
113*12720SWyllys.Ingersoll@Sun.COM 		REFRELE(session_p, ses_lock_held);
114*12720SWyllys.Ingersoll@Sun.COM 		return (rv);
115*12720SWyllys.Ingersoll@Sun.COM 	}
116*12720SWyllys.Ingersoll@Sun.COM 
117*12720SWyllys.Ingersoll@Sun.COM 	(void) pthread_mutex_lock(&old_object->object_mutex);
118*12720SWyllys.Ingersoll@Sun.COM 
119*12720SWyllys.Ingersoll@Sun.COM 	if (old_object->is_lib_obj) {
120*12720SWyllys.Ingersoll@Sun.COM 		/*
121*12720SWyllys.Ingersoll@Sun.COM 		 * Copy the old object to a new object.
122*12720SWyllys.Ingersoll@Sun.COM 		 * The 3rd argument with TRUE value indicates that
123*12720SWyllys.Ingersoll@Sun.COM 		 * everything in the object will be duplicated.
124*12720SWyllys.Ingersoll@Sun.COM 		 */
125*12720SWyllys.Ingersoll@Sun.COM 		rv = kms_copy_object(old_object, &new_object, B_TRUE,
126*12720SWyllys.Ingersoll@Sun.COM 		    session_p);
127*12720SWyllys.Ingersoll@Sun.COM 		(void) pthread_mutex_unlock(&old_object->object_mutex);
128*12720SWyllys.Ingersoll@Sun.COM 		if ((rv != CKR_OK) || (new_object == NULL)) {
129*12720SWyllys.Ingersoll@Sun.COM 			/*
130*12720SWyllys.Ingersoll@Sun.COM 			 * Most likely we ran out of space.
131*12720SWyllys.Ingersoll@Sun.COM 			 * Decrement the session reference count.
132*12720SWyllys.Ingersoll@Sun.COM 			 * We do not hold the session lock.
133*12720SWyllys.Ingersoll@Sun.COM 			 */
134*12720SWyllys.Ingersoll@Sun.COM 			OBJ_REFRELE(old_object);
135*12720SWyllys.Ingersoll@Sun.COM 			REFRELE(session_p, ses_lock_held);
136*12720SWyllys.Ingersoll@Sun.COM 			return (rv);
137*12720SWyllys.Ingersoll@Sun.COM 		}
138*12720SWyllys.Ingersoll@Sun.COM 
139*12720SWyllys.Ingersoll@Sun.COM 		new_object->is_lib_obj = B_TRUE;
140*12720SWyllys.Ingersoll@Sun.COM 
141*12720SWyllys.Ingersoll@Sun.COM 		/* Modify the object attribute if requested */
142*12720SWyllys.Ingersoll@Sun.COM 		for (i = 0; i < ulCount; i++) {
143*12720SWyllys.Ingersoll@Sun.COM 			/* Set the requested attribute into the new object. */
144*12720SWyllys.Ingersoll@Sun.COM 			rv = kms_set_attribute(new_object, &pTemplate[i],
145*12720SWyllys.Ingersoll@Sun.COM 			    B_TRUE);
146*12720SWyllys.Ingersoll@Sun.COM 
147*12720SWyllys.Ingersoll@Sun.COM 			if (rv != CKR_OK) {
148*12720SWyllys.Ingersoll@Sun.COM 				kms_cleanup_object(new_object);
149*12720SWyllys.Ingersoll@Sun.COM 				OBJ_REFRELE(old_object);
150*12720SWyllys.Ingersoll@Sun.COM 				REFRELE(session_p, ses_lock_held);
151*12720SWyllys.Ingersoll@Sun.COM 				return (rv);
152*12720SWyllys.Ingersoll@Sun.COM 			}
153*12720SWyllys.Ingersoll@Sun.COM 		}
154*12720SWyllys.Ingersoll@Sun.COM 
155*12720SWyllys.Ingersoll@Sun.COM 		/* Insert the new object into this session's object list. */
156*12720SWyllys.Ingersoll@Sun.COM 		kms_add_object_to_session(new_object, session_p);
157*12720SWyllys.Ingersoll@Sun.COM 
158*12720SWyllys.Ingersoll@Sun.COM 		/*
159*12720SWyllys.Ingersoll@Sun.COM 		 * Decrement the session reference count.
160*12720SWyllys.Ingersoll@Sun.COM 		 * We do not hold the session lock.
161*12720SWyllys.Ingersoll@Sun.COM 		 */
162*12720SWyllys.Ingersoll@Sun.COM 		OBJ_REFRELE(old_object);
163*12720SWyllys.Ingersoll@Sun.COM 		REFRELE(session_p, ses_lock_held);
164*12720SWyllys.Ingersoll@Sun.COM 
165*12720SWyllys.Ingersoll@Sun.COM 		/* set handle of the new object */
166*12720SWyllys.Ingersoll@Sun.COM 		*phNewObject = (CK_ULONG)new_object;
167*12720SWyllys.Ingersoll@Sun.COM 
168*12720SWyllys.Ingersoll@Sun.COM 	}
169*12720SWyllys.Ingersoll@Sun.COM 
170*12720SWyllys.Ingersoll@Sun.COM 	return (rv);
171*12720SWyllys.Ingersoll@Sun.COM 
172*12720SWyllys.Ingersoll@Sun.COM failed_cleanup:
173*12720SWyllys.Ingersoll@Sun.COM 	if (new_object != NULL) {
174*12720SWyllys.Ingersoll@Sun.COM 		(void) kms_free_object(new_object);
175*12720SWyllys.Ingersoll@Sun.COM 	}
176*12720SWyllys.Ingersoll@Sun.COM 
177*12720SWyllys.Ingersoll@Sun.COM 	OBJ_REFRELE(old_object);
178*12720SWyllys.Ingersoll@Sun.COM 	REFRELE(session_p, ses_lock_held);
179*12720SWyllys.Ingersoll@Sun.COM 	return (rv);
180*12720SWyllys.Ingersoll@Sun.COM }
181*12720SWyllys.Ingersoll@Sun.COM 
182*12720SWyllys.Ingersoll@Sun.COM CK_RV
C_DestroyObject(CK_SESSION_HANDLE hSession,CK_OBJECT_HANDLE hObject)183*12720SWyllys.Ingersoll@Sun.COM C_DestroyObject(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject)
184*12720SWyllys.Ingersoll@Sun.COM {
185*12720SWyllys.Ingersoll@Sun.COM 	CK_RV rv;
186*12720SWyllys.Ingersoll@Sun.COM 	kms_object_t *object_p;
187*12720SWyllys.Ingersoll@Sun.COM 	kms_session_t *session_p = (kms_session_t *)(hSession);
188*12720SWyllys.Ingersoll@Sun.COM 	kms_slot_t	*pslot;
189*12720SWyllys.Ingersoll@Sun.COM 	boolean_t ses_lock_held = B_FALSE;
190*12720SWyllys.Ingersoll@Sun.COM 	CK_SESSION_HANDLE creating_session;
191*12720SWyllys.Ingersoll@Sun.COM 
192*12720SWyllys.Ingersoll@Sun.COM 	if (!kms_initialized)
193*12720SWyllys.Ingersoll@Sun.COM 		return (CKR_CRYPTOKI_NOT_INITIALIZED);
194*12720SWyllys.Ingersoll@Sun.COM 
195*12720SWyllys.Ingersoll@Sun.COM 	/*
196*12720SWyllys.Ingersoll@Sun.COM 	 * The reason that we don't call handle2session is because
197*12720SWyllys.Ingersoll@Sun.COM 	 * the argument hSession may not be the creating_session of
198*12720SWyllys.Ingersoll@Sun.COM 	 * the object to be destroyed, and we want to avoid the lock
199*12720SWyllys.Ingersoll@Sun.COM 	 * contention. The handle2session will be called later for
200*12720SWyllys.Ingersoll@Sun.COM 	 * the creating_session.
201*12720SWyllys.Ingersoll@Sun.COM 	 */
202*12720SWyllys.Ingersoll@Sun.COM 	if ((session_p == NULL) ||
203*12720SWyllys.Ingersoll@Sun.COM 	    (session_p->magic_marker != KMSTOKEN_SESSION_MAGIC)) {
204*12720SWyllys.Ingersoll@Sun.COM 		return (CKR_SESSION_HANDLE_INVALID);
205*12720SWyllys.Ingersoll@Sun.COM 	}
206*12720SWyllys.Ingersoll@Sun.COM 	/* Obtain the object pointer without incrementing reference count. */
207*12720SWyllys.Ingersoll@Sun.COM 	HANDLE2OBJECT_DESTROY(hObject, object_p, rv);
208*12720SWyllys.Ingersoll@Sun.COM 	if (rv != CKR_OK) {
209*12720SWyllys.Ingersoll@Sun.COM 		return (rv);
210*12720SWyllys.Ingersoll@Sun.COM 	}
211*12720SWyllys.Ingersoll@Sun.COM 
212*12720SWyllys.Ingersoll@Sun.COM 	/* Only session objects can be destroyed at a read-only session. */
213*12720SWyllys.Ingersoll@Sun.COM 	if ((session_p->ses_RO) &&
214*12720SWyllys.Ingersoll@Sun.COM 	    (object_p->bool_attr_mask & TOKEN_BOOL_ON)) {
215*12720SWyllys.Ingersoll@Sun.COM 		return (CKR_SESSION_READ_ONLY);
216*12720SWyllys.Ingersoll@Sun.COM 	}
217*12720SWyllys.Ingersoll@Sun.COM 
218*12720SWyllys.Ingersoll@Sun.COM 
219*12720SWyllys.Ingersoll@Sun.COM 	/*
220*12720SWyllys.Ingersoll@Sun.COM 	 * If the object is a session object, obtain the session handle
221*12720SWyllys.Ingersoll@Sun.COM 	 * which object belongs to.  For a token object, we will use the
222*12720SWyllys.Ingersoll@Sun.COM 	 * session handle from the caller, because the session used to
223*12720SWyllys.Ingersoll@Sun.COM 	 * create the token object may no longer exist.
224*12720SWyllys.Ingersoll@Sun.COM 	 */
225*12720SWyllys.Ingersoll@Sun.COM 	if (!(object_p->bool_attr_mask & TOKEN_BOOL_ON))
226*12720SWyllys.Ingersoll@Sun.COM 		creating_session = object_p->session_handle;
227*12720SWyllys.Ingersoll@Sun.COM 	else
228*12720SWyllys.Ingersoll@Sun.COM 		creating_session = hSession;
229*12720SWyllys.Ingersoll@Sun.COM 
230*12720SWyllys.Ingersoll@Sun.COM 	rv = handle2session(creating_session, &session_p);
231*12720SWyllys.Ingersoll@Sun.COM 	if (rv != CKR_OK) {
232*12720SWyllys.Ingersoll@Sun.COM 		return (rv);
233*12720SWyllys.Ingersoll@Sun.COM 	}
234*12720SWyllys.Ingersoll@Sun.COM 
235*12720SWyllys.Ingersoll@Sun.COM 	/*
236*12720SWyllys.Ingersoll@Sun.COM 	 * Set OBJECT_IS_DELETING flag so any access to this
237*12720SWyllys.Ingersoll@Sun.COM 	 * object will be rejected.
238*12720SWyllys.Ingersoll@Sun.COM 	 */
239*12720SWyllys.Ingersoll@Sun.COM 	(void) pthread_mutex_lock(&object_p->object_mutex);
240*12720SWyllys.Ingersoll@Sun.COM 	if (object_p->obj_delete_sync & OBJECT_IS_DELETING) {
241*12720SWyllys.Ingersoll@Sun.COM 		(void) pthread_mutex_unlock(&object_p->object_mutex);
242*12720SWyllys.Ingersoll@Sun.COM 		REFRELE(session_p, ses_lock_held);
243*12720SWyllys.Ingersoll@Sun.COM 		return (CKR_OBJECT_HANDLE_INVALID);
244*12720SWyllys.Ingersoll@Sun.COM 	}
245*12720SWyllys.Ingersoll@Sun.COM 	object_p->obj_delete_sync |= OBJECT_IS_DELETING;
246*12720SWyllys.Ingersoll@Sun.COM 	(void) pthread_mutex_unlock(&object_p->object_mutex);
247*12720SWyllys.Ingersoll@Sun.COM 
248*12720SWyllys.Ingersoll@Sun.COM 	if (object_p->bool_attr_mask & TOKEN_BOOL_ON) {
249*12720SWyllys.Ingersoll@Sun.COM 		/*
250*12720SWyllys.Ingersoll@Sun.COM 		 * The first FALSE boolean argument indicates that the caller
251*12720SWyllys.Ingersoll@Sun.COM 		 * does not hold the slot lock.  The second FALSE boolean
252*12720SWyllys.Ingersoll@Sun.COM 		 * argument indicates that the caller wants to clean up the
253*12720SWyllys.Ingersoll@Sun.COM 		 * object in the HW provider also.
254*12720SWyllys.Ingersoll@Sun.COM 		 */
255*12720SWyllys.Ingersoll@Sun.COM 		pslot = get_slotinfo();
256*12720SWyllys.Ingersoll@Sun.COM 		rv = kms_delete_token_object(pslot, session_p, object_p,
257*12720SWyllys.Ingersoll@Sun.COM 		    B_FALSE, B_FALSE);
258*12720SWyllys.Ingersoll@Sun.COM 	} else {
259*12720SWyllys.Ingersoll@Sun.COM 		/*
260*12720SWyllys.Ingersoll@Sun.COM 		 * The first FALSE boolean argument indicates that the caller
261*12720SWyllys.Ingersoll@Sun.COM 		 * does not hold the session lock.  The second FALSE boolean
262*12720SWyllys.Ingersoll@Sun.COM 		 * argument indicates that the caller wants to clean the object
263*12720SWyllys.Ingersoll@Sun.COM 		 * in the HW provider also.
264*12720SWyllys.Ingersoll@Sun.COM 		 */
265*12720SWyllys.Ingersoll@Sun.COM 		rv = kms_delete_object(session_p, object_p, B_FALSE,
266*12720SWyllys.Ingersoll@Sun.COM 		    B_FALSE);
267*12720SWyllys.Ingersoll@Sun.COM 	}
268*12720SWyllys.Ingersoll@Sun.COM 	/*
269*12720SWyllys.Ingersoll@Sun.COM 	 * Decrement the session reference count.
270*12720SWyllys.Ingersoll@Sun.COM 	 * We do not hold the session lock.
271*12720SWyllys.Ingersoll@Sun.COM 	 */
272*12720SWyllys.Ingersoll@Sun.COM 	REFRELE(session_p, ses_lock_held);
273*12720SWyllys.Ingersoll@Sun.COM 	return (rv);
274*12720SWyllys.Ingersoll@Sun.COM }
275*12720SWyllys.Ingersoll@Sun.COM 
276*12720SWyllys.Ingersoll@Sun.COM CK_RV
C_GetAttributeValue(CK_SESSION_HANDLE hSession,CK_OBJECT_HANDLE hObject,CK_ATTRIBUTE_PTR pTemplate,CK_ULONG ulCount)277*12720SWyllys.Ingersoll@Sun.COM C_GetAttributeValue(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject,
278*12720SWyllys.Ingersoll@Sun.COM     CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount)
279*12720SWyllys.Ingersoll@Sun.COM {
280*12720SWyllys.Ingersoll@Sun.COM 
281*12720SWyllys.Ingersoll@Sun.COM 	CK_RV rv = CKR_OK, rv1 = CKR_OK;
282*12720SWyllys.Ingersoll@Sun.COM 	kms_object_t *object_p;
283*12720SWyllys.Ingersoll@Sun.COM 	kms_session_t *session_p;
284*12720SWyllys.Ingersoll@Sun.COM 	boolean_t ses_lock_held = B_FALSE;
285*12720SWyllys.Ingersoll@Sun.COM 	int i;
286*12720SWyllys.Ingersoll@Sun.COM 
287*12720SWyllys.Ingersoll@Sun.COM 	if (!kms_initialized)
288*12720SWyllys.Ingersoll@Sun.COM 		return (CKR_CRYPTOKI_NOT_INITIALIZED);
289*12720SWyllys.Ingersoll@Sun.COM 
290*12720SWyllys.Ingersoll@Sun.COM 	if ((pTemplate == NULL) || (ulCount == 0))
291*12720SWyllys.Ingersoll@Sun.COM 		return (CKR_ARGUMENTS_BAD);
292*12720SWyllys.Ingersoll@Sun.COM 
293*12720SWyllys.Ingersoll@Sun.COM 	/*
294*12720SWyllys.Ingersoll@Sun.COM 	 * Obtain the session pointer. Also, increment the session
295*12720SWyllys.Ingersoll@Sun.COM 	 * reference count.
296*12720SWyllys.Ingersoll@Sun.COM 	 */
297*12720SWyllys.Ingersoll@Sun.COM 	rv = handle2session(hSession, &session_p);
298*12720SWyllys.Ingersoll@Sun.COM 	if (rv != CKR_OK)
299*12720SWyllys.Ingersoll@Sun.COM 		return (rv);
300*12720SWyllys.Ingersoll@Sun.COM 
301*12720SWyllys.Ingersoll@Sun.COM 	/* Obtain the object pointer. */
302*12720SWyllys.Ingersoll@Sun.COM 	HANDLE2OBJECT(hObject, object_p, rv);
303*12720SWyllys.Ingersoll@Sun.COM 	if (rv != CKR_OK) {
304*12720SWyllys.Ingersoll@Sun.COM 		/*
305*12720SWyllys.Ingersoll@Sun.COM 		 * Decrement the session reference count.
306*12720SWyllys.Ingersoll@Sun.COM 		 * We do not hold the session lock.
307*12720SWyllys.Ingersoll@Sun.COM 		 */
308*12720SWyllys.Ingersoll@Sun.COM 		REFRELE(session_p, ses_lock_held);
309*12720SWyllys.Ingersoll@Sun.COM 		return (rv);
310*12720SWyllys.Ingersoll@Sun.COM 	}
311*12720SWyllys.Ingersoll@Sun.COM 
312*12720SWyllys.Ingersoll@Sun.COM 	/* Acquire the lock on the object. */
313*12720SWyllys.Ingersoll@Sun.COM 	(void) pthread_mutex_lock(&object_p->object_mutex);
314*12720SWyllys.Ingersoll@Sun.COM 
315*12720SWyllys.Ingersoll@Sun.COM 	/*
316*12720SWyllys.Ingersoll@Sun.COM 	 * The object was created in the library. The library
317*12720SWyllys.Ingersoll@Sun.COM 	 * contains the value information of each attribute.
318*12720SWyllys.Ingersoll@Sun.COM 	 */
319*12720SWyllys.Ingersoll@Sun.COM 	for (i = 0; i < ulCount; i++) {
320*12720SWyllys.Ingersoll@Sun.COM 		/*
321*12720SWyllys.Ingersoll@Sun.COM 		 * Get the value of each attribute in the template.
322*12720SWyllys.Ingersoll@Sun.COM 		 * (We must process EVERY attribute in the template.)
323*12720SWyllys.Ingersoll@Sun.COM 		 */
324*12720SWyllys.Ingersoll@Sun.COM 		rv = kms_get_attribute(object_p, &pTemplate[i]);
325*12720SWyllys.Ingersoll@Sun.COM 		if (rv != CKR_OK)
326*12720SWyllys.Ingersoll@Sun.COM 			rv1 = rv;
327*12720SWyllys.Ingersoll@Sun.COM 	}
328*12720SWyllys.Ingersoll@Sun.COM 	(void) pthread_mutex_unlock(&object_p->object_mutex);
329*12720SWyllys.Ingersoll@Sun.COM 
330*12720SWyllys.Ingersoll@Sun.COM clean_exit:
331*12720SWyllys.Ingersoll@Sun.COM 	/*
332*12720SWyllys.Ingersoll@Sun.COM 	 * Decrement the session reference count.
333*12720SWyllys.Ingersoll@Sun.COM 	 * We do not hold the session lock.
334*12720SWyllys.Ingersoll@Sun.COM 	 */
335*12720SWyllys.Ingersoll@Sun.COM 	OBJ_REFRELE(object_p);
336*12720SWyllys.Ingersoll@Sun.COM 	REFRELE(session_p, ses_lock_held);
337*12720SWyllys.Ingersoll@Sun.COM 	rv = rv1;
338*12720SWyllys.Ingersoll@Sun.COM 	return (rv);
339*12720SWyllys.Ingersoll@Sun.COM }
340*12720SWyllys.Ingersoll@Sun.COM 
341*12720SWyllys.Ingersoll@Sun.COM CK_RV
C_SetAttributeValue(CK_SESSION_HANDLE hSession,CK_OBJECT_HANDLE hObject,CK_ATTRIBUTE_PTR pTemplate,CK_ULONG ulCount)342*12720SWyllys.Ingersoll@Sun.COM C_SetAttributeValue(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject,
343*12720SWyllys.Ingersoll@Sun.COM     CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount)
344*12720SWyllys.Ingersoll@Sun.COM {
345*12720SWyllys.Ingersoll@Sun.COM 	CK_RV rv = CKR_OK;
346*12720SWyllys.Ingersoll@Sun.COM 	kms_object_t *object_p;
347*12720SWyllys.Ingersoll@Sun.COM 	kms_object_t *new_object = NULL;
348*12720SWyllys.Ingersoll@Sun.COM 	kms_session_t *session_p;
349*12720SWyllys.Ingersoll@Sun.COM 	boolean_t ses_lock_held = B_FALSE;
350*12720SWyllys.Ingersoll@Sun.COM 	int i;
351*12720SWyllys.Ingersoll@Sun.COM 
352*12720SWyllys.Ingersoll@Sun.COM 	if (!kms_initialized)
353*12720SWyllys.Ingersoll@Sun.COM 		return (CKR_CRYPTOKI_NOT_INITIALIZED);
354*12720SWyllys.Ingersoll@Sun.COM 
355*12720SWyllys.Ingersoll@Sun.COM 	if ((pTemplate == NULL) || (ulCount == 0))
356*12720SWyllys.Ingersoll@Sun.COM 		return (CKR_ARGUMENTS_BAD);
357*12720SWyllys.Ingersoll@Sun.COM 
358*12720SWyllys.Ingersoll@Sun.COM 	/*
359*12720SWyllys.Ingersoll@Sun.COM 	 * Obtain the session pointer. Also, increment the session
360*12720SWyllys.Ingersoll@Sun.COM 	 * reference count.
361*12720SWyllys.Ingersoll@Sun.COM 	 */
362*12720SWyllys.Ingersoll@Sun.COM 	rv = handle2session(hSession, &session_p);
363*12720SWyllys.Ingersoll@Sun.COM 	if (rv != CKR_OK)
364*12720SWyllys.Ingersoll@Sun.COM 		return (rv);
365*12720SWyllys.Ingersoll@Sun.COM 
366*12720SWyllys.Ingersoll@Sun.COM 	/* Obtain the object pointer. */
367*12720SWyllys.Ingersoll@Sun.COM 	HANDLE2OBJECT(hObject, object_p, rv);
368*12720SWyllys.Ingersoll@Sun.COM 	if (rv != CKR_OK) {
369*12720SWyllys.Ingersoll@Sun.COM 		/*
370*12720SWyllys.Ingersoll@Sun.COM 		 * Decrement the session reference count.
371*12720SWyllys.Ingersoll@Sun.COM 		 * We do not hold the session lock.
372*12720SWyllys.Ingersoll@Sun.COM 		 */
373*12720SWyllys.Ingersoll@Sun.COM 		REFRELE(session_p, ses_lock_held);
374*12720SWyllys.Ingersoll@Sun.COM 		return (rv);
375*12720SWyllys.Ingersoll@Sun.COM 	}
376*12720SWyllys.Ingersoll@Sun.COM 
377*12720SWyllys.Ingersoll@Sun.COM 	/* lock the object */
378*12720SWyllys.Ingersoll@Sun.COM 	(void) pthread_mutex_lock(&object_p->object_mutex);
379*12720SWyllys.Ingersoll@Sun.COM 
380*12720SWyllys.Ingersoll@Sun.COM 	/*
381*12720SWyllys.Ingersoll@Sun.COM 	 * If the object was created in the HW provider, changing its
382*12720SWyllys.Ingersoll@Sun.COM 	 * attributes' values need to be done in the provider too.
383*12720SWyllys.Ingersoll@Sun.COM 	 */
384*12720SWyllys.Ingersoll@Sun.COM 	if (!object_p->is_lib_obj) {
385*12720SWyllys.Ingersoll@Sun.COM 
386*12720SWyllys.Ingersoll@Sun.COM 		/* Cannot modify a token object with a READ-ONLY session */
387*12720SWyllys.Ingersoll@Sun.COM 		if (session_p->ses_RO &&
388*12720SWyllys.Ingersoll@Sun.COM 		    (object_p->bool_attr_mask & TOKEN_BOOL_ON)) {
389*12720SWyllys.Ingersoll@Sun.COM 			(void) pthread_mutex_unlock(&object_p->object_mutex);
390*12720SWyllys.Ingersoll@Sun.COM 			rv = CKR_SESSION_READ_ONLY;
391*12720SWyllys.Ingersoll@Sun.COM 			goto clean_exit;
392*12720SWyllys.Ingersoll@Sun.COM 		}
393*12720SWyllys.Ingersoll@Sun.COM 	}
394*12720SWyllys.Ingersoll@Sun.COM 
395*12720SWyllys.Ingersoll@Sun.COM 	/*
396*12720SWyllys.Ingersoll@Sun.COM 	 * if we come here, the object must have been created in the
397*12720SWyllys.Ingersoll@Sun.COM 	 * library.  The work will be done completely in the library.
398*12720SWyllys.Ingersoll@Sun.COM 	 *
399*12720SWyllys.Ingersoll@Sun.COM 	 * Copy the old object to a new object. We work on the copied
400*12720SWyllys.Ingersoll@Sun.COM 	 * version because in case of error we still keep the old one
401*12720SWyllys.Ingersoll@Sun.COM 	 * intact.
402*12720SWyllys.Ingersoll@Sun.COM 	 */
403*12720SWyllys.Ingersoll@Sun.COM 	rv = kms_copy_object(object_p, &new_object, B_FALSE, NULL);
404*12720SWyllys.Ingersoll@Sun.COM 	(void) pthread_mutex_unlock(&object_p->object_mutex);
405*12720SWyllys.Ingersoll@Sun.COM 	if ((rv != CKR_OK) || (new_object == NULL)) {
406*12720SWyllys.Ingersoll@Sun.COM 		/*
407*12720SWyllys.Ingersoll@Sun.COM 		 * Most likely we ran out of space.
408*12720SWyllys.Ingersoll@Sun.COM 		 * Decrement the session reference count.
409*12720SWyllys.Ingersoll@Sun.COM 		 * We do not hold the session lock.
410*12720SWyllys.Ingersoll@Sun.COM 		 */
411*12720SWyllys.Ingersoll@Sun.COM 		goto clean_exit;
412*12720SWyllys.Ingersoll@Sun.COM 	}
413*12720SWyllys.Ingersoll@Sun.COM 
414*12720SWyllys.Ingersoll@Sun.COM 	for (i = 0; i < ulCount; i++) {
415*12720SWyllys.Ingersoll@Sun.COM 		/* Set the requested attribute into the new object. */
416*12720SWyllys.Ingersoll@Sun.COM 		rv = kms_set_attribute(new_object, &pTemplate[i], B_FALSE);
417*12720SWyllys.Ingersoll@Sun.COM 
418*12720SWyllys.Ingersoll@Sun.COM 		if (rv != CKR_OK) {
419*12720SWyllys.Ingersoll@Sun.COM 			kms_cleanup_object(new_object);
420*12720SWyllys.Ingersoll@Sun.COM 			goto clean_exit;
421*12720SWyllys.Ingersoll@Sun.COM 		}
422*12720SWyllys.Ingersoll@Sun.COM 	}
423*12720SWyllys.Ingersoll@Sun.COM 
424*12720SWyllys.Ingersoll@Sun.COM 	/*
425*12720SWyllys.Ingersoll@Sun.COM 	 * We've successfully set all the requested attributes.
426*12720SWyllys.Ingersoll@Sun.COM 	 * Merge the new object with the old object, then destory
427*12720SWyllys.Ingersoll@Sun.COM 	 * the new one. The reason to do the merging is because we
428*12720SWyllys.Ingersoll@Sun.COM 	 * have to keep the original object handle (address of object).
429*12720SWyllys.Ingersoll@Sun.COM 	 */
430*12720SWyllys.Ingersoll@Sun.COM 	(void) pthread_mutex_lock(&object_p->object_mutex);
431*12720SWyllys.Ingersoll@Sun.COM 	kms_merge_object(object_p, new_object);
432*12720SWyllys.Ingersoll@Sun.COM 	(void) pthread_mutex_unlock(&object_p->object_mutex);
433*12720SWyllys.Ingersoll@Sun.COM 
434*12720SWyllys.Ingersoll@Sun.COM clean_exit:
435*12720SWyllys.Ingersoll@Sun.COM 	if (new_object != NULL)
436*12720SWyllys.Ingersoll@Sun.COM 		(void) kms_free_object(new_object);
437*12720SWyllys.Ingersoll@Sun.COM 
438*12720SWyllys.Ingersoll@Sun.COM 	/*
439*12720SWyllys.Ingersoll@Sun.COM 	 * Decrement the session reference count.
440*12720SWyllys.Ingersoll@Sun.COM 	 * We do not hold the session lock.
441*12720SWyllys.Ingersoll@Sun.COM 	 */
442*12720SWyllys.Ingersoll@Sun.COM 	OBJ_REFRELE(object_p);
443*12720SWyllys.Ingersoll@Sun.COM 	REFRELE(session_p, ses_lock_held);
444*12720SWyllys.Ingersoll@Sun.COM 
445*12720SWyllys.Ingersoll@Sun.COM 	return (rv);
446*12720SWyllys.Ingersoll@Sun.COM }
447*12720SWyllys.Ingersoll@Sun.COM 
448*12720SWyllys.Ingersoll@Sun.COM CK_RV
C_GetObjectSize(CK_SESSION_HANDLE hSession,CK_OBJECT_HANDLE hObject,CK_ULONG_PTR pulSize)449*12720SWyllys.Ingersoll@Sun.COM C_GetObjectSize(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject,
450*12720SWyllys.Ingersoll@Sun.COM     CK_ULONG_PTR pulSize)
451*12720SWyllys.Ingersoll@Sun.COM {
452*12720SWyllys.Ingersoll@Sun.COM 
453*12720SWyllys.Ingersoll@Sun.COM 	CK_RV rv = CKR_OK;
454*12720SWyllys.Ingersoll@Sun.COM 	kms_object_t *object_p;
455*12720SWyllys.Ingersoll@Sun.COM 	kms_session_t *session_p;
456*12720SWyllys.Ingersoll@Sun.COM 	boolean_t ses_lock_held = B_FALSE;
457*12720SWyllys.Ingersoll@Sun.COM 
458*12720SWyllys.Ingersoll@Sun.COM 	if (!kms_initialized)
459*12720SWyllys.Ingersoll@Sun.COM 		return (CKR_CRYPTOKI_NOT_INITIALIZED);
460*12720SWyllys.Ingersoll@Sun.COM 
461*12720SWyllys.Ingersoll@Sun.COM 	/* Check if pulSize is valid */
462*12720SWyllys.Ingersoll@Sun.COM 	if (pulSize == NULL) {
463*12720SWyllys.Ingersoll@Sun.COM 		return (CKR_ARGUMENTS_BAD);
464*12720SWyllys.Ingersoll@Sun.COM 	}
465*12720SWyllys.Ingersoll@Sun.COM 
466*12720SWyllys.Ingersoll@Sun.COM 	/*
467*12720SWyllys.Ingersoll@Sun.COM 	 * Obtain the session pointer. Also, increment the session
468*12720SWyllys.Ingersoll@Sun.COM 	 * reference count.
469*12720SWyllys.Ingersoll@Sun.COM 	 */
470*12720SWyllys.Ingersoll@Sun.COM 	rv = handle2session(hSession, &session_p);
471*12720SWyllys.Ingersoll@Sun.COM 	if (rv != CKR_OK)
472*12720SWyllys.Ingersoll@Sun.COM 		return (rv);
473*12720SWyllys.Ingersoll@Sun.COM 
474*12720SWyllys.Ingersoll@Sun.COM 	/* Obtain the object pointer. */
475*12720SWyllys.Ingersoll@Sun.COM 	HANDLE2OBJECT(hObject, object_p, rv);
476*12720SWyllys.Ingersoll@Sun.COM 	if (rv != CKR_OK) {
477*12720SWyllys.Ingersoll@Sun.COM 		/*
478*12720SWyllys.Ingersoll@Sun.COM 		 * Decrement the session reference count.
479*12720SWyllys.Ingersoll@Sun.COM 		 * We do not hold the session lock.
480*12720SWyllys.Ingersoll@Sun.COM 		 */
481*12720SWyllys.Ingersoll@Sun.COM 		REFRELE(session_p, ses_lock_held);
482*12720SWyllys.Ingersoll@Sun.COM 		return (rv);
483*12720SWyllys.Ingersoll@Sun.COM 	}
484*12720SWyllys.Ingersoll@Sun.COM 
485*12720SWyllys.Ingersoll@Sun.COM 	/* Acquire the lock on the object. */
486*12720SWyllys.Ingersoll@Sun.COM 	(void) pthread_mutex_lock(&object_p->object_mutex);
487*12720SWyllys.Ingersoll@Sun.COM 
488*12720SWyllys.Ingersoll@Sun.COM 	rv = kms_get_object_size(object_p, pulSize);
489*12720SWyllys.Ingersoll@Sun.COM 
490*12720SWyllys.Ingersoll@Sun.COM 	(void) pthread_mutex_unlock(&object_p->object_mutex);
491*12720SWyllys.Ingersoll@Sun.COM 
492*12720SWyllys.Ingersoll@Sun.COM 	/*
493*12720SWyllys.Ingersoll@Sun.COM 	 * Decrement the session reference count.
494*12720SWyllys.Ingersoll@Sun.COM 	 * We do not hold the session lock.
495*12720SWyllys.Ingersoll@Sun.COM 	 */
496*12720SWyllys.Ingersoll@Sun.COM 	OBJ_REFRELE(object_p);
497*12720SWyllys.Ingersoll@Sun.COM 	REFRELE(session_p, ses_lock_held);
498*12720SWyllys.Ingersoll@Sun.COM 	return (rv);
499*12720SWyllys.Ingersoll@Sun.COM }
500*12720SWyllys.Ingersoll@Sun.COM 
501*12720SWyllys.Ingersoll@Sun.COM CK_RV
C_FindObjectsInit(CK_SESSION_HANDLE sh,CK_ATTRIBUTE_PTR pTemplate,CK_ULONG ulCount)502*12720SWyllys.Ingersoll@Sun.COM C_FindObjectsInit(CK_SESSION_HANDLE sh, CK_ATTRIBUTE_PTR pTemplate,
503*12720SWyllys.Ingersoll@Sun.COM     CK_ULONG ulCount)
504*12720SWyllys.Ingersoll@Sun.COM {
505*12720SWyllys.Ingersoll@Sun.COM 	CK_RV		rv;
506*12720SWyllys.Ingersoll@Sun.COM 	kms_session_t	*session_p;
507*12720SWyllys.Ingersoll@Sun.COM 	boolean_t ses_lock_held = B_FALSE;
508*12720SWyllys.Ingersoll@Sun.COM 
509*12720SWyllys.Ingersoll@Sun.COM 	if (!kms_initialized)
510*12720SWyllys.Ingersoll@Sun.COM 		return (CKR_CRYPTOKI_NOT_INITIALIZED);
511*12720SWyllys.Ingersoll@Sun.COM 
512*12720SWyllys.Ingersoll@Sun.COM 	/* Check the arguments */
513*12720SWyllys.Ingersoll@Sun.COM 	if ((ulCount > 0) && (pTemplate == NULL)) {
514*12720SWyllys.Ingersoll@Sun.COM 		return (CKR_ARGUMENTS_BAD);
515*12720SWyllys.Ingersoll@Sun.COM 	}
516*12720SWyllys.Ingersoll@Sun.COM 
517*12720SWyllys.Ingersoll@Sun.COM 	/*
518*12720SWyllys.Ingersoll@Sun.COM 	 * Obtain the session pointer. Also, increment the session
519*12720SWyllys.Ingersoll@Sun.COM 	 * reference count.
520*12720SWyllys.Ingersoll@Sun.COM 	 */
521*12720SWyllys.Ingersoll@Sun.COM 	rv = handle2session(sh, &session_p);
522*12720SWyllys.Ingersoll@Sun.COM 	if (rv != CKR_OK)
523*12720SWyllys.Ingersoll@Sun.COM 		return (rv);
524*12720SWyllys.Ingersoll@Sun.COM 
525*12720SWyllys.Ingersoll@Sun.COM 	/* Acquire the session lock */
526*12720SWyllys.Ingersoll@Sun.COM 	(void) pthread_mutex_lock(&session_p->session_mutex);
527*12720SWyllys.Ingersoll@Sun.COM 	ses_lock_held = B_TRUE;
528*12720SWyllys.Ingersoll@Sun.COM 
529*12720SWyllys.Ingersoll@Sun.COM 	/* Check to see if find operation is already active */
530*12720SWyllys.Ingersoll@Sun.COM 	if (session_p->find_objects.flags & CRYPTO_OPERATION_ACTIVE) {
531*12720SWyllys.Ingersoll@Sun.COM 		/* decrement the session count, and unlock the mutex */
532*12720SWyllys.Ingersoll@Sun.COM 		REFRELE(session_p, ses_lock_held);
533*12720SWyllys.Ingersoll@Sun.COM 		return (CKR_OPERATION_ACTIVE);
534*12720SWyllys.Ingersoll@Sun.COM 	} else {
535*12720SWyllys.Ingersoll@Sun.COM 		/*
536*12720SWyllys.Ingersoll@Sun.COM 		 * This active flag will remain ON until application calls
537*12720SWyllys.Ingersoll@Sun.COM 		 * C_FindObjectsFinal.
538*12720SWyllys.Ingersoll@Sun.COM 		 */
539*12720SWyllys.Ingersoll@Sun.COM 		session_p->find_objects.flags = CRYPTO_OPERATION_ACTIVE;
540*12720SWyllys.Ingersoll@Sun.COM 	}
541*12720SWyllys.Ingersoll@Sun.COM 	(void) pthread_mutex_unlock(&session_p->session_mutex);
542*12720SWyllys.Ingersoll@Sun.COM 
543*12720SWyllys.Ingersoll@Sun.COM 	/*
544*12720SWyllys.Ingersoll@Sun.COM 	 * If the KMS provider supports object creation, we call the
545*12720SWyllys.Ingersoll@Sun.COM 	 * CRYPTO_OBJECT_FIND_INIT to initialize object finding.
546*12720SWyllys.Ingersoll@Sun.COM 	 * Otherwise, all the objects are created in the library and we
547*12720SWyllys.Ingersoll@Sun.COM 	 * do the find objects solely in the library.
548*12720SWyllys.Ingersoll@Sun.COM 	 */
549*12720SWyllys.Ingersoll@Sun.COM 	rv = kms_find_objects_init(session_p, pTemplate, ulCount);
550*12720SWyllys.Ingersoll@Sun.COM 	if (rv != CKR_OK) {
551*12720SWyllys.Ingersoll@Sun.COM 		(void) pthread_mutex_lock(&session_p->session_mutex);
552*12720SWyllys.Ingersoll@Sun.COM 		session_p->find_objects.flags = 0;
553*12720SWyllys.Ingersoll@Sun.COM 		(void) pthread_mutex_unlock(&session_p->session_mutex);
554*12720SWyllys.Ingersoll@Sun.COM 	}
555*12720SWyllys.Ingersoll@Sun.COM 	/* decrement the session count, and unlock the mutex */
556*12720SWyllys.Ingersoll@Sun.COM 	REFRELE(session_p, ses_lock_held);
557*12720SWyllys.Ingersoll@Sun.COM 	return (rv);
558*12720SWyllys.Ingersoll@Sun.COM }
559*12720SWyllys.Ingersoll@Sun.COM 
560*12720SWyllys.Ingersoll@Sun.COM CK_RV
C_FindObjects(CK_SESSION_HANDLE sh,CK_OBJECT_HANDLE_PTR phObject,CK_ULONG ulMaxObjectCount,CK_ULONG_PTR pulObjectCount)561*12720SWyllys.Ingersoll@Sun.COM C_FindObjects(CK_SESSION_HANDLE sh, CK_OBJECT_HANDLE_PTR phObject,
562*12720SWyllys.Ingersoll@Sun.COM     CK_ULONG ulMaxObjectCount, CK_ULONG_PTR pulObjectCount)
563*12720SWyllys.Ingersoll@Sun.COM {
564*12720SWyllys.Ingersoll@Sun.COM 	CK_RV rv = CKR_OK;
565*12720SWyllys.Ingersoll@Sun.COM 	kms_slot_t		*pslot = NULL;
566*12720SWyllys.Ingersoll@Sun.COM 	kms_session_t	*session_p;
567*12720SWyllys.Ingersoll@Sun.COM 	boolean_t ses_lock_held = B_FALSE;
568*12720SWyllys.Ingersoll@Sun.COM 
569*12720SWyllys.Ingersoll@Sun.COM 	if (!kms_initialized)
570*12720SWyllys.Ingersoll@Sun.COM 		return (CKR_CRYPTOKI_NOT_INITIALIZED);
571*12720SWyllys.Ingersoll@Sun.COM 
572*12720SWyllys.Ingersoll@Sun.COM 	/* check for invalid arguments */
573*12720SWyllys.Ingersoll@Sun.COM 	if (((phObject == NULL) && (ulMaxObjectCount != 0)) ||
574*12720SWyllys.Ingersoll@Sun.COM 	    (pulObjectCount == NULL)) {
575*12720SWyllys.Ingersoll@Sun.COM 		return (CKR_ARGUMENTS_BAD);
576*12720SWyllys.Ingersoll@Sun.COM 	}
577*12720SWyllys.Ingersoll@Sun.COM 
578*12720SWyllys.Ingersoll@Sun.COM 	if (ulMaxObjectCount == 0) {
579*12720SWyllys.Ingersoll@Sun.COM 		/* don't need to do anything, just return */
580*12720SWyllys.Ingersoll@Sun.COM 		*pulObjectCount = 0;
581*12720SWyllys.Ingersoll@Sun.COM 		return (CKR_OK);
582*12720SWyllys.Ingersoll@Sun.COM 	}
583*12720SWyllys.Ingersoll@Sun.COM 
584*12720SWyllys.Ingersoll@Sun.COM 	/*
585*12720SWyllys.Ingersoll@Sun.COM 	 * Obtain the session pointer. Also, increment the session
586*12720SWyllys.Ingersoll@Sun.COM 	 * reference count.
587*12720SWyllys.Ingersoll@Sun.COM 	 */
588*12720SWyllys.Ingersoll@Sun.COM 	rv = handle2session(sh, &session_p);
589*12720SWyllys.Ingersoll@Sun.COM 	if (rv != CKR_OK)
590*12720SWyllys.Ingersoll@Sun.COM 		return (rv);
591*12720SWyllys.Ingersoll@Sun.COM 
592*12720SWyllys.Ingersoll@Sun.COM 	/* Acquire the slot lock */
593*12720SWyllys.Ingersoll@Sun.COM 	pslot = get_slotinfo();
594*12720SWyllys.Ingersoll@Sun.COM 	(void) pthread_mutex_lock(&pslot->sl_mutex);
595*12720SWyllys.Ingersoll@Sun.COM 
596*12720SWyllys.Ingersoll@Sun.COM 	/* Acquire the session lock */
597*12720SWyllys.Ingersoll@Sun.COM 	(void) pthread_mutex_lock(&session_p->session_mutex);
598*12720SWyllys.Ingersoll@Sun.COM 	ses_lock_held = B_TRUE;
599*12720SWyllys.Ingersoll@Sun.COM 
600*12720SWyllys.Ingersoll@Sun.COM 	/* Check to see if find operation is active */
601*12720SWyllys.Ingersoll@Sun.COM 	if (!(session_p->find_objects.flags & CRYPTO_OPERATION_ACTIVE)) {
602*12720SWyllys.Ingersoll@Sun.COM 		rv = CKR_OPERATION_NOT_INITIALIZED;
603*12720SWyllys.Ingersoll@Sun.COM 		goto clean_exit;
604*12720SWyllys.Ingersoll@Sun.COM 	}
605*12720SWyllys.Ingersoll@Sun.COM 
606*12720SWyllys.Ingersoll@Sun.COM 	/*
607*12720SWyllys.Ingersoll@Sun.COM 	 * Similar to C_FindObjectInit(), if the KMS provider supports object
608*12720SWyllys.Ingersoll@Sun.COM 	 * creation, we need to find objects.
609*12720SWyllys.Ingersoll@Sun.COM 	 * Otherwise, all the objects are created in the library and we do
610*12720SWyllys.Ingersoll@Sun.COM 	 * the find objects solely in the library.
611*12720SWyllys.Ingersoll@Sun.COM 	 */
612*12720SWyllys.Ingersoll@Sun.COM 
613*12720SWyllys.Ingersoll@Sun.COM 	rv = kms_find_objects(session_p, phObject,
614*12720SWyllys.Ingersoll@Sun.COM 	    ulMaxObjectCount, pulObjectCount);
615*12720SWyllys.Ingersoll@Sun.COM 
616*12720SWyllys.Ingersoll@Sun.COM clean_exit:
617*12720SWyllys.Ingersoll@Sun.COM 	/* decrement the session count, and release the session lock */
618*12720SWyllys.Ingersoll@Sun.COM 	REFRELE(session_p, ses_lock_held);
619*12720SWyllys.Ingersoll@Sun.COM 
620*12720SWyllys.Ingersoll@Sun.COM 	/* release the slot lock */
621*12720SWyllys.Ingersoll@Sun.COM 	if (pslot)
622*12720SWyllys.Ingersoll@Sun.COM 		(void) pthread_mutex_unlock(&pslot->sl_mutex);
623*12720SWyllys.Ingersoll@Sun.COM 
624*12720SWyllys.Ingersoll@Sun.COM 	return (rv);
625*12720SWyllys.Ingersoll@Sun.COM }
626*12720SWyllys.Ingersoll@Sun.COM 
627*12720SWyllys.Ingersoll@Sun.COM CK_RV
C_FindObjectsFinal(CK_SESSION_HANDLE sh)628*12720SWyllys.Ingersoll@Sun.COM C_FindObjectsFinal(CK_SESSION_HANDLE sh)
629*12720SWyllys.Ingersoll@Sun.COM {
630*12720SWyllys.Ingersoll@Sun.COM 	kms_session_t	*session_p;
631*12720SWyllys.Ingersoll@Sun.COM 	CK_RV rv;
632*12720SWyllys.Ingersoll@Sun.COM 	boolean_t ses_lock_held = B_FALSE;
633*12720SWyllys.Ingersoll@Sun.COM 
634*12720SWyllys.Ingersoll@Sun.COM 	if (!kms_initialized)
635*12720SWyllys.Ingersoll@Sun.COM 		return (CKR_CRYPTOKI_NOT_INITIALIZED);
636*12720SWyllys.Ingersoll@Sun.COM 
637*12720SWyllys.Ingersoll@Sun.COM 	/*
638*12720SWyllys.Ingersoll@Sun.COM 	 * Obtain the session pointer. Also, increment the session
639*12720SWyllys.Ingersoll@Sun.COM 	 * reference count.
640*12720SWyllys.Ingersoll@Sun.COM 	 */
641*12720SWyllys.Ingersoll@Sun.COM 	rv = handle2session(sh, &session_p);
642*12720SWyllys.Ingersoll@Sun.COM 	if (rv != CKR_OK)
643*12720SWyllys.Ingersoll@Sun.COM 		return (rv);
644*12720SWyllys.Ingersoll@Sun.COM 
645*12720SWyllys.Ingersoll@Sun.COM 	/* Acquire the session lock */
646*12720SWyllys.Ingersoll@Sun.COM 	(void) pthread_mutex_lock(&session_p->session_mutex);
647*12720SWyllys.Ingersoll@Sun.COM 	ses_lock_held = B_TRUE;
648*12720SWyllys.Ingersoll@Sun.COM 
649*12720SWyllys.Ingersoll@Sun.COM 	/* Check to see if find operation is active */
650*12720SWyllys.Ingersoll@Sun.COM 	if (!(session_p->find_objects.flags & CRYPTO_OPERATION_ACTIVE)) {
651*12720SWyllys.Ingersoll@Sun.COM 		REFRELE(session_p, ses_lock_held);
652*12720SWyllys.Ingersoll@Sun.COM 		return (CKR_OPERATION_NOT_INITIALIZED);
653*12720SWyllys.Ingersoll@Sun.COM 	}
654*12720SWyllys.Ingersoll@Sun.COM 
655*12720SWyllys.Ingersoll@Sun.COM 	/*
656*12720SWyllys.Ingersoll@Sun.COM 	 * Similar to C_FindObjectInit(), if the KMS provider supports object
657*12720SWyllys.Ingersoll@Sun.COM 	 * creation, we need to finalize the search on the KMS side.
658*12720SWyllys.Ingersoll@Sun.COM 	 */
659*12720SWyllys.Ingersoll@Sun.COM 	kms_find_objects_final(session_p);
660*12720SWyllys.Ingersoll@Sun.COM 
661*12720SWyllys.Ingersoll@Sun.COM 	/* decrement the session count, and release the lock */
662*12720SWyllys.Ingersoll@Sun.COM 	REFRELE(session_p, ses_lock_held);
663*12720SWyllys.Ingersoll@Sun.COM 	return (rv);
664*12720SWyllys.Ingersoll@Sun.COM }
665