#include "cryptoki.h"
CK_DEFINE_FUNCTION(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 = CKR_OK;
P11_Session *session;
CK_ULONG pin_state;
P11_LOG_START("C_OpenSession");
thread_MutexLock(st.async_lock);
if (CKR_ERROR(rv = slot_TokenChanged()))
rv = CKR_DEVICE_REMOVED;
else if (INVALID_SLOT)
rv = CKR_SLOT_ID_INVALID;
else if (!phSession)
rv = CKR_ARGUMENTS_BAD;
else
{
if (!(flags & CKF_RW_SESSION) && slot_CheckRWSOsession(slotID))
rv = CKR_SESSION_READ_WRITE_SO_EXISTS;
else if (CKR_ERROR(rv = slot_EstablishConnection(slotID)))
;
else if (CKR_ERROR(rv = session_AddSession(phSession)))
;
else
{
log_Log(LOG_LOW, "New session handle: %X", *phSession);
session = (P11_Session *)*phSession;
session->session.slotID = slotID;
pin_state = st.slots[slotID - 1].pin_state;
if (flags & CKF_RW_SESSION)
{
if (pin_state == 1)
session->session.state = CKS_RW_USER_FUNCTIONS;
else if (pin_state == 2)
session->session.state = CKS_RW_SO_FUNCTIONS;
else
session->session.state = CKS_RW_PUBLIC_SESSION;
}
else
{
if (pin_state == 1)
session->session.state = CKS_RO_USER_FUNCTIONS;
else if (pin_state == 2)
session->session.state = CKS_RO_USER_FUNCTIONS;
else
session->session.state = CKS_RO_PUBLIC_SESSION;
}
session->session.flags = flags;
session->session.ulDeviceError = 0x1F;
session->application = pApplication;
session->notify = Notify;
}
}
thread_MutexUnlock(st.async_lock);
P11_LOG_END("C_OpenSession");
return rv;
}
CK_DEFINE_FUNCTION(CK_RV, C_CloseSession)
(
CK_SESSION_HANDLE hSession
)
{
CK_RV rv = CKR_OK;
P11_Session *session = (P11_Session *)hSession;
CK_SLOT_ID slotID = session->session.slotID;
P11_LOG_START("C_CloseSession");
thread_MutexLock(st.async_lock);
if (CKR_ERROR(rv = slot_TokenChanged()))
rv = CKR_DEVICE_REMOVED;
else if (INVALID_SESSION)
rv = CKR_SESSION_HANDLE_INVALID;
else if (!CKR_ERROR(rv = session_FreeSession(hSession)))
rv = slot_ReleaseConnection(slotID);
thread_MutexUnlock(st.async_lock);
P11_LOG_END("C_CloseSession");
return rv;
}
CK_DEFINE_FUNCTION(CK_RV, C_CloseAllSessions)
(
CK_SLOT_ID slotID
)
{
CK_RV rv = CKR_OK;
P11_Session *session_l;
P11_Session *session_l_temp;
P11_LOG_START("C_CloseAllSessions");
if (CKR_ERROR(rv = slot_TokenChanged()))
rv = CKR_DEVICE_REMOVED;
else
{
session_l = st.sessions;
while (session_l)
{
session_l_temp = session_l->next;
if (session_l->session.slotID == slotID)
C_CloseSession((CK_SESSION_HANDLE)session_l);
session_l = session_l_temp;
}
}
P11_LOG_END("C_CloseAllSessions");
return rv;
}
CK_DEFINE_FUNCTION(CK_RV, C_GetSessionInfo)
(
CK_SESSION_HANDLE hSession,
CK_SESSION_INFO_PTR pInfo
)
{
CK_RV rv = CKR_OK;
P11_Session *session = (P11_Session *)hSession;
P11_LOG_START("C_GetSessionInfo");
thread_MutexLock(st.async_lock);
if (CKR_ERROR(rv = slot_TokenChanged()))
rv = CKR_DEVICE_REMOVED;
else if (!pInfo)
rv = CKR_ARGUMENTS_BAD;
else if (INVALID_SESSION)
rv = CKR_SESSION_HANDLE_INVALID;
else
{
log_Log(LOG_LOW, "Session state: %lu", session->session.state);
memcpy(pInfo, &session->session, sizeof(CK_SESSION_INFO));
}
thread_MutexUnlock(st.async_lock);
P11_LOG_END("C_GetSessionInfo");
return rv;
}
CK_DEFINE_FUNCTION(CK_RV, C_GetOperationState)
(
CK_SESSION_HANDLE hSession,
CK_BYTE_PTR pOperationState,
CK_ULONG_PTR pulOperationStateLen
)
{
CK_RV rv = CKR_OK;
P11_LOG_START("C_GetOperationState");
thread_MutexLock(st.async_lock);
rv = CKR_FUNCTION_NOT_SUPPORTED;
log_Log(LOG_MED, "Function not supported");
thread_MutexUnlock(st.async_lock);
P11_LOG_END("C_GetOperationState");
return rv;
}
CK_DEFINE_FUNCTION(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 = CKR_OK;
P11_LOG_START("C_SetOperationState");
thread_MutexLock(st.async_lock);
rv = CKR_FUNCTION_NOT_SUPPORTED;
log_Log(LOG_MED, "Function not supported");
thread_MutexUnlock(st.async_lock);
P11_LOG_END("C_SetOperationState");
return rv;
}
CK_DEFINE_FUNCTION(CK_RV, C_Login)
(
CK_SESSION_HANDLE hSession,
CK_USER_TYPE userType,
CK_UTF8CHAR_PTR pPin,
CK_ULONG ulPinLen
)
{
CK_RV rv = CKR_OK;
P11_Session *session = (P11_Session *)hSession;
P11_LOG_START("C_Login");
thread_MutexLock(st.async_lock);
if (CKR_ERROR(rv = slot_TokenChanged()))
rv = CKR_DEVICE_REMOVED;
else if (!pPin || !ulPinLen)
rv = CKR_ARGUMENTS_BAD;
else if (INVALID_SESSION)
rv = CKR_SESSION_HANDLE_INVALID;
else if (!CKR_ERROR(rv = slot_BeginTransaction(session->session.slotID)))
{
if (userType == CKU_SO)
log_Log(LOG_LOW, "Verifying SO PIN");
else if (userType == CKU_USER)
log_Log(LOG_LOW, "Verifying USER PIN");
else
log_Log(LOG_LOW, "Verifying Unknown user PIN: %lu", userType);
rv = slot_VerifyPIN(session->session.slotID, userType, pPin, ulPinLen);
(void)CKR_ERROR(slot_EndTransaction(session->session.slotID, MSC_LEAVE_TOKEN));
if (rv == CKR_OK)
slot_UserMode(session->session.slotID);
}
thread_MutexUnlock(st.async_lock);
P11_LOG_END("C_Login");
return rv;
}
CK_DEFINE_FUNCTION(CK_RV, C_Logout)
(
CK_SESSION_HANDLE hSession
)
{
CK_RV rv = CKR_OK;
P11_Session *session = (P11_Session *)hSession;
P11_LOG_START("C_Logout");
thread_MutexLock(st.async_lock);
if (CKR_ERROR(rv = slot_TokenChanged()))
rv = CKR_DEVICE_REMOVED;
else if (INVALID_SESSION)
rv = CKR_SESSION_HANDLE_INVALID;
else if (!CKR_ERROR(rv = slot_BeginTransaction(session->session.slotID)))
{
if (rv == CKR_OK)
slot_PublicMode(session->session.slotID);
memset(st.slots[session->session.slotID - 1].pins, 0x00, sizeof(st.slots[session->session.slotID - 1].pins));
if (MSC_ERROR(msc_LogoutAll(&st.slots[session->session.slotID - 1].conn)))
(void)CKR_ERROR(rv = slot_EndTransaction(session->session.slotID, MSC_RESET_TOKEN));
else
(void)CKR_ERROR(rv = slot_EndTransaction(session->session.slotID, MSC_LEAVE_TOKEN));
}
thread_MutexUnlock(st.async_lock);
P11_LOG_END("C_Logout");
return rv;
}