]> granicus.if.org Git - p11-kit/commitdiff
filter: Respect CKF_WRITE_PROTECTED setting when allowing a token
authorDaiki Ueno <dueno@redhat.com>
Mon, 5 Feb 2018 10:57:17 +0000 (11:57 +0100)
committerDaiki Ueno <ueno@gnu.org>
Tue, 27 Feb 2018 11:27:45 +0000 (12:27 +0100)
p11-kit/filter.c
p11-kit/test-filter.c

index 09e1a452c8967cca3e874c925fc0b0074c0ba571..a7ffdb716f3bd1e26be14d41c99c1aa5942741f5 100644 (file)
 #include <errno.h>
 #include <stdarg.h>
 
+typedef struct {
+       CK_SLOT_ID slot;
+       const CK_TOKEN_INFO *token;
+} FilterSlot;
+
 typedef struct {
        p11_virtual virt;
        CK_X_FUNCTION_LIST *lower;
@@ -62,7 +67,7 @@ typedef struct {
        p11_array *entries;
        bool allowed;
        bool initialized;
-       CK_SLOT_ID *slots;
+       FilterSlot *slots;
        CK_ULONG n_slots;
        CK_ULONG max_slots;
 } FilterData;
@@ -70,7 +75,7 @@ typedef struct {
 extern int p11_match_uri_token_info (CK_TOKEN_INFO_PTR one,
                                     CK_TOKEN_INFO_PTR two);
 
-static bool
+static const CK_TOKEN_INFO *
 filter_match_token (FilterData *filter, CK_TOKEN_INFO *token)
 {
        unsigned int i;
@@ -81,23 +86,25 @@ filter_match_token (FilterData *filter, CK_TOKEN_INFO *token)
 
                if ((filter->allowed && matched) ||
                    (!filter->allowed && !matched))
-                       return true;
+                       return entry;
        }
 
-       return false;
+       return NULL;
 }
 
 static bool
-filter_add_slot (FilterData *filter, CK_SLOT_ID slot)
+filter_add_slot (FilterData *filter, CK_SLOT_ID slot, const CK_TOKEN_INFO *token)
 {
        if (filter->n_slots >= filter->max_slots) {
                filter->max_slots = filter->max_slots * 2 + 1;
                filter->slots = realloc (filter->slots,
-                                        filter->max_slots * sizeof (CK_SLOT_ID));
+                                        filter->max_slots * sizeof (FilterSlot));
                if (filter->slots == NULL)
                        return false;
        }
-       filter->slots[filter->n_slots++] = slot;
+       filter->slots[filter->n_slots].slot = slot;
+       filter->slots[filter->n_slots].token = token;
+       filter->n_slots++;
        return true;
 }
 
