summaryrefslogtreecommitdiff
path: root/p11-kit/tests
diff options
context:
space:
mode:
Diffstat (limited to 'p11-kit/tests')
-rw-r--r--p11-kit/tests/Makefile.am63
-rw-r--r--p11-kit/tests/conf-test.c415
-rw-r--r--p11-kit/tests/files/system-modules/four.module3
-rw-r--r--p11-kit/tests/files/system-modules/one.module3
-rw-r--r--p11-kit/tests/files/system-modules/two-duplicate.module3
-rw-r--r--p11-kit/tests/files/system-modules/two.badname5
-rw-r--r--p11-kit/tests/files/system-modules/win32/four.module3
-rw-r--r--p11-kit/tests/files/system-modules/win32/one.module3
-rw-r--r--p11-kit/tests/files/system-modules/win32/two-duplicate.module3
-rw-r--r--p11-kit/tests/files/system-modules/win32/two.badname5
-rw-r--r--p11-kit/tests/files/system-pkcs11.conf3
-rw-r--r--p11-kit/tests/files/test-1.conf6
-rw-r--r--p11-kit/tests/files/test-pinfile1
-rw-r--r--p11-kit/tests/files/test-pinfile-large53
-rw-r--r--p11-kit/tests/files/test-system-invalid.conf3
-rw-r--r--p11-kit/tests/files/test-system-merge.conf7
-rw-r--r--p11-kit/tests/files/test-system-none.conf8
-rw-r--r--p11-kit/tests/files/test-system-only.conf8
-rw-r--r--p11-kit/tests/files/test-user-invalid.conf3
-rw-r--r--p11-kit/tests/files/test-user-only.conf4
-rw-r--r--p11-kit/tests/files/test-user.conf3
-rw-r--r--p11-kit/tests/files/user-modules/one.module2
-rw-r--r--p11-kit/tests/files/user-modules/three.module5
-rw-r--r--p11-kit/tests/files/user-modules/win32/one.module2
-rw-r--r--p11-kit/tests/files/user-modules/win32/three.module5
-rw-r--r--p11-kit/tests/mock-module-ep.c52
-rw-r--r--p11-kit/tests/mock-module.c898
-rw-r--r--p11-kit/tests/mock-module.h337
-rw-r--r--p11-kit/tests/pin-test.c325
-rw-r--r--p11-kit/tests/print-messages.c137
-rw-r--r--p11-kit/tests/progname-test.c97
-rw-r--r--p11-kit/tests/test-init.c320
-rw-r--r--p11-kit/tests/test-modules.c246
-rw-r--r--p11-kit/tests/uri-test.c1223
34 files changed, 4254 insertions, 0 deletions
diff --git a/p11-kit/tests/Makefile.am b/p11-kit/tests/Makefile.am
new file mode 100644
index 0000000..bd08426
--- /dev/null
+++ b/p11-kit/tests/Makefile.am
@@ -0,0 +1,63 @@
+
+include $(top_srcdir)/build/Makefile.tests
+
+INCLUDES = \
+ -I$(top_srcdir) \
+ -I$(srcdir)/.. \
+ -I$(top_srcdir)/common \
+ $(CUTEST_CFLAGS)
+
+LDADD = \
+ $(top_builddir)/p11-kit/libp11-kit-testable.la \
+ $(CUTEST_LIBS) \
+ $(LTLIBINTL)
+
+CHECK_PROGS = \
+ progname-test \
+ conf-test \
+ uri-test \
+ pin-test \
+ test-init \
+ test-modules
+
+noinst_PROGRAMS = \
+ print-messages \
+ $(CHECK_PROGS)
+
+test_init_SOURCES = test-init.c \
+ mock-module.c mock-module.h
+test_init_CFLAGS = $(AM_CFLAGS)
+
+TESTS = $(CHECK_PROGS:=$(EXEEXT))
+
+noinst_LTLIBRARIES = \
+ mock-one.la \
+ mock-two.la \
+ mock-three.la \
+ mock-four.la
+
+mock_one_la_SOURCES = \
+ mock-module.c mock-module.h \
+ mock-module-ep.c
+
+mock_one_la_LIBADD = \
+ $(top_builddir)/p11-kit/libp11-kit-compat.la
+
+mock_one_la_LDFLAGS = \
+ -module -avoid-version -rpath /nowhere \
+ -no-undefined -export-symbols-regex 'C_GetFunctionList'
+
+mock_two_la_SOURCES = $(mock_one_la_SOURCES)
+mock_two_la_LDFLAGS = $(mock_one_la_LDFLAGS)
+mock_two_la_LIBADD = $(mock_one_la_LIBADD)
+
+mock_three_la_SOURCES = $(mock_one_la_SOURCES)
+mock_three_la_LDFLAGS = $(mock_one_la_LDFLAGS)
+mock_three_la_LIBADD = $(mock_one_la_LIBADD)
+
+mock_four_la_SOURCES = $(mock_one_la_SOURCES)
+mock_four_la_LDFLAGS = $(mock_one_la_LDFLAGS)
+mock_four_la_LIBADD = $(mock_one_la_LIBADD)
+
+EXTRA_DIST = \
+ files
diff --git a/p11-kit/tests/conf-test.c b/p11-kit/tests/conf-test.c
new file mode 100644
index 0000000..4ea1313
--- /dev/null
+++ b/p11-kit/tests/conf-test.c
@@ -0,0 +1,415 @@
+/*
+ * Copyright (c) 2011, Collabora Ltd.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the
+ * following disclaimer.
+ * * Redistributions in binary form must reproduce the
+ * above copyright notice, this list of conditions and
+ * the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ * * The names of contributors to this software may not be
+ * used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
+ * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * Author: Stef Walter <stefw@collabora.co.uk>
+ */
+
+#include "config.h"
+#include "CuTest.h"
+
+#include <errno.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "conf.h"
+#include "library.h"
+#include "p11-kit.h"
+#include "private.h"
+
+static void
+test_parse_conf_1 (CuTest *tc)
+{
+ p11_dict *map;
+ const char *value;
+
+ map = _p11_conf_parse_file (SRCDIR "/files/test-1.conf", 0);
+ CuAssertPtrNotNull (tc, map);
+
+ value = p11_dict_get (map, "key1");
+ CuAssertStrEquals (tc, "value1", value);
+
+ value = p11_dict_get (map, "with-colon");
+ CuAssertStrEquals (tc, "value-of-colon", value);
+
+ value = p11_dict_get (map, "with-whitespace");
+ CuAssertStrEquals (tc, "value-with-whitespace", value);
+
+ value = p11_dict_get (map, "embedded-comment");
+ CuAssertStrEquals (tc, "this is # not a comment", value);
+
+ p11_dict_free (map);
+}
+
+static void
+test_parse_ignore_missing (CuTest *tc)
+{
+ p11_dict *map;
+
+ map = _p11_conf_parse_file (SRCDIR "/files/non-existant.conf", CONF_IGNORE_MISSING);
+ CuAssertPtrNotNull (tc, map);
+
+ CuAssertIntEquals (tc, 0, p11_dict_size (map));
+ CuAssertPtrEquals (tc, NULL, (void*)p11_kit_message ());
+ p11_dict_free (map);
+}
+
+static void
+test_parse_fail_missing (CuTest *tc)
+{
+ p11_dict *map;
+
+ map = _p11_conf_parse_file (SRCDIR "/files/non-existant.conf", 0);
+ CuAssertPtrEquals (tc, map, NULL);
+ CuAssertPtrNotNull (tc, p11_kit_message ());
+}
+
+static void
+test_merge_defaults (CuTest *tc)
+{
+ p11_dict *values;
+ p11_dict *defaults;
+
+ values = p11_dict_new (p11_dict_str_hash, p11_dict_str_equal, free, free);
+ defaults = p11_dict_new (p11_dict_str_hash, p11_dict_str_equal, free, free);
+
+ p11_dict_set (values, strdup ("one"), strdup ("real1"));
+ p11_dict_set (values, strdup ("two"), strdup ("real2"));
+
+ p11_dict_set (defaults, strdup ("two"), strdup ("default2"));
+ p11_dict_set (defaults, strdup ("three"), strdup ("default3"));
+
+ if (_p11_conf_merge_defaults (values, defaults) < 0)
+ CuFail (tc, "should not be reached");
+
+ p11_dict_free (defaults);
+
+ CuAssertStrEquals (tc, p11_dict_get (values, "one"), "real1");
+ CuAssertStrEquals (tc, p11_dict_get (values, "two"), "real2");
+ CuAssertStrEquals (tc, p11_dict_get (values, "three"), "default3");
+
+ p11_dict_free (values);
+}
+
+static void
+test_load_globals_merge (CuTest *tc)
+{
+ int user_mode = -1;
+ p11_dict *config;
+
+ p11_message_clear ();
+
+ config = _p11_conf_load_globals (SRCDIR "/files/test-system-merge.conf",
+ SRCDIR "/files/test-user.conf",
+ &user_mode);
+ CuAssertPtrNotNull (tc, config);
+ CuAssertStrEquals (tc, NULL, p11_kit_message ());
+ CuAssertIntEquals (tc, CONF_USER_MERGE, user_mode);
+
+ CuAssertStrEquals (tc, p11_dict_get (config, "key1"), "system1");
+ CuAssertStrEquals (tc, p11_dict_get (config, "key2"), "user2");
+ CuAssertStrEquals (tc, p11_dict_get (config, "key3"), "user3");
+
+ p11_dict_free (config);
+}
+
+static void
+test_load_globals_no_user (CuTest *tc)
+{
+ int user_mode = -1;
+ p11_dict *config;
+
+ p11_message_clear ();
+
+ config = _p11_conf_load_globals (SRCDIR "/files/test-system-none.conf",
+ SRCDIR "/files/test-user.conf",
+ &user_mode);
+ CuAssertPtrNotNull (tc, config);
+ CuAssertStrEquals (tc, NULL, p11_kit_message ());
+ CuAssertIntEquals (tc, CONF_USER_NONE, user_mode);
+
+ CuAssertStrEquals (tc, p11_dict_get (config, "key1"), "system1");
+ CuAssertStrEquals (tc, p11_dict_get (config, "key2"), "system2");
+ CuAssertStrEquals (tc, p11_dict_get (config, "key3"), "system3");
+
+ p11_dict_free (config);
+}
+
+static void
+test_load_globals_user_sets_only (CuTest *tc)
+{
+ int user_mode = -1;
+ p11_dict *config;
+
+ p11_message_clear ();
+
+ config = _p11_conf_load_globals (SRCDIR "/files/test-system-merge.conf",
+ SRCDIR "/files/test-user-only.conf",
+ &user_mode);
+ CuAssertPtrNotNull (tc, config);
+ CuAssertStrEquals (tc, NULL, p11_kit_message ());
+ CuAssertIntEquals (tc, CONF_USER_ONLY, user_mode);
+
+ CuAssertStrEquals (tc, p11_dict_get (config, "key1"), NULL);
+ CuAssertStrEquals (tc, p11_dict_get (config, "key2"), "user2");
+ CuAssertStrEquals (tc, p11_dict_get (config, "key3"), "user3");
+
+ p11_dict_free (config);
+}
+
+static void
+test_load_globals_system_sets_only (CuTest *tc)
+{
+ int user_mode = -1;
+ p11_dict *config;
+
+ p11_message_clear ();
+
+ config = _p11_conf_load_globals (SRCDIR "/files/test-system-only.conf",
+ SRCDIR "/files/test-user.conf",
+ &user_mode);
+ CuAssertPtrNotNull (tc, config);
+ CuAssertStrEquals (tc, NULL, p11_kit_message ());
+ CuAssertIntEquals (tc, CONF_USER_ONLY, user_mode);
+
+ CuAssertStrEquals (tc, p11_dict_get (config, "key1"), NULL);
+ CuAssertStrEquals (tc, p11_dict_get (config, "key2"), "user2");
+ CuAssertStrEquals (tc, p11_dict_get (config, "key3"), "user3");
+
+ p11_dict_free (config);
+}
+
+static void
+test_load_globals_system_sets_invalid (CuTest *tc)
+{
+ int user_mode = -1;
+ p11_dict *config;
+ int error;
+
+ p11_message_clear ();
+
+ config = _p11_conf_load_globals (SRCDIR "/files/test-system-invalid.conf",
+ SRCDIR "/files/non-existant.conf",
+ &user_mode);
+ error = errno;
+ CuAssertPtrEquals (tc, NULL, config);
+ CuAssertIntEquals (tc, EINVAL, error);
+ CuAssertPtrNotNull (tc, p11_kit_message ());
+
+ p11_dict_free (config);
+}
+
+static void
+test_load_globals_user_sets_invalid (CuTest *tc)
+{
+ int user_mode = -1;
+ p11_dict *config;
+ int error;
+
+ p11_message_clear ();
+
+ config = _p11_conf_load_globals (SRCDIR "/files/test-system-merge.conf",
+ SRCDIR "/files/test-user-invalid.conf",
+ &user_mode);
+ error = errno;
+ CuAssertPtrEquals (tc, NULL, config);
+ CuAssertIntEquals (tc, EINVAL, error);
+ CuAssertPtrNotNull (tc, p11_kit_message ());
+
+ p11_dict_free (config);
+}
+
+static int
+assert_msg_contains (const char *msg,
+ const char *text)
+{
+ if (msg == NULL)
+ return 0;
+ return strstr (msg, text) ? 1 : 0;
+}
+
+static void
+test_load_modules_merge (CuTest *tc)
+{
+ p11_dict *configs;
+ p11_dict *config;
+
+ p11_message_clear ();
+
+ configs = _p11_conf_load_modules (CONF_USER_MERGE,
+ SRCDIR "/files/system-modules",
+ SRCDIR "/files/user-modules");
+ CuAssertPtrNotNull (tc, configs);
+ CuAssertTrue (tc, assert_msg_contains (p11_kit_message (), "invalid config filename"));
+
+ config = p11_dict_get (configs, "one");
+ CuAssertPtrNotNull (tc, config);
+ CuAssertStrEquals (tc, "mock-one.so", p11_dict_get (config, "module"));
+ CuAssertStrEquals (tc, p11_dict_get (config, "setting"), "user1");
+
+ config = p11_dict_get (configs, "two.badname");
+ CuAssertPtrNotNull (tc, config);
+ CuAssertStrEquals (tc, "mock-two.so", p11_dict_get (config, "module"));
+ CuAssertStrEquals (tc, p11_dict_get (config, "setting"), "system2");
+
+ config = p11_dict_get (configs, "three");
+ CuAssertPtrNotNull (tc, config);
+ CuAssertStrEquals (tc, "mock-three.so", p11_dict_get (config, "module"));
+ CuAssertStrEquals (tc, p11_dict_get (config, "setting"), "user3");
+
+ p11_dict_free (configs);
+}
+
+static void
+test_load_modules_user_none (CuTest *tc)
+{
+ p11_dict *configs;
+ p11_dict *config;
+
+ p11_message_clear ();
+
+ configs = _p11_conf_load_modules (CONF_USER_NONE,
+ SRCDIR "/files/system-modules",
+ SRCDIR "/files/user-modules");
+ CuAssertPtrNotNull (tc, configs);
+ CuAssertTrue (tc, assert_msg_contains (p11_kit_message (), "invalid config filename"));
+
+ config = p11_dict_get (configs, "one");
+ CuAssertPtrNotNull (tc, config);
+ CuAssertStrEquals (tc, "mock-one.so", p11_dict_get (config, "module"));
+ CuAssertStrEquals (tc, p11_dict_get (config, "setting"), "system1");
+
+ config = p11_dict_get (configs, "two.badname");
+ CuAssertPtrNotNull (tc, config);
+ CuAssertStrEquals (tc, "mock-two.so", p11_dict_get (config, "module"));
+ CuAssertStrEquals (tc, p11_dict_get (config, "setting"), "system2");
+
+ config = p11_dict_get (configs, "three");
+ CuAssertPtrEquals (tc, NULL, config);
+
+ p11_dict_free (configs);
+}
+
+static void
+test_load_modules_user_only (CuTest *tc)
+{
+ p11_dict *configs;
+ p11_dict *config;
+
+ p11_message_clear ();
+
+ configs = _p11_conf_load_modules (CONF_USER_ONLY,
+ SRCDIR "/files/system-modules",
+ SRCDIR "/files/user-modules");
+ CuAssertPtrNotNull (tc, configs);
+ CuAssertPtrEquals (tc, NULL, (void *)p11_kit_message ());
+
+ config = p11_dict_get (configs, "one");
+ CuAssertPtrNotNull (tc, config);
+ CuAssertStrEquals (tc, p11_dict_get (config, "module"), NULL);
+ CuAssertStrEquals (tc, p11_dict_get (config, "setting"), "user1");
+
+ config = p11_dict_get (configs, "two.badname");
+ CuAssertPtrEquals (tc, NULL, config);
+
+ config = p11_dict_get (configs, "three");
+ CuAssertPtrNotNull (tc, config);
+ CuAssertStrEquals (tc, "mock-three.so", p11_dict_get (config, "module"));
+ CuAssertStrEquals (tc, p11_dict_get (config, "setting"), "user3");
+
+ p11_dict_free (configs);
+}
+
+static void
+test_load_modules_no_user (CuTest *tc)
+{
+ p11_dict *configs;
+ p11_dict *config;
+
+ p11_message_clear ();
+
+ configs = _p11_conf_load_modules (CONF_USER_MERGE,
+ SRCDIR "/files/system-modules",
+ SRCDIR "/files/non-existant");
+ CuAssertPtrNotNull (tc, configs);
+ CuAssertTrue (tc, assert_msg_contains (p11_kit_message (), "invalid config filename"));
+
+ config = p11_dict_get (configs, "one");
+ CuAssertPtrNotNull (tc, config);
+ CuAssertStrEquals (tc, "mock-one.so", p11_dict_get (config, "module"));
+ CuAssertStrEquals (tc, p11_dict_get (config, "setting"), "system1");
+
+ config = p11_dict_get (configs, "two.badname");
+ CuAssertPtrNotNull (tc, config);
+ CuAssertStrEquals (tc, "mock-two.so", p11_dict_get (config, "module"));
+ CuAssertStrEquals (tc, p11_dict_get (config, "setting"), "system2");
+
+ config = p11_dict_get (configs, "three");
+ CuAssertPtrEquals (tc, NULL, config);
+
+ p11_dict_free (configs);
+}
+
+int
+main (void)
+{
+ CuString *output = CuStringNew ();
+ CuSuite* suite = CuSuiteNew ();
+ int ret;
+
+ p11_library_init ();
+
+ SUITE_ADD_TEST (suite, test_parse_conf_1);
+ SUITE_ADD_TEST (suite, test_parse_ignore_missing);
+ SUITE_ADD_TEST (suite, test_parse_fail_missing);
+ SUITE_ADD_TEST (suite, test_merge_defaults);
+ SUITE_ADD_TEST (suite, test_load_globals_merge);
+ SUITE_ADD_TEST (suite, test_load_globals_no_user);
+ SUITE_ADD_TEST (suite, test_load_globals_system_sets_only);
+ SUITE_ADD_TEST (suite, test_load_globals_user_sets_only);
+ SUITE_ADD_TEST (suite, test_load_globals_system_sets_invalid);
+ SUITE_ADD_TEST (suite, test_load_globals_user_sets_invalid);
+ SUITE_ADD_TEST (suite, test_load_modules_merge);
+ SUITE_ADD_TEST (suite, test_load_modules_no_user);
+ SUITE_ADD_TEST (suite, test_load_modules_user_only);
+ SUITE_ADD_TEST (suite, test_load_modules_user_none);
+
+ p11_kit_be_quiet ();
+
+ CuSuiteRun (suite);
+ CuSuiteSummary (suite, output);
+ CuSuiteDetails (suite, output);
+ printf ("%s\n", output->buffer);
+ ret = suite->failCount;
+ CuSuiteDelete (suite);
+ CuStringDelete (output);
+ return ret;
+}
diff --git a/p11-kit/tests/files/system-modules/four.module b/p11-kit/tests/files/system-modules/four.module
new file mode 100644
index 0000000..6eace3c
--- /dev/null
+++ b/p11-kit/tests/files/system-modules/four.module
@@ -0,0 +1,3 @@
+
+module: mock-four.so
+disable-in: test-disable, test-other
diff --git a/p11-kit/tests/files/system-modules/one.module b/p11-kit/tests/files/system-modules/one.module
new file mode 100644
index 0000000..3620869
--- /dev/null
+++ b/p11-kit/tests/files/system-modules/one.module
@@ -0,0 +1,3 @@
+
+module: mock-one.so
+setting: system1 \ No newline at end of file
diff --git a/p11-kit/tests/files/system-modules/two-duplicate.module b/p11-kit/tests/files/system-modules/two-duplicate.module
new file mode 100644
index 0000000..907aa75
--- /dev/null
+++ b/p11-kit/tests/files/system-modules/two-duplicate.module
@@ -0,0 +1,3 @@
+
+# This is a duplicate of the 'two' module
+module: mock-two.so
diff --git a/p11-kit/tests/files/system-modules/two.badname b/p11-kit/tests/files/system-modules/two.badname
new file mode 100644
index 0000000..0d41cac
--- /dev/null
+++ b/p11-kit/tests/files/system-modules/two.badname
@@ -0,0 +1,5 @@
+# This module doesn't have a .module extension, but p11-kit doesn't yet
+# enforce the naming, just warns, so it should still be loaded
+
+module: mock-two.so
+setting: system2
diff --git a/p11-kit/tests/files/system-modules/win32/four.module b/p11-kit/tests/files/system-modules/win32/four.module
new file mode 100644
index 0000000..7fd1540
--- /dev/null
+++ b/p11-kit/tests/files/system-modules/win32/four.module
@@ -0,0 +1,3 @@
+
+module: mock-four.dll
+disable-in: test-disable, test-other
diff --git a/p11-kit/tests/files/system-modules/win32/one.module b/p11-kit/tests/files/system-modules/win32/one.module
new file mode 100644
index 0000000..5f80304
--- /dev/null
+++ b/p11-kit/tests/files/system-modules/win32/one.module
@@ -0,0 +1,3 @@
+
+module: mock-one.dll
+setting: system1 \ No newline at end of file
diff --git a/p11-kit/tests/files/system-modules/win32/two-duplicate.module b/p11-kit/tests/files/system-modules/win32/two-duplicate.module
new file mode 100644
index 0000000..e80c9e8
--- /dev/null
+++ b/p11-kit/tests/files/system-modules/win32/two-duplicate.module
@@ -0,0 +1,3 @@
+
+# This is a duplicate of the 'two' module
+module: mock-two.dll
diff --git a/p11-kit/tests/files/system-modules/win32/two.badname b/p11-kit/tests/files/system-modules/win32/two.badname
new file mode 100644
index 0000000..ae44b83
--- /dev/null
+++ b/p11-kit/tests/files/system-modules/win32/two.badname
@@ -0,0 +1,5 @@
+# This module doesn't have a .module extension, but p11-kit doesn't yet
+# enforce the naming, just warns, so it should still be loaded
+
+module: mock-two.dll
+setting: system2
diff --git a/p11-kit/tests/files/system-pkcs11.conf b/p11-kit/tests/files/system-pkcs11.conf
new file mode 100644
index 0000000..20741e7
--- /dev/null
+++ b/p11-kit/tests/files/system-pkcs11.conf
@@ -0,0 +1,3 @@
+
+# Merge in user config
+user-config: merge \ No newline at end of file
diff --git a/p11-kit/tests/files/test-1.conf b/p11-kit/tests/files/test-1.conf
new file mode 100644
index 0000000..d4ae0a1
--- /dev/null
+++ b/p11-kit/tests/files/test-1.conf
@@ -0,0 +1,6 @@
+key1:value1
+with-whitespace : value-with-whitespace
+with-colon: value-of-colon
+
+# A comment
+embedded-comment: this is # not a comment
diff --git a/p11-kit/tests/files/test-pinfile b/p11-kit/tests/files/test-pinfile
new file mode 100644
index 0000000..f646f3d
--- /dev/null
+++ b/p11-kit/tests/files/test-pinfile
@@ -0,0 +1 @@
+yogabbagabba \ No newline at end of file
diff --git a/p11-kit/tests/files/test-pinfile-large b/p11-kit/tests/files/test-pinfile-large
new file mode 100644
index 0000000..506668d
--- /dev/null
+++ b/p11-kit/tests/files/test-pinfile-large
@@ -0,0 +1,53 @@
+yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba
+yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba
+yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba
+yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba
+yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba
+yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba
+yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba
+yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba
+yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba
+yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba
+yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba
+yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba
+yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba
+yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba
+yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba
+yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba
+yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba
+yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba
+yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba
+yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba
+yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba
+yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba
+yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba
+yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba
+yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba
+yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba
+yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba
+yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba
+yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba
+yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba
+yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba
+yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba
+yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba
+yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba
+yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba
+yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba
+yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba
+yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba
+yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba
+yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba
+yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba
+yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba
+yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba
+yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba
+yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba
+yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba
+yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba
+yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba
+yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba
+yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba
+yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba
+yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba
+yogabbagabba yogabbagabba yogabbagabba yo \ No newline at end of file
diff --git a/p11-kit/tests/files/test-system-invalid.conf b/p11-kit/tests/files/test-system-invalid.conf
new file mode 100644
index 0000000..344ee96
--- /dev/null
+++ b/p11-kit/tests/files/test-system-invalid.conf
@@ -0,0 +1,3 @@
+
+# Invalid user-config setting
+user-config: bad
diff --git a/p11-kit/tests/files/test-system-merge.conf b/p11-kit/tests/files/test-system-merge.conf
new file mode 100644
index 0000000..978427d
--- /dev/null
+++ b/p11-kit/tests/files/test-system-merge.conf
@@ -0,0 +1,7 @@
+
+# Merge in user config
+user-config: merge
+
+key1: system1
+key2: system2
+key3: system3 \ No newline at end of file
diff --git a/p11-kit/tests/files/test-system-none.conf b/p11-kit/tests/files/test-system-none.conf
new file mode 100644
index 0000000..95351e6
--- /dev/null
+++ b/p11-kit/tests/files/test-system-none.conf
@@ -0,0 +1,8 @@
+
+# Only user config
+user-config: none
+
+# These values will not be overriden
+key1: system1
+key2: system2
+key3: system3 \ No newline at end of file
diff --git a/p11-kit/tests/files/test-system-only.conf b/p11-kit/tests/files/test-system-only.conf
new file mode 100644
index 0000000..589f1c7
--- /dev/null
+++ b/p11-kit/tests/files/test-system-only.conf
@@ -0,0 +1,8 @@
+
+# Only user config
+user-config: only
+
+# This stuff will be ignored
+key1: system1
+key2: system2
+key3: system3 \ No newline at end of file
diff --git a/p11-kit/tests/files/test-user-invalid.conf b/p11-kit/tests/files/test-user-invalid.conf
new file mode 100644
index 0000000..344ee96
--- /dev/null
+++ b/p11-kit/tests/files/test-user-invalid.conf
@@ -0,0 +1,3 @@
+
+# Invalid user-config setting
+user-config: bad
diff --git a/p11-kit/tests/files/test-user-only.conf b/p11-kit/tests/files/test-user-only.conf
new file mode 100644
index 0000000..3224c01
--- /dev/null
+++ b/p11-kit/tests/files/test-user-only.conf
@@ -0,0 +1,4 @@
+
+user-config: only
+key2: user2
+key3: user3 \ No newline at end of file
diff --git a/p11-kit/tests/files/test-user.conf b/p11-kit/tests/files/test-user.conf
new file mode 100644
index 0000000..369544a
--- /dev/null
+++ b/p11-kit/tests/files/test-user.conf
@@ -0,0 +1,3 @@
+
+key2: user2
+key3: user3 \ No newline at end of file
diff --git a/p11-kit/tests/files/user-modules/one.module b/p11-kit/tests/files/user-modules/one.module
new file mode 100644
index 0000000..c371e4a
--- /dev/null
+++ b/p11-kit/tests/files/user-modules/one.module
@@ -0,0 +1,2 @@
+
+setting: user1 \ No newline at end of file
diff --git a/p11-kit/tests/files/user-modules/three.module b/p11-kit/tests/files/user-modules/three.module
new file mode 100644
index 0000000..00caab5
--- /dev/null
+++ b/p11-kit/tests/files/user-modules/three.module
@@ -0,0 +1,5 @@
+
+module: mock-three.so
+setting: user3
+
+enable-in: test-enable \ No newline at end of file
diff --git a/p11-kit/tests/files/user-modules/win32/one.module b/p11-kit/tests/files/user-modules/win32/one.module
new file mode 100644
index 0000000..c371e4a
--- /dev/null
+++ b/p11-kit/tests/files/user-modules/win32/one.module
@@ -0,0 +1,2 @@
+
+setting: user1 \ No newline at end of file
diff --git a/p11-kit/tests/files/user-modules/win32/three.module b/p11-kit/tests/files/user-modules/win32/three.module
new file mode 100644
index 0000000..58f883d
--- /dev/null
+++ b/p11-kit/tests/files/user-modules/win32/three.module
@@ -0,0 +1,5 @@
+
+module: mock-three.dll
+setting: user3
+
+enable-in: test-enable \ No newline at end of file
diff --git a/p11-kit/tests/mock-module-ep.c b/p11-kit/tests/mock-module-ep.c
new file mode 100644
index 0000000..7440a74
--- /dev/null
+++ b/p11-kit/tests/mock-module-ep.c
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2012 Stefan Walter
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the
+ * following disclaimer.
+ * * Redistributions in binary form must reproduce the
+ * above copyright notice, this list of conditions and
+ * the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ * * The names of contributors to this software may not be
+ * used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
+ * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * Author: Stef Walter <stef@thewalter.net>
+ */
+
+#include "config.h"
+
+#define CRYPTOKI_EXPORTS 1
+#include "pkcs11.h"
+#include "mock-module.h"
+
+#ifdef OS_WIN32
+__declspec(dllexport)
+#endif
+CK_RV
+C_GetFunctionList (CK_FUNCTION_LIST_PTR_PTR list)
+{
+ mock_module_init ();
+ if (list == NULL)
+ return CKR_ARGUMENTS_BAD;
+ *list = &mock_module_no_slots;
+ return CKR_OK;
+}
diff --git a/p11-kit/tests/mock-module.c b/p11-kit/tests/mock-module.c
new file mode 100644
index 0000000..1a74806
--- /dev/null
+++ b/p11-kit/tests/mock-module.c
@@ -0,0 +1,898 @@
+/*
+ * Copyright (c) 2011, Collabora Ltd.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the
+ * following disclaimer.
+ * * Redistributions in binary form must reproduce the
+ * above copyright notice, this list of conditions and
+ * the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ * * The names of contributors to this software may not be
+ * used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
+ * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * Author: Stef Walter <stefw@collabora.co.uk>
+ */
+
+#include "config.h"
+
+#include "library.h"
+#define CRYPTOKI_EXPORTS
+#include "pkcs11.h"
+
+#include "mock-module.h"
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+/* -------------------------------------------------------------------
+ * GLOBALS / DEFINES
+ */
+
+/* Various mutexes */
+static p11_mutex_t init_mutex;
+
+/* Whether we've been initialized, and on what process id it happened */
+static int pkcs11_initialized = 0;
+static pid_t pkcs11_initialized_pid = 0;
+
+/* -----------------------------------------------------------------------------
+ * LOGGING and DEBUGGING
+ */
+
+#define DEBUG_OUTPUT 0
+
+#if DEBUG_OUTPUT
+#define debug(x) mock_log x
+#else
+#define debug(x)
+#endif
+
+#define warning(x) mock_log x
+
+#define return_val_if_fail(x, v) \
+ if (!(x)) { mock_log ("'%s' not true at %s", #x, __func__); return v; }
+
+static void
+mock_log (const char *format, ...)
+{
+ va_list va;
+ va_start (va, format);
+ fprintf (stderr, "mock-module: ");
+ vfprintf (stderr, format, va);
+ fprintf (stderr, "\n");
+ va_end (va);
+}
+
+/* -------------------------------------------------------------------
+ * INITIALIZATION and 'GLOBAL' CALLS
+ */
+
+CK_RV
+mock_C_Initialize (CK_VOID_PTR init_args)
+{
+ CK_C_INITIALIZE_ARGS_PTR args = NULL;
+ CK_RV ret = CKR_OK;
+ pid_t pid;
+
+ debug (("C_Initialize: enter"));
+
+ p11_mutex_lock (&init_mutex);
+
+ if (init_args != NULL) {
+ int supplied_ok;
+
+ /* pReserved must be NULL */
+ args = init_args;
+
+ /* ALL supplied function pointers need to have the value either NULL or non-NULL. */
+ supplied_ok = (args->CreateMutex == NULL && args->DestroyMutex == NULL &&
+ args->LockMutex == NULL && args->UnlockMutex == NULL) ||
+ (args->CreateMutex != NULL && args->DestroyMutex != NULL &&
+ args->LockMutex != NULL && args->UnlockMutex != NULL);
+ if (!supplied_ok) {
+ warning (("invalid set of mutex calls supplied"));
+ ret = CKR_ARGUMENTS_BAD;
+ goto done;
+ }
+
+ /*
+ * When the CKF_OS_LOCKING_OK flag isn't set return an error.
+ * We must be able to use our pthread functionality.
+ */
+ if (!(args->flags & CKF_OS_LOCKING_OK)) {
+ warning (("can't do without os locking"));
+ ret = CKR_CANT_LOCK;
+ goto done;
+ }
+ }
+
+ pid = getpid ();
+ if (pkcs11_initialized) {
+
+ /* This process has called C_Initialize already */
+ if (pid == pkcs11_initialized_pid) {
+ warning (("C_Initialize called twice for same process"));
+ ret = CKR_CRYPTOKI_ALREADY_INITIALIZED;
+ goto done;
+ }
+ }
+
+done:
+ /* Mark us as officially initialized */
+ if (ret == CKR_OK) {
+ pkcs11_initialized = 1;
+ pkcs11_initialized_pid = pid;
+ } else if (ret != CKR_CRYPTOKI_ALREADY_INITIALIZED) {
+ pkcs11_initialized = 0;
+ pkcs11_initialized_pid = 0;
+ }
+
+ p11_mutex_unlock (&init_mutex);
+
+ debug (("C_Initialize: %d", ret));
+ return ret;
+}
+
+CK_RV
+mock_C_Finalize (CK_VOID_PTR reserved)
+{
+ debug (("C_Finalize: enter"));
+ return_val_if_fail (pkcs11_initialized != 0, CKR_CRYPTOKI_NOT_INITIALIZED);
+ return_val_if_fail (reserved == NULL, CKR_ARGUMENTS_BAD);
+
+ p11_mutex_lock (&init_mutex);
+
+ /* This should stop all other calls in */
+ pkcs11_initialized = 0;
+ pkcs11_initialized_pid = 0;
+
+ p11_mutex_unlock (&init_mutex);
+
+ debug (("C_Finalize: %d", CKR_OK));
+ return CKR_OK;
+}
+
+static const CK_INFO MOCK_INFO = {
+ { CRYPTOKI_VERSION_MAJOR, CRYPTOKI_VERSION_MINOR },
+ "MOCK MANUFACTURER ",
+ 0,
+ "MOCK LIBRARY ",
+ { 45, 145 }
+};
+
+
+CK_RV
+mock_C_GetInfo (CK_INFO_PTR info)
+{
+ return_val_if_fail (info, CKR_ARGUMENTS_BAD);
+
+ memcpy (info, &MOCK_INFO, sizeof (*info));
+ return CKR_OK;
+}
+
+CK_RV
+mock_C_GetFunctionList (CK_FUNCTION_LIST_PTR_PTR list)
+{
+ /* This would be a strange call to receive */
+ return C_GetFunctionList (list);
+}
+
+CK_RV
+mock_C_GetSlotList__no_tokens (CK_BBOOL token_present,
+ CK_SLOT_ID_PTR slot_list,
+ CK_ULONG_PTR count)
+{
+ return_val_if_fail (count, CKR_ARGUMENTS_BAD);
+
+ /* No tokens */
+ *count = 0;
+ return CKR_OK;
+}
+
+CK_RV
+mock_C_GetSlotInfo__invalid_slotid (CK_SLOT_ID id,
+ CK_SLOT_INFO_PTR info)
+{
+ return_val_if_fail (info, CKR_ARGUMENTS_BAD);
+
+ return CKR_SLOT_ID_INVALID;
+}
+
+CK_RV
+mock_C_GetTokenInfo__invalid_slotid (CK_SLOT_ID id,
+ CK_TOKEN_INFO_PTR info)
+{
+ return_val_if_fail (info, CKR_ARGUMENTS_BAD);
+
+ return CKR_SLOT_ID_INVALID;
+}
+
+CK_RV
+mock_C_GetMechanismList__invalid_slotid (CK_SLOT_ID id,
+ CK_MECHANISM_TYPE_PTR mechanism_list,
+ CK_ULONG_PTR count)
+{
+ return_val_if_fail (count, CKR_ARGUMENTS_BAD);
+
+ return CKR_SLOT_ID_INVALID;
+}
+
+CK_RV
+mock_C_GetMechanismInfo__invalid_slotid (CK_SLOT_ID id,
+ CK_MECHANISM_TYPE type,
+ CK_MECHANISM_INFO_PTR info)
+{
+ return_val_if_fail (info, CKR_ARGUMENTS_BAD);
+
+ return CKR_SLOT_ID_INVALID;
+}
+
+CK_RV
+mock_C_InitToken__invalid_slotid (CK_SLOT_ID id,
+ CK_UTF8CHAR_PTR pin,
+ CK_ULONG pin_len,
+ CK_UTF8CHAR_PTR label)
+{
+ return CKR_SLOT_ID_INVALID;
+}
+
+CK_RV
+mock_C_WaitForSlotEvent__no_event (CK_FLAGS flags,
+ CK_SLOT_ID_PTR slot,
+ CK_VOID_PTR reserved)
+{
+ return_val_if_fail (slot, CKR_ARGUMENTS_BAD);
+
+ return CKR_NO_EVENT;
+}
+
+CK_RV
+mock_C_OpenSession__invalid_slotid (CK_SLOT_ID id,
+ CK_FLAGS flags,
+ CK_VOID_PTR user_data,
+ CK_NOTIFY callback,
+ CK_SESSION_HANDLE_PTR session)
+{
+ return_val_if_fail (session, CKR_ARGUMENTS_BAD);
+
+ return CKR_SLOT_ID_INVALID;
+}
+
+CK_RV
+mock_C_CloseSession__invalid_handle (CK_SESSION_HANDLE session)
+{
+ return CKR_SESSION_HANDLE_INVALID;
+}
+
+CK_RV
+mock_C_CloseAllSessions__invalid_slotid (CK_SLOT_ID id)
+{
+ return CKR_SLOT_ID_INVALID;
+}
+
+CK_RV
+mock_C_GetFunctionStatus__not_parallel (CK_SESSION_HANDLE session)
+{
+ return CKR_FUNCTION_NOT_PARALLEL;
+}
+
+CK_RV
+mock_C_CancelFunction__not_parallel (CK_SESSION_HANDLE session)
+{
+ return CKR_FUNCTION_NOT_PARALLEL;
+}
+
+CK_RV
+mock_C_GetSessionInfo__invalid_handle (CK_SESSION_HANDLE session,
+ CK_SESSION_INFO_PTR info)
+{
+ return_val_if_fail (info, CKR_ARGUMENTS_BAD);
+
+ return CKR_SESSION_HANDLE_INVALID;
+}
+
+CK_RV
+mock_C_InitPIN__invalid_handle (CK_SESSION_HANDLE session,
+ CK_UTF8CHAR_PTR pin,
+ CK_ULONG pin_len)
+{
+ return CKR_SESSION_HANDLE_INVALID;
+}
+
+CK_RV
+mock_C_SetPIN__invalid_handle (CK_SESSION_HANDLE session,
+ CK_UTF8CHAR_PTR old_pin,
+ CK_ULONG old_pin_len,
+ CK_UTF8CHAR_PTR new_pin,
+ CK_ULONG new_pin_len)
+{
+ return CKR_SESSION_HANDLE_INVALID;
+}
+
+CK_RV
+mock_C_GetOperationState__invalid_handle (CK_SESSION_HANDLE session,
+ CK_BYTE_PTR operation_state,
+ CK_ULONG_PTR operation_state_len)
+{
+ return_val_if_fail (operation_state_len, CKR_ARGUMENTS_BAD);
+
+ return CKR_SESSION_HANDLE_INVALID;
+}
+
+CK_RV
+mock_C_SetOperationState__invalid_handle (CK_SESSION_HANDLE session,
+ CK_BYTE_PTR operation_state,
+ CK_ULONG operation_state_len,
+ CK_OBJECT_HANDLE encryption_key,
+ CK_OBJECT_HANDLE authentication_key)
+{
+ return CKR_SESSION_HANDLE_INVALID;
+}
+
+CK_RV
+mock_C_Login__invalid_handle (CK_SESSION_HANDLE session,
+ CK_USER_TYPE user_type,
+ CK_UTF8CHAR_PTR pin,
+ CK_ULONG pin_len)
+{
+ return CKR_SESSION_HANDLE_INVALID;
+
+}
+
+CK_RV
+mock_C_Logout__invalid_handle (CK_SESSION_HANDLE session)
+{
+ return CKR_SESSION_HANDLE_INVALID;
+
+}
+
+CK_RV
+mock_C_CreateObject__invalid_handle (CK_SESSION_HANDLE session,
+ CK_ATTRIBUTE_PTR template,
+ CK_ULONG count,
+ CK_OBJECT_HANDLE_PTR new_object)
+{
+ return_val_if_fail (new_object, CKR_ARGUMENTS_BAD);
+
+ return CKR_SESSION_HANDLE_INVALID;
+}
+
+CK_RV
+mock_C_CopyObject__invalid_handle (CK_SESSION_HANDLE session,
+ CK_OBJECT_HANDLE object,
+ CK_ATTRIBUTE_PTR template,
+ CK_ULONG count,
+ CK_OBJECT_HANDLE_PTR new_object)
+{
+ return_val_if_fail (new_object, CKR_ARGUMENTS_BAD);
+
+ return CKR_SESSION_HANDLE_INVALID;
+}
+
+
+CK_RV
+mock_C_DestroyObject__invalid_handle (CK_SESSION_HANDLE session,
+ CK_OBJECT_HANDLE object)
+{
+ return CKR_SESSION_HANDLE_INVALID;
+}
+
+CK_RV
+mock_C_GetObjectSize__invalid_handle (CK_SESSION_HANDLE session,
+ CK_OBJECT_HANDLE object,
+ CK_ULONG_PTR size)
+{
+ return_val_if_fail (size, CKR_ARGUMENTS_BAD);
+
+ return CKR_SESSION_HANDLE_INVALID;
+}
+
+CK_RV
+mock_C_GetAttributeValue__invalid_handle (CK_SESSION_HANDLE session,
+ CK_OBJECT_HANDLE object,
+ CK_ATTRIBUTE_PTR template,
+ CK_ULONG count)
+{
+ return CKR_SESSION_HANDLE_INVALID;
+}
+
+CK_RV
+mock_C_SetAttributeValue__invalid_handle (CK_SESSION_HANDLE session,
+ CK_OBJECT_HANDLE object,
+ CK_ATTRIBUTE_PTR template,
+ CK_ULONG count)
+{
+ return CKR_SESSION_HANDLE_INVALID;
+}
+
+CK_RV
+mock_C_FindObjectsInit__invalid_handle (CK_SESSION_HANDLE session,
+ CK_ATTRIBUTE_PTR template,
+ CK_ULONG count)
+{
+ return CKR_SESSION_HANDLE_INVALID;
+}
+
+CK_RV
+mock_C_FindObjects__invalid_handle (CK_SESSION_HANDLE session,
+ CK_OBJECT_HANDLE_PTR objects,
+ CK_ULONG max_count,
+ CK_ULONG_PTR count)
+{
+ return_val_if_fail (count, CKR_ARGUMENTS_BAD);
+
+ return CKR_SESSION_HANDLE_INVALID;
+}
+
+CK_RV
+mock_C_FindObjectsFinal__invalid_handle (CK_SESSION_HANDLE session)
+{
+ return CKR_SESSION_HANDLE_INVALID;
+}
+
+CK_RV
+mock_C_EncryptInit__invalid_handle (CK_SESSION_HANDLE session,
+ CK_MECHANISM_PTR mechanism,
+ CK_OBJECT_HANDLE key)
+{
+ return CKR_SESSION_HANDLE_INVALID;
+}
+
+CK_RV
+mock_C_Encrypt__invalid_handle (CK_SESSION_HANDLE session,
+ CK_BYTE_PTR data, CK_ULONG data_len,
+ CK_BYTE_PTR encrypted_data,
+ CK_ULONG_PTR encrypted_data_len)
+{
+ return_val_if_fail (encrypted_data_len, CKR_ARGUMENTS_BAD);
+
+ return CKR_SESSION_HANDLE_INVALID;
+}
+
+CK_RV
+mock_C_EncryptUpdate__invalid_handle (CK_SESSION_HANDLE session,
+ CK_BYTE_PTR part,
+ CK_ULONG part_len,
+ CK_BYTE_PTR encrypted_part,
+ CK_ULONG_PTR encrypted_part_len)
+{
+ return_val_if_fail (encrypted_part_len, CKR_ARGUMENTS_BAD);
+
+ return CKR_SESSION_HANDLE_INVALID;
+}
+
+CK_RV
+mock_C_EncryptFinal__invalid_handle (CK_SESSION_HANDLE session,
+ CK_BYTE_PTR last_part,
+ CK_ULONG_PTR last_part_len)
+{
+ return_val_if_fail (last_part_len, CKR_ARGUMENTS_BAD);
+
+ return CKR_SESSION_HANDLE_INVALID;
+}
+
+CK_RV
+mock_C_DecryptInit__invalid_handle (CK_SESSION_HANDLE session,
+ CK_MECHANISM_PTR mechanism,
+ CK_OBJECT_HANDLE key)
+{
+ return CKR_SESSION_HANDLE_INVALID;
+}
+
+CK_RV
+mock_C_Decrypt__invalid_handle (CK_SESSION_HANDLE session,
+ CK_BYTE_PTR enc_data,
+ CK_ULONG enc_data_len,
+ CK_BYTE_PTR data,
+ CK_ULONG_PTR data_len)
+{
+ return_val_if_fail (data_len, CKR_ARGUMENTS_BAD);
+
+ return CKR_SESSION_HANDLE_INVALID;
+}
+
+CK_RV
+mock_C_DecryptUpdate__invalid_handle (CK_SESSION_HANDLE session,
+ CK_BYTE_PTR enc_part,
+ CK_ULONG enc_part_len,
+ CK_BYTE_PTR part,
+ CK_ULONG_PTR part_len)
+{
+ return_val_if_fail (part_len, CKR_ARGUMENTS_BAD);
+
+ return CKR_SESSION_HANDLE_INVALID;
+}
+
+CK_RV
+mock_C_DecryptFinal__invalid_handle (CK_SESSION_HANDLE session,
+ CK_BYTE_PTR last_part,
+ CK_ULONG_PTR last_part_len)
+{
+ return_val_if_fail (last_part_len, CKR_ARGUMENTS_BAD);
+
+ return CKR_SESSION_HANDLE_INVALID;
+}
+
+CK_RV
+mock_C_DigestInit__invalid_handle (CK_SESSION_HANDLE session,
+ CK_MECHANISM_PTR mechanism)
+{
+ return CKR_SESSION_HANDLE_INVALID;
+}
+
+CK_RV
+mock_C_Digest__invalid_handle (CK_SESSION_HANDLE session,
+ CK_BYTE_PTR data,
+ CK_ULONG data_len,
+ CK_BYTE_PTR digest,
+ CK_ULONG_PTR digest_len)
+{
+ return_val_if_fail (digest_len, CKR_ARGUMENTS_BAD);
+
+ return CKR_SESSION_HANDLE_INVALID;
+}
+
+CK_RV
+mock_C_DigestUpdate__invalid_handle (CK_SESSION_HANDLE session,
+ CK_BYTE_PTR part,
+ CK_ULONG part_len)
+{
+ return CKR_SESSION_HANDLE_INVALID;
+}
+
+CK_RV
+mock_C_DigestKey__invalid_handle (CK_SESSION_HANDLE session,
+ CK_OBJECT_HANDLE key)
+{
+ return CKR_SESSION_HANDLE_INVALID;
+}
+
+CK_RV
+mock_C_DigestFinal__invalid_handle (CK_SESSION_HANDLE session,
+ CK_BYTE_PTR digest,
+ CK_ULONG_PTR digest_len)
+{
+ return_val_if_fail (digest_len, CKR_ARGUMENTS_BAD);
+
+ return CKR_SESSION_HANDLE_INVALID;
+}
+
+CK_RV
+mock_C_SignInit__invalid_handle (CK_SESSION_HANDLE session,
+ CK_MECHANISM_PTR mechanism,
+ CK_OBJECT_HANDLE key)
+{
+ return CKR_SESSION_HANDLE_INVALID;
+}
+
+CK_RV
+mock_C_Sign__invalid_handle (CK_SESSION_HANDLE session,
+ CK_BYTE_PTR data,
+ CK_ULONG data_len,
+ CK_BYTE_PTR signature,
+ CK_ULONG_PTR signature_len)
+{
+ return_val_if_fail (signature_len, CKR_ARGUMENTS_BAD);
+
+ return CKR_SESSION_HANDLE_INVALID;
+}
+
+CK_RV
+mock_C_SignUpdate__invalid_handle (CK_SESSION_HANDLE session,
+ CK_BYTE_PTR part,
+ CK_ULONG part_len)
+{
+ return_val_if_fail (part_len, CKR_ARGUMENTS_BAD);
+
+ return CKR_SESSION_HANDLE_INVALID;
+}
+
+CK_RV
+mock_C_SignFinal__invalid_handle (CK_SESSION_HANDLE session,
+ CK_BYTE_PTR signature,
+ CK_ULONG_PTR signature_len)
+{
+ return_val_if_fail (signature_len, CKR_ARGUMENTS_BAD);
+
+ return CKR_SESSION_HANDLE_INVALID;
+}
+
+CK_RV
+mock_C_SignRecoverInit__invalid_handle (CK_SESSION_HANDLE session,
+ CK_MECHANISM_PTR mechanism,
+ CK_OBJECT_HANDLE key)
+{
+ return CKR_SESSION_HANDLE_INVALID;
+}
+
+CK_RV
+mock_C_SignRecover__invalid_handle (CK_SESSION_HANDLE session,
+ CK_BYTE_PTR data,
+ CK_ULONG data_len,
+ CK_BYTE_PTR signature,
+ CK_ULONG_PTR signature_len)
+{
+ return_val_if_fail (signature_len, CKR_ARGUMENTS_BAD);
+
+ return CKR_SESSION_HANDLE_INVALID;
+}
+
+CK_RV
+mock_C_VerifyInit__invalid_handle (CK_SESSION_HANDLE session,
+ CK_MECHANISM_PTR mechanism,
+ CK_OBJECT_HANDLE key)
+{
+ return CKR_SESSION_HANDLE_INVALID;
+}
+
+CK_RV
+mock_C_Verify__invalid_handle (CK_SESSION_HANDLE session,
+ CK_BYTE_PTR data,
+ CK_ULONG data_len,
+ CK_BYTE_PTR signature,
+ CK_ULONG signature_len)
+{
+ return CKR_SESSION_HANDLE_INVALID;
+}
+
+CK_RV
+mock_C_VerifyUpdate__invalid_handle (CK_SESSION_HANDLE session,
+ CK_BYTE_PTR part,
+ CK_ULONG part_len)
+{
+ return CKR_SESSION_HANDLE_INVALID;
+}
+
+CK_RV
+mock_C_VerifyFinal__invalid_handle (CK_SESSION_HANDLE session,
+ CK_BYTE_PTR signature,
+ CK_ULONG signature_len)
+{
+ return CKR_SESSION_HANDLE_INVALID;
+}
+
+CK_RV
+mock_C_VerifyRecoverInit__invalid_handle (CK_SESSION_HANDLE session,
+ CK_MECHANISM_PTR mechanism,
+ CK_OBJECT_HANDLE key)
+{
+ return CKR_SESSION_HANDLE_INVALID;
+}
+
+CK_RV
+mock_C_VerifyRecover__invalid_handle (CK_SESSION_HANDLE session,
+ CK_BYTE_PTR signature,
+ CK_ULONG signature_len,
+ CK_BYTE_PTR data,
+ CK_ULONG_PTR data_len)
+{
+ return_val_if_fail (data_len, CKR_ARGUMENTS_BAD);
+
+ return CKR_SESSION_HANDLE_INVALID;
+}
+
+CK_RV
+mock_C_DigestEncryptUpdate__invalid_handle (CK_SESSION_HANDLE session,
+ CK_BYTE_PTR part,
+ CK_ULONG part_len, CK_BYTE_PTR enc_part,
+ CK_ULONG_PTR enc_part_len)
+{
+ return_val_if_fail (enc_part_len, CKR_ARGUMENTS_BAD);
+
+ return CKR_SESSION_HANDLE_INVALID;
+}
+
+CK_RV
+mock_C_DecryptDigestUpdate__invalid_handle (CK_SESSION_HANDLE session,
+ CK_BYTE_PTR enc_part,
+ CK_ULONG enc_part_len,
+ CK_BYTE_PTR part,
+ CK_ULONG_PTR part_len)
+{
+ return_val_if_fail (part_len, CKR_ARGUMENTS_BAD);
+
+ return CKR_SESSION_HANDLE_INVALID;
+}
+
+CK_RV
+mock_C_SignEncryptUpdate__invalid_handle (CK_SESSION_HANDLE session,
+ CK_BYTE_PTR part,
+ CK_ULONG part_len,
+ CK_BYTE_PTR enc_part,
+ CK_ULONG_PTR enc_part_len)
+{
+ return_val_if_fail (enc_part_len, CKR_ARGUMENTS_BAD);
+
+ return CKR_SESSION_HANDLE_INVALID;
+}
+
+CK_RV
+mock_C_DecryptVerifyUpdate__invalid_handle (CK_SESSION_HANDLE session,
+ CK_BYTE_PTR enc_part,
+ CK_ULONG enc_part_len,
+ CK_BYTE_PTR part,
+ CK_ULONG_PTR part_len)
+{
+ return_val_if_fail (part_len, CKR_ARGUMENTS_BAD);
+
+ return CKR_SESSION_HANDLE_INVALID;
+}
+
+CK_RV
+mock_C_GenerateKey__invalid_handle (CK_SESSION_HANDLE session,
+ CK_MECHANISM_PTR mechanism,
+ CK_ATTRIBUTE_PTR template,
+ CK_ULONG count,
+ CK_OBJECT_HANDLE_PTR key)
+{
+ return CKR_SESSION_HANDLE_INVALID;
+}
+
+CK_RV
+mock_C_GenerateKeyPair__invalid_handle (CK_SESSION_HANDLE session,
+ CK_MECHANISM_PTR mechanism,
+ CK_ATTRIBUTE_PTR pub_template,
+ CK_ULONG pub_count,
+ CK_ATTRIBUTE_PTR priv_template,
+ CK_ULONG priv_count,
+ CK_OBJECT_HANDLE_PTR pub_key,
+ CK_OBJECT_HANDLE_PTR priv_key)
+{
+ return CKR_SESSION_HANDLE_INVALID;
+}
+
+CK_RV
+mock_C_WrapKey__invalid_handle (CK_SESSION_HANDLE session,
+ CK_MECHANISM_PTR mechanism,
+ CK_OBJECT_HANDLE wrapping_key,
+ CK_OBJECT_HANDLE key,
+ CK_BYTE_PTR wrapped_key,
+ CK_ULONG_PTR wrapped_key_len)
+{
+ return_val_if_fail (wrapped_key_len, CKR_ARGUMENTS_BAD);
+
+ return CKR_SESSION_HANDLE_INVALID;
+}
+
+CK_RV
+mock_C_UnwrapKey__invalid_handle (CK_SESSION_HANDLE session,
+ CK_MECHANISM_PTR mechanism,
+ CK_OBJECT_HANDLE unwrapping_key,
+ CK_BYTE_PTR wrapped_key,
+ CK_ULONG wrapped_key_len,
+ CK_ATTRIBUTE_PTR template,
+ CK_ULONG count,
+ CK_OBJECT_HANDLE_PTR key)
+{
+ return CKR_SESSION_HANDLE_INVALID;
+}
+
+CK_RV
+mock_C_DeriveKey__invalid_handle (CK_SESSION_HANDLE session,
+ CK_MECHANISM_PTR mechanism,
+ CK_OBJECT_HANDLE base_key,
+ CK_ATTRIBUTE_PTR template,
+ CK_ULONG count,
+ CK_OBJECT_HANDLE_PTR key)
+{
+ return CKR_SESSION_HANDLE_INVALID;
+}
+
+CK_RV
+mock_C_SeedRandom__invalid_handle (CK_SESSION_HANDLE session,
+ CK_BYTE_PTR seed,
+ CK_ULONG seed_len)
+{
+ return CKR_SESSION_HANDLE_INVALID;
+}
+
+CK_RV
+mock_C_GenerateRandom__invalid_handle (CK_SESSION_HANDLE session,
+ CK_BYTE_PTR random_data,
+ CK_ULONG random_len)
+{
+ return CKR_SESSION_HANDLE_INVALID;
+}
+
+CK_FUNCTION_LIST mock_module_no_slots = {
+ { CRYPTOKI_VERSION_MAJOR, CRYPTOKI_VERSION_MINOR }, /* version */
+ mock_C_Initialize,
+ mock_C_Finalize,
+ mock_C_GetInfo,
+ mock_C_GetFunctionList,
+ mock_C_GetSlotList__no_tokens,
+ mock_C_GetSlotInfo__invalid_slotid,
+ mock_C_GetTokenInfo__invalid_slotid,
+ mock_C_GetMechanismList__invalid_slotid,
+ mock_C_GetMechanismInfo__invalid_slotid,
+ mock_C_InitToken__invalid_slotid,
+ mock_C_InitPIN__invalid_handle,
+ mock_C_SetPIN__invalid_handle,
+ mock_C_OpenSession__invalid_slotid,
+ mock_C_CloseSession__invalid_handle,
+ mock_C_CloseAllSessions__invalid_slotid,
+ mock_C_GetSessionInfo__invalid_handle,
+ mock_C_GetOperationState__invalid_handle,
+ mock_C_SetOperationState__invalid_handle,
+ mock_C_Login__invalid_handle,
+ mock_C_Logout__invalid_handle,
+ mock_C_CreateObject__invalid_handle,
+ mock_C_CopyObject__invalid_handle,
+ mock_C_DestroyObject__invalid_handle,
+ mock_C_GetObjectSize__invalid_handle,
+ mock_C_GetAttributeValue__invalid_handle,
+ mock_C_SetAttributeValue__invalid_handle,
+ mock_C_FindObjectsInit__invalid_handle,
+ mock_C_FindObjects__invalid_handle,
+ mock_C_FindObjectsFinal__invalid_handle,
+ mock_C_EncryptInit__invalid_handle,
+ mock_C_Encrypt__invalid_handle,
+ mock_C_EncryptUpdate__invalid_handle,
+ mock_C_EncryptFinal__invalid_handle,
+ mock_C_DecryptInit__invalid_handle,
+ mock_C_Decrypt__invalid_handle,
+ mock_C_DecryptUpdate__invalid_handle,
+ mock_C_DecryptFinal__invalid_handle,
+ mock_C_DigestInit__invalid_handle,
+ mock_C_Digest__invalid_handle,
+ mock_C_DigestUpdate__invalid_handle,
+ mock_C_DigestKey__invalid_handle,
+ mock_C_DigestFinal__invalid_handle,
+ mock_C_SignInit__invalid_handle,
+ mock_C_Sign__invalid_handle,
+ mock_C_SignUpdate__invalid_handle,
+ mock_C_SignFinal__invalid_handle,
+ mock_C_SignRecoverInit__invalid_handle,
+ mock_C_SignRecover__invalid_handle,
+ mock_C_VerifyInit__invalid_handle,
+ mock_C_Verify__invalid_handle,
+ mock_C_VerifyUpdate__invalid_handle,
+ mock_C_VerifyFinal__invalid_handle,
+ mock_C_VerifyRecoverInit__invalid_handle,
+ mock_C_VerifyRecover__invalid_handle,
+ mock_C_DigestEncryptUpdate__invalid_handle,
+ mock_C_DecryptDigestUpdate__invalid_handle,
+ mock_C_SignEncryptUpdate__invalid_handle,
+ mock_C_DecryptVerifyUpdate__invalid_handle,
+ mock_C_GenerateKey__invalid_handle,
+ mock_C_GenerateKeyPair__invalid_handle,
+ mock_C_WrapKey__invalid_handle,
+ mock_C_UnwrapKey__invalid_handle,
+ mock_C_DeriveKey__invalid_handle,
+ mock_C_SeedRandom__invalid_handle,
+ mock_C_GenerateRandom__invalid_handle,
+ mock_C_GetFunctionStatus__not_parallel,
+ mock_C_CancelFunction__not_parallel,
+ mock_C_WaitForSlotEvent__no_event,
+};
+
+void
+mock_module_init (void)
+{
+ static int initialized = 0;
+ if (!initialized) {
+ p11_mutex_init (&init_mutex);
+ initialized = 1;
+ }
+}
diff --git a/p11-kit/tests/mock-module.h b/p11-kit/tests/mock-module.h
new file mode 100644
index 0000000..9557f70
--- /dev/null
+++ b/p11-kit/tests/mock-module.h
@@ -0,0 +1,337 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/* mock-module.c - a mock PKCS#11 module
+
+ 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,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+
+ Author: Stef Walter <stefw@collabora.co.uk>
+*/
+
+#ifndef __MOCK_MODULE_H__
+#define __MOCK_MODULE_H__
+
+#include "pkcs11.h"
+
+extern CK_FUNCTION_LIST mock_module_no_slots;
+
+void mock_module_init (void);
+
+CK_RV mock_C_Initialize (CK_VOID_PTR init_args);
+
+CK_RV mock_C_Finalize (CK_VOID_PTR reserved);
+
+CK_RV mock_C_GetInfo (CK_INFO_PTR info);
+
+CK_RV mock_C_GetFunctionList (CK_FUNCTION_LIST_PTR_PTR list);
+
+CK_RV mock_C_GetSlotList__no_tokens (CK_BBOOL token_present,
+ CK_SLOT_ID_PTR slot_list,
+ CK_ULONG_PTR count);
+
+CK_RV mock_C_GetSlotInfo__invalid_slotid (CK_SLOT_ID id,
+ CK_SLOT_INFO_PTR info);
+
+CK_RV mock_C_GetTokenInfo__invalid_slotid (CK_SLOT_ID id,
+ CK_TOKEN_INFO_PTR info);
+
+CK_RV mock_C_GetMechanismList__invalid_slotid (CK_SLOT_ID id,
+ CK_MECHANISM_TYPE_PTR mechanism_list,
+ CK_ULONG_PTR count);
+
+CK_RV mock_C_GetMechanismInfo__invalid_slotid (CK_SLOT_ID id,
+ CK_MECHANISM_TYPE type,
+ CK_MECHANISM_INFO_PTR info);
+
+CK_RV mock_C_InitToken__invalid_slotid (CK_SLOT_ID id,
+ CK_UTF8CHAR_PTR pin,
+ CK_ULONG pin_len,
+ CK_UTF8CHAR_PTR label);
+
+CK_RV mock_C_WaitForSlotEvent__no_event (CK_FLAGS flags,
+ CK_SLOT_ID_PTR slot,
+ CK_VOID_PTR reserved);
+
+CK_RV mock_C_OpenSession__invalid_slotid (CK_SLOT_ID id,
+ CK_FLAGS flags,
+ CK_VOID_PTR user_data,
+ CK_NOTIFY callback,
+ CK_SESSION_HANDLE_PTR session);
+
+CK_RV mock_C_CloseSession__invalid_handle (CK_SESSION_HANDLE session);
+
+CK_RV mock_C_CloseAllSessions__invalid_slotid (CK_SLOT_ID id);
+
+CK_RV mock_C_GetFunctionStatus__not_parallel (CK_SESSION_HANDLE session);
+
+CK_RV mock_C_CancelFunction__not_parallel (CK_SESSION_HANDLE session);
+
+CK_RV mock_C_GetSessionInfo__invalid_handle (CK_SESSION_HANDLE session,
+ CK_SESSION_INFO_PTR info);
+
+CK_RV mock_C_InitPIN__invalid_handle (CK_SESSION_HANDLE session,
+ CK_UTF8CHAR_PTR pin,
+ CK_ULONG pin_len);
+
+CK_RV mock_C_SetPIN__invalid_handle (CK_SESSION_HANDLE session,
+ CK_UTF8CHAR_PTR old_pin,
+ CK_ULONG old_pin_len,
+ CK_UTF8CHAR_PTR new_pin,
+ CK_ULONG new_pin_len);
+
+CK_RV mock_C_GetOperationState__invalid_handle (CK_SESSION_HANDLE session,
+ CK_BYTE_PTR operation_state,
+ CK_ULONG_PTR operation_state_len);
+
+CK_RV mock_C_SetOperationState__invalid_handle (CK_SESSION_HANDLE session,
+ CK_BYTE_PTR operation_state,
+ CK_ULONG operation_state_len,
+ CK_OBJECT_HANDLE encryption_key,
+ CK_OBJECT_HANDLE authentication_key);
+
+CK_RV mock_C_Login__invalid_handle (CK_SESSION_HANDLE session,
+ CK_USER_TYPE user_type,
+ CK_UTF8CHAR_PTR pin,
+ CK_ULONG pin_len);
+
+CK_RV mock_C_Logout__invalid_handle (CK_SESSION_HANDLE session);
+
+CK_RV mock_C_CreateObject__invalid_handle (CK_SESSION_HANDLE session,
+ CK_ATTRIBUTE_PTR template,
+ CK_ULONG count,
+ CK_OBJECT_HANDLE_PTR new_object);
+
+CK_RV mock_C_CopyObject__invalid_handle (CK_SESSION_HANDLE session,
+ CK_OBJECT_HANDLE object,
+ CK_ATTRIBUTE_PTR template,
+ CK_ULONG count,
+ CK_OBJECT_HANDLE_PTR new_object);
+
+CK_RV mock_C_DestroyObject__invalid_handle (CK_SESSION_HANDLE session,
+ CK_OBJECT_HANDLE object);
+
+CK_RV mock_C_GetObjectSize__invalid_handle (CK_SESSION_HANDLE session,
+ CK_OBJECT_HANDLE object,
+ CK_ULONG_PTR size);
+
+CK_RV mock_C_GetAttributeValue__invalid_handle (CK_SESSION_HANDLE session,
+ CK_OBJECT_HANDLE object,
+ CK_ATTRIBUTE_PTR template,
+ CK_ULONG count);
+
+CK_RV mock_C_SetAttributeValue__invalid_handle (CK_SESSION_HANDLE session,
+ CK_OBJECT_HANDLE object,
+ CK_ATTRIBUTE_PTR template,
+ CK_ULONG count);
+
+CK_RV mock_C_FindObjectsInit__invalid_handle (CK_SESSION_HANDLE session,
+ CK_ATTRIBUTE_PTR template,
+ CK_ULONG count);
+
+CK_RV mock_C_FindObjects__invalid_handle (CK_SESSION_HANDLE session,
+ CK_OBJECT_HANDLE_PTR objects,
+ CK_ULONG max_count,
+ CK_ULONG_PTR count);
+
+CK_RV mock_C_FindObjectsFinal__invalid_handle (CK_SESSION_HANDLE session);
+
+CK_RV mock_C_EncryptInit__invalid_handle (CK_SESSION_HANDLE session,
+ CK_MECHANISM_PTR mechanism,
+ CK_OBJECT_HANDLE key);
+
+CK_RV mock_C_Encrypt__invalid_handle (CK_SESSION_HANDLE session,
+ CK_BYTE_PTR data,
+ CK_ULONG data_len,
+ CK_BYTE_PTR encrypted_data,
+ CK_ULONG_PTR encrypted_data_len);
+
+CK_RV mock_C_EncryptUpdate__invalid_handle (CK_SESSION_HANDLE session,
+ CK_BYTE_PTR part,
+ CK_ULONG part_len,
+ CK_BYTE_PTR encrypted_part,
+ CK_ULONG_PTR encrypted_part_len);
+
+CK_RV mock_C_EncryptFinal__invalid_handle (CK_SESSION_HANDLE session,
+ CK_BYTE_PTR last_part,
+ CK_ULONG_PTR last_part_len);
+
+CK_RV mock_C_DecryptInit__invalid_handle (CK_SESSION_HANDLE session,
+ CK_MECHANISM_PTR mechanism,
+ CK_OBJECT_HANDLE key);
+
+CK_RV mock_C_Decrypt__invalid_handle (CK_SESSION_HANDLE session,
+ CK_BYTE_PTR enc_data,
+ CK_ULONG enc_data_len,
+ CK_BYTE_PTR data,
+ CK_ULONG_PTR data_len);
+
+CK_RV mock_C_DecryptUpdate__invalid_handle (CK_SESSION_HANDLE session,
+ CK_BYTE_PTR enc_part,
+ CK_ULONG enc_part_len,
+ CK_BYTE_PTR part,
+ CK_ULONG_PTR part_len);
+
+CK_RV mock_C_DecryptFinal__invalid_handle (CK_SESSION_HANDLE session,
+ CK_BYTE_PTR last_part,
+ CK_ULONG_PTR last_part_len);
+
+CK_RV mock_C_DigestInit__invalid_handle (CK_SESSION_HANDLE session,
+ CK_MECHANISM_PTR mechanism);
+
+CK_RV mock_C_Digest__invalid_handle (CK_SESSION_HANDLE session,
+ CK_BYTE_PTR data,
+ CK_ULONG data_len,
+ CK_BYTE_PTR digest,
+ CK_ULONG_PTR digest_len);
+
+CK_RV mock_C_DigestUpdate__invalid_handle (CK_SESSION_HANDLE session,
+ CK_BYTE_PTR part,
+ CK_ULONG part_len);
+
+CK_RV mock_C_DigestKey__invalid_handle (CK_SESSION_HANDLE session,
+ CK_OBJECT_HANDLE key);
+
+CK_RV mock_C_DigestFinal__invalid_handle (CK_SESSION_HANDLE session,
+ CK_BYTE_PTR digest,
+ CK_ULONG_PTR digest_len);
+
+CK_RV mock_C_SignInit__invalid_handle (CK_SESSION_HANDLE session,
+ CK_MECHANISM_PTR mechanism,
+ CK_OBJECT_HANDLE key);
+
+CK_RV mock_C_Sign__invalid_handle (CK_SESSION_HANDLE session,
+ CK_BYTE_PTR data,
+ CK_ULONG data_len,
+ CK_BYTE_PTR signature,
+ CK_ULONG_PTR signature_len);
+
+CK_RV mock_C_SignUpdate__invalid_handle (CK_SESSION_HANDLE session,
+ CK_BYTE_PTR part,
+ CK_ULONG part_len);
+
+CK_RV mock_C_SignFinal__invalid_handle (CK_SESSION_HANDLE session,
+ CK_BYTE_PTR signature,
+ CK_ULONG_PTR signature_len);
+
+CK_RV mock_C_SignRecoverInit__invalid_handle (CK_SESSION_HANDLE session,
+ CK_MECHANISM_PTR mechanism,
+ CK_OBJECT_HANDLE key);
+
+CK_RV mock_C_SignRecover__invalid_handle (CK_SESSION_HANDLE session,
+ CK_BYTE_PTR data,
+ CK_ULONG data_len,
+ CK_BYTE_PTR signature,
+ CK_ULONG_PTR signature_len);
+
+CK_RV mock_C_VerifyInit__invalid_handle (CK_SESSION_HANDLE session,
+ CK_MECHANISM_PTR mechanism,
+ CK_OBJECT_HANDLE key);
+
+CK_RV mock_C_Verify__invalid_handle (CK_SESSION_HANDLE session,
+ CK_BYTE_PTR data,
+ CK_ULONG data_len,
+ CK_BYTE_PTR signature,
+ CK_ULONG signature_len);
+
+CK_RV mock_C_VerifyUpdate__invalid_handle (CK_SESSION_HANDLE session,
+ CK_BYTE_PTR part,
+ CK_ULONG part_len);
+
+CK_RV mock_C_VerifyFinal__invalid_handle (CK_SESSION_HANDLE session,
+ CK_BYTE_PTR signature,
+ CK_ULONG signature_len);
+
+CK_RV mock_C_VerifyRecoverInit__invalid_handle (CK_SESSION_HANDLE session,
+ CK_MECHANISM_PTR mechanism,
+ CK_OBJECT_HANDLE key);
+
+CK_RV mock_C_VerifyRecover__invalid_handle (CK_SESSION_HANDLE session,
+ CK_BYTE_PTR signature,
+ CK_ULONG signature_len,
+ CK_BYTE_PTR data,
+ CK_ULONG_PTR data_len);
+
+CK_RV mock_C_DigestEncryptUpdate__invalid_handle (CK_SESSION_HANDLE session,
+ CK_BYTE_PTR part,
+ CK_ULONG part_len,
+ CK_BYTE_PTR enc_part,
+ CK_ULONG_PTR enc_part_len);
+
+CK_RV mock_C_DecryptDigestUpdate__invalid_handle (CK_SESSION_HANDLE session,
+ CK_BYTE_PTR enc_part,
+ CK_ULONG enc_part_len,
+ CK_BYTE_PTR part,
+ CK_ULONG_PTR part_len);
+
+CK_RV mock_C_SignEncryptUpdate__invalid_handle (CK_SESSION_HANDLE session,
+ CK_BYTE_PTR part,
+ CK_ULONG part_len,
+ CK_BYTE_PTR enc_part,
+ CK_ULONG_PTR enc_part_len);
+
+CK_RV mock_C_DecryptVerifyUpdate__invalid_handle (CK_SESSION_HANDLE session,
+ CK_BYTE_PTR enc_part,
+ CK_ULONG enc_part_len,
+ CK_BYTE_PTR part,
+ CK_ULONG_PTR part_len);
+
+CK_RV mock_C_GenerateKey__invalid_handle (CK_SESSION_HANDLE session,
+ CK_MECHANISM_PTR mechanism,
+ CK_ATTRIBUTE_PTR template,
+ CK_ULONG count,
+ CK_OBJECT_HANDLE_PTR key);
+
+CK_RV mock_C_GenerateKeyPair__invalid_handle (CK_SESSION_HANDLE session,
+ CK_MECHANISM_PTR mechanism,
+ CK_ATTRIBUTE_PTR pub_template,
+ CK_ULONG pub_count,
+ CK_ATTRIBUTE_PTR priv_template,
+ CK_ULONG priv_count,
+ CK_OBJECT_HANDLE_PTR pub_key,
+ CK_OBJECT_HANDLE_PTR priv_key);
+
+CK_RV mock_C_WrapKey__invalid_handle (CK_SESSION_HANDLE session,
+ CK_MECHANISM_PTR mechanism,
+ CK_OBJECT_HANDLE wrapping_key,
+ CK_OBJECT_HANDLE key,
+ CK_BYTE_PTR wrapped_key,
+ CK_ULONG_PTR wrapped_key_len);
+
+CK_RV mock_C_UnwrapKey__invalid_handle (CK_SESSION_HANDLE session,
+ CK_MECHANISM_PTR mechanism,
+ CK_OBJECT_HANDLE unwrapping_key,
+ CK_BYTE_PTR wrapped_key,
+ CK_ULONG wrapped_key_len,
+ CK_ATTRIBUTE_PTR template,
+ CK_ULONG count,
+ CK_OBJECT_HANDLE_PTR key);
+
+CK_RV mock_C_DeriveKey__invalid_handle (CK_SESSION_HANDLE session,
+ CK_MECHANISM_PTR mechanism,
+ CK_OBJECT_HANDLE base_key,
+ CK_ATTRIBUTE_PTR template,
+ CK_ULONG count,
+ CK_OBJECT_HANDLE_PTR key);
+
+CK_RV mock_C_SeedRandom__invalid_handle (CK_SESSION_HANDLE session,
+ CK_BYTE_PTR seed,
+ CK_ULONG seed_len);
+
+CK_RV mock_C_GenerateRandom__invalid_handle (CK_SESSION_HANDLE session,
+ CK_BYTE_PTR random_data,
+ CK_ULONG random_len);
+
+#endif /* __MOCK_MODULE_H__ */
diff --git a/p11-kit/tests/pin-test.c b/p11-kit/tests/pin-test.c
new file mode 100644
index 0000000..5427f8b
--- /dev/null
+++ b/p11-kit/tests/pin-test.c
@@ -0,0 +1,325 @@
+/*
+ * Copyright (c) 2011, Collabora Ltd.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the
+ * following disclaimer.
+ * * Redistributions in binary form must reproduce the
+ * above copyright notice, this list of conditions and
+ * the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ * * The names of contributors to this software may not be
+ * used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
+ * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * Author: Stef Walter <stefw@collabora.co.uk>
+ */
+
+#include "config.h"
+#include "CuTest.h"
+
+#include "library.h"
+
+#include <assert.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "p11-kit/pin.h"
+#include "p11-kit/private.h"
+
+static P11KitPin *
+callback_one (const char *pin_source, P11KitUri *pin_uri, const char *pin_description,
+ P11KitPinFlags pin_flags, void *callback_data)
+{
+ int *data = callback_data;
+ assert (*data == 33);
+ return p11_kit_pin_new_for_buffer ((unsigned char*)strdup ("one"), 3, free);
+}
+
+static P11KitPin*
+callback_other (const char *pin_source, P11KitUri *pin_uri, const char *pin_description,
+ P11KitPinFlags pin_flags, void *callback_data)
+{
+ char *data = callback_data;
+ return p11_kit_pin_new_for_string (data);
+}
+
+static void
+destroy_data (void *callback_data)
+{
+ int *data = callback_data;
+ (*data)++;
+}
+
+static void
+test_pin_register_unregister (CuTest *tc)
+{
+ int data = 33;
+
+ p11_kit_pin_register_callback ("/the/pin_source", callback_one,
+ &data, destroy_data);
+
+ p11_kit_pin_unregister_callback ("/the/pin_source", callback_one,
+ &data);
+
+ CuAssertIntEquals (tc, 34, data);
+}
+
+static void
+test_pin_read (CuTest *tc)
+{
+ P11KitUri *uri;
+ P11KitPin *pin;
+ int data = 33;
+ size_t length;
+ const unsigned char *ptr;
+
+ p11_kit_pin_register_callback ("/the/pin_source", callback_one,
+ &data, destroy_data);
+
+ uri = p11_kit_uri_new ();
+ pin = p11_kit_pin_request ("/the/pin_source", uri, "The token",
+ P11_KIT_PIN_FLAGS_USER_LOGIN);
+ p11_kit_uri_free (uri);
+
+ CuAssertPtrNotNull (tc, pin);
+ ptr = p11_kit_pin_get_value (pin, &length);
+ CuAssertIntEquals (tc, 3, length);
+ CuAssertTrue (tc, memcmp (ptr, "one", 3) == 0);
+
+ p11_kit_pin_unregister_callback ("/the/pin_source", callback_one,
+ &data);
+
+ p11_kit_pin_ref (pin);
+ p11_kit_pin_unref (pin);
+}
+
+static void
+test_pin_read_no_match (CuTest *tc)
+{
+ P11KitUri *uri;
+ P11KitPin *pin;
+
+ uri = p11_kit_uri_new ();
+ pin = p11_kit_pin_request ("/the/pin_source", uri, "The token",
+ P11_KIT_PIN_FLAGS_USER_LOGIN);
+ p11_kit_uri_free (uri);
+
+ CuAssertPtrEquals (tc, NULL, pin);
+}
+
+static void
+test_pin_register_duplicate (CuTest *tc)
+{
+ P11KitUri *uri;
+ P11KitPin *pin;
+ char *value = "secret";
+ int data = 33;
+ size_t length;
+ const unsigned char *ptr;
+
+ uri = p11_kit_uri_new ();
+
+ p11_kit_pin_register_callback ("/the/pin_source", callback_one,
+ &data, destroy_data);
+
+ p11_kit_pin_register_callback ("/the/pin_source", callback_other,
+ value, NULL);
+
+ pin = p11_kit_pin_request ("/the/pin_source", uri, "The token",
+ P11_KIT_PIN_FLAGS_USER_LOGIN);
+
+ CuAssertPtrNotNull (tc, pin);
+ ptr = p11_kit_pin_get_value (pin, &length);
+ CuAssertIntEquals (tc, 6, length);
+ CuAssertTrue (tc, memcmp (ptr, "secret", length) == 0);
+ p11_kit_pin_unref (pin);
+
+ p11_kit_pin_unregister_callback ("/the/pin_source", callback_other,
+ value);
+
+ pin = p11_kit_pin_request ("/the/pin_source", uri, "The token",
+ P11_KIT_PIN_FLAGS_USER_LOGIN);
+
+ CuAssertPtrNotNull (tc, pin);
+ ptr = p11_kit_pin_get_value (pin, &length);
+ CuAssertIntEquals (tc, 3, length);
+ CuAssertTrue (tc, memcmp (ptr, "one", length) == 0);
+ p11_kit_pin_unref (pin);
+
+ p11_kit_pin_unregister_callback ("/the/pin_source", callback_one,
+ &data);
+
+ pin = p11_kit_pin_request ("/the/pin_source", uri, "The token",
+ P11_KIT_PIN_FLAGS_USER_LOGIN);
+
+ CuAssertPtrEquals (tc, NULL, pin);
+
+ p11_kit_uri_free (uri);
+}
+
+static void
+test_pin_register_fallback (CuTest *tc)
+{
+ char *value = "secret";
+ P11KitUri *uri;
+ P11KitPin *pin;
+ int data = 33;
+ size_t length;
+ const unsigned char *ptr;
+
+ uri = p11_kit_uri_new ();
+
+ p11_kit_pin_register_callback (P11_KIT_PIN_FALLBACK, callback_one,
+ &data, destroy_data);
+
+ pin = p11_kit_pin_request ("/the/pin_source", uri, "The token",
+ P11_KIT_PIN_FLAGS_USER_LOGIN);
+
+ CuAssertPtrNotNull (tc, pin);
+ ptr = p11_kit_pin_get_value (pin, &length);
+ CuAssertIntEquals (tc, 3, length);
+ CuAssertTrue (tc, memcmp (ptr, "one", length) == 0);
+ p11_kit_pin_unref (pin);
+
+ p11_kit_pin_register_callback ("/the/pin_source", callback_other,
+ value, NULL);
+
+ pin = p11_kit_pin_request ("/the/pin_source", uri, "The token",
+ P11_KIT_PIN_FLAGS_USER_LOGIN);
+
+ CuAssertPtrNotNull (tc, pin);
+ ptr = p11_kit_pin_get_value (pin, &length);
+ CuAssertIntEquals (tc, 6, length);
+ CuAssertTrue (tc, memcmp (ptr, "secret", length) == 0);
+ p11_kit_pin_unref (pin);
+
+ p11_kit_pin_unregister_callback ("/the/pin_source", callback_other,
+ value);
+
+ p11_kit_pin_unregister_callback (P11_KIT_PIN_FALLBACK, callback_one,
+ &data);
+
+ p11_kit_uri_free (uri);
+}
+
+static void
+test_pin_file (CuTest *tc)
+{
+ P11KitUri *uri;
+ P11KitPin *pin;
+ size_t length;
+ const unsigned char *ptr;
+
+ uri = p11_kit_uri_new ();
+
+ p11_kit_pin_register_callback (P11_KIT_PIN_FALLBACK, p11_kit_pin_file_callback,
+ NULL, NULL);
+
+ pin = p11_kit_pin_request (SRCDIR "/files/test-pinfile", uri, "The token",
+ P11_KIT_PIN_FLAGS_USER_LOGIN);
+
+ CuAssertPtrNotNull (tc, pin);
+ ptr = p11_kit_pin_get_value (pin, &length);
+ CuAssertIntEquals (tc, 12, length);
+ CuAssertTrue (tc, memcmp (ptr, "yogabbagabba", length) == 0);
+ p11_kit_pin_unref (pin);
+
+ pin = p11_kit_pin_request (SRCDIR "/files/nonexistant", uri, "The token",
+ P11_KIT_PIN_FLAGS_USER_LOGIN);
+
+ CuAssertPtrEquals (tc, NULL, pin);
+
+ p11_kit_pin_unregister_callback (P11_KIT_PIN_FALLBACK, p11_kit_pin_file_callback,
+ NULL);
+
+ p11_kit_uri_free (uri);
+}
+
+static void
+test_pin_file_large (CuTest *tc)
+{
+ P11KitUri *uri;
+ P11KitPin *pin;
+ int error;
+
+ uri = p11_kit_uri_new ();
+
+ p11_kit_pin_register_callback (P11_KIT_PIN_FALLBACK, p11_kit_pin_file_callback,
+ NULL, NULL);
+
+ pin = p11_kit_pin_request (SRCDIR "/files/test-pinfile-large", uri, "The token",
+ P11_KIT_PIN_FLAGS_USER_LOGIN);
+
+ error = errno;
+ CuAssertPtrEquals (tc, NULL, pin);
+ CuAssertIntEquals (tc, EFBIG, error);
+
+ p11_kit_pin_unregister_callback (P11_KIT_PIN_FALLBACK, p11_kit_pin_file_callback,
+ NULL);
+
+ p11_kit_uri_free (uri);
+}
+
+static void
+test_pin_ref_unref (CuTest *tc)
+{
+ P11KitPin *pin;
+ P11KitPin *check;
+
+ pin = p11_kit_pin_new_for_string ("crack of lies");
+
+ check = p11_kit_pin_ref (pin);
+ CuAssertPtrEquals (tc, pin, check);
+
+ p11_kit_pin_unref (pin);
+ p11_kit_pin_unref (check);
+}
+
+int
+main (void)
+{
+ CuString *output = CuStringNew ();
+ CuSuite* suite = CuSuiteNew ();
+ int ret;
+
+ p11_library_init ();
+
+ SUITE_ADD_TEST (suite, test_pin_register_unregister);
+ SUITE_ADD_TEST (suite, test_pin_read);
+ SUITE_ADD_TEST (suite, test_pin_read_no_match);
+ SUITE_ADD_TEST (suite, test_pin_register_duplicate);
+ SUITE_ADD_TEST (suite, test_pin_register_fallback);
+ SUITE_ADD_TEST (suite, test_pin_file);
+ SUITE_ADD_TEST (suite, test_pin_file_large);
+ SUITE_ADD_TEST (suite, test_pin_ref_unref);
+
+ CuSuiteRun (suite);
+ CuSuiteSummary (suite, output);
+ CuSuiteDetails (suite, output);
+ printf ("%s\n", output->buffer);
+ ret = suite->failCount;
+ CuSuiteDelete (suite);
+ CuStringDelete (output);
+
+ return ret;
+}
diff --git a/p11-kit/tests/print-messages.c b/p11-kit/tests/print-messages.c
new file mode 100644
index 0000000..5870ad1
--- /dev/null
+++ b/p11-kit/tests/print-messages.c
@@ -0,0 +1,137 @@
+/*
+ * Copyright (c) 2011, Collabora Ltd.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met);
+ *
+ * * Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the
+ * following disclaimer.
+ * * Redistributions in binary form must reproduce the
+ * above copyright notice, this list of conditions and
+ * the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ * * The names of contributors to this software may not be
+ * used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
+ * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * Author: Stef Walter <stefw@collabora.co.uk>
+ */
+
+#include "config.h"
+
+#include <assert.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "p11-kit.h"
+
+int
+main (int argc, char *argv[])
+{
+ if (argc != 1) {
+ fprintf (stderr, "usage: print-messages\n");
+ exit (2);
+ }
+
+ #define X(x) printf ("%s: %s\n", #x, p11_kit_strerror (x))
+ X(CKR_CANCEL);
+ X(CKR_FUNCTION_CANCELED);
+ X(CKR_HOST_MEMORY);
+ X(CKR_SLOT_ID_INVALID);
+ X(CKR_GENERAL_ERROR);
+ X(CKR_FUNCTION_FAILED);
+ X(CKR_ARGUMENTS_BAD);
+ X(CKR_NEED_TO_CREATE_THREADS);
+ X(CKR_CANT_LOCK);
+ X(CKR_ATTRIBUTE_READ_ONLY);
+ X(CKR_ATTRIBUTE_SENSITIVE);
+ X(CKR_ATTRIBUTE_TYPE_INVALID);
+ X(CKR_ATTRIBUTE_VALUE_INVALID);
+ X(CKR_DATA_INVALID);
+ X(CKR_DATA_LEN_RANGE);
+ X(CKR_DEVICE_ERROR);
+ X(CKR_DEVICE_MEMORY);
+ X(CKR_DEVICE_REMOVED);
+ X(CKR_ENCRYPTED_DATA_INVALID);
+ X(CKR_ENCRYPTED_DATA_LEN_RANGE);
+ X(CKR_FUNCTION_NOT_SUPPORTED);
+ X(CKR_KEY_HANDLE_INVALID);
+ X(CKR_KEY_SIZE_RANGE);
+ X(CKR_KEY_TYPE_INCONSISTENT);
+ X(CKR_KEY_NOT_NEEDED);
+ X(CKR_KEY_CHANGED);
+ X(CKR_KEY_NEEDED);
+ X(CKR_KEY_INDIGESTIBLE);
+ X(CKR_KEY_FUNCTION_NOT_PERMITTED);
+ X(CKR_KEY_NOT_WRAPPABLE);
+ X(CKR_KEY_UNEXTRACTABLE);
+ X(CKR_MECHANISM_INVALID);
+ X(CKR_MECHANISM_PARAM_INVALID);
+ X(CKR_OBJECT_HANDLE_INVALID);
+ X(CKR_OPERATION_ACTIVE);
+ X(CKR_OPERATION_NOT_INITIALIZED);
+ X(CKR_PIN_INCORRECT);
+ X(CKR_PIN_INVALID);
+ X(CKR_PIN_LEN_RANGE);
+ X(CKR_PIN_EXPIRED);
+ X(CKR_PIN_LOCKED);
+ X(CKR_SESSION_CLOSED);
+ X(CKR_SESSION_COUNT);
+ X(CKR_SESSION_HANDLE_INVALID);
+ X(CKR_SESSION_READ_ONLY);
+ X(CKR_SESSION_EXISTS);
+ X(CKR_SESSION_READ_ONLY_EXISTS);
+ X(CKR_SESSION_READ_WRITE_SO_EXISTS);
+ X(CKR_SIGNATURE_INVALID);
+ X(CKR_SIGNATURE_LEN_RANGE);
+ X(CKR_TEMPLATE_INCOMPLETE);
+ X(CKR_TEMPLATE_INCONSISTENT);
+ X(CKR_TOKEN_NOT_PRESENT);
+ X(CKR_TOKEN_NOT_RECOGNIZED);
+ X(CKR_TOKEN_WRITE_PROTECTED);
+ X(CKR_UNWRAPPING_KEY_HANDLE_INVALID);
+ X(CKR_UNWRAPPING_KEY_SIZE_RANGE);
+ X(CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT);
+ X(CKR_USER_ALREADY_LOGGED_IN);
+ X(CKR_USER_NOT_LOGGED_IN);
+ X(CKR_USER_PIN_NOT_INITIALIZED);
+ X(CKR_USER_TYPE_INVALID);
+ X(CKR_USER_ANOTHER_ALREADY_LOGGED_IN);
+ X(CKR_USER_TOO_MANY_TYPES);
+ X(CKR_WRAPPED_KEY_INVALID);
+ X(CKR_WRAPPED_KEY_LEN_RANGE);
+ X(CKR_WRAPPING_KEY_HANDLE_INVALID);
+ X(CKR_WRAPPING_KEY_SIZE_RANGE);
+ X(CKR_WRAPPING_KEY_TYPE_INCONSISTENT);
+ X(CKR_RANDOM_SEED_NOT_SUPPORTED);
+ X(CKR_RANDOM_NO_RNG);
+ X(CKR_DOMAIN_PARAMS_INVALID);
+ X(CKR_BUFFER_TOO_SMALL);
+ X(CKR_SAVED_STATE_INVALID);
+ X(CKR_INFORMATION_SENSITIVE);
+ X(CKR_STATE_UNSAVEABLE);
+ X(CKR_CRYPTOKI_NOT_INITIALIZED);
+ X(CKR_CRYPTOKI_ALREADY_INITIALIZED);
+ X(CKR_MUTEX_BAD);
+ X(CKR_MUTEX_NOT_LOCKED);
+ X(CKR_FUNCTION_REJECTED);
+ #undef X
+
+ return 0;
+}
diff --git a/p11-kit/tests/progname-test.c b/p11-kit/tests/progname-test.c
new file mode 100644
index 0000000..bd37400
--- /dev/null
+++ b/p11-kit/tests/progname-test.c
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2012 Stefan Walter
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the
+ * following disclaimer.
+ * * Redistributions in binary form must reproduce the
+ * above copyright notice, this list of conditions and
+ * the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ * * The names of contributors to this software may not be
+ * used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
+ * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * Author: Stef Walter <stef@thewalter.net>
+ */
+
+#include "config.h"
+#include "CuTest.h"
+
+#include "library.h"
+
+#include <assert.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "p11-kit/uri.h"
+#include "p11-kit/p11-kit.h"
+#include "p11-kit/private.h"
+
+static void
+test_progname_default (CuTest *tc)
+{
+ const char *progname;
+
+ progname = _p11_get_progname_unlocked ();
+ CuAssertStrEquals (tc, "progname-test", progname);
+}
+
+static void
+test_progname_set (CuTest *tc)
+{
+ const char *progname;
+
+ p11_kit_set_progname ("love-generation");
+
+ progname = _p11_get_progname_unlocked ();
+ CuAssertStrEquals (tc, "love-generation", progname);
+
+ _p11_set_progname_unlocked (NULL);
+
+ progname = _p11_get_progname_unlocked ();
+ CuAssertStrEquals (tc, "progname-test", progname);
+}
+
+/* Defined in util.c */
+extern char p11_my_progname[];
+
+int
+main (void)
+{
+ CuString *output = CuStringNew ();
+ CuSuite* suite = CuSuiteNew ();
+ int ret;
+
+ p11_library_init ();
+
+ SUITE_ADD_TEST (suite, test_progname_default);
+ SUITE_ADD_TEST (suite, test_progname_set);
+
+ CuSuiteRun (suite);
+ CuSuiteSummary (suite, output);
+ CuSuiteDetails (suite, output);
+ printf ("%s\n", output->buffer);
+ ret = suite->failCount;
+ CuSuiteDelete (suite);
+ CuStringDelete (output);
+ return ret;
+}
diff --git a/p11-kit/tests/test-init.c b/p11-kit/tests/test-init.c
new file mode 100644
index 0000000..5861bbf
--- /dev/null
+++ b/p11-kit/tests/test-init.c
@@ -0,0 +1,320 @@
+/*
+ * Copyright (c) 2011, Collabora Ltd.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the
+ * following disclaimer.
+ * * Redistributions in binary form must reproduce the
+ * above copyright notice, this list of conditions and
+ * the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ * * The names of contributors to this software may not be
+ * used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
+ * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * Author: Stef Walter <stefw@collabora.co.uk>
+ */
+
+#include "config.h"
+#include "CuTest.h"
+
+#include <sys/types.h>
+
+#include "library.h"
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <unistd.h>
+
+#include "p11-kit/p11-kit.h"
+
+#include "mock-module.h"
+
+CK_FUNCTION_LIST module;
+
+#ifdef OS_UNIX
+
+#include <sys/wait.h>
+
+static CK_RV
+mock_C_Initialize__with_fork (CK_VOID_PTR init_args)
+{
+ struct timespec ts = { 0, 100 * 1000 * 1000 };
+ CK_RV rv;
+ pid_t child;
+ pid_t ret;
+ int status;
+
+ rv = mock_C_Initialize (init_args);
+ assert (rv == CKR_OK);
+
+ /* Fork during the initialization */
+ child = fork ();
+ if (child == 0) {
+ nanosleep (&ts, NULL);
+ exit (66);
+ }
+
+ ret = waitpid (child, &status, 0);
+ assert (ret == child);
+ assert (WIFEXITED (status));
+ assert (WEXITSTATUS (status) == 66);
+
+ return CKR_OK;
+}
+
+static void
+test_fork_initialization (CuTest *tc)
+{
+ CK_RV rv;
+
+ /* Build up our own function list */
+ memcpy (&module, &mock_module_no_slots, sizeof (CK_FUNCTION_LIST));
+ module.C_Initialize = mock_C_Initialize__with_fork;
+
+ rv = p11_kit_initialize_module (&module);
+ CuAssertTrue (tc, rv == CKR_OK);
+
+ rv = p11_kit_finalize_module (&module);
+ CuAssertTrue (tc, rv == CKR_OK);
+}
+
+#endif /* OS_UNIX */
+
+static CK_RV
+mock_C_Initialize__with_recursive (CK_VOID_PTR init_args)
+{
+ CK_RV rv;
+
+ rv = mock_C_Initialize (init_args);
+ assert (rv == CKR_OK);
+
+ /* Recursively initialize, this is broken */
+ return p11_kit_initialize_module (&module);
+}
+
+static void
+test_recursive_initialization (CuTest *tc)
+{
+ CK_RV rv;
+
+ /* Build up our own function list */
+ memcpy (&module, &mock_module_no_slots, sizeof (CK_FUNCTION_LIST));
+ module.C_Initialize = mock_C_Initialize__with_recursive;
+
+ rv = p11_kit_initialize_module (&module);
+ CuAssertTrue (tc, rv == CKR_FUNCTION_FAILED);
+}
+
+static p11_mutex_t race_mutex;
+static int initialization_count = 0;
+static int finalization_count = 0;
+
+#include "private.h"
+
+static CK_RV
+mock_C_Initialize__threaded_race (CK_VOID_PTR init_args)
+{
+ /* Atomically increment value */
+ p11_mutex_lock (&race_mutex);
+ initialization_count += 1;
+ p11_mutex_unlock (&race_mutex);
+
+ p11_sleep_ms (100);
+ return CKR_OK;
+}
+
+static CK_RV
+mock_C_Finalize__threaded_race (CK_VOID_PTR reserved)
+{
+ /* Atomically increment value */
+ p11_mutex_lock (&race_mutex);
+ finalization_count += 1;
+ p11_mutex_unlock (&race_mutex);
+
+ p11_sleep_ms (100);
+ return CKR_OK;
+}
+
+static void *
+initialization_thread (void *data)
+{
+ CuTest *tc = data;
+ CK_RV rv;
+
+ rv = p11_kit_initialize_module (&module);
+ CuAssertTrue (tc, rv == CKR_OK);
+
+ return tc;
+}
+
+static void *
+finalization_thread (void *data)
+{
+ CuTest *tc = data;
+ CK_RV rv;
+
+ rv = p11_kit_finalize_module (&module);
+ CuAssertTrue (tc, rv == CKR_OK);
+
+ return tc;
+}
+
+static void
+test_threaded_initialization (CuTest *tc)
+{
+ static const int num_threads = 2;
+ p11_thread_t threads[num_threads];
+ int ret;
+ int i;
+
+ /* Build up our own function list */
+ memcpy (&module, &mock_module_no_slots, sizeof (CK_FUNCTION_LIST));
+ module.C_Initialize = mock_C_Initialize__threaded_race;
+ module.C_Finalize = mock_C_Finalize__threaded_race;
+
+ initialization_count = 0;
+ finalization_count = 0;
+
+ for (i = 0; i < num_threads; i++) {
+ ret = p11_thread_create (&threads[i], initialization_thread, tc);
+ CuAssertIntEquals (tc, 0, ret);
+ CuAssertTrue (tc, threads[i] != 0);
+ }
+
+ for (i = 0; i < num_threads; i++) {
+ ret = p11_thread_join (threads[i]);
+ CuAssertIntEquals (tc, 0, ret);
+ threads[i] = 0;
+ }
+
+ for (i = 0; i < num_threads; i++) {
+ ret = p11_thread_create (&threads[i], finalization_thread, tc);
+ CuAssertIntEquals (tc, 0, ret);
+ CuAssertTrue (tc, threads[i] != 0);
+ }
+
+ for (i = 0; i < num_threads; i++) {
+ ret = p11_thread_join (threads[i]);
+ CuAssertIntEquals (tc, 0, ret);
+ threads[i] = 0;
+ }
+
+ /* C_Initialize should have been called exactly once */
+ CuAssertIntEquals (tc, 1, initialization_count);
+ CuAssertIntEquals (tc, 1, finalization_count);
+}
+
+static CK_RV
+mock_C_Initialize__test_mutexes (CK_VOID_PTR args)
+{
+ CK_C_INITIALIZE_ARGS_PTR init_args;
+ void *mutex = NULL;
+ CK_RV rv;
+
+ assert (args != NULL);
+ init_args = args;
+
+ rv = (init_args->CreateMutex) (&mutex);
+ assert (rv == CKR_OK);
+
+ rv = (init_args->LockMutex) (mutex);
+ assert (rv == CKR_OK);
+
+ rv = (init_args->UnlockMutex) (mutex);
+ assert (rv == CKR_OK);
+
+ rv = (init_args->DestroyMutex) (mutex);
+ assert (rv == CKR_OK);
+
+ return CKR_OK;
+}
+
+static void
+test_mutexes (CuTest *tc)
+{
+ CK_RV rv;
+
+ /* Build up our own function list */
+ memcpy (&module, &mock_module_no_slots, sizeof (CK_FUNCTION_LIST));
+ module.C_Initialize = mock_C_Initialize__test_mutexes;
+
+ rv = p11_kit_initialize_module (&module);
+ CuAssertTrue (tc, rv == CKR_OK);
+
+ rv = p11_kit_finalize_module (&module);
+ CuAssertTrue (tc, rv == CKR_OK);
+}
+
+static void
+test_load_and_initialize (CuTest *tc)
+{
+ CK_FUNCTION_LIST_PTR module;
+ CK_INFO info;
+ CK_RV rv;
+ int ret;
+
+ rv = p11_kit_load_initialize_module (BUILDDIR "/.libs/mock-one" SHLEXT, &module);
+ CuAssertTrue (tc, rv == CKR_OK);
+ CuAssertTrue (tc, module != NULL);
+
+ rv = (module->C_GetInfo) (&info);
+ CuAssertTrue (tc, rv == CKR_OK);
+
+ ret = memcmp (info.manufacturerID, "MOCK MANUFACTURER ", 32);
+ CuAssertTrue (tc, ret == 0);
+
+ rv = p11_kit_finalize_module (module);
+ CuAssertTrue (tc, ret == CKR_OK);
+}
+
+int
+main (void)
+{
+ CuString *output = CuStringNew ();
+ CuSuite* suite = CuSuiteNew ();
+ int ret;
+
+ p11_mutex_init (&race_mutex);
+ mock_module_init ();
+ p11_library_init ();
+
+#ifdef OS_UNIX
+ SUITE_ADD_TEST (suite, test_fork_initialization);
+#endif
+
+ SUITE_ADD_TEST (suite, test_recursive_initialization);
+ SUITE_ADD_TEST (suite, test_threaded_initialization);
+ SUITE_ADD_TEST (suite, test_mutexes);
+ SUITE_ADD_TEST (suite, test_load_and_initialize);
+
+ CuSuiteRun (suite);
+ CuSuiteSummary (suite, output);
+ CuSuiteDetails (suite, output);
+ printf ("%s\n", output->buffer);
+ ret = suite->failCount;
+ CuSuiteDelete (suite);
+ CuStringDelete (output);
+
+ return ret;
+}
diff --git a/p11-kit/tests/test-modules.c b/p11-kit/tests/test-modules.c
new file mode 100644
index 0000000..159e04e
--- /dev/null
+++ b/p11-kit/tests/test-modules.c
@@ -0,0 +1,246 @@
+/*
+ * Copyright (c) 2012 Red Hat Inc
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the
+ * following disclaimer.
+ * * Redistributions in binary form must reproduce the
+ * above copyright notice, this list of conditions and
+ * the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ * * The names of contributors to this software may not be
+ * used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
+ * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * Author: Stef Walter <stefw@redhat.com>
+ */
+
+#include "config.h"
+#include "CuTest.h"
+
+#include <errno.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "library.h"
+#include "p11-kit.h"
+#include "private.h"
+#include "dict.h"
+
+static CK_FUNCTION_LIST_PTR_PTR
+initialize_and_get_modules (CuTest *tc)
+{
+ CK_FUNCTION_LIST_PTR_PTR modules;
+ CK_RV rv;
+
+ rv = p11_kit_initialize_registered ();
+ CuAssertIntEquals (tc, CKR_OK, rv);
+ modules = p11_kit_registered_modules ();
+ CuAssertTrue (tc, modules != NULL && modules[0] != NULL);
+
+ return modules;
+}
+
+static void
+finalize_and_free_modules (CuTest *tc,
+ CK_FUNCTION_LIST_PTR_PTR modules)
+{
+ CK_RV rv;
+
+ free (modules);
+ rv = p11_kit_finalize_registered ();
+ CuAssertIntEquals (tc, CKR_OK, rv);
+}
+
+static void
+test_no_duplicates (CuTest *tc)
+{
+ CK_FUNCTION_LIST_PTR_PTR modules;
+ p11_dict *paths;
+ p11_dict *funcs;
+ char *path;
+ int i;
+
+ modules = initialize_and_get_modules (tc);
+ paths = p11_dict_new (p11_dict_str_hash, p11_dict_str_equal, NULL, NULL);
+ funcs = p11_dict_new (p11_dict_direct_hash, p11_dict_direct_equal, NULL, NULL);
+
+ /* The loaded modules should not contain duplicates */
+ for (i = 0; modules[i] != NULL; i++) {
+ path = p11_kit_registered_option (modules[i], "module");
+
+ if (p11_dict_get (funcs, modules[i]))
+ CuAssert (tc, "found duplicate function list pointer", 0);
+ if (p11_dict_get (paths, path))
+ CuAssert (tc, "found duplicate path name", 0);
+
+ if (!p11_dict_set (funcs, modules[i], ""))
+ CuAssert (tc, "shouldn't be reached", 0);
+ if (!p11_dict_set (paths, path, ""))
+ CuAssert (tc, "shouldn't be reached", 0);
+ }
+
+ p11_dict_free (paths);
+ p11_dict_free (funcs);
+ finalize_and_free_modules (tc, modules);
+}
+
+static CK_FUNCTION_LIST_PTR
+lookup_module_with_name (CuTest *tc,
+ CK_FUNCTION_LIST_PTR_PTR modules,
+ const char *name)
+{
+ CK_FUNCTION_LIST_PTR match = NULL;
+ CK_FUNCTION_LIST_PTR module;
+ char *module_name;
+ int i;
+
+ for (i = 0; match == NULL && modules[i] != NULL; i++) {
+ module_name = p11_kit_registered_module_to_name (modules[i]);
+ CuAssertPtrNotNull (tc, module_name);
+ if (strcmp (module_name, name) == 0)
+ match = modules[i];
+ free (module_name);
+ }
+
+ /*
+ * As a side effect, we should check that the results of this function
+ * matches the above search.
+ */
+ module = p11_kit_registered_name_to_module (name);
+ CuAssert(tc, "different result from p11_kit_registered_name_to_module()",
+ module == match);
+
+ return match;
+}
+
+static void
+test_disable (CuTest *tc)
+{
+ CK_FUNCTION_LIST_PTR_PTR modules;
+
+ /*
+ * The module four should be present, as we don't match any prognames
+ * that it has disabled.
+ */
+
+ modules = initialize_and_get_modules (tc);
+ CuAssertTrue (tc, lookup_module_with_name (tc, modules, "four") != NULL);
+ finalize_and_free_modules (tc, modules);
+
+ /*
+ * The module two shouldn't have been loaded, because in its config
+ * file we have:
+ *
+ * disable-in: test-disable
+ */
+
+ p11_kit_set_progname ("test-disable");
+
+ modules = initialize_and_get_modules (tc);
+ CuAssertTrue (tc, lookup_module_with_name (tc, modules, "four") == NULL);
+ finalize_and_free_modules (tc, modules);
+
+ p11_kit_set_progname (NULL);
+}
+
+static void
+test_disable_later (CuTest *tc)
+{
+ CK_FUNCTION_LIST_PTR_PTR modules;
+ CK_RV rv;
+
+ /*
+ * The module two shouldn't be matched, because in its config
+ * file we have:
+ *
+ * disable-in: test-disable
+ */
+
+ rv = p11_kit_initialize_registered ();
+ CuAssertIntEquals (tc, CKR_OK, rv);
+
+ p11_kit_set_progname ("test-disable");
+
+ modules = p11_kit_registered_modules ();
+ CuAssertTrue (tc, modules != NULL && modules[0] != NULL);
+
+ CuAssertTrue (tc, lookup_module_with_name (tc, modules, "two") == NULL);
+ finalize_and_free_modules (tc, modules);
+
+ p11_kit_set_progname (NULL);
+}
+
+static void
+test_enable (CuTest *tc)
+{
+ CK_FUNCTION_LIST_PTR_PTR modules;
+
+ /*
+ * The module three should not be present, as we don't match the current
+ * program.
+ */
+
+ modules = initialize_and_get_modules (tc);
+ CuAssertTrue (tc, lookup_module_with_name (tc, modules, "three") == NULL);
+ finalize_and_free_modules (tc, modules);
+
+ /*
+ * The module three should be loaded here , because in its config
+ * file we have:
+ *
+ * enable-in: test-enable
+ */
+
+ p11_kit_set_progname ("test-enable");
+
+ modules = initialize_and_get_modules (tc);
+ CuAssertTrue (tc, lookup_module_with_name (tc, modules, "three") != NULL);
+ finalize_and_free_modules (tc, modules);
+
+ p11_kit_set_progname (NULL);
+}
+
+int
+main (void)
+{
+ CuString *output = CuStringNew ();
+ CuSuite* suite = CuSuiteNew ();
+ int ret;
+
+ p11_library_init ();
+
+ SUITE_ADD_TEST (suite, test_no_duplicates);
+ SUITE_ADD_TEST (suite, test_disable);
+ SUITE_ADD_TEST (suite, test_disable_later);
+ SUITE_ADD_TEST (suite, test_enable);
+
+ p11_kit_be_quiet ();
+
+ CuSuiteRun (suite);
+ CuSuiteSummary (suite, output);
+ CuSuiteDetails (suite, output);
+ printf ("%s\n", output->buffer);
+ ret = suite->failCount;
+ CuSuiteDelete (suite);
+ CuStringDelete (output);
+ return ret;
+}
diff --git a/p11-kit/tests/uri-test.c b/p11-kit/tests/uri-test.c
new file mode 100644
index 0000000..0e3e722
--- /dev/null
+++ b/p11-kit/tests/uri-test.c
@@ -0,0 +1,1223 @@
+/*
+ * Copyright (c) 2011, Collabora Ltd.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above
+ * copyright notice, this list of conditions and the
+ * following disclaimer.
+ * * Redistributions in binary form must reproduce the
+ * above copyright notice, this list of conditions and
+ * the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ * * The names of contributors to this software may not be
+ * used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
+ * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * Author: Stef Walter <stefw@collabora.co.uk>
+ */
+
+#include "config.h"
+#include "CuTest.h"
+
+#include "library.h"
+
+#include <assert.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "p11-kit/uri.h"
+#include "p11-kit/private.h"
+
+static int
+is_module_empty (P11KitUri *uri)
+{
+ CK_INFO_PTR info = p11_kit_uri_get_module_info (uri);
+ return (info->libraryDescription[0] == 0 &&
+ info->manufacturerID[0] == 0 &&
+ info->libraryVersion.major == (CK_BYTE)-1 &&
+ info->libraryVersion.minor == (CK_BYTE)-1);
+}
+
+static int
+is_token_empty (P11KitUri *uri)
+{
+ CK_TOKEN_INFO_PTR token = p11_kit_uri_get_token_info (uri);
+ return (token->serialNumber[0] == 0 &&
+ token->manufacturerID[0] == 0 &&
+ token->label[0] == 0 &&
+ token->model[0] == 0);
+}
+
+static int
+are_attributes_empty (P11KitUri *uri)
+{
+ return (p11_kit_uri_get_attribute (uri, CKA_LABEL) == NULL &&
+ p11_kit_uri_get_attribute (uri, CKA_ID) == NULL &&
+ p11_kit_uri_get_attribute (uri, CKA_CLASS) == NULL);
+}
+
+static void
+test_uri_parse (CuTest *tc)
+{
+ P11KitUri *uri;
+ int ret;
+
+ uri = p11_kit_uri_new ();
+ CuAssertPtrNotNull (tc, uri);
+
+ ret = p11_kit_uri_parse ("pkcs11:", P11_KIT_URI_FOR_MODULE, uri);
+ CuAssertIntEquals (tc, P11_KIT_URI_OK, ret);
+
+ CuAssertTrue (tc, is_module_empty (uri));
+ CuAssertTrue (tc, is_token_empty (uri));
+ CuAssertTrue (tc, are_attributes_empty (uri));
+
+ p11_kit_uri_free (uri);
+}
+
+static void
+test_uri_parse_bad_scheme (CuTest *tc)
+{
+ P11KitUri *uri;
+ int ret;
+
+ uri = p11_kit_uri_new ();
+ CuAssertPtrNotNull (tc, uri);
+
+ ret = p11_kit_uri_parse ("http:\\example.com\test", P11_KIT_URI_FOR_ANY, uri);
+ CuAssertIntEquals (tc, P11_KIT_URI_BAD_SCHEME, ret);
+
+ p11_kit_uri_free (uri);
+}
+
+static void
+test_uri_parse_with_label (CuTest *tc)
+{
+ CK_ATTRIBUTE_PTR attr;
+ P11KitUri *uri;
+ int ret;
+
+ uri = p11_kit_uri_new ();
+ CuAssertPtrNotNull (tc, uri);
+
+ ret = p11_kit_uri_parse ("pkcs11:object=Test%20Label", P11_KIT_URI_FOR_ANY, uri);
+ CuAssertIntEquals (tc, P11_KIT_URI_OK, ret);
+
+ CuAssertTrue (tc, is_module_empty (uri));
+ CuAssertTrue (tc, is_token_empty (uri));
+
+ attr = p11_kit_uri_get_attribute (uri, CKA_LABEL);
+ CuAssertPtrNotNull (tc, attr);
+ CuAssertTrue (tc, attr->ulValueLen == strlen ("Test Label"));
+ CuAssertTrue (tc, memcmp (attr->pValue, "Test Label", attr->ulValueLen) == 0);
+
+ p11_kit_uri_free (uri);
+}
+
+static void
+test_uri_parse_with_label_and_klass (CuTest *tc)
+{
+ CK_ATTRIBUTE_PTR attr;
+ P11KitUri *uri;
+ int ret;
+
+ uri = p11_kit_uri_new ();
+ CuAssertPtrNotNull (tc, uri);
+
+ ret = p11_kit_uri_parse ("pkcs11:object=Test%20Label;object-type=cert", P11_KIT_URI_FOR_ANY, uri);
+ CuAssertIntEquals (tc, P11_KIT_URI_OK, ret);
+
+ attr = p11_kit_uri_get_attribute (uri, CKA_LABEL);
+ CuAssertPtrNotNull (tc, attr);
+ CuAssertTrue (tc, attr->ulValueLen == strlen ("Test Label"));
+ CuAssertTrue (tc, memcmp (attr->pValue, "Test Label", attr->ulValueLen) == 0);
+
+ attr = p11_kit_uri_get_attribute (uri, CKA_CLASS);
+ CuAssertPtrNotNull (tc, attr);
+ CuAssertTrue (tc, attr->ulValueLen == sizeof (CK_OBJECT_CLASS));
+ CuAssertTrue (tc, *((CK_OBJECT_CLASS_PTR)attr->pValue) == CKO_CERTIFICATE);
+
+ p11_kit_uri_free (uri);
+}
+
+static void
+test_uri_parse_with_id (CuTest *tc)
+{
+ CK_ATTRIBUTE_PTR attr;
+ P11KitUri *uri;
+ int ret;
+
+ uri = p11_kit_uri_new ();
+ CuAssertPtrNotNull (tc, uri);
+
+ ret = p11_kit_uri_parse ("pkcs11:id=%54%45%53%54%00", P11_KIT_URI_FOR_OBJECT, uri);
+ CuAssertIntEquals (tc, P11_KIT_URI_OK, ret);
+
+ /* Note that there's a NULL in the attribute (end) */
+ attr = p11_kit_uri_get_attribute (uri, CKA_ID);
+ CuAssertPtrNotNull (tc, attr);
+ CuAssertTrue (tc, attr->ulValueLen == 5);
+ CuAssertTrue (tc, memcmp (attr->pValue, "TEST", 5) == 0);
+
+
+ p11_kit_uri_free (uri);
+}
+
+static void
+test_uri_parse_with_bad_string_encoding (CuTest *tc)
+{
+ P11KitUri *uri;
+ int ret;
+
+ uri = p11_kit_uri_new ();
+ CuAssertPtrNotNull (tc, uri);
+
+ ret = p11_kit_uri_parse ("pkcs11:object=Test%", P11_KIT_URI_FOR_OBJECT, uri);
+ CuAssertIntEquals (tc, P11_KIT_URI_BAD_ENCODING, ret);
+
+ p11_kit_uri_free (uri);
+}
+
+static void
+test_uri_parse_with_bad_hex_encoding (CuTest *tc)
+{
+ P11KitUri *uri;
+ int ret;
+
+ uri = p11_kit_uri_new ();
+ CuAssertPtrNotNull (tc, uri);
+
+ ret = p11_kit_uri_parse ("pkcs11:object=T%xxest", P11_KIT_URI_FOR_OBJECT, uri);
+ CuAssertIntEquals (tc, P11_KIT_URI_BAD_ENCODING, ret);
+
+ p11_kit_uri_free (uri);
+}
+
+static int
+is_space_string (CK_UTF8CHAR_PTR string, CK_ULONG size, const char *check)
+{
+ size_t i, len = strlen (check);
+ if (len > size)
+ return 0;
+ if (memcmp (string, check, len) != 0)
+ return 0;
+ for (i = len; i < size; ++i)
+ if (string[i] != ' ')
+ return 0;
+ return 1;
+}
+
+static void
+test_uri_parse_with_token (CuTest *tc)
+{
+ P11KitUri *uri = NULL;
+ CK_TOKEN_INFO_PTR token;
+ int ret;
+
+ uri = p11_kit_uri_new ();
+ CuAssertPtrNotNull (tc, uri);
+
+ ret = p11_kit_uri_parse ("pkcs11:token=Token%20Label;serial=3333;model=Deluxe;manufacturer=Me",
+ P11_KIT_URI_FOR_TOKEN, uri);
+ CuAssertIntEquals (tc, P11_KIT_URI_OK, ret);
+
+ token = p11_kit_uri_get_token_info (uri);
+ CuAssertTrue (tc, is_space_string (token->label, sizeof (token->label), "Token Label"));
+ CuAssertTrue (tc, is_space_string (token->serialNumber, sizeof (token->serialNumber), "3333"));
+ CuAssertTrue (tc, is_space_string (token->model, sizeof (token->model), "Deluxe"));
+ CuAssertTrue (tc, is_space_string (token->manufacturerID, sizeof (token->manufacturerID), "Me"));
+
+ p11_kit_uri_free (uri);
+}
+
+static void
+test_uri_parse_with_token_bad_encoding (CuTest *tc)
+{
+ P11KitUri *uri;
+ int ret;
+
+ uri = p11_kit_uri_new ();
+ CuAssertPtrNotNull (tc, uri);
+
+ ret = p11_kit_uri_parse ("pkcs11:token=Token%", P11_KIT_URI_FOR_TOKEN, uri);
+ CuAssertIntEquals (tc, P11_KIT_URI_BAD_ENCODING, ret);
+
+ p11_kit_uri_free (uri);
+}
+
+static void
+test_uri_parse_with_bad_syntax (CuTest *tc)
+{
+ P11KitUri *uri;
+ int ret;
+
+ uri = p11_kit_uri_new ();
+ CuAssertPtrNotNull (tc, uri);
+
+ ret = p11_kit_uri_parse ("pkcs11:token", P11_KIT_URI_FOR_ANY, uri);
+ CuAssertIntEquals (tc, P11_KIT_URI_BAD_SYNTAX, ret);
+
+ p11_kit_uri_free (uri);
+}
+
+static void
+test_uri_parse_with_spaces (CuTest *tc)
+{
+ P11KitUri *uri = NULL;
+ CK_INFO_PTR info;
+ int ret;
+
+ uri = p11_kit_uri_new ();
+ CuAssertPtrNotNull (tc, uri);
+
+ ret = p11_kit_uri_parse ("pkc\ns11: lib rary-desc\rrip \n tion =The%20Library;\n\n\nlibrary-manufacturer=\rMe",
+ P11_KIT_URI_FOR_MODULE, uri);
+ CuAssertIntEquals (tc, P11_KIT_URI_OK, ret);
+
+ info = p11_kit_uri_get_module_info (uri);
+
+ CuAssertTrue (tc, is_space_string (info->manufacturerID, sizeof (info->manufacturerID), "Me"));
+ CuAssertTrue (tc, is_space_string (info->libraryDescription, sizeof (info->libraryDescription), "The Library"));
+
+ p11_kit_uri_free (uri);
+}
+
+
+static void
+test_uri_parse_with_library (CuTest *tc)
+{
+ P11KitUri *uri = NULL;
+ CK_INFO_PTR info;
+ int ret;
+
+ uri = p11_kit_uri_new ();
+ CuAssertPtrNotNull (tc, uri);
+
+ ret = p11_kit_uri_parse ("pkcs11:library-description=The%20Library;library-manufacturer=Me",
+ P11_KIT_URI_FOR_MODULE, uri);
+ CuAssertIntEquals (tc, P11_KIT_URI_OK, ret);
+
+ info = p11_kit_uri_get_module_info (uri);
+
+ CuAssertTrue (tc, is_space_string (info->manufacturerID, sizeof (info->manufacturerID), "Me"));
+ CuAssertTrue (tc, is_space_string (info->libraryDescription, sizeof (info->libraryDescription), "The Library"));
+
+ p11_kit_uri_free (uri);
+}
+
+static void
+test_uri_parse_with_library_bad_encoding (CuTest *tc)
+{
+ P11KitUri *uri;
+ int ret;
+
+ uri = p11_kit_uri_new ();
+ CuAssertPtrNotNull (tc, uri);
+
+ ret = p11_kit_uri_parse ("pkcs11:library-description=Library%", P11_KIT_URI_FOR_MODULE, uri);
+ CuAssertIntEquals (tc, P11_KIT_URI_BAD_ENCODING, ret);
+
+ p11_kit_uri_free (uri);
+}
+
+static void
+test_uri_build_empty (CuTest *tc)
+{
+ P11KitUri *uri;
+ char *string;
+ int ret;
+
+ uri = p11_kit_uri_new ();
+ CuAssertPtrNotNull (tc, uri);
+
+ ret = p11_kit_uri_format (uri, P11_KIT_URI_FOR_ANY, &string);
+ CuAssertIntEquals (tc, P11_KIT_URI_OK, ret);
+ CuAssertStrEquals (tc, "pkcs11:", string);
+ free (string);
+
+ p11_kit_uri_free (uri);
+}
+
+static void
+set_space_string (CK_BYTE_PTR buffer, CK_ULONG length, const char *string)
+{
+ size_t len = strlen (string);
+ assert (len <= length);
+ memset (buffer, ' ', length);
+ memcpy (buffer, string, len);
+}
+
+static void
+test_uri_build_with_token_info (CuTest *tc)
+{
+ char *string = NULL;
+ P11KitUri *uri;
+ P11KitUri *check;
+ CK_TOKEN_INFO_PTR token;
+ int ret;
+
+ uri = p11_kit_uri_new ();
+ CuAssertPtrNotNull (tc, uri);
+
+ token = p11_kit_uri_get_token_info (uri);
+ set_space_string (token->label, sizeof (token->label), "The Label");
+ set_space_string (token->serialNumber, sizeof (token->serialNumber), "44444");
+ set_space_string (token->manufacturerID, sizeof (token->manufacturerID), "Me");
+ set_space_string (token->model, sizeof (token->model), "Deluxe");
+
+ ret = p11_kit_uri_format (uri, P11_KIT_URI_FOR_ANY, &string);
+ CuAssertIntEquals (tc, P11_KIT_URI_OK, ret);
+ CuAssertPtrNotNull (tc, string);
+
+ check = p11_kit_uri_new ();
+ CuAssertPtrNotNull (tc, check);
+
+ ret = p11_kit_uri_parse (string, P11_KIT_URI_FOR_TOKEN, check);
+ CuAssertIntEquals (tc, P11_KIT_URI_OK, ret);
+
+ p11_kit_uri_match_token_info (check, p11_kit_uri_get_token_info (uri));
+
+ p11_kit_uri_free (uri);
+ p11_kit_uri_free (check);
+
+ CuAssertTrue (tc, strstr (string, "token=The%20Label") != NULL);
+ CuAssertTrue (tc, strstr (string, "serial=44444") != NULL);
+ CuAssertTrue (tc, strstr (string, "manufacturer=Me") != NULL);
+ CuAssertTrue (tc, strstr (string, "model=Deluxe") != NULL);
+
+ free (string);
+}
+
+static void
+test_uri_build_with_token_null_info (CuTest *tc)
+{
+ char *string = NULL;
+ P11KitUri *uri;
+ CK_TOKEN_INFO_PTR token;
+ int ret;
+
+ uri = p11_kit_uri_new ();
+ CuAssertPtrNotNull (tc, uri);
+
+ token = p11_kit_uri_get_token_info (uri);
+ set_space_string (token->label, sizeof (token->label), "The Label");
+
+ ret = p11_kit_uri_format (uri, P11_KIT_URI_FOR_ANY, &string);
+ CuAssertIntEquals (tc, P11_KIT_URI_OK, ret);
+
+ CuAssertTrue (tc, strstr (string, "token=The%20Label") != NULL);
+ CuAssertTrue (tc, strstr (string, "serial=") == NULL);
+
+ free (string);
+ p11_kit_uri_free (uri);
+}
+
+static void
+test_uri_build_with_token_empty_info (CuTest *tc)
+{
+ char *string = NULL;
+ P11KitUri *uri;
+ CK_TOKEN_INFO_PTR token;
+ int ret;
+
+ uri = p11_kit_uri_new ();
+ CuAssertPtrNotNull (tc, uri);
+
+ token = p11_kit_uri_get_token_info (uri);
+ set_space_string (token->label, sizeof (token->label), "");
+ set_space_string (token->serialNumber, sizeof (token->serialNumber), "");
+
+ ret = p11_kit_uri_format (uri, P11_KIT_URI_FOR_ANY, &string);
+ CuAssertIntEquals (tc, P11_KIT_URI_OK, ret);
+
+ CuAssertTrue (tc, strstr (string, "token=") != NULL);
+ CuAssertTrue (tc, strstr (string, "serial=") != NULL);
+
+ free (string);
+ p11_kit_uri_free (uri);
+}
+
+static void
+test_uri_build_with_attributes (CuTest *tc)
+{
+ char *string = NULL;
+ P11KitUri *uri;
+ P11KitUri *check;
+ CK_OBJECT_CLASS klass;
+ CK_ATTRIBUTE_PTR attr;
+ CK_ATTRIBUTE at;
+ int ret;
+
+ uri = p11_kit_uri_new ();
+ CuAssertPtrNotNull (tc, uri);
+
+ at.type = CKA_LABEL;
+ at.pValue = "The Label";
+ at.ulValueLen = 9;
+ ret = p11_kit_uri_set_attribute (uri, &at);
+
+ at.type = CKA_ID;
+ at.pValue = "HELLO";
+ at.ulValueLen = 5;
+ ret = p11_kit_uri_set_attribute (uri, &at);
+
+ klass = CKO_DATA;
+ at.type = CKA_CLASS;
+ at.pValue = &klass;
+ at.ulValueLen = sizeof (klass);
+ ret = p11_kit_uri_set_attribute (uri, &at);
+
+ ret = p11_kit_uri_format (uri, P11_KIT_URI_FOR_ANY, &string);
+ CuAssertIntEquals (tc, P11_KIT_URI_OK, ret);
+
+ check = p11_kit_uri_new ();
+ CuAssertPtrNotNull (tc, check);
+
+ ret = p11_kit_uri_parse (string, P11_KIT_URI_FOR_ANY, check);
+ CuAssertIntEquals (tc, P11_KIT_URI_OK, ret);
+
+ attr = p11_kit_uri_get_attribute (check, CKA_LABEL);
+ CuAssertPtrNotNull (tc, attr);
+ CuAssertTrue (tc, attr->ulValueLen == 9);
+ CuAssertTrue (tc, memcmp (attr->pValue, "The Label", attr->ulValueLen) == 0);
+
+ attr = p11_kit_uri_get_attribute (check, CKA_CLASS);
+ CuAssertPtrNotNull (tc, attr);
+ CuAssertTrue (tc, attr->ulValueLen == sizeof (klass));
+ CuAssertTrue (tc, *((CK_OBJECT_CLASS_PTR)attr->pValue) == klass);
+
+ attr = p11_kit_uri_get_attribute (check, CKA_ID);
+ CuAssertPtrNotNull (tc, attr);
+ CuAssertTrue (tc, attr->ulValueLen == 5);
+ CuAssertTrue (tc, memcmp (attr->pValue, "HELLO", attr->ulValueLen) == 0);
+
+ p11_kit_uri_free (check);
+
+ CuAssertTrue (tc, strstr (string, "object=The%20Label") != NULL);
+ CuAssertTrue (tc, strstr (string, "object-type=data") != NULL);
+ CuAssertTrue (tc, strstr (string, "id=%48%45%4c%4c%4f") != NULL);
+
+ free (string);
+ p11_kit_uri_free (uri);
+}
+
+static void
+test_uri_parse_private_key (CuTest *tc)
+{
+ P11KitUri *uri;
+ CK_ATTRIBUTE_PTR attr;
+ int ret;
+
+ uri = p11_kit_uri_new ();
+ CuAssertPtrNotNull (tc, uri);
+
+ ret = p11_kit_uri_parse ("pkcs11:object-type=private", P11_KIT_URI_FOR_OBJECT, uri);
+ CuAssertIntEquals (tc, P11_KIT_URI_OK, ret);
+
+ attr = p11_kit_uri_get_attribute (uri, CKA_CLASS);
+ CuAssertPtrNotNull (tc, attr);
+ CuAssertTrue (tc, attr->ulValueLen == sizeof (CK_OBJECT_CLASS));
+ CuAssertTrue (tc, *((CK_OBJECT_CLASS_PTR)attr->pValue) == CKO_PRIVATE_KEY);
+
+ p11_kit_uri_free (uri);
+}
+
+static void
+test_uri_parse_secret_key (CuTest *tc)
+{
+ P11KitUri *uri;
+ CK_ATTRIBUTE_PTR attr;
+ int ret;
+
+ uri = p11_kit_uri_new ();
+ CuAssertPtrNotNull (tc, uri);
+
+ ret = p11_kit_uri_parse ("pkcs11:object-type=secret-key", P11_KIT_URI_FOR_OBJECT, uri);
+ CuAssertIntEquals (tc, P11_KIT_URI_OK, ret);
+
+ attr = p11_kit_uri_get_attribute (uri, CKA_CLASS);
+ CuAssertPtrNotNull (tc, attr);
+ CuAssertTrue (tc, attr->ulValueLen == sizeof (CK_OBJECT_CLASS));
+ CuAssertTrue (tc, *((CK_OBJECT_CLASS_PTR)attr->pValue) == CKO_SECRET_KEY);
+
+ p11_kit_uri_free (uri);
+}
+
+static void
+test_uri_parse_library_version (CuTest *tc)
+{
+ P11KitUri *uri;
+ CK_INFO_PTR info;
+ int ret;
+
+ uri = p11_kit_uri_new ();
+ CuAssertPtrNotNull (tc, uri);
+
+ ret = p11_kit_uri_parse ("pkcs11:library-version=2.101", P11_KIT_URI_FOR_MODULE_WITH_VERSION, uri);
+ CuAssertIntEquals (tc, P11_KIT_URI_OK, ret);
+
+ info = p11_kit_uri_get_module_info (uri);
+ CuAssertIntEquals (tc, 2, info->libraryVersion.major);
+ CuAssertIntEquals (tc, 101, info->libraryVersion.minor);
+
+ ret = p11_kit_uri_parse ("pkcs11:library-version=23", P11_KIT_URI_FOR_MODULE_WITH_VERSION, uri);
+ CuAssertIntEquals (tc, P11_KIT_URI_OK, ret);
+
+ info = p11_kit_uri_get_module_info (uri);
+ CuAssertIntEquals (tc, 23, info->libraryVersion.major);
+ CuAssertIntEquals (tc, 0, info->libraryVersion.minor);
+
+ ret = p11_kit_uri_parse ("pkcs11:library-version=23.", P11_KIT_URI_FOR_MODULE_WITH_VERSION, uri);
+ CuAssertIntEquals (tc, P11_KIT_URI_BAD_VERSION, ret);
+
+ ret = p11_kit_uri_parse ("pkcs11:library-version=a.a", P11_KIT_URI_FOR_MODULE_WITH_VERSION, uri);
+ CuAssertIntEquals (tc, P11_KIT_URI_BAD_VERSION, ret);
+
+ ret = p11_kit_uri_parse ("pkcs11:library-version=.23", P11_KIT_URI_FOR_MODULE_WITH_VERSION, uri);
+ CuAssertIntEquals (tc, P11_KIT_URI_BAD_VERSION, ret);
+
+ ret = p11_kit_uri_parse ("pkcs11:library-version=1000", P11_KIT_URI_FOR_MODULE_WITH_VERSION, uri);
+ CuAssertIntEquals (tc, P11_KIT_URI_BAD_VERSION, ret);
+
+ ret = p11_kit_uri_parse ("pkcs11:library-version=2.1000", P11_KIT_URI_FOR_MODULE_WITH_VERSION, uri);
+ CuAssertIntEquals (tc, P11_KIT_URI_BAD_VERSION, ret);
+
+ p11_kit_uri_free (uri);
+}
+
+static void
+test_uri_parse_parse_unknown_object_type (CuTest *tc)
+{
+ P11KitUri *uri;
+ CK_ATTRIBUTE_PTR attr;
+ int ret;
+
+ uri = p11_kit_uri_new ();
+ CuAssertPtrNotNull (tc, uri);
+
+ ret = p11_kit_uri_parse ("pkcs11:object-type=unknown", P11_KIT_URI_FOR_OBJECT, uri);
+ CuAssertIntEquals (tc, P11_KIT_URI_OK, ret);
+
+ attr = p11_kit_uri_get_attribute (uri, CKA_CLASS);
+ CuAssertPtrEquals (tc, NULL, attr);
+
+ p11_kit_uri_free (uri);
+}
+
+static void
+test_uri_parse_unrecognized (CuTest *tc)
+{
+ P11KitUri *uri;
+ int ret;
+
+ uri = p11_kit_uri_new ();
+ CuAssertPtrNotNull (tc, uri);
+
+ ret = p11_kit_uri_parse ("pkcs11:x-blah=some-value", P11_KIT_URI_FOR_ANY, uri);
+ CuAssertIntEquals (tc, P11_KIT_URI_OK, ret);
+
+ ret = p11_kit_uri_any_unrecognized (uri);
+ CuAssertIntEquals (tc, 1, ret);
+
+ p11_kit_uri_free (uri);
+}
+
+static void
+test_uri_parse_too_long_is_unrecognized (CuTest *tc)
+{
+ P11KitUri *uri;
+ int ret;
+
+ uri = p11_kit_uri_new ();
+ CuAssertPtrNotNull (tc, uri);
+
+ ret = p11_kit_uri_parse ("pkcs11:model=a-value-that-is-too-long-for-the-field-that-it-goes-with",
+ P11_KIT_URI_FOR_ANY, uri);
+ CuAssertIntEquals (tc, P11_KIT_URI_OK, ret);
+
+ ret = p11_kit_uri_any_unrecognized (uri);
+ CuAssertIntEquals (tc, 1, ret);
+
+ p11_kit_uri_free (uri);
+}
+
+
+
+static void
+test_uri_build_object_type_cert (CuTest *tc)
+{
+ CK_ATTRIBUTE attr;
+ CK_OBJECT_CLASS klass;
+ P11KitUri *uri;
+ char *string;
+ int ret;
+
+ uri = p11_kit_uri_new ();
+ CuAssertPtrNotNull (tc, uri);
+
+ klass = CKO_CERTIFICATE;
+ attr.type = CKA_CLASS;
+ attr.pValue = &klass;
+ attr.ulValueLen = sizeof (klass);
+ p11_kit_uri_set_attribute (uri, &attr);
+
+ ret = p11_kit_uri_format (uri, P11_KIT_URI_FOR_ANY, &string);
+ CuAssertIntEquals (tc, P11_KIT_URI_OK, ret);
+ CuAssertTrue (tc, strstr (string, "object-type=cert") != NULL);
+
+ p11_kit_uri_free (uri);
+ free (string);
+}
+
+static void
+test_uri_build_object_type_private (CuTest *tc)
+{
+ CK_ATTRIBUTE attr;
+ CK_OBJECT_CLASS klass;
+ P11KitUri *uri;
+ char *string;
+ int ret;
+
+ uri = p11_kit_uri_new ();
+ CuAssertPtrNotNull (tc, uri);
+
+ klass = CKO_PRIVATE_KEY;
+ attr.type = CKA_CLASS;
+ attr.pValue = &klass;
+ attr.ulValueLen = sizeof (klass);
+ p11_kit_uri_set_attribute (uri, &attr);
+
+ ret = p11_kit_uri_format (uri, P11_KIT_URI_FOR_ANY, &string);
+ CuAssertIntEquals (tc, P11_KIT_URI_OK, ret);
+ CuAssertTrue (tc, strstr (string, "object-type=private") != NULL);
+
+ p11_kit_uri_free (uri);
+ free (string);
+}
+
+static void
+test_uri_build_object_type_public (CuTest *tc)
+{
+ CK_ATTRIBUTE attr;
+ CK_OBJECT_CLASS klass;
+ P11KitUri *uri;
+ char *string;
+ int ret;
+
+ uri = p11_kit_uri_new ();
+ CuAssertPtrNotNull (tc, uri);
+
+ klass = CKO_PUBLIC_KEY;
+ attr.type = CKA_CLASS;
+ attr.pValue = &klass;
+ attr.ulValueLen = sizeof (klass);
+ p11_kit_uri_set_attribute (uri, &attr);
+
+ ret = p11_kit_uri_format (uri, P11_KIT_URI_FOR_ANY, &string);
+ CuAssertIntEquals (tc, P11_KIT_URI_OK, ret);
+ CuAssertTrue (tc, strstr (string, "object-type=public") != NULL);
+
+ p11_kit_uri_free (uri);
+ free (string);
+}
+
+static void
+test_uri_build_object_type_secret (CuTest *tc)
+{
+ CK_ATTRIBUTE attr;
+ CK_OBJECT_CLASS klass;
+ P11KitUri *uri;
+ char *string;
+ int ret;
+
+ uri = p11_kit_uri_new ();
+ CuAssertPtrNotNull (tc, uri);
+
+ klass = CKO_SECRET_KEY;
+ attr.type = CKA_CLASS;
+ attr.pValue = &klass;
+ attr.ulValueLen = sizeof (klass);
+ p11_kit_uri_set_attribute (uri, &attr);
+
+ ret = p11_kit_uri_format (uri, P11_KIT_URI_FOR_ANY, &string);
+ CuAssertIntEquals (tc, P11_KIT_URI_OK, ret);
+ CuAssertTrue (tc, strstr (string, "object-type=secret-key") != NULL);
+
+ p11_kit_uri_free (uri);
+ free (string);
+}
+
+static void
+test_uri_build_with_library (CuTest *tc)
+{
+ CK_INFO_PTR info;
+ P11KitUri *uri;
+ char *string;
+ int ret;
+
+ uri = p11_kit_uri_new ();
+ CuAssertPtrNotNull (tc, uri);
+
+ info = p11_kit_uri_get_module_info (uri);
+ set_space_string (info->libraryDescription, sizeof (info->libraryDescription), "The Description");
+
+ ret = p11_kit_uri_format (uri, P11_KIT_URI_FOR_ANY, &string);
+ CuAssertIntEquals (tc, P11_KIT_URI_OK, ret);
+ CuAssertTrue (tc, strstr (string, "library-description=The%20Description") != NULL);
+
+ p11_kit_uri_free (uri);
+ free (string);
+}
+
+static void
+test_uri_build_library_version (CuTest *tc)
+{
+ CK_INFO_PTR info;
+ P11KitUri *uri;
+ char *string;
+ int ret;
+
+ uri = p11_kit_uri_new ();
+ CuAssertPtrNotNull (tc, uri);
+
+ info = p11_kit_uri_get_module_info (uri);
+ info->libraryVersion.major = 2;
+ info->libraryVersion.minor = 10;
+
+ ret = p11_kit_uri_format (uri, P11_KIT_URI_FOR_ANY, &string);
+ CuAssertIntEquals (tc, P11_KIT_URI_OK, ret);
+ CuAssertTrue (tc, strstr (string, "library-version=2.10") != NULL);
+
+ p11_kit_uri_free (uri);
+ free (string);
+}
+
+static void
+test_uri_get_set_unrecognized (CuTest *tc)
+{
+ P11KitUri *uri;
+ int ret;
+
+ uri = p11_kit_uri_new ();
+ CuAssertPtrNotNull (tc, uri);
+
+ ret = p11_kit_uri_any_unrecognized (uri);
+ CuAssertIntEquals (tc, 0, ret);
+
+ p11_kit_uri_set_unrecognized (uri, 1);
+
+ ret = p11_kit_uri_any_unrecognized (uri);
+ CuAssertIntEquals (tc, 1, ret);
+
+ p11_kit_uri_set_unrecognized (uri, 0);
+
+ ret = p11_kit_uri_any_unrecognized (uri);
+ CuAssertIntEquals (tc, 0, ret);
+
+ p11_kit_uri_free (uri);
+}
+
+static void
+test_uri_match_token (CuTest *tc)
+{
+ CK_TOKEN_INFO token;
+ P11KitUri *uri;
+ int ret;
+
+ uri = p11_kit_uri_new ();
+ CuAssertPtrNotNull (tc, uri);
+
+ ret = p11_kit_uri_parse ("pkcs11:model=Giselle", P11_KIT_URI_FOR_ANY, uri);
+ CuAssertIntEquals (tc, P11_KIT_URI_OK, ret);
+
+ set_space_string (token.label, sizeof (token.label), "A label");
+ set_space_string (token.model, sizeof (token.model), "Giselle");
+
+ ret = p11_kit_uri_match_token_info (uri, &token);
+ CuAssertIntEquals (tc, 1, ret);
+
+ set_space_string (token.label, sizeof (token.label), "Another label");
+
+ ret = p11_kit_uri_match_token_info (uri, &token);
+ CuAssertIntEquals (tc, 1, ret);
+
+ set_space_string (token.model, sizeof (token.model), "Zoolander");
+
+ ret = p11_kit_uri_match_token_info (uri, &token);
+ CuAssertIntEquals (tc, 0, ret);
+
+ p11_kit_uri_set_unrecognized (uri, 1);
+
+ ret = p11_kit_uri_match_token_info (uri, &token);
+ CuAssertIntEquals (tc, 0, ret);
+
+ p11_kit_uri_free (uri);
+}
+
+static void
+test_uri_match_module (CuTest *tc)
+{
+ CK_INFO info;
+ P11KitUri *uri;
+ int ret;
+
+ uri = p11_kit_uri_new ();
+ CuAssertPtrNotNull (tc, uri);
+
+ ret = p11_kit_uri_parse ("pkcs11:library-description=Quiet", P11_KIT_URI_FOR_ANY, uri);
+ CuAssertIntEquals (tc, P11_KIT_URI_OK, ret);
+
+ set_space_string (info.libraryDescription, sizeof (info.libraryDescription), "Quiet");
+ set_space_string (info.manufacturerID, sizeof (info.manufacturerID), "Someone");
+
+ ret = p11_kit_uri_match_module_info (uri, &info);
+ CuAssertIntEquals (tc, 1, ret);
+
+ set_space_string (info.manufacturerID, sizeof (info.manufacturerID), "Someone else");
+
+ ret = p11_kit_uri_match_module_info (uri, &info);
+ CuAssertIntEquals (tc, 1, ret);
+
+ set_space_string (info.libraryDescription, sizeof (info.libraryDescription), "Leise");
+
+ ret = p11_kit_uri_match_module_info (uri, &info);
+ CuAssertIntEquals (tc, 0, ret);
+
+ p11_kit_uri_set_unrecognized (uri, 1);
+
+ ret = p11_kit_uri_match_module_info (uri, &info);
+ CuAssertIntEquals (tc, 0, ret);
+
+ p11_kit_uri_free (uri);
+}
+
+static void
+test_uri_match_attributes (CuTest *tc)
+{
+ CK_ATTRIBUTE attrs[4];
+ CK_OBJECT_CLASS klass;
+ P11KitUri *uri;
+ int ret;
+
+ attrs[0].type = CKA_ID;
+ attrs[0].pValue = "Blah";
+ attrs[0].ulValueLen = 4;
+
+ attrs[1].type = CKA_LABEL;
+ attrs[1].pValue = "Junk";
+ attrs[1].ulValueLen = 4;
+
+ attrs[2].type = CKA_COLOR;
+ attrs[2].pValue = "blue";
+ attrs[2].ulValueLen = 4;
+
+ klass = CKO_DATA;
+ attrs[3].type = CKA_CLASS;
+ attrs[3].pValue = &klass;
+ attrs[3].ulValueLen = sizeof (klass);
+
+ uri = p11_kit_uri_new ();
+ CuAssertPtrNotNull (tc, uri);
+
+ ret = p11_kit_uri_parse ("pkcs11:object=Fancy;id=Blah;object-type=data", P11_KIT_URI_FOR_ANY, uri);
+ CuAssertIntEquals (tc, P11_KIT_URI_OK, ret);
+
+ ret = p11_kit_uri_match_attributes (uri, attrs, 4);
+ CuAssertIntEquals (tc, 0, ret);
+
+ attrs[1].pValue = "Fancy";
+ attrs[1].ulValueLen = 5;
+
+ ret = p11_kit_uri_match_attributes (uri, attrs, 4);
+ CuAssertIntEquals (tc, 1, ret);
+
+ p11_kit_uri_clear_attribute (uri, CKA_CLASS);
+
+ ret = p11_kit_uri_match_attributes (uri, attrs, 4);
+ CuAssertIntEquals (tc, 1, ret);
+
+ attrs[2].pValue = "pink";
+
+ ret = p11_kit_uri_match_attributes (uri, attrs, 4);
+ CuAssertIntEquals (tc, 1, ret);
+
+ p11_kit_uri_set_unrecognized (uri, 1);
+
+ ret = p11_kit_uri_match_attributes (uri, attrs, 4);
+ CuAssertIntEquals (tc, 0, ret);
+
+ p11_kit_uri_free (uri);
+}
+
+static void
+test_uri_get_set_attribute (CuTest *tc)
+{
+ CK_ATTRIBUTE attr;
+ CK_ATTRIBUTE_PTR ptr;
+ P11KitUri *uri;
+ int ret;
+
+ uri = p11_kit_uri_new ();
+ CuAssertPtrNotNull (tc, uri);
+
+ ptr = p11_kit_uri_get_attribute (uri, CKA_LABEL);
+ CuAssertPtrEquals (tc, NULL, ptr);
+
+ ret = p11_kit_uri_clear_attribute (uri, CKA_LABEL);
+ CuAssertIntEquals (tc, P11_KIT_URI_OK, ret);
+
+ ret = p11_kit_uri_clear_attribute (uri, CKA_COLOR);
+ CuAssertIntEquals (tc, P11_KIT_URI_NOT_FOUND, ret);
+
+ attr.type = CKA_LABEL;
+ attr.pValue = "Test";
+ attr.ulValueLen = 4;
+
+ ret = p11_kit_uri_set_attribute (uri, &attr);
+ CuAssertIntEquals (tc, P11_KIT_URI_OK, ret);
+
+ attr.type = CKA_COLOR;
+ ret = p11_kit_uri_set_attribute (uri, &attr);
+ CuAssertIntEquals (tc, P11_KIT_URI_NOT_FOUND, ret);
+
+ ptr = p11_kit_uri_get_attribute (uri, CKA_COLOR);
+ CuAssertPtrEquals (tc, NULL, ptr);
+
+ ptr = p11_kit_uri_get_attribute (uri, CKA_LABEL);
+ CuAssertPtrNotNull (tc, ptr);
+
+ CuAssertTrue (tc, ptr->type == CKA_LABEL);
+ CuAssertTrue (tc, ptr->ulValueLen == 4);
+ CuAssertTrue (tc, memcmp (ptr->pValue, "Test", 4) == 0);
+
+ ret = p11_kit_uri_clear_attribute (uri, CKA_LABEL);
+ CuAssertIntEquals (tc, P11_KIT_URI_OK, ret);
+
+ ptr = p11_kit_uri_get_attribute (uri, CKA_LABEL);
+ CuAssertPtrEquals (tc, NULL, ptr);
+
+ p11_kit_uri_free (uri);
+}
+
+static void
+test_uri_get_set_attributes (CuTest *tc)
+{
+ CK_ATTRIBUTE_PTR attrs;
+ CK_OBJECT_CLASS klass;
+ CK_ATTRIBUTE attr;
+ CK_ULONG n_attrs;
+ P11KitUri *uri;
+ int ret;
+
+ uri = p11_kit_uri_new ();
+ CuAssertPtrNotNull (tc, uri);
+
+ attrs = p11_kit_uri_get_attributes (uri, &n_attrs);
+ CuAssertPtrNotNull (tc, attrs);
+ CuAssertIntEquals (tc, 0, n_attrs);
+
+ attr.type = CKA_LABEL;
+ attr.pValue = "Test";
+ attr.ulValueLen = 4;
+
+ ret = p11_kit_uri_set_attribute (uri, &attr);
+ CuAssertIntEquals (tc, P11_KIT_URI_OK, ret);
+
+ attrs = p11_kit_uri_get_attributes (uri, &n_attrs);
+ CuAssertPtrNotNull (tc, attrs);
+ CuAssertIntEquals (tc, 1, n_attrs);
+ CuAssertTrue (tc, attrs[0].type == CKA_LABEL);
+ CuAssertTrue (tc, attrs[0].ulValueLen == 4);
+ CuAssertTrue (tc, memcmp (attrs[0].pValue, "Test", 4) == 0);
+
+ attr.type = CKA_LABEL;
+ attr.pValue = "Kablooey";
+ attr.ulValueLen = 8;
+
+ ret = p11_kit_uri_set_attribute (uri, &attr);
+ CuAssertIntEquals (tc, P11_KIT_URI_OK, ret);
+
+ attrs = p11_kit_uri_get_attributes (uri, &n_attrs);
+ CuAssertPtrNotNull (tc, attrs);
+ CuAssertIntEquals (tc, 1, n_attrs);
+ CuAssertTrue (tc, attrs[0].type == CKA_LABEL);
+ CuAssertTrue (tc, attrs[0].ulValueLen == 8);
+ CuAssertTrue (tc, memcmp (attrs[0].pValue, "Kablooey", 8) == 0);
+
+ klass = CKO_DATA;
+ attr.type = CKA_CLASS;
+ attr.pValue = &klass;
+ attr.ulValueLen = sizeof (klass);
+
+ ret = p11_kit_uri_set_attribute (uri, &attr);
+ CuAssertIntEquals (tc, P11_KIT_URI_OK, ret);
+
+ attrs = p11_kit_uri_get_attributes (uri, &n_attrs);
+ CuAssertPtrNotNull (tc, attrs);
+ CuAssertIntEquals (tc, 2, n_attrs);
+ CuAssertTrue (tc, attrs[0].type == CKA_LABEL);
+ CuAssertTrue (tc, attrs[0].ulValueLen == 8);
+ CuAssertTrue (tc, memcmp (attrs[0].pValue, "Kablooey", 8) == 0);
+ CuAssertTrue (tc, attrs[1].type == CKA_CLASS);
+ CuAssertTrue (tc, attrs[1].ulValueLen == sizeof (klass));
+ CuAssertTrue (tc, memcmp (attrs[1].pValue, &klass, sizeof (klass)) == 0);
+
+ ret = p11_kit_uri_clear_attribute (uri, CKA_LABEL);
+ CuAssertIntEquals (tc, P11_KIT_URI_OK, ret);
+
+ attrs = p11_kit_uri_get_attributes (uri, &n_attrs);
+ CuAssertPtrNotNull (tc, attrs);
+ CuAssertIntEquals (tc, 1, n_attrs);
+ CuAssertTrue (tc, attrs[0].type == CKA_CLASS);
+ CuAssertTrue (tc, attrs[0].ulValueLen == sizeof (klass));
+ CuAssertTrue (tc, memcmp (attrs[0].pValue, &klass, sizeof (klass)) == 0);
+
+ attr.type = CKA_LABEL;
+ attr.pValue = "Three";
+ attr.ulValueLen = 5;
+
+ ret = p11_kit_uri_set_attributes (uri, &attr, 1);
+ CuAssertIntEquals (tc, P11_KIT_URI_OK, ret);
+
+ attrs = p11_kit_uri_get_attributes (uri, &n_attrs);
+ CuAssertPtrNotNull (tc, attrs);
+ CuAssertIntEquals (tc, 1, n_attrs);
+ CuAssertTrue (tc, attrs[0].type == CKA_LABEL);
+ CuAssertTrue (tc, attrs[0].ulValueLen == 5);
+ CuAssertTrue (tc, memcmp (attrs[0].pValue, "Three", 5) == 0);
+
+ p11_kit_uri_clear_attributes (uri);
+
+ attrs = p11_kit_uri_get_attributes (uri, &n_attrs);
+ CuAssertPtrNotNull (tc, attrs);
+ CuAssertIntEquals (tc, 0, n_attrs);
+
+ p11_kit_uri_free (uri);
+}
+static void
+test_uri_pin_source (CuTest *tc)
+{
+ P11KitUri *uri;
+ const char *pin_source;
+ char *string;
+ int ret;
+
+ uri = p11_kit_uri_new ();
+ CuAssertPtrNotNull (tc, uri);
+
+ p11_kit_uri_set_pin_source (uri, "|my-pin-source");
+
+ pin_source = p11_kit_uri_get_pin_source (uri);
+ CuAssertStrEquals (tc, "|my-pin-source", pin_source);
+
+ pin_source = p11_kit_uri_get_pinfile (uri);
+ CuAssertStrEquals (tc, "|my-pin-source", pin_source);
+
+ p11_kit_uri_set_pinfile (uri, "|my-pin-file");
+
+ pin_source = p11_kit_uri_get_pin_source (uri);
+ CuAssertStrEquals (tc, "|my-pin-file", pin_source);
+
+ ret = p11_kit_uri_format (uri, P11_KIT_URI_FOR_ANY, &string);
+ CuAssertIntEquals (tc, P11_KIT_URI_OK, ret);
+ CuAssertTrue (tc, strstr (string, "pin-source=%7cmy-pin-file") != NULL);
+ free (string);
+
+ ret = p11_kit_uri_parse ("pkcs11:pin-source=blah%2Fblah", P11_KIT_URI_FOR_ANY, uri);
+ CuAssertIntEquals (tc, P11_KIT_URI_OK, ret);
+
+ pin_source = p11_kit_uri_get_pin_source (uri);
+ CuAssertStrEquals (tc, "blah/blah", pin_source);
+
+ p11_kit_uri_free (uri);
+}
+
+static void
+test_uri_free_null (CuTest *tc)
+{
+ p11_kit_uri_free (NULL);
+}
+
+static void
+test_uri_message (CuTest *tc)
+{
+ CuAssertTrue (tc, p11_kit_uri_message (P11_KIT_URI_OK) == NULL);
+ CuAssertPtrNotNull (tc, p11_kit_uri_message (P11_KIT_URI_UNEXPECTED));
+ CuAssertPtrNotNull (tc, p11_kit_uri_message (-555555));
+}
+
+int
+main (void)
+{
+ CuString *output = CuStringNew ();
+ CuSuite* suite = CuSuiteNew ();
+ int ret;
+
+ p11_library_init ();
+
+ SUITE_ADD_TEST (suite, test_uri_parse);
+ SUITE_ADD_TEST (suite, test_uri_parse_bad_scheme);
+ SUITE_ADD_TEST (suite, test_uri_parse_with_label);
+ SUITE_ADD_TEST (suite, test_uri_parse_with_label_and_klass);
+ SUITE_ADD_TEST (suite, test_uri_parse_with_id);
+ SUITE_ADD_TEST (suite, test_uri_parse_with_bad_string_encoding);
+ SUITE_ADD_TEST (suite, test_uri_parse_with_bad_hex_encoding);
+ SUITE_ADD_TEST (suite, test_uri_parse_with_token);
+ SUITE_ADD_TEST (suite, test_uri_parse_with_token_bad_encoding);
+ SUITE_ADD_TEST (suite, test_uri_parse_with_bad_syntax);
+ SUITE_ADD_TEST (suite, test_uri_parse_with_spaces);
+ SUITE_ADD_TEST (suite, test_uri_parse_with_library);
+ SUITE_ADD_TEST (suite, test_uri_parse_with_library_bad_encoding);
+ SUITE_ADD_TEST (suite, test_uri_build_empty);
+ SUITE_ADD_TEST (suite, test_uri_build_with_token_info);
+ SUITE_ADD_TEST (suite, test_uri_build_with_token_null_info);
+ SUITE_ADD_TEST (suite, test_uri_build_with_token_empty_info);
+ SUITE_ADD_TEST (suite, test_uri_build_with_attributes);
+ SUITE_ADD_TEST (suite, test_uri_parse_private_key);
+ SUITE_ADD_TEST (suite, test_uri_parse_secret_key);
+ SUITE_ADD_TEST (suite, test_uri_parse_library_version);
+ SUITE_ADD_TEST (suite, test_uri_parse_parse_unknown_object_type);
+ SUITE_ADD_TEST (suite, test_uri_parse_unrecognized);
+ SUITE_ADD_TEST (suite, test_uri_parse_too_long_is_unrecognized);
+ SUITE_ADD_TEST (suite, test_uri_build_object_type_cert);
+ SUITE_ADD_TEST (suite, test_uri_build_object_type_private);
+ SUITE_ADD_TEST (suite, test_uri_build_object_type_public);
+ SUITE_ADD_TEST (suite, test_uri_build_object_type_secret);
+ SUITE_ADD_TEST (suite, test_uri_build_with_library);
+ SUITE_ADD_TEST (suite, test_uri_build_library_version);
+ SUITE_ADD_TEST (suite, test_uri_get_set_unrecognized);
+ SUITE_ADD_TEST (suite, test_uri_match_token);
+ SUITE_ADD_TEST (suite, test_uri_match_module);
+ SUITE_ADD_TEST (suite, test_uri_match_attributes);
+ SUITE_ADD_TEST (suite, test_uri_get_set_attribute);
+ SUITE_ADD_TEST (suite, test_uri_get_set_attributes);
+ SUITE_ADD_TEST (suite, test_uri_pin_source);
+ SUITE_ADD_TEST (suite, test_uri_free_null);
+ SUITE_ADD_TEST (suite, test_uri_message);
+
+ CuSuiteRun (suite);
+ CuSuiteSummary (suite, output);
+ CuSuiteDetails (suite, output);
+ printf ("%s\n", output->buffer);
+ ret = suite->failCount;
+ CuSuiteDelete (suite);
+ CuStringDelete (output);
+ return ret;
+}