summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ckcapi-session.c36
-rw-r--r--ckcapi-session.h7
-rw-r--r--ckcapi.c22
3 files changed, 50 insertions, 15 deletions
diff --git a/ckcapi-session.c b/ckcapi-session.c
index 1fdb07e..f4f00aa 100644
--- a/ckcapi-session.c
+++ b/ckcapi-session.c
@@ -214,7 +214,7 @@ ckcapi_session_destroy(CkCapiSession* sess)
static CK_RV
lock_ref_internal(CkCapiArray* sessions, CK_SESSION_HANDLE id,
- int remove, CkCapiSession** sess_ret)
+ BOOL remove, BOOL writable, CkCapiSession** sess_ret)
{
CkCapiSession *sess;
DWORD r;
@@ -238,6 +238,10 @@ lock_ref_internal(CkCapiArray* sessions, CK_SESSION_HANDLE id,
return CKR_SESSION_HANDLE_INVALID;
}
+ /* Make sure it's the right kind of session */
+ if(writable && !sess->read_write)
+ return CKR_SESSION_READ_ONLY;
+
ASSERT(sess->id == id);
/* Closing takes precedence over active operations */
@@ -297,7 +301,31 @@ lock_ref_internal(CkCapiArray* sessions, CK_SESSION_HANDLE id,
}
CK_RV
-ckcapi_session_get_lock_ref(CK_ULONG id, int remove, CkCapiSession **sess)
+ckcapi_session_get_lock_ref(CK_ULONG id, BOOL writable, CkCapiSession **sess)
+{
+ /* This must be called without any locks held */
+
+ CK_RV ret = CKR_OK;
+
+ ASSERT(sess);
+
+ if(id <= 0)
+ {
+ DBG(("invalid session id passed: %d", id));
+ return CKR_ARGUMENTS_BAD;
+ }
+
+ ckcapi_lock_global();
+
+ ret = lock_ref_internal (all_sessions, id, FALSE, writable, sess);
+
+ ckcapi_unlock_global();
+
+ return ret;
+}
+
+CK_RV
+ckcapi_session_remove_lock_ref(CK_ULONG id, CkCapiSession **sess)
{
/* This must be called without any locks held */
@@ -313,7 +341,7 @@ ckcapi_session_get_lock_ref(CK_ULONG id, int remove, CkCapiSession **sess)
ckcapi_lock_global();
- ret = lock_ref_internal (all_sessions, id, remove, sess);
+ ret = lock_ref_internal (all_sessions, id, TRUE, FALSE, sess);
ckcapi_unlock_global();
@@ -414,7 +442,7 @@ ckcapi_session_close_all(CK_SLOT_ID slot)
continue;
/* We need any calls in other threads to finish, so wait here */
- if(lock_ref_internal(sessions, i, 1, &sess) == CKR_OK)
+ if(lock_ref_internal(sessions, i, TRUE, FALSE, &sess) == CKR_OK)
ckcapi_session_unref_unlock(sess);
}
diff --git a/ckcapi-session.h b/ckcapi-session.h
index 4fb68fa..7b71c07 100644
--- a/ckcapi-session.h
+++ b/ckcapi-session.h
@@ -34,6 +34,8 @@ typedef struct _CkCapiSession
HCERTSTORE store; /* Handle to an open certificate store */
+ BOOL read_write; /* A read-write session? */
+
int operation_type; /* Whether an operation is happening or not */
void* operation_data; /* Data for this operation */
CkCapiSessionCancel operation_cancel; /* Callback to cancel operation when necessary */
@@ -62,9 +64,12 @@ void ckcapi_session_destroy (CkCapiSession* sess);
CK_RV ckcapi_session_register (CkCapiSession* sess);
/* Get a session from a handle, and lock it */
-CK_RV ckcapi_session_get_lock_ref (CK_ULONG id, int remove,
+CK_RV ckcapi_session_get_lock_ref (CK_ULONG id, BOOL writable,
CkCapiSession **sess);
+/* Get a session from a handle, remove it from list, and lock it */
+CK_RV ckcapi_session_remove_lock_ref (CK_ULONG id, CkCapiSession **sess);
+
/* Unlock and unreference a session */
void ckcapi_session_unref_unlock (CkCapiSession* sess);
diff --git a/ckcapi.c b/ckcapi.c
index 1bc6dd9..378746e 100644
--- a/ckcapi.c
+++ b/ckcapi.c
@@ -595,6 +595,9 @@ CC_C_OpenSession(CK_SLOT_ID id, CK_FLAGS flags, CK_VOID_PTR application,
sess->notify_callback = notify;
sess->user_data = application;
+ if(flags & CKF_RW_SESSION)
+ sess->read_write = TRUE;
+
ret = ckcapi_session_register(sess);
if(ret == CKR_OK)
{
@@ -619,8 +622,7 @@ CC_C_CloseSession(CK_SESSION_HANDLE session)
ENTER(C_CloseSession);
PREREQ(cryptoki_initialized, CKR_CRYPTOKI_NOT_INITIALIZED);
- /* The 'remove' flag removes it from the main session list */
- ret = ckcapi_session_get_lock_ref(session, 1, &sess);
+ ret = ckcapi_session_remove_lock_ref(session, &sess);
if(ret == CKR_OK)
{
/* This will unref and possibly destroy the session */
@@ -794,7 +796,7 @@ CC_C_GetAttributeValue(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE object,
PREREQ(object, CKR_OBJECT_HANDLE_INVALID);
PREREQ(!count || templ, CKR_ARGUMENTS_BAD);
- ret = ckcapi_session_get_lock_ref(session, 0, &sess);
+ ret = ckcapi_session_get_lock_ref(session, FALSE, &sess);
if(ret == CKR_OK)
{
ret = ckcapi_session_get_object_data_for(sess, object, &objdata);
@@ -829,7 +831,7 @@ CC_C_FindObjectsInit(CK_SESSION_HANDLE session, CK_ATTRIBUTE_PTR templ,
PREREQ(cryptoki_initialized, CKR_CRYPTOKI_NOT_INITIALIZED);
PREREQ(!count || templ, CKR_ARGUMENTS_BAD);
- ret = ckcapi_session_get_lock_ref(session, 0, &sess);
+ ret = ckcapi_session_get_lock_ref(session, FALSE, &sess);
if(ret == CKR_OK)
{
ret = ckcapi_session_find_init(sess, templ, count);
@@ -851,7 +853,7 @@ CC_C_FindObjects(CK_SESSION_HANDLE session, CK_OBJECT_HANDLE_PTR objects,
PREREQ(object_count, CKR_ARGUMENTS_BAD);
PREREQ(!max_object_count || objects, CKR_ARGUMENTS_BAD);
- ret = ckcapi_session_get_lock_ref(session, 0, &sess);
+ ret = ckcapi_session_get_lock_ref(session, FALSE, &sess);
if(ret == CKR_OK)
{
ret = ckcapi_session_find(sess, objects, max_object_count, object_count);
@@ -870,7 +872,7 @@ CC_C_FindObjectsFinal(CK_SESSION_HANDLE session)
ENTER(C_FindObjectsFinal);
PREREQ(cryptoki_initialized, CKR_CRYPTOKI_NOT_INITIALIZED);
- ret = ckcapi_session_get_lock_ref(session, 0, &sess);
+ ret = ckcapi_session_get_lock_ref(session, FALSE, &sess);
if(ret == CKR_OK)
{
ret = ckcapi_session_find_final(sess);
@@ -938,7 +940,7 @@ CC_C_DecryptInit(CK_SESSION_HANDLE session, CK_MECHANISM_PTR mechanism,
PREREQ(mechanism, CKR_ARGUMENTS_BAD);
PREREQ(key, CKR_ARGUMENTS_BAD);
- ret = ckcapi_session_get_lock_ref(session, 0, &sess);
+ ret = ckcapi_session_get_lock_ref(session, FALSE, &sess);
if(ret == CKR_OK)
{
ret = ckcapi_session_get_object_data_for(sess, key, &objdata);
@@ -963,7 +965,7 @@ CC_C_Decrypt(CK_SESSION_HANDLE session, CK_BYTE_PTR encrypted_data,
PREREQ(encrypted_data, CKR_ARGUMENTS_BAD);
PREREQ(encrypted_data_len, CKR_ARGUMENTS_BAD);
- ret = ckcapi_session_get_lock_ref(session, 0, &sess);
+ ret = ckcapi_session_get_lock_ref(session, FALSE, &sess);
if(ret == CKR_OK)
{
ret = ckcapi_session_decrypt(sess, encrypted_data, encrypted_data_len,
@@ -1061,7 +1063,7 @@ CC_C_SignInit(CK_SESSION_HANDLE session, CK_MECHANISM_PTR mechanism,
PREREQ(mechanism, CKR_ARGUMENTS_BAD);
PREREQ(key, CKR_ARGUMENTS_BAD);
- ret = ckcapi_session_get_lock_ref(session, 0, &sess);
+ ret = ckcapi_session_get_lock_ref(session, FALSE, &sess);
if(ret == CKR_OK)
{
ret = ckcapi_session_get_object_data_for(sess, key, &objdata);
@@ -1086,7 +1088,7 @@ CC_C_Sign(CK_SESSION_HANDLE session, CK_BYTE_PTR data, CK_ULONG data_len,
PREREQ(data, CKR_ARGUMENTS_BAD);
PREREQ(data_len, CKR_ARGUMENTS_BAD);
- ret = ckcapi_session_get_lock_ref(session, 0, &sess);
+ ret = ckcapi_session_get_lock_ref(session, FALSE, &sess);
if(ret == CKR_OK)
{
ret = ckcapi_session_sign(sess, data, data_len, signature, signature_len);