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
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]
23 * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 #pragma ident "%Z%%M% %I% %E% SMI"
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.
43 C_OpenSession(CK_SLOT_ID slotID
, CK_FLAGS flags
, CK_VOID_PTR pApplication
,
44 CK_NOTIFY Notify
, CK_SESSION_HANDLE_PTR phSession
)
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
));
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
);
78 /* Check that slotID is valid */
79 if (pkcs11_validate_and_convert_slotid(slotID
, &fw_st_id
)
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 */
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
);
102 rv
= pkcs11_session_add(slottable
->st_slots
[fw_st_id
],
103 fw_st_id
, phSession
, prov_sess
);
107 /* Trouble in the framework, clean up provider session */
108 FUNCLIST(slotID
)->C_CloseSession(prov_sess
);
114 * C_CloseSession will close a session with the underlying provider,
115 * and if that's successful will close it in the framework.
118 C_CloseSession(CK_SESSION_HANDLE hSession
)
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
);
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 */
150 /* Delete session from the framework */
151 pkcs11_session_delete(slottable
->st_slots
[sessp
->se_slotid
], sessp
);
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.
164 C_CloseAllSessions(CK_SLOT_ID slotID
)
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(
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 */
211 (void) pthread_mutex_lock(&slotp
->sl_mutex
);
212 sessp
= slotp
->sl_sess_list
;
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
)) {
228 (void) pthread_mutex_unlock(&slotp
->sl_mutex
);
232 /* could not delete sessionlist with provider, return now */
236 /* Delete sessions from the framework */
237 pkcs11_sessionlist_delete(slotp
);
243 * C_GetSessionInfo is a pure wrapper to the underlying provider.
244 * The only argument checked is whether or not hSession is valid.
247 C_GetSessionInfo(CK_SESSION_HANDLE hSession
, CK_SESSION_INFO_PTR pInfo
)
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
265 if (metaslot_enabled
) {
266 pInfo
->slotID
= METASLOT_FRAMEWORK_ID
;
271 if (!pkcs11_initialized
) {
272 return (CKR_CRYPTOKI_NOT_INITIALIZED
);
275 /* Obtain the session pointer */
276 HANDLE2SESSION(hSession
, sessp
, 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
;
301 * C_GetOperationState is a pure wrapper to the underlying provider.
302 * The only argument checked is whether or not hSession is valid.
305 C_GetOperationState(CK_SESSION_HANDLE hSession
, CK_BYTE_PTR pOperationState
,
306 CK_ULONG_PTR pulOperationStateLen
)
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
);
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
);
343 * C_SetOperationState is a pure wrapper to the underlying provider.
344 * The only argument checked is whether or not hSession is valid.
347 C_SetOperationState(CK_SESSION_HANDLE hSession
, CK_BYTE_PTR pOperationState
,
348 CK_ULONG ulOperationStateLen
, CK_OBJECT_HANDLE hEncryptionKey
,
349 CK_OBJECT_HANDLE hAuthenticationKey
)
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
);
372 /* Set the operation state with the provider */
373 rv
= FUNCLIST(sessp
->se_slotid
)->C_SetOperationState(sessp
->se_handle
,
374 pOperationState
, ulOperationStateLen
, hEncryptionKey
,
377 /* Present consistent interface to the application */
378 if (rv
== CKR_FUNCTION_NOT_SUPPORTED
) {
379 return (CKR_FUNCTION_FAILED
);
387 * C_Login is a pure wrapper to the underlying provider.
388 * The only argument checked is whether or not hSession is valid.
391 C_Login(CK_SESSION_HANDLE hSession
, CK_USER_TYPE userType
,
392 CK_UTF8CHAR_PTR pPin
, CK_ULONG ulPinLen
)
395 pkcs11_session_t
*sessp
;
397 /* Check for a fastpath */
398 if (purefastpath
|| policyfastpath
) {
399 return (fast_funcs
->C_Login(hSession
, userType
, pPin
,
403 if (!pkcs11_initialized
) {
404 return (CKR_CRYPTOKI_NOT_INITIALIZED
);
407 /* Obtain the session pointer */
408 HANDLE2SESSION(hSession
, sessp
, 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
);
427 * C_Logout is a pure wrapper to the underlying provider.
428 * The only argument checked is whether or not hSession is valid.
431 C_Logout(CK_SESSION_HANDLE hSession
)
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
);
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
);