summaryrefslogtreecommitdiff
path: root/trust
diff options
context:
space:
mode:
Diffstat (limited to 'trust')
-rw-r--r--trust/module.c88
-rw-r--r--trust/session.h1
-rw-r--r--trust/tests/test-module.c38
3 files changed, 100 insertions, 27 deletions
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);
}