#include <pthread.h>
#include <security/cryptoki.h>
#include "pkcs11Global.h"
#include "pkcs11Session.h"
#include "pkcs11Slot.h"
#include "metaGlobal.h"
CK_RV
C_OpenSession(CK_SLOT_ID slotID, CK_FLAGS flags, CK_VOID_PTR pApplication,
CK_NOTIFY Notify, CK_SESSION_HANDLE_PTR phSession)
{
CK_RV rv;
CK_SLOT_ID true_id;
CK_SLOT_ID fw_st_id;
CK_SESSION_HANDLE prov_sess;
if (!pkcs11_initialized) {
return (CKR_CRYPTOKI_NOT_INITIALIZED);
}
if (purefastpath || policyfastpath) {
if (metaslot_enabled) {
return (fast_funcs->C_OpenSession(TRUEID(slotID+1),
flags, pApplication, Notify, phSession));
} else {
return (fast_funcs->C_OpenSession(slotID, flags,
pApplication, Notify, phSession));
}
}
if (slotID == METASLOT_FRAMEWORK_ID) {
rv = meta_OpenSession(METASLOT_SLOTID, flags,
pApplication, Notify, &prov_sess);
} else {
if (pkcs11_validate_and_convert_slotid(slotID, &fw_st_id)
!= CKR_OK) {
return (CKR_SLOT_ID_INVALID);
}
true_id = TRUEID(fw_st_id);
rv = FUNCLIST(fw_st_id)->C_OpenSession(true_id, flags,
pApplication, Notify, &prov_sess);
}
if (rv == CKR_FUNCTION_NOT_SUPPORTED) {
return (CKR_FUNCTION_FAILED);
} else if (rv != CKR_OK) {
return (rv);
}
if (slotID == METASLOT_FRAMEWORK_ID) {
rv = pkcs11_session_add(
slottable->st_slots[METASLOT_FRAMEWORK_ID],
METASLOT_FRAMEWORK_ID, phSession, prov_sess);
} else {
rv = pkcs11_session_add(slottable->st_slots[fw_st_id],
fw_st_id, phSession, prov_sess);
}
if (rv != CKR_OK) {
FUNCLIST(slotID)->C_CloseSession(prov_sess);
}
return (rv);
}
CK_RV
C_CloseSession(CK_SESSION_HANDLE hSession)
{
CK_RV rv;
pkcs11_session_t *sessp;
if (purefastpath || policyfastpath) {
return (fast_funcs->C_CloseSession(hSession));
}
if (!pkcs11_initialized) {
return (CKR_CRYPTOKI_NOT_INITIALIZED);
}
HANDLE2SESSION(hSession, sessp, rv);
if (rv != CKR_OK) {
return (rv);
}
rv = FUNCLIST(sessp->se_slotid)->C_CloseSession(sessp->se_handle);
if (rv == CKR_FUNCTION_NOT_SUPPORTED) {
return (CKR_FUNCTION_FAILED);
} else if (rv != CKR_OK) {
return (rv);
}
pkcs11_session_delete(slottable->st_slots[sessp->se_slotid], sessp);
return (rv);
}
CK_RV
C_CloseAllSessions(CK_SLOT_ID slotID)
{
CK_RV rv, rv1;
CK_SLOT_ID true_id;
CK_SLOT_ID fw_st_id;
pkcs11_session_t *sessp, *sess_nextp;
pkcs11_slot_t *slotp;
if (!pkcs11_initialized) {
return (CKR_CRYPTOKI_NOT_INITIALIZED);
}
if (purefastpath || policyfastpath) {
if (metaslot_enabled) {
return (fast_funcs->C_CloseAllSessions(
TRUEID(slotID+1)));
} else {
return (fast_funcs->C_CloseAllSessions(slotID));
}
}
if (pkcs11_validate_and_convert_slotid(slotID, &fw_st_id) != CKR_OK) {
return (CKR_SLOT_ID_INVALID);
}
slotp = slottable->st_slots[fw_st_id];
true_id = TRUEID(fw_st_id);
rv = FUNCLIST(fw_st_id)->C_CloseAllSessions(true_id);
if (rv == CKR_FUNCTION_NOT_SUPPORTED) {
rv = CKR_OK;
(void) pthread_mutex_lock(&slotp->sl_mutex);
sessp = slotp->sl_sess_list;
while (sessp) {
sess_nextp = sessp->se_next;
rv1 = FUNCLIST(fw_st_id)->
C_CloseSession(sessp->se_handle);
if ((rv == CKR_OK) && (rv1 != CKR_OK)) {
rv = rv1;
}
sessp = sess_nextp;
}
(void) pthread_mutex_unlock(&slotp->sl_mutex);
}
if (rv != CKR_OK) {
return (rv);
}
pkcs11_sessionlist_delete(slotp);
return (rv);
}
CK_RV
C_GetSessionInfo(CK_SESSION_HANDLE hSession, CK_SESSION_INFO_PTR pInfo)
{
CK_RV rv;
CK_SLOT_ID slot_id;
pkcs11_session_t *sessp;
if (purefastpath || policyfastpath) {
rv = fast_funcs->C_GetSessionInfo(hSession, pInfo);
if (metaslot_enabled) {
pInfo->slotID = METASLOT_FRAMEWORK_ID;
}
return (rv);
}
if (!pkcs11_initialized) {
return (CKR_CRYPTOKI_NOT_INITIALIZED);
}
HANDLE2SESSION(hSession, sessp, rv);
if (rv != CKR_OK) {
return (rv);
}
slot_id = sessp->se_slotid;
rv = FUNCLIST(slot_id)->
C_GetSessionInfo(sessp->se_handle, pInfo);
if (rv == CKR_FUNCTION_NOT_SUPPORTED) {
return (CKR_FUNCTION_FAILED);
}
pInfo->slotID = slot_id;
return (rv);
}
CK_RV
C_GetOperationState(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pOperationState,
CK_ULONG_PTR pulOperationStateLen)
{
CK_RV rv;
pkcs11_session_t *sessp;
if (purefastpath || policyfastpath) {
return (fast_funcs->C_GetOperationState(hSession,
pOperationState, pulOperationStateLen));
}
if (!pkcs11_initialized) {
return (CKR_CRYPTOKI_NOT_INITIALIZED);
}
HANDLE2SESSION(hSession, sessp, rv);
if (rv != CKR_OK) {
return (rv);
}
rv = FUNCLIST(sessp->se_slotid)->C_GetOperationState(sessp->se_handle,
pOperationState, pulOperationStateLen);
if (rv == CKR_FUNCTION_NOT_SUPPORTED) {
return (CKR_FUNCTION_FAILED);
}
return (rv);
}
CK_RV
C_SetOperationState(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pOperationState,
CK_ULONG ulOperationStateLen, CK_OBJECT_HANDLE hEncryptionKey,
CK_OBJECT_HANDLE hAuthenticationKey)
{
CK_RV rv;
pkcs11_session_t *sessp;
if (purefastpath || policyfastpath) {
return (fast_funcs->C_SetOperationState(hSession,
pOperationState, ulOperationStateLen,
hEncryptionKey, hAuthenticationKey));
}
if (!pkcs11_initialized) {
return (CKR_CRYPTOKI_NOT_INITIALIZED);
}
HANDLE2SESSION(hSession, sessp, rv);
if (rv != CKR_OK) {
return (rv);
}
rv = FUNCLIST(sessp->se_slotid)->C_SetOperationState(sessp->se_handle,
pOperationState, ulOperationStateLen, hEncryptionKey,
hAuthenticationKey);
if (rv == CKR_FUNCTION_NOT_SUPPORTED) {
return (CKR_FUNCTION_FAILED);
}
return (rv);
}
CK_RV
C_Login(CK_SESSION_HANDLE hSession, CK_USER_TYPE userType,
CK_UTF8CHAR_PTR pPin, CK_ULONG ulPinLen)
{
CK_RV rv;
pkcs11_session_t *sessp;
if (purefastpath || policyfastpath) {
return (fast_funcs->C_Login(hSession, userType, pPin,
ulPinLen));
}
if (!pkcs11_initialized) {
return (CKR_CRYPTOKI_NOT_INITIALIZED);
}
HANDLE2SESSION(hSession, sessp, rv);
if (rv != CKR_OK) {
return (rv);
}
rv = FUNCLIST(sessp->se_slotid)->C_Login(sessp->se_handle,
userType, pPin, ulPinLen);
if (rv == CKR_FUNCTION_NOT_SUPPORTED) {
return (CKR_FUNCTION_FAILED);
}
return (rv);
}
CK_RV
C_Logout(CK_SESSION_HANDLE hSession)
{
CK_RV rv;
pkcs11_session_t *sessp;
if (purefastpath || policyfastpath) {
return (fast_funcs->C_Logout(hSession));
}
if (!pkcs11_initialized) {
return (CKR_CRYPTOKI_NOT_INITIALIZED);
}
HANDLE2SESSION(hSession, sessp, rv);
if (rv != CKR_OK) {
return (rv);
}
rv = FUNCLIST(sessp->se_slotid)->C_Logout(sessp->se_handle);
if (rv == CKR_FUNCTION_NOT_SUPPORTED) {
return (CKR_FUNCTION_FAILED);
}
return (rv);
}