From 1caa8801f6d888befb3515d24171bf77a172a93c Mon Sep 17 00:00:00 2001 From: Stef Walter Date: Fri, 14 Jun 2013 22:00:42 +0200 Subject: trust: Writable module PKCS#11 token functions Although we don't actually write anything out yet, make the various PKCS#11 functions behave properly when faced with requests to write to token objects --- trust/module.c | 88 ++++++++++++++++++++++++++++++++++++----------- trust/session.h | 1 + trust/tests/test-module.c | 38 ++++++++++++++++---- 3 files changed, 100 insertions(+), 27 deletions(-) (limited to 'trust') diff --git a/trust/module.c b/trust/module.c index ea514b1..5f8692b 100644 --- a/trust/module.c +++ b/trust/module.c @@ -134,6 +134,19 @@ lookup_object_inlock (p11_session *session, return NULL; } +static CK_RV +check_index_writable (p11_session *session, + p11_index *index) +{ + if (index == p11_token_index (session->token)) { + if (!p11_token_is_writable (session->token)) + return CKR_TOKEN_WRITE_PROTECTED; + else if (!session->read_write) + return CKR_SESSION_READ_ONLY; + } + + return CKR_OK; +} static CK_RV lookup_slot_inlock (CK_SLOT_ID id, @@ -610,8 +623,8 @@ sys_C_InitToken (CK_SLOT_ID id, CK_ULONG pin_len, CK_UTF8CHAR_PTR label) { - return_val_if_fail (check_slot (id), CKR_SLOT_ID_INVALID); - return_val_if_reached (CKR_TOKEN_WRITE_PROTECTED); + p11_debug ("not supported"); + return CKR_FUNCTION_NOT_SUPPORTED; } static CK_RV @@ -648,13 +661,16 @@ sys_C_OpenSession (CK_SLOT_ID id, } else if (!(flags & CKF_SERIAL_SESSION)) { rv = CKR_SESSION_PARALLEL_NOT_SUPPORTED; - } else if (flags & CKF_RW_SESSION) { + } else if ((flags & CKF_RW_SESSION) && + !p11_token_is_writable (token)) { rv = CKR_TOKEN_WRITE_PROTECTED; } else { session = p11_session_new (token); if (p11_dict_set (gl.sessions, &session->handle, session)) { rv = CKR_OK; + if (flags & CKF_RW_SESSION) + session->read_write = true; *handle = session->handle; p11_debug ("session: %lu", *handle); } else { @@ -771,7 +787,8 @@ sys_C_InitPIN (CK_SESSION_HANDLE handle, CK_UTF8CHAR_PTR pin, CK_ULONG pin_len) { - return_val_if_reached (CKR_TOKEN_WRITE_PROTECTED); + p11_debug ("not supported"); + return CKR_FUNCTION_NOT_SUPPORTED; } static CK_RV @@ -781,7 +798,8 @@ sys_C_SetPIN (CK_SESSION_HANDLE handle, CK_UTF8CHAR_PTR new_pin, CK_ULONG new_pin_len) { - return_val_if_reached (CKR_TOKEN_WRITE_PROTECTED); + p11_debug ("not supported"); + return CKR_FUNCTION_NOT_SUPPORTED; } static CK_RV @@ -854,7 +872,8 @@ sys_C_CreateObject (CK_SESSION_HANDLE handle, CK_OBJECT_HANDLE_PTR new_object) { p11_session *session; - CK_BBOOL token; + p11_index *index; + CK_BBOOL val; CK_RV rv; return_val_if_fail (new_object != NULL, CKR_ARGUMENTS_BAD); @@ -865,12 +884,15 @@ sys_C_CreateObject (CK_SESSION_HANDLE handle, rv = lookup_session (handle, &session); if (rv == CKR_OK) { - if (p11_attrs_findn_bool (template, count, CKA_TOKEN, &token) && token) - rv = CKR_TOKEN_WRITE_PROTECTED; + if (p11_attrs_findn_bool (template, count, CKA_TOKEN, &val) && val) + index = p11_token_index (session->token); + else + index = session->index; + rv = check_index_writable (session, index); } if (rv == CKR_OK) - rv = p11_index_add (session->index, template, count, new_object); + rv = p11_index_add (index, template, count, new_object); p11_unlock (); @@ -891,6 +913,7 @@ sys_C_CopyObject (CK_SESSION_HANDLE handle, p11_session *session; CK_ATTRIBUTE *original; CK_ATTRIBUTE *attrs; + p11_index *index; CK_BBOOL val; CK_RV rv; @@ -902,21 +925,22 @@ sys_C_CopyObject (CK_SESSION_HANDLE handle, rv = lookup_session (handle, &session); if (rv == CKR_OK) { - original = lookup_object_inlock (session, object, NULL); + original = lookup_object_inlock (session, object, &index); if (original == NULL) rv = CKR_OBJECT_HANDLE_INVALID; } if (rv == CKR_OK) { - if (p11_attrs_findn_bool (template, count, CKA_TOKEN, &val) && val) - rv = CKR_TOKEN_WRITE_PROTECTED; + if (p11_attrs_findn_bool (template, count, CKA_TOKEN, &val)) + index = val ? p11_token_index (session->token) : session->index; + rv = check_index_writable (session, index); } if (rv == CKR_OK) { attrs = p11_attrs_dup (original); attrs = p11_attrs_buildn (attrs, template, count); attrs = p11_attrs_build (attrs, &token, NULL); - rv = p11_index_take (session->index, attrs, new_object); + rv = p11_index_take (index, attrs, new_object); } p11_unlock (); @@ -931,6 +955,9 @@ sys_C_DestroyObject (CK_SESSION_HANDLE handle, CK_OBJECT_HANDLE object) { p11_session *session; + CK_ATTRIBUTE *attrs; + p11_index *index; + CK_BBOOL val; CK_RV rv; p11_debug ("in"); @@ -939,11 +966,19 @@ sys_C_DestroyObject (CK_SESSION_HANDLE handle, rv = lookup_session (handle, &session); if (rv == CKR_OK) { - rv = p11_index_remove (session->index, object); - if (rv == CKR_OBJECT_HANDLE_INVALID) { - if (p11_index_lookup (p11_token_index (session->token), object)) - rv = CKR_TOKEN_WRITE_PROTECTED; + attrs = lookup_object_inlock (session, object, &index); + if (attrs == NULL) + rv = CKR_OBJECT_HANDLE_INVALID; + else + rv = check_index_writable (session, index); + + if (rv == CKR_OK && p11_attrs_find_bool (attrs, CKA_MODIFIABLE, &val) && !val) { + /* TODO: This should be replaced with CKR_ACTION_PROHIBITED */ + rv = CKR_FUNCTION_REJECTED; } + + if (rv == CKR_OK) + rv = p11_index_remove (index, object); } p11_unlock (); @@ -1053,6 +1088,9 @@ sys_C_SetAttributeValue (CK_SESSION_HANDLE handle, CK_ULONG count) { p11_session *session; + CK_ATTRIBUTE *attrs; + p11_index *index; + CK_BBOOL val; CK_RV rv; p11_debug ("in"); @@ -1061,11 +1099,19 @@ sys_C_SetAttributeValue (CK_SESSION_HANDLE handle, rv = lookup_session (handle, &session); if (rv == CKR_OK) { - rv = p11_index_set (session->index, object, template, count); - if (rv == CKR_OBJECT_HANDLE_INVALID) { - if (p11_index_lookup (p11_token_index (session->token), object)) - rv = CKR_TOKEN_WRITE_PROTECTED; + attrs = lookup_object_inlock (session, object, &index); + if (attrs == NULL) { + rv = CKR_OBJECT_HANDLE_INVALID; + + } else if (p11_attrs_find_bool (attrs, CKA_MODIFIABLE, &val) && !val) { + /* TODO: This should be replaced with CKR_ACTION_PROHIBITED */ + rv = CKR_ATTRIBUTE_READ_ONLY; } + + if (rv == CKR_OK) + rv = check_index_writable (session, index); + if (rv == CKR_OK) + rv = p11_index_set (index, object, template, count); } p11_unlock (); diff --git a/trust/session.h b/trust/session.h index b820770..ec394b1 100644 --- a/trust/session.h +++ b/trust/session.h @@ -48,6 +48,7 @@ typedef struct { p11_builder *builder; p11_token *token; CK_BBOOL loaded; + bool read_write; /* Used by various operations */ p11_session_cleanup cleanup; diff --git a/trust/tests/test-module.c b/trust/tests/test-module.c index 910b9b4..3d6c00b 100644 --- a/trust/tests/test-module.c +++ b/trust/tests/test-module.c @@ -148,8 +148,8 @@ setup_writable (void *unused) count = 1; rv = test.module->C_GetSlotList (CK_TRUE, test.slots, &count); - assert (rv == CKR_OK); - assert (count == 1); + assert_num_eq (rv, CKR_OK); + assert_num_eq (count, 1); } static void @@ -762,7 +762,7 @@ test_remove_token (void) CK_ULONG count; CK_RV rv; - rv = test.module->C_OpenSession (test.slots[0], CKF_SERIAL_SESSION, NULL, NULL, &session); + rv = test.module->C_OpenSession (test.slots[0], CKF_SERIAL_SESSION | CKF_RW_SESSION, NULL, NULL, &session); assert (rv == CKR_OK); rv = test.module->C_FindObjectsInit (session, NULL, 0); @@ -773,7 +773,7 @@ test_remove_token (void) assert_num_eq (1, count); rv = test.module->C_DestroyObject (session, handle); - assert (rv == CKR_TOKEN_WRITE_PROTECTED); + assert_num_eq (rv, CKR_FUNCTION_REJECTED); } static void @@ -791,7 +791,7 @@ test_setattr_token (void) CK_ULONG count; CK_RV rv; - rv = test.module->C_OpenSession (test.slots[0], CKF_SERIAL_SESSION, NULL, NULL, &session); + rv = test.module->C_OpenSession (test.slots[0], CKF_SERIAL_SESSION | CKF_RW_SESSION, NULL, NULL, &session); assert (rv == CKR_OK); rv = test.module->C_FindObjectsInit (session, NULL, 0); @@ -802,7 +802,7 @@ test_setattr_token (void) assert_num_eq (1, count); rv = test.module->C_SetAttributeValue (session, handle, original, 2); - assert (rv == CKR_TOKEN_WRITE_PROTECTED); + assert_num_eq (rv, CKR_ATTRIBUTE_READ_ONLY); } static void @@ -1037,6 +1037,31 @@ test_token_writable (void) assert_num_eq (info.flags & CKF_WRITE_PROTECTED, 0); } +static void +test_session_read_only_create (void) +{ + CK_ATTRIBUTE original[] = { + { CKA_CLASS, &data, sizeof (data) }, + { CKA_LABEL, "yay", 3 }, + { CKA_VALUE, "eight", 5 }, + { CKA_TOKEN, &vtrue, sizeof (vtrue) }, + { CKA_INVALID } + }; + + CK_SESSION_HANDLE session; + CK_OBJECT_HANDLE handle; + CK_RV rv; + + /* Read-only session */ + rv = test.module->C_OpenSession (test.slots[0], CKF_SERIAL_SESSION, + NULL, NULL, &session); + assert (rv == CKR_OK); + + /* Create a token object */ + rv = test.module->C_CreateObject (session, original, 4, &handle); + assert_num_eq (rv, CKR_SESSION_READ_ONLY); +} + int main (int argc, char *argv[]) @@ -1072,6 +1097,7 @@ main (int argc, p11_fixture (setup_writable, teardown); p11_test (test_token_writable, "/module/token-writable"); + p11_test (test_session_read_only_create, "/module/session-read-only-create"); return p11_test_run (argc, argv); } -- cgit v1.1