dmake: do not set MAKEFLAGS=k
[unleashed/tickless.git] / usr / src / lib / pkcs11 / libpkcs11 / common / pkcs11Session.c
blobdd38ddc6b67539bf38cc1f14ad38983a83ef2cfd
1 /*
2 * CDDL HEADER START
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
7 * with the License.
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
20 * CDDL HEADER END
23 * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 #pragma ident "%Z%%M% %I% %E% SMI"
29 #include <pthread.h>
30 #include <security/cryptoki.h>
31 #include "pkcs11Global.h"
32 #include "pkcs11Session.h"
33 #include "pkcs11Slot.h"
34 #include "metaGlobal.h"
37 * C_OpenSession will need to create a pseudo session associated
38 * with the session created by the plugged in provider. Only
39 * minimal argument checking is done here, as we rely on the
40 * underlying provider to catch most errors.
42 CK_RV
43 C_OpenSession(CK_SLOT_ID slotID, CK_FLAGS flags, CK_VOID_PTR pApplication,
44 CK_NOTIFY Notify, CK_SESSION_HANDLE_PTR phSession)
47 CK_RV rv;
48 CK_SLOT_ID true_id;
49 CK_SLOT_ID fw_st_id; /* id for accessing framework's slottable */
50 CK_SESSION_HANDLE prov_sess;
52 if (!pkcs11_initialized) {
53 return (CKR_CRYPTOKI_NOT_INITIALIZED);
56 /* Check for a fastpath */
57 if (purefastpath || policyfastpath) {
58 if (metaslot_enabled) {
60 * if metaslot is enabled and we are in fastpath
61 * mode, only one other slot is in the framework
62 * so, need to go to that slot's entry
63 * to look up the true slot ID for the slot
65 return (fast_funcs->C_OpenSession(TRUEID(slotID+1),
66 flags, pApplication, Notify, phSession));
67 } else {
68 return (fast_funcs->C_OpenSession(slotID, flags,
69 pApplication, Notify, phSession));
74 if (slotID == METASLOT_FRAMEWORK_ID) {
75 rv = meta_OpenSession(METASLOT_SLOTID, flags,
76 pApplication, Notify, &prov_sess);
77 } else {
78 /* Check that slotID is valid */
79 if (pkcs11_validate_and_convert_slotid(slotID, &fw_st_id)
80 != CKR_OK) {
81 return (CKR_SLOT_ID_INVALID);
83 true_id = TRUEID(fw_st_id);
84 rv = FUNCLIST(fw_st_id)->C_OpenSession(true_id, flags,
85 pApplication, Notify, &prov_sess);
88 /* Present consistent interface for framework */
89 if (rv == CKR_FUNCTION_NOT_SUPPORTED) {
90 return (CKR_FUNCTION_FAILED);
91 } else if (rv != CKR_OK) {
92 /* could not create session with provider, return now */
93 return (rv);
96 /* Provider was successful, now create session in framework */
97 if (slotID == METASLOT_FRAMEWORK_ID) {
98 rv = pkcs11_session_add(
99 slottable->st_slots[METASLOT_FRAMEWORK_ID],
100 METASLOT_FRAMEWORK_ID, phSession, prov_sess);
101 } else {
102 rv = pkcs11_session_add(slottable->st_slots[fw_st_id],
103 fw_st_id, phSession, prov_sess);
106 if (rv != CKR_OK) {
107 /* Trouble in the framework, clean up provider session */
108 FUNCLIST(slotID)->C_CloseSession(prov_sess);
110 return (rv);
114 * C_CloseSession will close a session with the underlying provider,
115 * and if that's successful will close it in the framework.
117 CK_RV
118 C_CloseSession(CK_SESSION_HANDLE hSession)
120 CK_RV rv;
121 pkcs11_session_t *sessp;
123 /* Check for a fastpath */
124 if (purefastpath || policyfastpath) {
125 return (fast_funcs->C_CloseSession(hSession));
128 if (!pkcs11_initialized) {
129 return (CKR_CRYPTOKI_NOT_INITIALIZED);
132 /* Obtain the session pointer */
133 HANDLE2SESSION(hSession, sessp, rv);
135 if (rv != CKR_OK) {
136 return (rv);
139 /* Delete the session with the provider */
140 rv = FUNCLIST(sessp->se_slotid)->C_CloseSession(sessp->se_handle);
142 /* Present consistent interface for framework */
143 if (rv == CKR_FUNCTION_NOT_SUPPORTED) {
144 return (CKR_FUNCTION_FAILED);
145 } else if (rv != CKR_OK) {
146 /* could not delete session with provider, return now */
147 return (rv);
150 /* Delete session from the framework */
151 pkcs11_session_delete(slottable->st_slots[sessp->se_slotid], sessp);
153 return (rv);
157 * C_CloseAllSessions will close all sessions associated with this
158 * slot with the underlying provider. If that is successful, will
159 * close the associated sessions in the framework. If the provider
160 * has not implemented C_CloseAllSessions, then we will loop through
161 * the list of sessions and individually call C_CloseSession.
163 CK_RV
164 C_CloseAllSessions(CK_SLOT_ID slotID)
167 CK_RV rv, rv1;
169 CK_SLOT_ID true_id;
170 CK_SLOT_ID fw_st_id; /* id for accessing framework's slottable */
171 pkcs11_session_t *sessp, *sess_nextp;
172 pkcs11_slot_t *slotp;
174 if (!pkcs11_initialized) {
175 return (CKR_CRYPTOKI_NOT_INITIALIZED);
178 /* Check for a fastpath */
179 if (purefastpath || policyfastpath) {
180 if (metaslot_enabled) {
182 * if metaslot is enabled and we are in fastpath
183 * mode, only one other slot is in the framework
184 * so, need to go to that slot's entry
185 * to look up the true slot ID for the slot
187 return (fast_funcs->C_CloseAllSessions(
188 TRUEID(slotID+1)));
189 } else {
190 return (fast_funcs->C_CloseAllSessions(slotID));
194 /* Check that slotID is valid */
195 if (pkcs11_validate_and_convert_slotid(slotID, &fw_st_id) != CKR_OK) {
196 return (CKR_SLOT_ID_INVALID);
199 slotp = slottable->st_slots[fw_st_id];
200 true_id = TRUEID(fw_st_id);
202 rv = FUNCLIST(fw_st_id)->C_CloseAllSessions(true_id);
204 /* Present consistent interface for framework */
205 if (rv == CKR_FUNCTION_NOT_SUPPORTED) {
206 /* Need to attempt to individually delete sessions */
208 /* reset rv */
209 rv = CKR_OK;
211 (void) pthread_mutex_lock(&slotp->sl_mutex);
212 sessp = slotp->sl_sess_list;
214 while (sessp) {
215 sess_nextp = sessp->se_next;
217 rv1 = FUNCLIST(fw_st_id)->
218 C_CloseSession(sessp->se_handle);
220 /* Record the first error encountered */
221 if ((rv == CKR_OK) && (rv1 != CKR_OK)) {
222 rv = rv1;
225 sessp = sess_nextp;
228 (void) pthread_mutex_unlock(&slotp->sl_mutex);
231 if (rv != CKR_OK) {
232 /* could not delete sessionlist with provider, return now */
233 return (rv);
236 /* Delete sessions from the framework */
237 pkcs11_sessionlist_delete(slotp);
239 return (rv);
243 * C_GetSessionInfo is a pure wrapper to the underlying provider.
244 * The only argument checked is whether or not hSession is valid.
246 CK_RV
247 C_GetSessionInfo(CK_SESSION_HANDLE hSession, CK_SESSION_INFO_PTR pInfo)
250 CK_RV rv;
251 CK_SLOT_ID slot_id;
252 pkcs11_session_t *sessp;
254 /* Check for a fastpath */
255 if (purefastpath || policyfastpath) {
256 rv = fast_funcs->C_GetSessionInfo(hSession, pInfo);
259 * If metaslot is enabled, and we are here, that
260 * that means there's only 1 other slot in the
261 * framework, and that slot should be hidden.
262 * so, override value of slot id to be metaslot's
263 * slot id.
265 if (metaslot_enabled) {
266 pInfo->slotID = METASLOT_FRAMEWORK_ID;
268 return (rv);
271 if (!pkcs11_initialized) {
272 return (CKR_CRYPTOKI_NOT_INITIALIZED);
275 /* Obtain the session pointer */
276 HANDLE2SESSION(hSession, sessp, rv);
278 if (rv != CKR_OK) {
279 return (rv);
282 /* Find the slot id for the framework */
283 slot_id = sessp->se_slotid;
285 /* Get session info from the provider */
286 rv = FUNCLIST(slot_id)->
287 C_GetSessionInfo(sessp->se_handle, pInfo);
289 /* Present consistent interface to the application */
290 if (rv == CKR_FUNCTION_NOT_SUPPORTED) {
291 return (CKR_FUNCTION_FAILED);
294 /* Override value of slot id to framework's */
295 pInfo->slotID = slot_id;
297 return (rv);
301 * C_GetOperationState is a pure wrapper to the underlying provider.
302 * The only argument checked is whether or not hSession is valid.
304 CK_RV
305 C_GetOperationState(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pOperationState,
306 CK_ULONG_PTR pulOperationStateLen)
309 CK_RV rv;
310 pkcs11_session_t *sessp;
312 /* Check for a fastpath */
313 if (purefastpath || policyfastpath) {
314 return (fast_funcs->C_GetOperationState(hSession,
315 pOperationState, pulOperationStateLen));
318 if (!pkcs11_initialized) {
319 return (CKR_CRYPTOKI_NOT_INITIALIZED);
322 /* Obtain the session pointer */
323 HANDLE2SESSION(hSession, sessp, rv);
325 if (rv != CKR_OK) {
326 return (rv);
329 /* Get the operation state with the provider */
330 rv = FUNCLIST(sessp->se_slotid)->C_GetOperationState(sessp->se_handle,
331 pOperationState, pulOperationStateLen);
333 /* Present consistent interface to the application */
334 if (rv == CKR_FUNCTION_NOT_SUPPORTED) {
335 return (CKR_FUNCTION_FAILED);
338 return (rv);
343 * C_SetOperationState is a pure wrapper to the underlying provider.
344 * The only argument checked is whether or not hSession is valid.
346 CK_RV
347 C_SetOperationState(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pOperationState,
348 CK_ULONG ulOperationStateLen, CK_OBJECT_HANDLE hEncryptionKey,
349 CK_OBJECT_HANDLE hAuthenticationKey)
351 CK_RV rv;
352 pkcs11_session_t *sessp;
354 /* Check for a fastpath */
355 if (purefastpath || policyfastpath) {
356 return (fast_funcs->C_SetOperationState(hSession,
357 pOperationState, ulOperationStateLen,
358 hEncryptionKey, hAuthenticationKey));
361 if (!pkcs11_initialized) {
362 return (CKR_CRYPTOKI_NOT_INITIALIZED);
365 /* Obtain the session pointer */
366 HANDLE2SESSION(hSession, sessp, rv);
368 if (rv != CKR_OK) {
369 return (rv);
372 /* Set the operation state with the provider */
373 rv = FUNCLIST(sessp->se_slotid)->C_SetOperationState(sessp->se_handle,
374 pOperationState, ulOperationStateLen, hEncryptionKey,
375 hAuthenticationKey);
377 /* Present consistent interface to the application */
378 if (rv == CKR_FUNCTION_NOT_SUPPORTED) {
379 return (CKR_FUNCTION_FAILED);
382 return (rv);
387 * C_Login is a pure wrapper to the underlying provider.
388 * The only argument checked is whether or not hSession is valid.
390 CK_RV
391 C_Login(CK_SESSION_HANDLE hSession, CK_USER_TYPE userType,
392 CK_UTF8CHAR_PTR pPin, CK_ULONG ulPinLen)
394 CK_RV rv;
395 pkcs11_session_t *sessp;
397 /* Check for a fastpath */
398 if (purefastpath || policyfastpath) {
399 return (fast_funcs->C_Login(hSession, userType, pPin,
400 ulPinLen));
403 if (!pkcs11_initialized) {
404 return (CKR_CRYPTOKI_NOT_INITIALIZED);
407 /* Obtain the session pointer */
408 HANDLE2SESSION(hSession, sessp, rv);
410 if (rv != CKR_OK) {
411 return (rv);
414 /* Login with the provider */
415 rv = FUNCLIST(sessp->se_slotid)->C_Login(sessp->se_handle,
416 userType, pPin, ulPinLen);
418 /* Present consistent interface to the application */
419 if (rv == CKR_FUNCTION_NOT_SUPPORTED) {
420 return (CKR_FUNCTION_FAILED);
423 return (rv);
427 * C_Logout is a pure wrapper to the underlying provider.
428 * The only argument checked is whether or not hSession is valid.
430 CK_RV
431 C_Logout(CK_SESSION_HANDLE hSession)
433 CK_RV rv;
434 pkcs11_session_t *sessp;
436 /* Check for a fastpath */
437 if (purefastpath || policyfastpath) {
438 return (fast_funcs->C_Logout(hSession));
441 if (!pkcs11_initialized) {
442 return (CKR_CRYPTOKI_NOT_INITIALIZED);
445 /* Obtain the session pointer */
446 HANDLE2SESSION(hSession, sessp, rv);
448 if (rv != CKR_OK) {
449 return (rv);
452 rv = FUNCLIST(sessp->se_slotid)->C_Logout(sessp->se_handle);
454 /* Present consistent interface to the application */
455 if (rv == CKR_FUNCTION_NOT_SUPPORTED) {
456 return (CKR_FUNCTION_FAILED);
459 return (rv);