summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaiki Ueno <dueno@redhat.com>2018-02-05 11:57:17 +0100
committerDaiki Ueno <ueno@gnu.org>2018-02-27 12:27:45 +0100
commita0984024470218295d74bed364c37862d4c61d60 (patch)
tree8774e86d111354d31c3d4c7a2c7102355bc4a65b
parentd3a1498ef9b8a626bbd864a6c90e45a6278a0e75 (diff)
filter: Respect CKF_WRITE_PROTECTED setting when allowing a token
-rw-r--r--p11-kit/filter.c48
-rw-r--r--p11-kit/test-filter.c102
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 <stdarg.h>
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);
}