diff options
Diffstat (limited to 'trust')
-rw-r--r-- | trust/tests/test-token.c | 99 | ||||
-rw-r--r-- | trust/token.c | 87 |
2 files changed, 185 insertions, 1 deletions
diff --git a/trust/tests/test-token.c b/trust/tests/test-token.c index 855b56b..965de76 100644 --- a/trust/tests/test-token.c +++ b/trust/tests/test-token.c @@ -658,6 +658,103 @@ test_modify_multiple (void) test_check_attrs (third, parsed->elem[2]); } +static void +test_remove_one (void) +{ + const char *test_data = + "[p11-kit-object-v1]\n" + "class: data\n" + "label: \"first\"\n" + "value: \"1\"\n" + "\n"; + + CK_ATTRIBUTE match = { CKA_LABEL, "first", 5 }; + + CK_OBJECT_HANDLE handle; + CK_RV rv; + + test_write_file (test.directory, "Test.p11-kit", test_data, strlen (test_data)); + test_check_directory (test.directory, ("Test.p11-kit", NULL)); + + /* Reload now that we have this new file */ + p11_token_load (test.token); + + handle = p11_index_find (test.index, &match, 1); + assert_num_cmp (handle, !=, 0); + + rv = p11_index_remove (test.index, handle); + assert_num_eq (rv, CKR_OK); + + /* No other files in the test directory, all files gone */ + test_check_directory (test.directory, (NULL, NULL)); +} + +static void +test_remove_multiple (void) +{ + const char *test_data = + "[p11-kit-object-v1]\n" + "class: data\n" + "label: \"first\"\n" + "value: \"1\"\n" + "\n" + "[p11-kit-object-v1]\n" + "class: data\n" + "label: \"second\"\n" + "value: \"2\"\n" + "\n" + "[p11-kit-object-v1]\n" + "class: data\n" + "label: \"third\"\n" + "value: \"3\"\n"; + + CK_ATTRIBUTE first[] = { + { CKA_CLASS, &data, sizeof (data) }, + { CKA_LABEL, "first", 5 }, + { CKA_VALUE, "1", 1 }, + { CKA_INVALID }, + }; + + CK_ATTRIBUTE third[] = { + { CKA_CLASS, &data, sizeof (data) }, + { CKA_LABEL, "third", 5 }, + { CKA_VALUE, "3", 1 }, + { CKA_INVALID }, + }; + + CK_ATTRIBUTE match = { CKA_LABEL, "second", 6 }; + + CK_OBJECT_HANDLE handle; + p11_array *parsed; + char *path; + int ret; + CK_RV rv; + + test_write_file (test.directory, "Test.p11-kit", test_data, strlen (test_data)); + + /* Reload now that we have this new file */ + p11_token_load (test.token); + + handle = p11_index_find (test.index, &match, 1); + assert_num_cmp (handle, !=, 0); + + rv = p11_index_remove (test.index, handle); + assert_num_eq (rv, CKR_OK); + + /* Now read in the file and make sure it has all the objects */ + path = p11_path_build (test.directory, "Test.p11-kit", NULL); + ret = p11_parse_file (test.parser, path, NULL, 0); + assert_num_eq (ret, P11_PARSE_SUCCESS); + free (path); + + parsed = p11_parser_parsed (test.parser); + assert_num_eq (parsed->num, 2); + + /* The modified one will be first */ + test_check_attrs (first, parsed->elem[0]); + test_check_attrs (third, parsed->elem[1]); +} + int main (int argc, char *argv[]) @@ -685,6 +782,8 @@ main (int argc, p11_test (test_write_new, "/token/write-new"); p11_test (test_write_no_label, "/token/write-no-label"); p11_test (test_modify_multiple, "/token/modify-multiple"); + p11_test (test_remove_one, "/token/remove-one"); + p11_test (test_remove_multiple, "/token/remove-multiple"); return p11_test_run (argc, argv); } diff --git a/trust/token.c b/trust/token.c index eeebb82..15ca018 100644 --- a/trust/token.c +++ b/trust/token.c @@ -479,6 +479,25 @@ check_token_directory (p11_token *token) return token->checked_path; } +static bool +writer_remove_origin (p11_token *token, + CK_ATTRIBUTE *origin) +{ + bool ret = true; + char *path; + + path = strndup (origin->pValue, origin->ulValueLen); + return_val_if_fail (path != NULL, false); + + if (unlink (path) < 0) { + p11_message_err (errno, "couldn't remove file: %s", path); + ret = false; + } + + free (path); + return ret; +} + static p11_save_file * writer_overwrite_origin (p11_token *token, CK_ATTRIBUTE *origin) @@ -701,6 +720,72 @@ on_index_store (void *data, return rv; } +static CK_RV +on_index_remove (void *data, + p11_index *index, + CK_ATTRIBUTE *attrs) +{ + p11_token *token = data; + CK_OBJECT_HANDLE *other; + p11_persist *persist; + p11_buffer buffer; + CK_ATTRIBUTE *origin; + CK_ATTRIBUTE *object; + p11_save_file *file; + CK_RV rv = CKR_OK; + int i; + + /* Signifies that data is being loaded, don't write out */ + if (p11_index_loading (index)) + return CKR_OK; + + if (!check_token_directory (token)) + return CKR_FUNCTION_FAILED; + + /* We should have a file name */ + origin = p11_attrs_find (attrs, CKA_X_ORIGIN); + return_val_if_fail (origin != NULL, CKR_GENERAL_ERROR); + + /* If there are other objects in this file, then rewrite it */ + other = p11_index_find_all (index, origin, 1); + if (other && other[0]) { + file = writer_overwrite_origin (token, origin); + if (file == NULL) { + free (other); + return CKR_GENERAL_ERROR; + } + + persist = p11_persist_new (); + p11_buffer_init (&buffer, 1024); + + rv = writer_put_header (file); + for (i = 0; rv == CKR_OK && other && other[i] != 0; i++) { + object = p11_index_lookup (index, other[i]); + if (object != NULL) + rv = writer_put_object (file, persist, &buffer, object); + } + + if (rv == CKR_OK) { + if (!p11_save_finish_file (file, NULL, true)) + rv = CKR_FUNCTION_FAILED; + } else { + p11_save_finish_file (file, NULL, false); + } + + p11_persist_free (persist); + p11_buffer_uninit (&buffer); + + /* Otherwise just remove the file */ + } else { + if (!writer_remove_origin (token, origin)) + rv = CKR_FUNCTION_FAILED; + } + + free (other); + + return rv; +} + static void on_index_notify (void *data, p11_index *index, @@ -746,7 +831,7 @@ p11_token_new (CK_SLOT_ID slot, token->index = p11_index_new (on_index_build, on_index_store, - NULL, + on_index_remove, on_index_notify, token); return_val_if_fail (token->index != NULL, NULL); |