#include "config.h" #include "p11-tests.h" #include static const char *login_pin = NULL; void session_info(CK_SESSION_HANDLE session, CK_SLOT_ID slot, CK_FLAGS flags, CK_STATE state) { CK_SESSION_INFO info; CK_RV rv; if(session == CK_INVALID) return; /** C_GetSessionInfo */ if(p11t_test_unexpected) { /** - Invalid session */ rv = (p11t_module_funcs->C_GetSessionInfo)((CK_SESSION_HANDLE)-33, &info); p11t_check_returns("C_GetSessionInfo: with invalid session", rv, CKR_SESSION_HANDLE_INVALID); /** - NULL arguments */ rv = (p11t_module_funcs->C_GetSessionInfo)(session, NULL); p11t_check_returns("C_GetSessionInfo: with null", rv, CKR_ARGUMENTS_BAD); } /** - Valid call */ rv = (p11t_module_funcs->C_GetSessionInfo)(session, &info); if(!p11t_check_returns("C_GetSessionInfo", rv, CKR_OK)) return; /** - Valid slot id */ p11t_check_ulong("CK_SESSION_INFO.slotID", info.slotID, slot); /** - Valid state for session */ p11t_check_ulong("CK_SESSION_INFO.state", info.state, state); /** - Valid flags for session */ p11t_check_flag("CK_SESSION_INFO.flags", info.flags, flags); } void session_main(CK_SLOT_ID slot) { CK_SESSION_HANDLE session_ro = CK_INVALID; CK_SESSION_HANDLE session_rw = CK_INVALID; CK_SESSION_HANDLE session_ro2 = CK_INVALID; CK_SESSION_INFO info; CK_RV rv; assert(p11t_module_funcs); /** C_OpenSession */ if(p11t_test_unexpected) { /** - Invalid slot */ rv = (p11t_module_funcs->C_OpenSession)((CK_SLOT_ID)-5, CKF_SERIAL_SESSION, NULL, NULL, &session_ro); p11t_check_returns("C_OpenSession: with invalid slot", rv, CKR_SLOT_ID_INVALID); /** - Null arguments */ rv = (p11t_module_funcs->C_OpenSession)(slot, CKF_SERIAL_SESSION, NULL, NULL, NULL); p11t_check_returns("C_OpenSession: with invalid slot", rv, CKR_ARGUMENTS_BAD); /** - No flags */ rv = (p11t_module_funcs->C_OpenSession)(slot, 0, NULL, NULL, &session_ro); p11t_check_returns("C_OpenSession: with 0 flags", rv, CKR_SESSION_PARALLEL_NOT_SUPPORTED); /** - Without serial flag */ rv = (p11t_module_funcs->C_OpenSession)(slot, CKF_RW_SESSION, NULL, NULL, &session_ro); p11t_check_returns("C_OpenSession: with RW flags", rv, CKR_SESSION_PARALLEL_NOT_SUPPORTED); } /** - Valid flags */ rv = (p11t_module_funcs->C_OpenSession)(slot, CKF_SERIAL_SESSION, NULL, NULL, &session_ro); p11t_check_returns("C_OpenSession: with serial flags", rv, CKR_OK); rv = (p11t_module_funcs->C_OpenSession)(slot, CKF_SERIAL_SESSION, NULL, NULL, &session_ro2); p11t_check_returns("C_OpenSession: with serial flags", rv, CKR_OK); /** - Read write session */ rv = (p11t_module_funcs->C_OpenSession)(slot, CKF_SERIAL_SESSION | CKF_RW_SESSION, NULL, NULL, &session_rw); if(rv == CKR_TOKEN_WRITE_PROTECTED) session_rw = CK_INVALID; else p11t_check_returns("C_OpenSession: with read write flags", rv, CKR_OK); /* Test all the sessions and validate their state */ session_info(session_ro, slot, CKF_SERIAL_SESSION, CKS_RO_PUBLIC_SESSION); session_info(session_ro2, slot, CKF_SERIAL_SESSION, CKS_RO_PUBLIC_SESSION); if(session_rw) session_info(session_rw, slot, CKF_SERIAL_SESSION | CKF_RW_SESSION, CKS_RW_PUBLIC_SESSION); /** C_CloseSession */ if(p11t_test_unexpected) { /** - Invalid session */ rv = (p11t_module_funcs->C_CloseSession)((CK_SESSION_HANDLE)-10); p11t_check_returns("C_CloseSession: invalid handle", rv, CKR_SESSION_HANDLE_INVALID); } if(session_ro != CK_INVALID) { /** - Normal call */ rv = (p11t_module_funcs->C_CloseSession)(session_ro); p11t_check_returns("C_CloseSession: valid", rv, CKR_OK); if(p11t_test_unexpected) { /** - Check open session was closed */ rv = (p11t_module_funcs->C_GetSessionInfo)(session_ro, &info); p11t_check_returns("C_GetSessionInfo: after close", rv, CKR_SESSION_HANDLE_INVALID); /** - Close twice */ /* * Note that CKR_SESSION_CLOSED is a valid return in this case. * That should only be returned in the rare case when a session * was closed during the execution of a function. A corner case. */ rv = (p11t_module_funcs->C_CloseSession)(session_ro); p11t_check_returns("C_CloseSession: valid", rv, CKR_SESSION_HANDLE_INVALID); } } if(session_rw != CK_INVALID) { rv = (p11t_module_funcs->C_CloseSession)(session_rw); p11t_check_returns("C_CloseSession: read write", rv, CKR_OK); } /** C_CloseAllSessions */ if(p11t_test_unexpected) { /** - Invalid slot id */ rv = (p11t_module_funcs->C_CloseAllSessions)((CK_SLOT_ID)-34); p11t_check_returns("C_CloseAllSessions: invalid slot", rv, CKR_SLOT_ID_INVALID); } /** - Normal call */ rv = (p11t_module_funcs->C_CloseAllSessions)(slot); p11t_check_returns("C_CloseAllSessions", rv, CKR_OK); if(p11t_test_unexpected) { /** - Check open session was closed */ rv = (p11t_module_funcs->C_GetSessionInfo)(session_ro2, &info); p11t_check_returns("C_GetSessionInfo: after close all", rv, CKR_SESSION_HANDLE_INVALID); /** - Call when no sessions open */ rv = (p11t_module_funcs->C_CloseAllSessions)(slot); p11t_check_returns("C_CloseAllSessions", rv, CKR_OK); } } void session_pin(CK_SLOT_ID slot) { /** C_InitPIN */ /** - Not Implemented */ /** C_SetPIN */ /** - Not Implemented */ } void p11t_session_tests() { CK_ULONG i; for(i = 0; i < p11t_slot_count; ++i) { CK_SLOT_ID slot = p11t_slot_ids[i]; session_pin(slot); session_main(slot); } } void p11t_session_config(const char *name, const char *value) { if(strcmp(name, "login-pin") == 0) login_pin = value; }