summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--p11-kit/Makefile.am7
-rw-r--r--p11-kit/fixtures/package-modules/six.module7
-rw-r--r--p11-kit/mock-module-ep4.c69
-rw-r--r--p11-kit/proxy.c25
-rw-r--r--p11-kit/test-proxy.c18
5 files changed, 122 insertions, 4 deletions
diff --git a/p11-kit/Makefile.am b/p11-kit/Makefile.am
index 955719a..434c257 100644
--- a/p11-kit/Makefile.am
+++ b/p11-kit/Makefile.am
@@ -307,6 +307,13 @@ mock_five_la_SOURCES = p11-kit/mock-module-ep3.c
mock_five_la_LDFLAGS = $(mock_one_la_LDFLAGS)
mock_five_la_LIBADD = $(mock_one_la_LIBADD)
+if !OS_WIN32
+noinst_LTLIBRARIES += mock-six.la
+mock_six_la_SOURCES = p11-kit/mock-module-ep4.c
+mock_six_la_LDFLAGS = $(mock_one_la_LDFLAGS)
+mock_six_la_LIBADD = $(mock_one_la_LIBADD)
+endif
+
EXTRA_DIST += \
p11-kit/fixtures \
p11-kit/test-mock.c \
diff --git a/p11-kit/fixtures/package-modules/six.module b/p11-kit/fixtures/package-modules/six.module
new file mode 100644
index 0000000..bad9379
--- /dev/null
+++ b/p11-kit/fixtures/package-modules/six.module
@@ -0,0 +1,7 @@
+
+module: mock-six.so
+
+enable-in: test-proxy
+
+# the highest priority among others loaded by test-proxy
+priority: 100
diff --git a/p11-kit/mock-module-ep4.c b/p11-kit/mock-module-ep4.c
new file mode 100644
index 0000000..5170b6b
--- /dev/null
+++ b/p11-kit/mock-module-ep4.c
@@ -0,0 +1,69 @@
+/*
+ * 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.h"
+#include "test.h"
+
+#include <unistd.h>
+
+static pid_t init_pid;
+
+static CK_RV
+override_initialize (CK_VOID_PTR init_args)
+{
+ if (init_pid != getpid ())
+ return CKR_GENERAL_ERROR;
+ return mock_C_Initialize (init_args);
+}
+
+#ifdef OS_WIN32
+__declspec(dllexport)
+#endif
+CK_RV
+C_GetFunctionList (CK_FUNCTION_LIST_PTR_PTR list)
+{
+ mock_module_init ();
+ mock_module.C_GetFunctionList = C_GetFunctionList;
+ if (list == NULL)
+ return CKR_ARGUMENTS_BAD;
+ init_pid = getpid ();
+ mock_module.C_Initialize = override_initialize;
+ *list = &mock_module;
+ return CKR_OK;
+}
diff --git a/p11-kit/proxy.c b/p11-kit/proxy.c
index 8c437a0..6f5aedd 100644
--- a/p11-kit/proxy.c
+++ b/p11-kit/proxy.c
@@ -248,12 +248,13 @@ modules_dup (CK_FUNCTION_LIST **modules)
}
static CK_RV
-proxy_create (Proxy **res)
+proxy_create (Proxy **res, Mapping *mappings, unsigned int n_mappings)
{
CK_FUNCTION_LIST_PTR *f;
CK_FUNCTION_LIST_PTR funcs;
CK_SLOT_ID_PTR slots;
CK_ULONG i, count;
+ unsigned int j;
CK_RV rv = CKR_OK;
Proxy *py;
@@ -293,8 +294,14 @@ proxy_create (Proxy **res)
/* And now add a mapping for each of those slots */
for (i = 0; i < count; ++i) {
+ /* Reuse the existing mapping if any */
+ for (j = 0; j < n_mappings; ++j) {
+ if (mappings[j].funcs == funcs &&
+ mappings[j].real_slot == slots[i])
+ break;
+ }
py->mappings[py->n_mappings].funcs = funcs;
- py->mappings[py->n_mappings].wrap_slot = py->n_mappings + MAPPING_OFFSET;
+ py->mappings[py->n_mappings].wrap_slot = j == n_mappings ? py->n_mappings + MAPPING_OFFSET : mappings[j].wrap_slot;
py->mappings[py->n_mappings].real_slot = slots[i];
++py->n_mappings;
}
@@ -323,6 +330,8 @@ proxy_C_Initialize (CK_X_FUNCTION_LIST *self,
{
State *state = (State *)self;
bool initialize = false;
+ Mapping *mappings = NULL;
+ unsigned int n_mappings = 0;
Proxy *py;
CK_RV rv;
@@ -338,8 +347,15 @@ proxy_C_Initialize (CK_X_FUNCTION_LIST *self,
unsigned call_finalize = 1;
initialize = true;
- if (PROXY_FORKED(state->px))
+ if (PROXY_FORKED(state->px)) {
call_finalize = 0;
+ if (state->px->mappings) {
+ mappings = state->px->mappings;
+ n_mappings = state->px->n_mappings;
+ state->px->mappings = NULL;
+ state->px->n_mappings = 0;
+ }
+ }
proxy_free (state->px, call_finalize);
state->px = NULL;
@@ -354,7 +370,8 @@ proxy_C_Initialize (CK_X_FUNCTION_LIST *self,
return CKR_OK;
}
- rv = proxy_create (&py);
+ rv = proxy_create (&py, mappings, n_mappings);
+ free (mappings);
if (rv != CKR_OK) {
p11_debug ("out: %lu", rv);
return rv;
diff --git a/p11-kit/test-proxy.c b/p11-kit/test-proxy.c
index 9d894bf..3229002 100644
--- a/p11-kit/test-proxy.c
+++ b/p11-kit/test-proxy.c
@@ -121,6 +121,8 @@ test_initialize_child (void)
CK_RV rv;
pid_t pid;
int st;
+ CK_SLOT_ID slots[32], last_slot;
+ CK_ULONG count, last_count;
rv = C_GetFunctionList (&proxy);
assert (rv == CKR_OK);
@@ -130,6 +132,11 @@ test_initialize_child (void)
rv = proxy->C_Initialize(NULL);
assert_num_eq (rv, CKR_OK);
+ rv = proxy->C_GetSlotList (CK_FALSE, slots, &count);
+ assert_num_cmp (count, >=, 2);
+ last_slot = slots[count - 1];
+ last_count = count;
+
pid = fork ();
if (!pid) {
/* The PKCS#11 Usage Guide (v2.40) advocates in ยง2.5.2 that
@@ -149,6 +156,17 @@ test_initialize_child (void)
rv = proxy->C_Initialize(NULL);
assert_num_eq (rv, CKR_OK);
+ rv = proxy->C_GetSlotList (CK_FALSE, slots, &count);
+ assert_num_eq (rv, CKR_OK);
+ assert_num_cmp (count, >=, 2);
+
+ /* One of the module initializations should fail after
+ * fork (see mock-module-ep4.c) and the total number
+ * of slots should be less than last_count. */
+ assert_num_cmp (count, <, last_count);
+ /* Check if the last valid slot ID is preserved */
+ assert_num_eq (slots[count - 1], last_slot);
+
rv = proxy->C_Finalize (NULL);
assert_num_eq (rv, CKR_OK);