@@ -132,13 +139,15 @@ filter_ensure (FilterData *filter)
        p11_kit_iter_begin_with (iter, lower, 0, CK_INVALID_HANDLE);
        while (p11_kit_iter_next (iter) == CKR_OK) {
                CK_TOKEN_INFO *token;
+               const CK_TOKEN_INFO *match;
 
                token = p11_kit_iter_get_token (iter);
-               if (filter_match_token (filter, token)) {
+               match = filter_match_token (filter, token);
+               if (match) {
                        CK_SLOT_ID slot;
 
                        slot = p11_kit_iter_get_slot (iter);
-                       if (!filter_add_slot (filter, slot)) {
+                       if (!filter_add_slot (filter, slot, match)) {
                                rv = CKR_HOST_MEMORY;
                                goto out;
                        }
@@ -232,7 +241,7 @@ filter_C_GetSlotInfo (CK_X_FUNCTION_LIST *self,
        if (slotID >= filter->n_slots)
                return CKR_SLOT_ID_INVALID;
 
-       return filter->lower->C_GetSlotInfo (filter->lower, filter->slots[slotID], pInfo);
+       return filter->lower->C_GetSlotInfo (filter->lower, filter->slots[slotID].slot, pInfo);
 }
 
 static CK_RV
@@ -245,7 +254,7 @@ filter_C_GetTokenInfo (CK_X_FUNCTION_LIST *self,
        if (slotID >= filter->n_slots)
                return CKR_SLOT_ID_INVALID;
 
-       return filter->lower->C_GetTokenInfo (filter->lower, filter->slots[slotID], pInfo);
+       return filter->lower->C_GetTokenInfo (filter->lower, filter->slots[slotID].slot, pInfo);
 }
 
 static CK_RV
@@ -260,7 +269,7 @@ filter_C_GetMechanismList (CK_X_FUNCTION_LIST *self,
                return CKR_SLOT_ID_INVALID;
 
        return filter->lower->C_GetMechanismList (filter->lower,
-                                                 filter->slots[slotID],
+                                                 filter->slots[slotID].slot,
                                                  pMechanismList,
                                                  pulCount);
 }
@@ -277,7 +286,7 @@ filter_C_GetMechanismInfo (CK_X_FUNCTION_LIST *self,
                return CKR_SLOT_ID_INVALID;
 
        return filter->lower->C_GetMechanismInfo (filter->lower,
-                                                 filter->slots[slotID],
+                                                 filter->slots[slotID].slot,
                                                  type,
                                                  pInfo);
 }
@@ -294,7 +303,10 @@ filter_C_InitToken (CK_X_FUNCTION_LIST *self,
        if (slotID >= filter->n_slots)
                return CKR_SLOT_ID_INVALID;
 
-       return filter->lower->C_InitToken (filter->lower, filter->slots[slotID],
+       if (filter->slots[slotID].token->flags & CKF_WRITE_PROTECTED)
+               return CKR_TOKEN_WRITE_PROTECTED;
+
+       return filter->lower->C_InitToken (filter->lower, filter->slots[slotID].slot,
                                           pPin, ulPinLen, pLabel);
 }
 
@@ -320,8 +332,12 @@ filter_C_OpenSession (CK_X_FUNCTION_LIST *self,
        if (slotID >= filter->n_slots)
                return CKR_SLOT_ID_INVALID;
 
+       if ((flags & CKF_RW_SESSION) &&
+           (filter->slots[slotID].token->flags & CKF_WRITE_PROTECTED))
+               return CKR_TOKEN_WRITE_PROTECTED;
+
        return filter->lower->C_OpenSession (filter->lower,
-                                            filter->slots[slotID], flags,
+                                            filter->slots[slotID].slot, flags,
                                             pApplication, Notify,
                                             phSession);
 }
@@ -336,7 +352,7 @@ filter_C_CloseAllSessions (CK_X_FUNCTION_LIST *self,
                return CKR_SLOT_ID_INVALID;
 
        return filter->lower->C_CloseAllSessions (filter->lower,
-                                                 filter->slots[slotID]);
+                                                 filter->slots[slotID].slot);
 }
 
 void
index 74f8d4e0ad6ace51d8f77fe38c9e3db4efa4863f..a22f0e169ac6f09ff88c4f117578174ea5b8c710 100644 (file)
@@ -196,6 +196,107 @@ test_denied (void)
        p11_filter_release (filter);
 }
 
+static void
+test_write_protected (void)
+{
+       CK_FUNCTION_LIST_PTR module;
+       CK_SLOT_ID slots[1], slot;
+       CK_SLOT_INFO slot_info;
+       CK_TOKEN_INFO token_info;
+       CK_TOKEN_INFO token_one;
+       CK_MECHANISM_TYPE mechs[8];
+       CK_MECHANISM_INFO mech;
+       CK_SESSION_HANDLE session = 0;
+       p11_virtual virt;
+       p11_virtual *filter;
+       CK_ULONG count;
+       CK_RV rv;
+
+       p11_virtual_init (&virt, &p11_virtual_base, &mock_module, NULL);
+       filter = p11_filter_subclass (&virt, NULL);
+       module = p11_virtual_wrap (filter, (p11_destroyer)p11_virtual_uninit);
+       assert_ptr_not_null (module);
+
+       memcpy (&token_one, &TOKEN_ONE, sizeof (CK_TOKEN_INFO));
+       token_one.flags |= CKF_WRITE_PROTECTED;
+
+       p11_filter_allow_token (filter, &token_one);
+
+       rv = (module->C_Initialize) (NULL);
+       assert_num_eq (CKR_OK, rv);
+
+       rv = (module->C_GetSlotList) (CK_TRUE, NULL, NULL);
+       assert_num_eq (CKR_ARGUMENTS_BAD, rv);
+
+       rv = (module->C_GetSlotList) (CK_TRUE, NULL, &count);
+       assert_num_eq (CKR_OK, rv);
+       assert_num_eq (count, 1);
+
+       count = 0;
+       rv = (module->C_GetSlotList) (CK_TRUE, slots, &count);
+       assert_num_eq (CKR_BUFFER_TOO_SMALL, rv);
+
+       count = 1;
+       rv = (module->C_GetSlotList) (CK_TRUE, slots, &count);
+       assert_num_eq (CKR_OK, rv);
+       assert_num_eq (count, 1);
+
+       rv = (module->C_GetSlotInfo) (99, &slot_info);
+       assert_num_eq (CKR_SLOT_ID_INVALID, rv);
+
+       rv = (module->C_GetSlotInfo) (slots[0], &slot_info);
+       assert_num_eq (CKR_OK, rv);
+
+       rv = (module->C_GetTokenInfo) (99, &token_info);
+       assert_num_eq (CKR_SLOT_ID_INVALID, rv);
+
+       rv = (module->C_GetTokenInfo) (slots[0], &token_info);
+       assert_num_eq (CKR_OK, rv);
+
+       rv = (module->C_GetMechanismList) (99, NULL, &count);
+       assert_num_eq (CKR_SLOT_ID_INVALID, rv);
+
+       rv = (module->C_GetMechanismList) (slots[0], NULL, &count);
+       assert_num_eq (CKR_OK, rv);
+
+       rv = (module->C_GetMechanismList) (slots[0], mechs, &count);
+       assert_num_eq (CKR_OK, rv);
+       assert_num_eq (2, count);
+
+       rv = (module->C_GetMechanismInfo) (99, mechs[0], &mech);
+       assert_num_eq (CKR_SLOT_ID_INVALID, rv);
+
+       rv = (module->C_GetMechanismInfo) (slots[0], mechs[0], &mech);
+       assert_num_eq (CKR_OK, rv);
+
+       rv = (module->C_InitToken) (99, (CK_UTF8CHAR_PTR)"TEST PIN", 8, (CK_UTF8CHAR_PTR)"TEST LABEL");
+       assert_num_eq (CKR_SLOT_ID_INVALID, rv);
+
+       rv = (module->C_InitToken) (slots[0], (CK_UTF8CHAR_PTR)"TEST PIN", 8, (CK_UTF8CHAR_PTR)"TEST LABEL");
+       assert_num_eq (CKR_TOKEN_WRITE_PROTECTED, rv);
+
+       rv = (module->C_WaitForSlotEvent) (0, &slot, NULL);
+       assert_num_eq (CKR_FUNCTION_NOT_SUPPORTED, rv);
+
+       rv = (module->C_OpenSession) (99, CKF_SERIAL_SESSION | CKF_RW_SESSION, NULL, NULL, &session);
+       assert_num_eq (CKR_SLOT_ID_INVALID, rv);
+
+       rv = (module->C_OpenSession) (slots[0], CKF_SERIAL_SESSION | CKF_RW_SESSION, NULL, NULL, &session);
+       assert_num_eq (CKR_TOKEN_WRITE_PROTECTED, rv);
+
+       rv = (module->C_CloseAllSessions) (99);
+       assert_num_eq (CKR_SLOT_ID_INVALID, rv);
+
+       rv = (module->C_CloseAllSessions) (slots[0]);
+       assert_num_eq (CKR_OK, rv);
+
+       rv = (module->C_Finalize) (NULL);
+       assert_num_eq (CKR_OK, rv);
+
+       p11_virtual_unwrap (module);
+       p11_filter_release (filter);
+}
+
 int
 main (int argc,
       char *argv[])
@@ -205,6 +306,7 @@ main (int argc,
 
        p11_test (test_allowed, "/filter/test_allowed");
        p11_test (test_denied, "/filter/test_denied");
+       p11_test (test_write_protected, "/filter/test_write_protected");
 
        return p11_test_run (argc, argv);
 }