From a0984024470218295d74bed364c37862d4c61d60 Mon Sep 17 00:00:00 2001 From: Daiki Ueno Date: Mon, 5 Feb 2018 11:57:17 +0100 Subject: filter: Respect CKF_WRITE_PROTECTED setting when allowing a token --- p11-kit/filter.c | 48 ++++++++++++++++-------- p11-kit/test-filter.c | 102 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 134 insertions(+), 16 deletions(-) diff --git a/p11-kit/filter.c b/p11-kit/filter.c index 09e1a45..a7ffdb7 100644 --- a/p11-kit/filter.c +++ b/p11-kit/filter.c @@ -56,13 +56,18 @@ #include typedef struct { + CK_SLOT_ID slot; + const CK_TOKEN_INFO *token; +} FilterSlot; + +typedef struct { p11_virtual virt; CK_X_FUNCTION_LIST *lower; p11_destroyer destroyer; 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 diff --git a/p11-kit/test-filter.c b/p11-kit/test-filter.c index 74f8d4e..a22f0e1 100644 --- a/p11-kit/test-filter.c +++ b/p11-kit/test-filter.c @@ -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); } -- cgit v1.1