summaryrefslogtreecommitdiff
path: root/p11-kit
diff options
context:
space:
mode:
authorDaiki Ueno <dueno@redhat.com>2019-05-16 16:52:37 +0200
committerDaiki Ueno <ueno@gnu.org>2019-05-21 08:07:12 +0200
commit381d16e651d5bcace316fbab4095c8dea8c43a92 (patch)
tree7e1ba604a22ec1151f940e91079e54dfb1db4665 /p11-kit
parent68ce31aae9a22d18b28f4aa44b3e1006b7fe3aa7 (diff)
proxy: Support C_WaitForSlotEvent() if CKF_DONT_BLOCK is specified
While fully implementing C_WaitForSlotEvent() would require a separate thread to monitor events, it is straightforward to implement the function if the CKF_DONT_BLOCK flag is given. Suggested by David Ward.
Diffstat (limited to 'p11-kit')
-rw-r--r--p11-kit/Makefile.am7
-rw-r--r--p11-kit/mock-module-ep7.c70
-rw-r--r--p11-kit/proxy.c64
-rw-r--r--p11-kit/test-proxy.c40
4 files changed, 166 insertions, 15 deletions
diff --git a/p11-kit/Makefile.am b/p11-kit/Makefile.am
index 0155f7c..09a068e 100644
--- a/p11-kit/Makefile.am
+++ b/p11-kit/Makefile.am
@@ -409,7 +409,8 @@ check_LTLIBRARIES += \
mock-four.la \
mock-five.la \
mock-seven.la \
- mock-eight.la
+ mock-eight.la \
+ mock-nine.la
mock_one_la_SOURCES = p11-kit/mock-module-ep.c
mock_one_la_LIBADD = libp11-test.la libp11-common.la
@@ -448,6 +449,10 @@ mock_eight_la_SOURCES = p11-kit/mock-module-ep6.c
mock_eight_la_LDFLAGS = $(mock_one_la_LDFLAGS)
mock_eight_la_LIBADD = $(mock_one_la_LIBADD)
+mock_nine_la_SOURCES = p11-kit/mock-module-ep7.c
+mock_nine_la_LDFLAGS = $(mock_one_la_LDFLAGS)
+mock_nine_la_LIBADD = $(mock_one_la_LIBADD)
+
EXTRA_DIST += \
p11-kit/fixtures \
p11-kit/test-mock.c \
diff --git a/p11-kit/mock-module-ep7.c b/p11-kit/mock-module-ep7.c
new file mode 100644
index 0000000..51fad06
--- /dev/null
+++ b/p11-kit/mock-module-ep7.c
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2012 Stefan Walter
+ * Copyright (c) 2019 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 <stef@thewalter.net>, Daiki Ueno
+ */
+
+#include "config.h"
+
+#define CRYPTOKI_EXPORTS 1
+#include "pkcs11.h"
+
+#include "mock.h"
+#include "test.h"
+
+static CK_RV
+override_wait_for_slot_event (CK_FLAGS flags,
+ CK_SLOT_ID_PTR slot,
+ CK_VOID_PTR reserved)
+{
+ if (flags & CKF_DONT_BLOCK) {
+ *slot = MOCK_SLOT_ONE_ID;
+ return CKR_OK;
+ }
+
+ return mock_C_WaitForSlotEvent(flags, slot, reserved);
+}
+
+#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;
+ mock_module.C_WaitForSlotEvent = override_wait_for_slot_event;
+ *list = &mock_module;
+ return CKR_OK;
+}
diff --git a/p11-kit/proxy.c b/p11-kit/proxy.c
index ae88318..a9c7055 100644
--- a/p11-kit/proxy.c
+++ b/p11-kit/proxy.c
@@ -604,7 +604,40 @@ proxy_C_WaitForSlotEvent (CK_X_FUNCTION_LIST *self,
CK_SLOT_ID_PTR slot,
CK_VOID_PTR reserved)
{
- return CKR_FUNCTION_NOT_SUPPORTED;
+ State *state = (State *)self;
+ Proxy *py = state->px;
+ CK_FUNCTION_LIST_PTR *f;
+ CK_FUNCTION_LIST_PTR funcs;
+ CK_SLOT_ID real_slot;
+ unsigned int i;
+ CK_RV rv = CKR_NO_EVENT;
+
+ /* Only the non-blocking case is supported. */
+ if ((flags & CKF_DONT_BLOCK) == 0)
+ return CKR_FUNCTION_NOT_SUPPORTED;
+
+ p11_lock ();
+
+ for (f = py->inited; *f; ++f) {
+ funcs = *f;
+ assert (funcs != NULL);
+
+ rv = (funcs->C_WaitForSlotEvent) (flags, &real_slot, reserved);
+ if (rv == CKR_NO_EVENT)
+ continue;
+ if (rv != CKR_OK)
+ break;
+ for (i = 0; i < py->n_mappings; i++)
+ if (py->mappings[i].funcs == funcs &&
+ py->mappings[i].real_slot == real_slot) {
+ *slot = py->mappings[i].wrap_slot;
+ break;
+ }
+ }
+
+ p11_unlock ();
+
+ return rv;
}
static CK_RV
@@ -1617,14 +1650,6 @@ proxy_C_GenerateRandom (CK_X_FUNCTION_LIST *self,
return (map.funcs->C_GenerateRandom) (handle, random_data, random_len);
}
-static CK_RV
-module_C_WaitForSlotEvent (CK_FLAGS flags,
- CK_SLOT_ID_PTR slot,
- CK_VOID_PTR reserved)
-{
- return proxy_C_WaitForSlotEvent (&global.virt.funcs, flags, slot, reserved);
-}
-
/* --------------------------------------------------------------------
* MODULE ENTRY POINT
*/
@@ -1737,11 +1762,8 @@ C_GetFunctionList (CK_FUNCTION_LIST_PTR_PTR list)
}
}
- if (rv == CKR_OK) {
- /* We use this as a check below */
- module->C_WaitForSlotEvent = module_C_WaitForSlotEvent;
+ if (rv == CKR_OK)
*list = module;
- }
if (loaded)
p11_kit_modules_release (loaded);
@@ -1769,7 +1791,21 @@ p11_proxy_module_cleanup (void)
bool
p11_proxy_module_check (CK_FUNCTION_LIST_PTR module)
{
- return (module->C_WaitForSlotEvent == module_C_WaitForSlotEvent);
+ State *state;
+ bool ret = false;
+
+ if (!p11_virtual_is_wrapper (module))
+ return false;
+
+ p11_lock ();
+ for (state = all_instances; state != NULL; state = state->next)
+ if (state->wrapped == module) {
+ ret = true;
+ break;
+ }
+ p11_unlock ();
+
+ return ret;
}
CK_RV
diff --git a/p11-kit/test-proxy.c b/p11-kit/test-proxy.c
index f61f37e..9a8f71d 100644
--- a/p11-kit/test-proxy.c
+++ b/p11-kit/test-proxy.c
@@ -234,6 +234,7 @@ teardown (void *unused)
#define ENABLED "enable-in: test-proxy, p11-kit-proxy\n"
#define DISABLED "disable-in: p11-kit-proxy\n"
#define EIGHT_MODULE "module: mock-eight" SHLEXT "\n"
+#define NINE_MODULE "module: mock-nine" SHLEXT "\n"
static CK_ULONG
load_modules_and_count_slots (void)
@@ -343,6 +344,44 @@ test_slot_appear (void)
p11_proxy_module_cleanup ();
}
+static void
+test_slot_event (void)
+{
+ CK_FUNCTION_LIST_PTR proxy;
+ CK_SLOT_ID slot;
+ CK_SLOT_ID slots[32];
+ CK_ULONG count;
+ CK_RV rv;
+
+ p11_test_file_write (test.directory, "nine.module", NINE_MODULE, strlen (NINE_MODULE));
+
+ rv = C_GetFunctionList (&proxy);
+ assert (rv == CKR_OK);
+
+ assert (p11_proxy_module_check (proxy));
+
+ rv = proxy->C_Initialize (NULL);
+ assert (rv == CKR_OK);
+
+ rv = proxy->C_GetSlotList (CK_FALSE, slots, &count);
+ assert (rv == CKR_OK);
+ assert (count == 2);
+
+ slot = 0;
+ rv = proxy->C_WaitForSlotEvent (0, &slot, NULL);
+ assert_num_eq (rv, CKR_FUNCTION_NOT_SUPPORTED);
+ assert_num_eq (slot, 0);
+
+ rv = proxy->C_WaitForSlotEvent (CKF_DONT_BLOCK, &slot, NULL);
+ assert_num_eq (rv, CKR_OK);
+ assert_num_eq (slot, slots[0]);
+
+ rv = proxy->C_Finalize (NULL);
+ assert_num_eq (rv, CKR_OK);
+
+ p11_proxy_module_cleanup ();
+}
+
static CK_FUNCTION_LIST_PTR
setup_mock_module (CK_SESSION_HANDLE *session)
{
@@ -430,6 +469,7 @@ main (int argc,
p11_test (test_disable, "/proxy/disable");
p11_test (test_no_slot, "/proxy/no-slot");
p11_test (test_slot_appear, "/proxy/slot-appear");
+ p11_test (test_slot_event, "/proxy/slot-event");
test_mock_add_tests ("/proxy");