diff options
Diffstat (limited to 'ckcapi-session.c')
-rw-r--r-- | ckcapi-session.c | 168 |
1 files changed, 150 insertions, 18 deletions
diff --git a/ckcapi-session.c b/ckcapi-session.c index dc700c1..1076fbd 100644 --- a/ckcapi-session.c +++ b/ckcapi-session.c @@ -1,10 +1,10 @@ #include <stdlib.h> -#include "cryptoki-capi.h" +#include "ckcapi.h" typedef struct _SessionList { - Session **list; + CkCapiSession **list; size_t lmax; } SessionList; @@ -12,10 +12,10 @@ typedef struct _SessionList { static SessionList the_sessions = { NULL, 0 }; -Session* +CkCapiSession* ckcapi_session_create(void) { - Session* sess = calloc(1, sizeof(Session)); + CkCapiSession* sess = calloc(1, sizeof(CkCapiSession)); if(!sess) return NULL; @@ -31,7 +31,7 @@ ckcapi_session_create(void) } CK_RV -ckcapi_session_register(Session* sess) +ckcapi_session_register(CkCapiSession* sess) { CK_ULONG id = 0; CK_RV ret = CKR_OK; @@ -67,13 +67,13 @@ ckcapi_session_register(Session* sess) /* Couldn't find a handle, reallocate */ if(id == 0) { - Session** buf; + CkCapiSession** buf; size_t oldmax, newmax; oldmax = the_sessions.lmax; newmax = oldmax + 16; - buf = realloc(the_sessions.list, newmax * sizeof(Session*)); + buf = realloc(the_sessions.list, newmax * sizeof(CkCapiSession*)); if(!buf) { DBGS(sess, ("couldn't allocate session list, out of memory")); @@ -116,7 +116,7 @@ ckcapi_session_register(Session* sess) } void -ckcapi_session_destroy(Session* sess) +ckcapi_session_destroy(CkCapiSession* sess) { ASSERT(sess); ASSERT(sess->refs == 0); @@ -141,10 +141,10 @@ ckcapi_session_destroy(Session* sess) } static CK_RV -find_lock_ref_internal(SessionList* sessions, CK_SESSION_HANDLE id, - int remove, Session** sess_ret) +lock_ref_internal(SessionList* sessions, CK_SESSION_HANDLE id, + int remove, CkCapiSession** sess_ret) { - Session *sess; + CkCapiSession *sess; DWORD r; ASSERT(sessions); @@ -185,7 +185,7 @@ find_lock_ref_internal(SessionList* sessions, CK_SESSION_HANDLE id, } } - /* Lock the CallSession */ + /* Lock the CallCkCapiSession */ r = WaitForSingleObject(sess->mutex, INFINITE); ASSERT(r == WAIT_OBJECT_0); @@ -225,7 +225,7 @@ find_lock_ref_internal(SessionList* sessions, CK_SESSION_HANDLE id, } CK_RV -ckcapi_session_find_lock_ref(CK_ULONG id, int remove, Session **sess) +ckcapi_session_get_lock_ref(CK_ULONG id, int remove, CkCapiSession **sess) { /* This must be called without any locks held */ @@ -241,7 +241,7 @@ ckcapi_session_find_lock_ref(CK_ULONG id, int remove, Session **sess) ckcapi_lock_global(); - ret = find_lock_ref_internal (&the_sessions, id, remove, sess); + ret = lock_ref_internal (&the_sessions, id, remove, sess); ckcapi_unlock_global(); @@ -249,9 +249,9 @@ ckcapi_session_find_lock_ref(CK_ULONG id, int remove, Session **sess) } void -ckcapi_session_unref_unlock(Session* sess) +ckcapi_session_unref_unlock(CkCapiSession* sess) { - /* The CallSession must be locked at this point */ + /* The CallCkCapiSession must be locked at this point */ int refs; BOOL r; @@ -284,7 +284,7 @@ ckcapi_session_close_all() /* This must be called without any locks held */ SessionList sessions; - Session *sess; + CkCapiSession *sess; size_t i; CK_RV ret; @@ -313,7 +313,7 @@ ckcapi_session_close_all() if(!sessions.list[i]) continue; - ret = find_lock_ref_internal (&sessions, i, 1, &sess); + ret = lock_ref_internal (&sessions, i, 1, &sess); ASSERT(ret == CKR_OK); ckcapi_session_unref_unlock(sess); @@ -327,3 +327,135 @@ ckcapi_session_close_all() } } +/* ---------------------------------------------------------------------------- + * FIND OPERATION + */ + +static BOOL +get_ulong_attribute(CK_ATTRIBUTE_TYPE type, CK_ATTRIBUTE_PTR templ, + CK_ULONG count, CK_ULONG* val) +{ + CK_ULONG i; + + ASSERT(val); + ASSERT(!count || templ); + + for(i = 0; i < count; ++i) + { + if(templ[i].type == type) + { + *val = *((CK_ULONG*)templ[i].pValue); + return TRUE; + } + } + + return FALSE; +} + +static CK_RV +gather_objects(CkCapiSession* sess, CK_ATTRIBUTE_PTR match, + CK_ULONG count, CkCapiArray* arr) +{ + CK_OBJECT_CLASS ocls = CK_INVALID_HANDLE; + CK_RV ret = CKR_OK; + + get_ulong_attribute(CKA_CLASS, match, count, &ocls); + switch(ocls) + { + /* all different classes */ + case CK_INVALID_HANDLE: + case CKO_CERTIFICATE: + ret = ckcapi_cert_find_all(sess, match, count, arr); + break; + case CKO_PUBLIC_KEY: + case CKO_PRIVATE_KEY: + default: + break; + }; + + return ret; +} + +void +cleanup_find_operation(CkCapiSession* sess) +{ + ASSERT(sess->operation_type == OPERATION_FIND); + if(sess->operation_data) + ckcapi_array_free((CkCapiArray*)sess->operation_data, TRUE); + sess->operation_type = OPERATION_NONE; + sess->operation_data = NULL; + sess->operation_cancel = NULL; +} + +CK_RV +ckcapi_session_find_init(CkCapiSession* sess, CK_ATTRIBUTE_PTR match, + CK_ULONG count) +{ + CkCapiArray* arr; + CK_RV ret; + + ASSERT(sess); + ASSERT(!count || match); + + if(sess->operation_type != OPERATION_NONE) + return CKR_OPERATION_ACTIVE; + + arr = ckcapi_array_new(0, 1, sizeof(CK_OBJECT_HANDLE)); + if(!arr) + return CKR_HOST_MEMORY; + + ret = gather_objects(sess, match, count, arr); + if(ret != CKR_OK) + { + ckcapi_array_free(arr, TRUE); + return ret; + } + + sess->operation_type = OPERATION_FIND; + sess->operation_data = arr; + sess->operation_cancel = cleanup_find_operation; + + return CKR_OK; +} + +CK_RV +ckcapi_session_find(CkCapiSession* sess, CK_OBJECT_HANDLE_PTR objects, + CK_ULONG max_object_count, CK_ULONG_PTR object_count) +{ + CkCapiArray* arr; + size_t i; + + ASSERT(sess); + ASSERT(object_count); + ASSERT(!max_object_count || objects); + + if(sess->operation_type != OPERATION_FIND) + return CKR_OPERATION_NOT_INITIALIZED; + + if(!max_object_count) + { + *object_count = 0; + return CKR_OK; + } + + arr = (CkCapiArray*)sess->operation_data; + *object_count = (max_object_count > arr->len ? arr->len : max_object_count); + for(i = 0; i < *object_count; ++i) + objects[i] = ckcapi_array_index(arr, CK_OBJECT_HANDLE, i); + ckcapi_array_remove_range(arr, 0, *object_count); + + return CKR_OK; +} + +CK_RV +ckcapi_session_find_final(CkCapiSession* sess) +{ + ASSERT(sess); + + if(sess->operation_type != OPERATION_FIND) + return CKR_OPERATION_NOT_INITIALIZED; + + cleanup_find_operation(sess); + return CKR_OK; +} + |