Skip to content

Commit

Permalink
proxy: Support C_WaitForSlotEvent() if CKF_DONT_BLOCK is specified
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
ueno committed May 21, 2019
1 parent 68ce31a commit 381d16e
Show file tree
Hide file tree
Showing 4 changed files with 166 additions and 15 deletions.
7 changes: 6 additions & 1 deletion p11-kit/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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 \
Expand Down
70 changes: 70 additions & 0 deletions p11-kit/mock-module-ep7.c
Original file line number Diff line number Diff line change
@@ -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;
}
64 changes: 50 additions & 14 deletions p11-kit/proxy.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
*/
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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
Expand Down
40 changes: 40 additions & 0 deletions p11-kit/test-proxy.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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)
{
Expand Down Expand Up @@ -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");

Expand Down

0 comments on commit 381d16e

Please sign in to comment.