diff options
author | Stef Walter <stefw@gnome.org> | 2014-03-04 16:12:16 +0100 |
---|---|---|
committer | Stef Walter <stefw@gnome.org> | 2014-03-05 13:02:15 +0100 |
commit | 50e0feec5d80263ba2c65d005290a3e9837905f4 (patch) | |
tree | b014be9d7a182affbd4440a5c7ac59fb79f0bbde /pkcs11/gkm/test-memory-store.c | |
parent | beea17679b71bdcb5363bc5844f1ed826d4424be (diff) |
Makefile.am: Move tests into same directories as tested code
This allows for a cleaner build tree, and will provide benefits
when moving to a single Makefile.
Diffstat (limited to 'pkcs11/gkm/test-memory-store.c')
-rw-r--r-- | pkcs11/gkm/test-memory-store.c | 483 |
1 files changed, 483 insertions, 0 deletions
diff --git a/pkcs11/gkm/test-memory-store.c b/pkcs11/gkm/test-memory-store.c new file mode 100644 index 00000000..54566764 --- /dev/null +++ b/pkcs11/gkm/test-memory-store.c @@ -0,0 +1,483 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* unit-test-memory-test->store.c: Test memory test->store functionality + + Copyright (C) 2008 Stefan Walter + + The Gnome Keyring Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Keyring Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + <http://www.gnu.org/licenses/>. + + Author: Stef Walter <stef@memberwebs.com> +*/ + +#include "config.h" + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <unistd.h> + +#include "mock-module.h" + +#include "egg/egg-secure-memory.h" +#include "gkm/gkm-object.h" +#include "gkm/gkm-memory-store.h" +#include "gkm/gkm-transaction.h" + +typedef struct { + GkmModule *module; + GkmStore *store; + GkmObject *object; + GkmTransaction *transaction; + guchar buffer[1024]; +} Test; + +static CK_RV +check_validator (GkmObject *obj, CK_ATTRIBUTE_PTR attr) +{ + const gchar *data; + guint i; + + g_assert (attr); + g_assert (attr->type == CKA_LABEL); + + /* Test that the whole string is ascii and lower case */ + data = attr->pValue; + for (i = 0; i < attr->ulValueLen; ++i) { + if (!g_ascii_isprint(data[i]) || !g_ascii_islower (data[i])) + return CKR_ATTRIBUTE_VALUE_INVALID; + } + + return CKR_OK; +} + +static void +setup (Test *test, gconstpointer unused) +{ + CK_ATTRIBUTE attr; + CK_ULONG twentyfour = 24; + + test->module = mock_module_initialize_and_enter (); + + attr.type = CKA_LABEL; + attr.pValue = "label"; + attr.ulValueLen = 5; + + test->store = GKM_STORE (gkm_memory_store_new ()); + + gkm_store_register_schema (test->store, &attr, check_validator, 0); + g_assert (gkm_store_lookup_schema (test->store, CKA_LABEL, NULL)); + + attr.type = CKA_VALUE; + attr.pValue = NULL; + attr.ulValueLen = 0; + + gkm_store_register_schema (test->store, &attr, NULL, GKM_STORE_IS_SENSITIVE); + + attr.type = CKA_BITS_PER_PIXEL; + attr.pValue = &twentyfour; + attr.ulValueLen = sizeof (twentyfour); + + gkm_store_register_schema (test->store, &attr, NULL, GKM_STORE_IS_INTERNAL); + + test->object = g_object_new (GKM_TYPE_OBJECT, "module", test->module, NULL); + + test->transaction = gkm_transaction_new (); +} + +static void +teardown (Test *test, gconstpointer unused) +{ + g_object_unref (test->store); + test->store = NULL; + + g_object_unref (test->transaction); + test->transaction = NULL; + + if (test->object != NULL) + g_object_unref (test->object); + test->object = NULL; + + mock_module_leave_and_finalize (); + test->module = NULL; +} + +static void +test_get_attribute_default (Test *test, gconstpointer unused) +{ + CK_ATTRIBUTE attr; + CK_RV rv; + + attr.type = CKA_LABEL; + attr.pValue = NULL; + rv = gkm_store_get_attribute (test->store, test->object, &attr); + g_assert (rv == CKR_OK); + g_assert (attr.ulValueLen == 5); + attr.pValue = test->buffer; + rv = gkm_store_get_attribute (test->store, test->object, &attr); + g_assert (rv == CKR_OK); + g_assert (attr.ulValueLen == 5); + g_assert (memcmp (attr.pValue, "label", 5) == 0); +} + +static void +test_read_value_default (Test *test, gconstpointer unused) +{ + gconstpointer value; + gsize n_value; + + value = gkm_store_read_value (test->store, test->object, CKA_LABEL, &n_value); + g_assert (value); + g_assert (n_value == 5); + g_assert (memcmp (value, "label", 5) == 0); + + value = gkm_store_read_value (test->store, test->object, CKA_BITS_PER_PIXEL, &n_value); + g_assert (value); + g_assert (n_value == sizeof (CK_ULONG)); + g_assert (*((CK_ULONG_PTR)value) == 24); +} + +static void +test_read_string (Test *test, gconstpointer unused) +{ + gchar *str; + + str = gkm_store_read_string (test->store, test->object, CKA_LABEL); + g_assert_cmpstr (str, ==, "label"); + g_free (str); +} + +static void +test_get_invalid (Test *test, gconstpointer unused) +{ + CK_ATTRIBUTE attr; + CK_RV rv; + + attr.type = CKA_APPLICATION; + attr.pValue = NULL; + attr.ulValueLen = 0; + + rv = gkm_store_get_attribute (test->store, test->object, &attr); + g_assert (rv == CKR_ATTRIBUTE_TYPE_INVALID); +} + +static void +test_get_sensitive (Test *test, gconstpointer unused) +{ + CK_ATTRIBUTE attr; + CK_RV rv; + + attr.type = CKA_VALUE; + attr.pValue = NULL; + attr.ulValueLen = 0; + + rv = gkm_store_get_attribute (test->store, test->object, &attr); + g_assert (rv == CKR_ATTRIBUTE_SENSITIVE); +} + +static void +test_get_internal (Test *test, gconstpointer unused) +{ + CK_ATTRIBUTE attr; + CK_RV rv; + + attr.type = CKA_BITS_PER_PIXEL; + attr.pValue = NULL; + attr.ulValueLen = 0; + + rv = gkm_store_get_attribute (test->store, test->object, &attr); + g_assert (rv == CKR_ATTRIBUTE_TYPE_INVALID); +} + +static void +test_set_invalid (Test *test, gconstpointer unused) +{ + CK_ATTRIBUTE attr; + + attr.type = CKA_APPLICATION; + attr.pValue = "me"; + attr.ulValueLen = 2; + + gkm_store_set_attribute (test->store, test->transaction, test->object, &attr); + g_assert (gkm_transaction_get_result (test->transaction) == CKR_ATTRIBUTE_TYPE_INVALID); +} + +static void +test_set_internal (Test *test, gconstpointer unused) +{ + CK_ATTRIBUTE attr; + CK_ULONG five = 5; + + attr.type = CKA_BITS_PER_PIXEL; + attr.pValue = &five; + attr.ulValueLen = sizeof (five); + + gkm_store_set_attribute (test->store, test->transaction, test->object, &attr); + g_assert (gkm_transaction_get_result (test->transaction) == CKR_ATTRIBUTE_TYPE_INVALID); +} + +static void +test_set_get_attribute (Test *test, gconstpointer unused) +{ + CK_ATTRIBUTE attr; + CK_RV rv; + + attr.type = CKA_LABEL; + attr.pValue = "booyah"; + attr.ulValueLen = 6; + + gkm_store_set_attribute (test->store, test->transaction, test->object, &attr); + + gkm_transaction_complete (test->transaction); + g_assert (gkm_transaction_get_result (test->transaction) == CKR_OK); + + attr.pValue = test->buffer; + attr.ulValueLen = 1024; + rv = gkm_store_get_attribute (test->store, test->object, &attr); + g_assert (rv == CKR_OK); + g_assert (attr.ulValueLen == 6); + g_assert (memcmp (attr.pValue, "booyah", 6) == 0); +} + +static void +test_write_read_value (Test *test, gconstpointer unused) +{ + CK_ATTRIBUTE attr; + CK_ULONG five = 5; + gconstpointer value; + gsize n_value; + + attr.type = CKA_BITS_PER_PIXEL; + attr.pValue = &five; + attr.ulValueLen = sizeof (five); + + gkm_store_write_value (test->store, test->transaction, test->object, &attr); + + gkm_transaction_complete (test->transaction); + g_assert (gkm_transaction_get_result (test->transaction) == CKR_OK); + + value = gkm_store_read_value (test->store, test->object, CKA_BITS_PER_PIXEL, &n_value); + g_assert (value); + g_assert (n_value == sizeof (five)); + g_assert (memcmp (value, &five, sizeof (five)) == 0); +} + +static void +test_set_no_validate (Test *test, gconstpointer unused) +{ + CK_ATTRIBUTE attr; + + attr.type = CKA_LABEL; + attr.pValue = "CAPITALS"; + attr.ulValueLen = 8; + + gkm_store_set_attribute (test->store, test->transaction, test->object, &attr); + g_assert (gkm_transaction_get_failed (test->transaction)); + + gkm_transaction_complete (test->transaction); + g_assert (gkm_transaction_get_result (test->transaction) == CKR_ATTRIBUTE_VALUE_INVALID); +} + +static void +test_set_transaction_default (Test *test, gconstpointer unused) +{ + CK_ATTRIBUTE attr; + gconstpointer value; + gsize n_value; + + + attr.type = CKA_LABEL; + attr.pValue = "another"; + attr.ulValueLen = 7; + + /* Change the attribute */ + gkm_store_set_attribute (test->store, test->transaction, test->object, &attr); + g_assert (gkm_transaction_get_failed (test->transaction) == FALSE); + + /* Should get new value */ + value = gkm_store_read_value (test->store, test->object, CKA_LABEL, &n_value); + g_assert (value && n_value == attr.ulValueLen); + g_assert (memcmp (attr.pValue, value, n_value) == 0); + + /* Fail for some arbitrary reason */ + gkm_transaction_fail (test->transaction, CKR_ATTRIBUTE_VALUE_INVALID); + + /* Value should not have changed yet */ + value = gkm_store_read_value (test->store, test->object, CKA_LABEL, &n_value); + g_assert (value && n_value == attr.ulValueLen); + g_assert (memcmp (attr.pValue, value, n_value) == 0); + + /* Now complete the test->transaction */ + gkm_transaction_complete (test->transaction); + g_assert (gkm_transaction_get_failed (test->transaction) == TRUE); + + /* Value should now have changed, back to default */ + value = gkm_store_read_value (test->store, test->object, CKA_LABEL, &n_value); + g_assert (value && n_value == 5); + g_assert (memcmp (value, "label", 5) == 0); +} + +static void +test_set_transaction_revert_first (Test *test, gconstpointer unused) +{ + CK_ATTRIBUTE attr, prev; + gconstpointer value; + gsize n_value; + + prev.type = CKA_LABEL; + prev.pValue = "numberone"; + prev.ulValueLen = 9; + + /* Change the attribute */ + gkm_store_set_attribute (test->store, test->transaction, test->object, &prev); + gkm_transaction_complete (test->transaction); + g_assert (gkm_transaction_get_failed (test->transaction) == FALSE); + + /* Value should be new value */ + value = gkm_store_read_value (test->store, test->object, CKA_LABEL, &n_value); + g_assert (value && n_value == prev.ulValueLen); + g_assert (memcmp (prev.pValue, value, n_value) == 0); + + /* A new test->transaction */ + g_object_unref (test->transaction); + test->transaction = gkm_transaction_new (); + + attr.type = CKA_LABEL; + attr.pValue = "second"; + attr.ulValueLen = 6; + + gkm_store_set_attribute (test->store, test->transaction, test->object, &attr); + g_assert (gkm_transaction_get_failed (test->transaction) == FALSE); + + /* Should get new value */ + value = gkm_store_read_value (test->store, test->object, CKA_LABEL, &n_value); + g_assert (value && n_value == attr.ulValueLen); + g_assert (memcmp (attr.pValue, value, n_value) == 0); + + attr.type = CKA_LABEL; + attr.pValue = "third"; + attr.ulValueLen = 5; + + gkm_store_set_attribute (test->store, test->transaction, test->object, &attr); + g_assert (gkm_transaction_get_failed (test->transaction) == FALSE); + + /* Should get new value */ + value = gkm_store_read_value (test->store, test->object, CKA_LABEL, &n_value); + g_assert (value && n_value == attr.ulValueLen); + g_assert (memcmp (attr.pValue, value, n_value) == 0); + + /* Fail for some arbitrary reason */ + gkm_transaction_fail (test->transaction, CKR_ATTRIBUTE_VALUE_INVALID); + + /* Value should not have changed yet */ + value = gkm_store_read_value (test->store, test->object, CKA_LABEL, &n_value); + g_assert (value && n_value == attr.ulValueLen); + g_assert (memcmp (attr.pValue, value, n_value) == 0); + + /* Now complete the test->transaction */ + gkm_transaction_complete (test->transaction); + g_assert (gkm_transaction_get_failed (test->transaction) == TRUE); + + /* Value should now have changed, back to default */ + value = gkm_store_read_value (test->store, test->object, CKA_LABEL, &n_value); + g_assert (value && n_value == prev.ulValueLen); + g_assert (memcmp (prev.pValue, value, n_value) == 0); +} + +static void +notify_attribute (GkmObject *obj, CK_ATTRIBUTE_TYPE type, gpointer data) +{ + g_assert (type == CKA_LABEL); + g_assert (data); + + *((CK_ATTRIBUTE_TYPE*)data) = type; +} + +static void +test_set_notifies (Test *test, gconstpointer unused) +{ + CK_ATTRIBUTE attr; + CK_ATTRIBUTE_TYPE type = 0; + + attr.type = CKA_LABEL; + attr.pValue = "valid"; + attr.ulValueLen = 5; + + g_signal_connect (test->object, "notify-attribute", G_CALLBACK (notify_attribute), &type); + + gkm_store_set_attribute (test->store, test->transaction, test->object, &attr); + + /* We should have been notified that the attribute changed at this point */ + g_assert (type == CKA_LABEL); + + /* Reset for next notify */ + type = 0; + + /* Fail for some arbitrary reason */ + gkm_transaction_fail (test->transaction, CKR_ATTRIBUTE_VALUE_INVALID); + + /* We should not have been notified yet */ + g_assert (type == 0); + + /* Now complete the test->transaction */ + gkm_transaction_complete (test->transaction); + g_assert (gkm_transaction_get_failed (test->transaction) == TRUE); + + /* Now we should have been notified that this changed back */ + g_assert (type == CKA_LABEL); +} + +static void +test_set_object_gone_first (Test *test, gconstpointer unused) +{ + CK_ATTRIBUTE attr; + + attr.type = CKA_LABEL; + attr.pValue = "valid"; + attr.ulValueLen = 5; + + gkm_store_set_attribute (test->store, test->transaction, test->object, &attr); + gkm_transaction_complete (test->transaction); + g_assert (gkm_transaction_get_result (test->transaction) == CKR_OK); + + /* This tests memory test->store internal tracking */ + g_object_unref (test->object); + test->object = NULL; +} + +int +main (int argc, char **argv) +{ +#if !GLIB_CHECK_VERSION(2,35,0) + g_type_init (); +#endif + g_test_init (&argc, &argv, NULL); + + g_test_add ("/gkm/memory-test->store/get_attribute_default", Test, NULL, setup, test_get_attribute_default, teardown); + g_test_add ("/gkm/memory-test->store/read_value_default", Test, NULL, setup, test_read_value_default, teardown); + g_test_add ("/gkm/memory-test->store/read_string", Test, NULL, setup, test_read_string, teardown); + g_test_add ("/gkm/memory-test->store/get_invalid", Test, NULL, setup, test_get_invalid, teardown); + g_test_add ("/gkm/memory-test->store/get_sensitive", Test, NULL, setup, test_get_sensitive, teardown); + g_test_add ("/gkm/memory-test->store/get_internal", Test, NULL, setup, test_get_internal, teardown); + g_test_add ("/gkm/memory-test->store/set_invalid", Test, NULL, setup, test_set_invalid, teardown); + g_test_add ("/gkm/memory-test->store/set_internal", Test, NULL, setup, test_set_internal, teardown); + g_test_add ("/gkm/memory-test->store/set_get_attribute", Test, NULL, setup, test_set_get_attribute, teardown); + g_test_add ("/gkm/memory-test->store/write_read_value", Test, NULL, setup, test_write_read_value, teardown); + g_test_add ("/gkm/memory-test->store/set_no_validate", Test, NULL, setup, test_set_no_validate, teardown); + g_test_add ("/gkm/memory-test->store/set_transaction_default", Test, NULL, setup, test_set_transaction_default, teardown); + g_test_add ("/gkm/memory-test->store/set_transaction_revert_first", Test, NULL, setup, test_set_transaction_revert_first, teardown); + g_test_add ("/gkm/memory-test->store/set_notifies", Test, NULL, setup, test_set_notifies, teardown); + g_test_add ("/gkm/memory-test->store/set_object_gone_first", Test, NULL, setup, test_set_object_gone_first, teardown); + + return g_test_run (); +} |