]> granicus.if.org Git - p11-kit/commitdiff
trust: Writable module PKCS#11 token functions
authorStef Walter <stef@thewalter.net>
Fri, 14 Jun 2013 20:00:42 +0000 (22:00 +0200)
committerStef Walter <stef@thewalter.net>
Mon, 17 Jun 2013 19:55:34 +0000 (21:55 +0200)
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

common/test.c
trust/module.c
trust/session.h
trust/tests/test-module.c

index 122e78a61bcd8e844bb931fb19c418c23b1112a5..b6ad01287266cfb77816bafdb7de0b563025bc1f 100644 (file)
@@ -200,6 +200,7 @@ p11_test_run (int argc,
        test_item *next;
        int count;
        int ret = 0;
+       int setup;
 
        /* p11-kit specific stuff */
        putenv ("P11_KIT_STRICT=1");
@@ -229,20 +230,27 @@ p11_test_run (int argc,
                assert (item->type == TEST);
                gl.last = item;
                gl.number++;
+               setup = 0;
 
                if (setjmp (gl.jump) == 0) {
                        if (fixture && fixture->x.fix.setup)
                                (fixture->x.fix.setup) (item->x.test.argument);
 
+                       setup = 1;
+
                        assert (item->x.test.func);
                        (item->x.test.func)(item->x.test.argument);
 
-                       if (fixture && fixture->x.fix.teardown)
-                               (fixture->x.fix.teardown) (item->x.test.argument);
-
                        printf ("ok %d %s\n", gl.number, item->x.test.name);
                }
 
+               if (setup) {
+                       if (setjmp (gl.jump) == 0) {
+                               if (fixture && fixture->x.fix.teardown)
+                                       (fixture->x.fix.teardown) (item->x.test.argument);
+                       }
+               }
+
                gl.last = NULL;
        }
 
index ea514b16692ebe8934b66c14b886c4e5b84b26db..5f8692b21ce3f31af98397212601ed9ab3273386 100644 (file)
@@ -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 ();
index b82077024592e345b8bf9abc3fa8b605c59b25b3..ec394b16c327ed55f7f7db323b5c9a85aa8d216f 100644 (file)
@@ -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;
index 910b9b49617db088350d8e407719f9916a7cd379..3d6c00b7430e2648eeec4494db2a374495d80bc7 100644 (file)
@@ -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);
 }