From a96f354c3068edb6c8ac80ae6d9a6611651145d7 Mon Sep 17 00:00:00 2001 From: Daiki Ueno Date: Mon, 19 Sep 2016 16:36:19 +0200 Subject: rpc: Send x-init-reserved to remote module Signed-off-by: Stef Walter * Fixed up indentation https://bugs.freedesktop.org/show_bug.cgi?id=80519 --- p11-kit/Makefile.am | 7 ++++- p11-kit/mock-module-ep3.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++ p11-kit/modules.c | 30 ++++++++++++--------- p11-kit/rpc-client.c | 16 ++++++++++- p11-kit/rpc-message.h | 2 +- p11-kit/rpc-server.c | 13 +++++++++ p11-kit/test-transport.c | 24 +++++++++++++++++ 7 files changed, 144 insertions(+), 16 deletions(-) create mode 100644 p11-kit/mock-module-ep3.c diff --git a/p11-kit/Makefile.am b/p11-kit/Makefile.am index 62cf70d..14ec4d6 100644 --- a/p11-kit/Makefile.am +++ b/p11-kit/Makefile.am @@ -222,7 +222,8 @@ noinst_LTLIBRARIES += \ mock-one.la \ mock-two.la \ mock-three.la \ - mock-four.la + mock-four.la \ + mock-five.la mock_one_la_SOURCES = p11-kit/mock-module-ep.c mock_one_la_LIBADD = libp11-test.la libp11-common.la @@ -242,6 +243,10 @@ mock_four_la_SOURCES = $(mock_one_la_SOURCES) mock_four_la_LDFLAGS = $(mock_one_la_LDFLAGS) mock_four_la_LIBADD = $(mock_one_la_LIBADD) +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) + EXTRA_DIST += \ p11-kit/fixtures \ p11-kit/test-mock.c \ diff --git a/p11-kit/mock-module-ep3.c b/p11-kit/mock-module-ep3.c new file mode 100644 index 0000000..4bf403c --- /dev/null +++ b/p11-kit/mock-module-ep3.c @@ -0,0 +1,68 @@ +/* + * 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 + */ + +#include "config.h" + +#define CRYPTOKI_EXPORTS 1 +#include "pkcs11.h" + +#include "mock.h" +#include "test.h" + +#include + +static CK_RV +override_initialize (CK_VOID_PTR init_args) +{ + CK_C_INITIALIZE_ARGS_PTR args = init_args; + + assert_str_eq ("initialize-arg", args->pReserved); + + 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; + mock_module.C_Initialize = override_initialize; + *list = &mock_module; + return CKR_OK; +} diff --git a/p11-kit/modules.c b/p11-kit/modules.c index 1ec0f1d..6e15c1d 100644 --- a/p11-kit/modules.c +++ b/p11-kit/modules.c @@ -518,15 +518,15 @@ take_config_and_load_module_inlock (char **name, rv = load_module_from_file_inlock (*name, filename, &mod); if (rv != CKR_OK) goto out; - - /* - * We support setting of CK_C_INITIALIZE_ARGS.pReserved from - * 'x-init-reserved' setting in the config. This only works with specific - * PKCS#11 modules, and is non-standard use of that field. - */ - mod->init_args.pReserved = p11_dict_get (*config, "x-init-reserved"); } + /* + * We support setting of CK_C_INITIALIZE_ARGS.pReserved from + * 'x-init-reserved' setting in the config. This only works with specific + * PKCS#11 modules, and is non-standard use of that field. + */ + mod->init_args.pReserved = p11_dict_get (*config, "x-init-reserved"); + /* Take ownership of thes evariables */ p11_dict_free (mod->config); mod->config = *config; @@ -610,7 +610,7 @@ load_registered_modules_unlocked (void) } static CK_RV -initialize_module_inlock_reentrant (Module *mod) +initialize_module_inlock_reentrant (Module *mod, CK_C_INITIALIZE_ARGS *init_args) { CK_RV rv = CKR_OK; p11_thread_id_t self; @@ -638,8 +638,12 @@ initialize_module_inlock_reentrant (Module *mod) if (mod->initialize_called != p11_forkid) { p11_debug ("C_Initialize: calling"); + /* The init_args argument takes precedence over mod->init_args */ + if (init_args == NULL) + init_args = &mod->init_args; + rv = mod->virt.funcs.C_Initialize (&mod->virt.funcs, - &mod->init_args); + init_args); p11_debug ("C_Initialize: result: %lu", rv); @@ -793,7 +797,7 @@ initialize_registered_inlock_reentrant (void) if (mod->name == NULL || !is_module_enabled_unlocked (mod->name, mod->config)) continue; - rv = initialize_module_inlock_reentrant (mod); + rv = initialize_module_inlock_reentrant (mod, NULL); if (rv != CKR_OK) { if (mod->critical) { p11_message ("initialization of critical module '%s' failed: %s", @@ -1478,7 +1482,7 @@ managed_C_Initialize (CK_X_FUNCTION_LIST *self, if (!sessions) rv = CKR_HOST_MEMORY; else - rv = initialize_module_inlock_reentrant (managed->mod); + rv = initialize_module_inlock_reentrant (managed->mod, init_args); if (rv == CKR_OK) { if (managed->sessions) p11_dict_free (managed->sessions); @@ -2294,7 +2298,7 @@ p11_kit_initialize_module (CK_FUNCTION_LIST_PTR module) if (rv == CKR_OK) { mod = p11_dict_get (gl.unmanaged_by_funcs, module); assert (mod != NULL); - rv = initialize_module_inlock_reentrant (mod); + rv = initialize_module_inlock_reentrant (mod, NULL); if (rv != CKR_OK) { p11_message ("module initialization failed: %s", p11_kit_strerror (rv)); p11_module_release_inlock_reentrant (module); @@ -2674,7 +2678,7 @@ p11_kit_load_initialize_module (const char *module_path, if (rv == CKR_OK) { /* WARNING: Reentrancy can occur here */ - rv = initialize_module_inlock_reentrant (mod); + rv = initialize_module_inlock_reentrant (mod, NULL); } } diff --git a/p11-kit/rpc-client.c b/p11-kit/rpc-client.c index 8607bb5..c69dcfd 100644 --- a/p11-kit/rpc-client.c +++ b/p11-kit/rpc-client.c @@ -857,7 +857,10 @@ rpc_C_Initialize (CK_X_FUNCTION_LIST *self, if (init_args != NULL) { int supplied_ok; - /* pReserved must be NULL */ + /* + * pReserved is either a string or NULL. Other cases + * should be rejected by the caller of this function. + */ args = init_args; /* ALL supplied function pointers need to have the value either NULL or non-NULL. */ @@ -919,6 +922,17 @@ rpc_C_Initialize (CK_X_FUNCTION_LIST *self, if (ret == CKR_OK) if (!p11_rpc_message_write_byte_array (&msg, P11_RPC_HANDSHAKE, P11_RPC_HANDSHAKE_LEN)) ret = CKR_HOST_MEMORY; + if (ret == CKR_OK) { + if (!p11_rpc_message_write_byte (&msg, reserved != NULL)) + ret = CKR_HOST_MEMORY; + } + if (ret == CKR_OK) { + char *reserved_string = ""; + if (reserved != NULL) + reserved_string = (char *) reserved; + if (!p11_rpc_message_write_byte_array (&msg, (CK_BYTE_PTR) reserved_string, strlen (reserved_string) + 1)) + ret = CKR_HOST_MEMORY; + } if (ret == CKR_OK) ret = call_run (module, &msg); call_done (module, &msg, ret); diff --git a/p11-kit/rpc-message.h b/p11-kit/rpc-message.h index fc4d06e..9827097 100644 --- a/p11-kit/rpc-message.h +++ b/p11-kit/rpc-message.h @@ -137,7 +137,7 @@ typedef struct { static const p11_rpc_call p11_rpc_calls[] = { { P11_RPC_CALL_ERROR, "ERROR", NULL, "u" }, - { P11_RPC_CALL_C_Initialize, "C_Initialize", "ay", "" }, + { P11_RPC_CALL_C_Initialize, "C_Initialize", "ayyay", "" }, { P11_RPC_CALL_C_Finalize, "C_Finalize", "", "" }, { P11_RPC_CALL_C_GetInfo, "C_GetInfo", "", "vsusv" }, { P11_RPC_CALL_C_GetSlotList, "C_GetSlotList", "yfu", "au" }, diff --git a/p11-kit/rpc-server.c b/p11-kit/rpc-server.c index 6be75bd..225cc86 100644 --- a/p11-kit/rpc-server.c +++ b/p11-kit/rpc-server.c @@ -662,6 +662,9 @@ rpc_C_Initialize (CK_X_FUNCTION_LIST *self, CK_C_INITIALIZE_ARGS init_args; CK_BYTE_PTR handshake; CK_ULONG n_handshake; + CK_BYTE reserved_present = 0; + CK_BYTE_PTR reserved = NULL; + CK_ULONG n_reserved; CK_RV ret = CKR_OK; p11_debug ("C_Initialize: enter"); @@ -678,6 +681,15 @@ rpc_C_Initialize (CK_X_FUNCTION_LIST *self, p11_message ("invalid handshake received from connecting module"); ret = CKR_GENERAL_ERROR; } + } + + if (ret == CKR_OK) { + if (!p11_rpc_message_read_byte (msg, &reserved_present)) + ret = PARSE_ERROR; + } + + if (ret == CKR_OK) { + ret = proto_read_byte_array (msg, &reserved, &n_reserved); assert (p11_rpc_message_is_verified (msg)); } @@ -685,6 +697,7 @@ rpc_C_Initialize (CK_X_FUNCTION_LIST *self, if (ret == CKR_OK) { memset (&init_args, 0, sizeof (init_args)); init_args.flags = CKF_OS_LOCKING_OK; + init_args.pReserved = reserved_present ? reserved : NULL; func = self->C_Initialize; assert (func != NULL); diff --git a/p11-kit/test-transport.c b/p11-kit/test-transport.c index 397a65a..227d7ce 100644 --- a/p11-kit/test-transport.c +++ b/p11-kit/test-transport.c @@ -77,6 +77,8 @@ setup_remote (void *unused) setenv ("P11_KIT_PRIVATEDIR", BUILDDIR, 1); data = "remote: |" BUILDDIR "/p11-kit/p11-kit remote " BUILDDIR "/.libs/mock-two.so\n"; p11_test_file_write (test.user_modules, "remote.module", data, strlen (data)); + data = "remote: |" BUILDDIR "/p11-kit/p11-kit remote " BUILDDIR "/.libs/mock-five.so\nx-init-reserved: initialize-arg"; + p11_test_file_write (test.user_modules, "init-arg.module", data, strlen (data)); p11_config_user_modules = test.user_modules; p11_config_user_file = test.user_config; @@ -155,6 +157,27 @@ test_basic_exec (void) p11_kit_modules_release (modules); } +static void +test_basic_exec_with_init_arg (void) +{ + CK_FUNCTION_LIST **modules; + CK_FUNCTION_LIST *module; + CK_RV rv; + + modules = p11_kit_modules_load (NULL, 0); + + module = p11_kit_module_for_name (modules, "init-arg"); + assert (module != NULL); + + rv = p11_kit_module_initialize (module); + assert_num_eq (rv, CKR_OK); + + rv = p11_kit_module_finalize (module); + assert_num_eq (rv, CKR_OK); + + p11_kit_modules_release (modules); +} + static void * invoke_in_thread (void *arg) { @@ -282,6 +305,7 @@ main (int argc, p11_fixture (setup_remote, teardown_remote); p11_test (test_basic_exec, "/transport/basic"); + p11_test (test_basic_exec_with_init_arg, "/transport/init-arg"); p11_test (test_simultaneous_functions, "/transport/simultaneous-functions"); #ifdef OS_UNIX -- cgit v1.2.1