/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ /* test-gck-object.c - the GObject PKCS#11 wrapper library Copyright (C) 2011 Collabora Ltd. 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, see . Author: Stef Walter */ #include "config.h" #include "gck/gck.h" #include "gck/gck-mock.h" #include "gck/gck-test.h" #include "egg/egg-testing.h" #include #include #include #include #include typedef struct { GckModule *module; GckSlot *slot; GckSession *session; GckObject *object; } Test; static void setup (Test *test, gconstpointer unused) { GError *err = NULL; GList *slots; /* Successful load */ test->module = gck_module_initialize (_GCK_TEST_MODULE_PATH, NULL, &err); g_assert_no_error (err); g_assert_true (GCK_IS_MODULE (test->module)); slots = gck_module_get_slots (test->module, TRUE); g_assert_nonnull (slots); test->slot = GCK_SLOT (slots->data); g_object_ref (test->slot); g_clear_list (&slots, g_object_unref); test->session = gck_slot_open_session (test->slot, 0, NULL, NULL, &err); g_assert_no_error (err); g_assert_true (GCK_IS_SESSION (test->session)); /* Our module always exports a token object with this */ test->object = gck_object_from_handle (test->session, 2); g_assert_nonnull (test->object); } static void teardown (Test *test, gconstpointer unused) { g_object_unref (test->object); g_object_unref (test->session); g_object_unref (test->slot); g_object_unref (test->module); } static void test_object_props (Test *test, gconstpointer unused) { GckSession *sess; GckModule *mod; CK_OBJECT_HANDLE handle; g_object_get (test->object, "session", &sess, "module", &mod, "handle", &handle, NULL); g_assert_true (test->session == sess); g_object_unref (sess); g_assert_true (test->module == mod); g_object_unref (mod); g_assert_cmpuint (handle, ==, 2); } static void test_object_equals_hash (Test *test, gconstpointer unused) { GckSlot *other_slot; GckSession *other_session; GckObject *other_object; GObject *obj; GError *err = NULL; guint hash; hash = gck_object_hash (test->object); g_assert_cmpuint (hash, !=, 0); g_assert_true (gck_object_equal (test->object, test->object)); other_slot = g_object_new (GCK_TYPE_SLOT, "module", test->module, "handle", GCK_MOCK_SLOT_TWO_ID, NULL); other_session = gck_slot_open_session (other_slot, 0, NULL, NULL, &err); g_assert_no_error (err); g_assert_true (GCK_IS_SESSION (other_session)); other_object = gck_object_from_handle (other_session, gck_object_get_handle (test->object)); g_assert_false (gck_object_equal (test->object, other_object)); g_object_unref (other_slot); g_object_unref (other_session); g_object_unref (other_object); obj = g_object_new (G_TYPE_OBJECT, NULL); g_assert_false (gck_object_equal (test->object, (GckObject *) obj)); g_object_unref (obj); other_object = gck_object_from_handle (test->session, 383838); g_assert_false (gck_object_equal (test->object, other_object)); g_object_unref (other_object); other_object = gck_object_from_handle (test->session, gck_object_get_handle (test->object)); g_assert_true (gck_object_equal (test->object, other_object)); g_object_unref (other_object); } static void fetch_async_result (GObject *source, GAsyncResult *result, gpointer user_data) { *((GAsyncResult**)user_data) = result; g_object_ref (result); egg_test_wait_stop (); } static void test_create_object (Test *test, gconstpointer unused) { GckBuilder builder = GCK_BUILDER_INIT; GAsyncResult *result = NULL; GckAttributes *attrs; GckObject *object; CK_OBJECT_HANDLE last_handle; GError *err = NULL; gck_builder_add_ulong (&builder, CKA_CLASS, CKO_DATA); gck_builder_add_string (&builder, CKA_LABEL, "TEST LABEL"); gck_builder_add_boolean (&builder, CKA_TOKEN, CK_FALSE); gck_builder_add_data (&builder, CKA_VALUE, (const guchar *)"BLAH", 4); attrs = gck_builder_end (&builder); object = gck_session_create_object (test->session, attrs, NULL, &err); g_assert_true (GCK_IS_OBJECT (object)); g_assert_no_error (err); last_handle = gck_object_get_handle (object); g_object_unref (object); /* Using async */ gck_session_create_object_async (test->session, attrs, NULL, fetch_async_result, &result); egg_test_wait_until (500); g_assert_nonnull (result); object = gck_session_create_object_finish (test->session, result, &err); g_object_unref (result); g_assert_no_error (err); g_assert_true (GCK_IS_OBJECT (object)); g_assert_cmpuint (last_handle, !=, gck_object_get_handle (object)); g_object_unref (object); gck_attributes_unref (attrs); } static void test_destroy_object (Test *test, gconstpointer unused) { GckBuilder builder = GCK_BUILDER_INIT; GAsyncResult *result = NULL; GckAttributes *attrs; GckObject *object; GError *err = NULL; gboolean ret; gck_builder_add_ulong (&builder, CKA_CLASS, CKO_DATA); gck_builder_add_string (&builder, CKA_LABEL, "TEST OBJECT"); gck_builder_add_boolean (&builder, CKA_TOKEN, CK_TRUE); attrs = gck_builder_end (&builder); /* Using simple */ object = gck_session_create_object (test->session, attrs, NULL, &err); g_assert_no_error (err); g_assert_true (GCK_IS_OBJECT (object)); ret = gck_object_destroy (object, NULL, &err); g_assert_no_error (err); g_assert_true (ret); g_object_unref (object); /* Using async */ object = gck_session_create_object (test->session, attrs, NULL, &err); g_assert_no_error (err); g_assert_true (GCK_IS_OBJECT (object)); /* Using async */ gck_object_destroy_async (object, NULL, fetch_async_result, &result); egg_test_wait_until (500); g_assert_nonnull (result); ret = gck_object_destroy_finish (object, result, &err); g_object_unref (result); g_assert_no_error (err); g_assert_true (ret); g_object_unref (object); gck_attributes_unref (attrs); } static void test_get_attributes (Test *test, gconstpointer unused) { GAsyncResult *result = NULL; GckAttributes *attrs; gulong attr_types[2]; GError *err = NULL; gulong klass; gchar *value = NULL; attr_types[0] = CKA_CLASS; attr_types[1] = CKA_LABEL; /* Simple */ attrs = gck_object_get (test->object, NULL, &err, CKA_CLASS, CKA_LABEL, GCK_INVALID); g_assert_no_error (err); if (attrs != NULL) { g_assert_true (gck_attributes_find_ulong (attrs, CKA_CLASS, &klass) && klass == CKO_DATA); g_assert_true (gck_attributes_find_string (attrs, CKA_LABEL, &value) && strcmp (value, "TEST LABEL") == 0); g_free (value); value = NULL; } gck_attributes_unref (attrs); /* Full */ attrs = gck_object_get_full (test->object, attr_types, G_N_ELEMENTS (attr_types), NULL, &err); g_assert_no_error (err); g_assert_nonnull (attrs); g_assert_true (gck_attributes_find_ulong (attrs, CKA_CLASS, &klass) && klass == CKO_DATA); g_assert_true (gck_attributes_find_string (attrs, CKA_LABEL, &value) && strcmp (value, "TEST LABEL") == 0); g_free (value); value = NULL; gck_attributes_unref (attrs); /* Async */ gck_object_get_async (test->object, attr_types, G_N_ELEMENTS (attr_types), NULL, fetch_async_result, &result); egg_test_wait_until (500); g_assert_nonnull (result); attrs = gck_object_get_finish (test->object, result, &err); g_object_unref (result); g_assert_no_error (err); g_assert_nonnull (attrs); g_assert_true (gck_attributes_find_ulong (attrs, CKA_CLASS, &klass) && klass == CKO_DATA); g_assert_true (gck_attributes_find_string (attrs, CKA_LABEL, &value) && strcmp (value, "TEST LABEL") == 0); g_free (value); value = NULL; gck_attributes_unref (attrs); } static void test_get_data_attribute (Test *test, gconstpointer unused) { GAsyncResult *result = NULL; CK_OBJECT_CLASS_PTR klass; gsize n_data; GError *err = NULL; /* Simple */ klass = (gulong *)gck_object_get_data (test->object, CKA_CLASS, NULL, &n_data, &err); g_assert_no_error (err); g_assert_nonnull (klass); g_assert_cmpuint (n_data, ==, sizeof (CK_OBJECT_CLASS)); g_assert_true (*klass == CKO_DATA); g_free (klass); /* Full */ klass = (gulong *)gck_object_get_data_full (test->object, CKA_CLASS, NULL, NULL, &n_data, &err); g_assert_no_error (err); g_assert_nonnull (klass); g_assert_cmpuint (n_data, ==, sizeof (CK_OBJECT_CLASS)); g_assert_true (*klass == CKO_DATA); g_free (klass); /* Async */ gck_object_get_data_async (test->object, CKA_CLASS, NULL, NULL, fetch_async_result, &result); egg_test_wait_until (500); g_assert_nonnull (result); klass = (gulong *)gck_object_get_data_finish (test->object, result, &n_data, &err); g_object_unref (result); g_assert_no_error (err); g_assert_nonnull (klass); g_assert_cmpuint (n_data, ==, sizeof (CK_OBJECT_CLASS)); g_assert_true (*klass == CKO_DATA); g_free (klass); } static void test_set_attributes (Test *test, gconstpointer unused) { GckBuilder builder = GCK_BUILDER_INIT; GAsyncResult *result = NULL; GckAttributes *attrs; GError *err = NULL; gulong klass; gchar *value = NULL; gboolean ret; gck_builder_add_ulong (&builder, CKA_CLASS, 6); gck_builder_add_string (&builder, CKA_LABEL, "CHANGE TWO"); /* Full */ attrs = gck_builder_end (&builder); ret = gck_object_set (test->object, attrs, NULL, &err); gck_attributes_unref (attrs); g_assert_no_error (err); g_assert_true (ret); attrs = gck_object_get (test->object, NULL, &err, CKA_CLASS, CKA_LABEL, GCK_INVALID); g_assert_true (gck_attributes_find_ulong (attrs, CKA_CLASS, &klass) && klass == 6); g_assert_true (gck_attributes_find_string (attrs, CKA_LABEL, &value) && strcmp (value, "CHANGE TWO") == 0); g_free (value); value = NULL; gck_attributes_unref (attrs); gck_builder_add_ulong (&builder, CKA_CLASS, 7); gck_builder_add_string (&builder, CKA_LABEL, "CHANGE THREE"); /* Async */ attrs = gck_builder_end (&builder); gck_object_set_async (test->object, attrs, NULL, fetch_async_result, &result); gck_attributes_unref (attrs); egg_test_wait_until (500); g_assert_nonnull (result); ret = gck_object_set_finish (test->object, result, &err); g_object_unref (result); g_assert_no_error (err); g_assert_true (ret); attrs = gck_object_get (test->object, NULL, &err, CKA_CLASS, CKA_LABEL, GCK_INVALID); g_assert_true (gck_attributes_find_ulong (attrs, CKA_CLASS, &klass) && klass == 7); g_assert_true (gck_attributes_find_string (attrs, CKA_LABEL, &value) && strcmp (value, "CHANGE THREE") == 0); g_free (value); value = NULL; gck_attributes_unref (attrs); } static void test_find_objects (Test *test, gconstpointer unused) { GckBuilder builder = GCK_BUILDER_INIT; GAsyncResult *result = NULL; GckAttributes *attributes; GList *objects; GckObject *testobj; GError *err = NULL; gck_builder_add_ulong (&builder, CKA_CLASS, CKO_DATA); gck_builder_add_string (&builder, CKA_LABEL, "UNIQUE LABEL"); attributes = gck_builder_end (&builder); testobj = gck_session_create_object (test->session, attributes, NULL, &err); gck_attributes_unref (attributes); g_object_unref (testobj); gck_builder_add_ulong (&builder, CKA_CLASS, CKO_DATA); gck_builder_add_string (&builder, CKA_LABEL, "OTHER LABEL"); attributes = gck_builder_end (&builder); testobj = gck_session_create_object (test->session, attributes, NULL, &err); gck_attributes_unref (attributes); g_object_unref (testobj); /* Simple, "TEST LABEL" */ gck_builder_add_string (&builder, CKA_LABEL, "UNIQUE LABEL"); attributes = gck_builder_end (&builder); objects = gck_session_find_objects (test->session, attributes, NULL, &err); gck_attributes_unref (attributes); g_assert_no_error (err); g_assert_cmpuint (g_list_length (objects), ==, 1); g_clear_list (&objects, g_object_unref); /* Full, All */ attributes = gck_builder_end (&builder); objects = gck_session_find_objects (test->session, attributes, NULL, &err); gck_attributes_unref (attributes); g_assert_no_error (err); g_assert_cmpuint (g_list_length (objects), >, 1); g_clear_list (&objects, g_object_unref); /* Async, None */ gck_builder_add_string (&builder, CKA_LABEL, "blah blah"); attributes = gck_builder_end (&builder); gck_session_find_objects_async (test->session, attributes, NULL, fetch_async_result, &result); gck_attributes_unref (attributes); egg_test_wait_until (500); g_assert_nonnull (result); objects = gck_session_find_objects_finish (test->session, result, &err); g_object_unref (result); g_assert_null (objects); g_clear_list (&objects, g_object_unref); } int main (int argc, char **argv) { g_test_init (&argc, &argv, NULL); g_test_add ("/gck/object/object_props", Test, NULL, setup, test_object_props, teardown); g_test_add ("/gck/object/object_equals_hash", Test, NULL, setup, test_object_equals_hash, teardown); g_test_add ("/gck/object/create_object", Test, NULL, setup, test_create_object, teardown); g_test_add ("/gck/object/destroy_object", Test, NULL, setup, test_destroy_object, teardown); g_test_add ("/gck/object/get_attributes", Test, NULL, setup, test_get_attributes, teardown); g_test_add ("/gck/object/get_data_attribute", Test, NULL, setup, test_get_data_attribute, teardown); g_test_add ("/gck/object/set_attributes", Test, NULL, setup, test_set_attributes, teardown); g_test_add ("/gck/object/find_objects", Test, NULL, setup, test_find_objects, teardown); return egg_tests_run_with_loop (); }