diff options
author | Daiki Ueno <dueno@redhat.com> | 2016-08-26 17:20:06 +0200 |
---|---|---|
committer | Daiki Ueno <ueno@gnu.org> | 2017-01-24 12:36:06 +0100 |
commit | 9f632bed73c8800af16a69c97bd4c315bd350f8b (patch) | |
tree | 014408e1632b4d436b85cfbbfd34f28e892ab2ca /p11-kit | |
parent | 91861f634a1299af28a29de70c45f469562123f6 (diff) |
build: Make libffi closure optional
libffi's closure support is not available on all platforms and may fail
at run time if running under a stricter SELinux policy. Fallback to
pre-compiled closures if it is not usable.
https://bugs.freedesktop.org/show_bug.cgi?id=97611
Diffstat (limited to 'p11-kit')
-rw-r--r-- | p11-kit/Makefile.am | 5 | ||||
-rw-r--r-- | p11-kit/modules.c | 26 | ||||
-rw-r--r-- | p11-kit/proxy.c | 2 | ||||
-rw-r--r-- | p11-kit/test-init.c | 12 | ||||
-rw-r--r-- | p11-kit/test-virtual.c | 1 | ||||
-rw-r--r-- | p11-kit/util.c | 5 | ||||
-rw-r--r-- | p11-kit/virtual-fixed.h | 1135 | ||||
-rw-r--r-- | p11-kit/virtual.c | 614 | ||||
-rw-r--r-- | p11-kit/virtual.h | 6 |
9 files changed, 1661 insertions, 145 deletions
diff --git a/p11-kit/Makefile.am b/p11-kit/Makefile.am index 507be5f..c55746a 100644 --- a/p11-kit/Makefile.am +++ b/p11-kit/Makefile.am @@ -25,6 +25,7 @@ MODULE_SRCS = \ p11-kit/rpc-client.c p11-kit/rpc-server.c \ p11-kit/uri.c \ p11-kit/virtual.c p11-kit/virtual.h \ + p11-kit/virtual-fixed.h \ $(inc_HEADERS) lib_LTLIBRARIES += \ @@ -212,8 +213,6 @@ print_messages_LDADD = $(p11_kit_LIBS) frob_setuid_SOURCES = p11-kit/frob-setuid.c frob_setuid_LDADD = $(p11_kit_LIBS) -if WITH_FFI - CHECK_PROGS += \ test-virtual \ test-managed \ @@ -233,8 +232,6 @@ test_transport_LDADD = $(p11_kit_LIBS) test_virtual_SOURCES = p11-kit/test-virtual.c test_virtual_LDADD = $(p11_kit_LIBS) -endif - noinst_LTLIBRARIES += \ mock-one.la \ mock-two.la \ diff --git a/p11-kit/modules.c b/p11-kit/modules.c index 5cdc8b2..85eb53e 100644 --- a/p11-kit/modules.c +++ b/p11-kit/modules.c @@ -1758,22 +1758,11 @@ lookup_managed_option (Module *mod, value = _p11_conf_parse_boolean (string, def_value); if (!supported && value != supported) { - if (!p11_virtual_can_wrap ()) { - /* - * This is because libffi dependency was not built. The libffi dependency - * is highly recommended and building without it results in a large loss - * of functionality. - */ - p11_message ("the '%s' option for module '%s' is not supported on this system", - option, mod->name); - } else { - /* - * This is because the module is running in unmanaged mode, so turn off the - */ - p11_message ("the '%s' option for module '%s' is only supported for managed modules", - option, mod->name); - } - return false; + /* + * This is because the module is running in unmanaged mode, so turn off the + */ + p11_message ("the '%s' option for module '%s' is only supported for managed modules", + option, mod->name); } return value; @@ -1855,7 +1844,7 @@ prepare_module_inlock_reentrant (Module *mod, is_managed = false; with_log = false; } else { - is_managed = lookup_managed_option (mod, p11_virtual_can_wrap (), "managed", true); + is_managed = lookup_managed_option (mod, true, "managed", true); with_log = lookup_managed_option (mod, is_managed, "log-calls", false); } @@ -1871,7 +1860,8 @@ prepare_module_inlock_reentrant (Module *mod, } *module = p11_virtual_wrap (virt, destroyer); - return_val_if_fail (*module != NULL, CKR_GENERAL_ERROR); + if (*module == NULL) + return CKR_GENERAL_ERROR; if (!p11_dict_set (gl.managed_by_closure, *module, mod)) return_val_if_reached (CKR_HOST_MEMORY); diff --git a/p11-kit/proxy.c b/p11-kit/proxy.c index ad3caa5..6f91fa4 100644 --- a/p11-kit/proxy.c +++ b/p11-kit/proxy.c @@ -2365,7 +2365,7 @@ C_GetFunctionList (CK_FUNCTION_LIST_PTR_PTR list) } } - if (rv == CKR_OK && p11_virtual_can_wrap ()) { + if (rv == CKR_OK) { state = calloc (1, sizeof (State)); if (!state) { rv = CKR_HOST_MEMORY; diff --git a/p11-kit/test-init.c b/p11-kit/test-init.c index c4fcecb..18eb025 100644 --- a/p11-kit/test-init.c +++ b/p11-kit/test-init.c @@ -402,16 +402,14 @@ main (int argc, p11_library_init (); /* These only work when managed */ - if (p11_virtual_can_wrap ()) { - p11_test (test_recursive_initialization, "/init/test_recursive_initialization"); - p11_test (test_threaded_initialization, "/init/test_threaded_initialization"); - p11_test (test_mutexes, "/init/test_mutexes"); - p11_test (test_load_and_initialize, "/init/test_load_and_initialize"); + p11_test (test_recursive_initialization, "/init/test_recursive_initialization"); + p11_test (test_threaded_initialization, "/init/test_threaded_initialization"); + p11_test (test_mutexes, "/init/test_mutexes"); + p11_test (test_load_and_initialize, "/init/test_load_and_initialize"); #ifdef OS_UNIX - p11_test (test_fork_initialization, "/init/test_fork_initialization"); + p11_test (test_fork_initialization, "/init/test_fork_initialization"); #endif - } p11_test (test_initalize_fail, "/init/test_initalize_fail"); p11_test (test_finalize_fail, "/init/test_finalize_fail"); diff --git a/p11-kit/test-virtual.c b/p11-kit/test-virtual.c index e642820..fd9eba9 100644 --- a/p11-kit/test-virtual.c +++ b/p11-kit/test-virtual.c @@ -162,7 +162,6 @@ main (int argc, mock_module_init (); p11_library_init (); - assert (p11_virtual_can_wrap ()); p11_test (test_initialize, "/virtual/test_initialize"); p11_test (test_fall_through, "/virtual/test_fall_through"); p11_test (test_get_function_list, "/virtual/test_get_function_list"); diff --git a/p11-kit/util.c b/p11-kit/util.c index 325d669..816952f 100644 --- a/p11-kit/util.c +++ b/p11-kit/util.c @@ -45,6 +45,7 @@ #include "p11-kit.h" #include "private.h" #include "proxy.h" +#include "virtual.h" #include <assert.h> #include <stdarg.h> @@ -251,6 +252,7 @@ void _p11_kit_init (void) { p11_library_init_once (); + p11_virtual_init_fixed (); } #ifdef __GNUC__ @@ -260,6 +262,7 @@ void _p11_kit_fini (void) { p11_proxy_module_cleanup (); + p11_virtual_uninit_fixed (); p11_library_uninit (); } @@ -277,12 +280,14 @@ DllMain (HINSTANCE instance, switch (reason) { case DLL_PROCESS_ATTACH: p11_library_init (); + p11_virtual_init_fixed (); break; case DLL_THREAD_DETACH: p11_library_thread_cleanup (); break; case DLL_PROCESS_DETACH: p11_proxy_module_cleanup (); + p11_virtual_uninit_fixed (); p11_library_uninit (); break; default: diff --git a/p11-kit/virtual-fixed.h b/p11-kit/virtual-fixed.h new file mode 100644 index 0000000..1cb685d --- /dev/null +++ b/p11-kit/virtual-fixed.h @@ -0,0 +1,1135 @@ +/* + * Copyright (c) 2016 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: Daiki Ueno + */ + +#define P11_VIRTUAL_MAX_FIXED 64 + +#define P11_VIRTUAL_FIXED_FUNCTIONS(fixed_index) \ +static CK_RV \ +fixed ## fixed_index ## _C_Initialize (CK_VOID_PTR init_args) \ +{ \ + CK_FUNCTION_LIST *bound; \ + Wrapper *wrapper; \ + CK_X_FUNCTION_LIST *funcs; \ + bound = fixed_closures[fixed_index]; \ + return_val_if_fail (bound != NULL, CKR_GENERAL_ERROR); \ + wrapper = (Wrapper *) bound; \ + funcs = &wrapper->virt->funcs; \ + return funcs->C_Initialize (funcs, init_args); \ +} \ +\ +static CK_RV \ +fixed ## fixed_index ## _C_Finalize (CK_VOID_PTR reserved) \ +{ \ + CK_FUNCTION_LIST *bound; \ + Wrapper *wrapper; \ + CK_X_FUNCTION_LIST *funcs; \ + bound = fixed_closures[fixed_index]; \ + return_val_if_fail (bound != NULL, CKR_GENERAL_ERROR); \ + wrapper = (Wrapper *) bound; \ + funcs = &wrapper->virt->funcs; \ + return funcs->C_Finalize (funcs, reserved); \ +} \ +\ +static CK_RV \ +fixed ## fixed_index ## _C_GetInfo (CK_INFO_PTR info) \ +{ \ + CK_FUNCTION_LIST *bound; \ + Wrapper *wrapper; \ + CK_X_FUNCTION_LIST *funcs; \ + bound = fixed_closures[fixed_index]; \ + return_val_if_fail (bound != NULL, CKR_GENERAL_ERROR); \ + wrapper = (Wrapper *) bound; \ + funcs = &wrapper->virt->funcs; \ + return funcs->C_GetInfo (funcs, info); \ +} \ +\ +static CK_RV \ +fixed ## fixed_index ## _C_GetSlotList (CK_BBOOL token_present, \ + CK_SLOT_ID_PTR slot_list, \ + CK_ULONG_PTR count) \ +{ \ + CK_FUNCTION_LIST *bound; \ + Wrapper *wrapper; \ + CK_X_FUNCTION_LIST *funcs; \ + bound = fixed_closures[fixed_index]; \ + return_val_if_fail (bound != NULL, CKR_GENERAL_ERROR); \ + wrapper = (Wrapper *) bound; \ + funcs = &wrapper->virt->funcs; \ + return funcs->C_GetSlotList (funcs, token_present, slot_list, count); \ +} \ +\ +static CK_RV \ +fixed ## fixed_index ## _C_GetSlotInfo (CK_SLOT_ID slot_id, \ + CK_SLOT_INFO_PTR info) \ +{ \ + CK_FUNCTION_LIST *bound; \ + Wrapper *wrapper; \ + CK_X_FUNCTION_LIST *funcs; \ + bound = fixed_closures[fixed_index]; \ + return_val_if_fail (bound != NULL, CKR_GENERAL_ERROR); \ + wrapper = (Wrapper *) bound; \ + funcs = &wrapper->virt->funcs; \ + return funcs->C_GetSlotInfo (funcs, slot_id, info); \ +} \ +\ +static CK_RV \ +fixed ## fixed_index ## _C_GetTokenInfo (CK_SLOT_ID slot_id, \ + CK_TOKEN_INFO_PTR info) \ +{ \ + CK_FUNCTION_LIST *bound; \ + Wrapper *wrapper; \ + CK_X_FUNCTION_LIST *funcs; \ + bound = fixed_closures[fixed_index]; \ + return_val_if_fail (bound != NULL, CKR_GENERAL_ERROR); \ + wrapper = (Wrapper *) bound; \ + funcs = &wrapper->virt->funcs; \ + return funcs->C_GetTokenInfo (funcs, slot_id, info); \ +} \ +\ +static CK_RV \ +fixed ## fixed_index ## _C_GetMechanismList (CK_SLOT_ID slot_id, \ + CK_MECHANISM_TYPE_PTR mechanism_list, \ + CK_ULONG_PTR count) \ +{ \ + CK_FUNCTION_LIST *bound; \ + Wrapper *wrapper; \ + CK_X_FUNCTION_LIST *funcs; \ + bound = fixed_closures[fixed_index]; \ + return_val_if_fail (bound != NULL, CKR_GENERAL_ERROR); \ + wrapper = (Wrapper *) bound; \ + funcs = &wrapper->virt->funcs; \ + return funcs->C_GetMechanismList (funcs, slot_id, mechanism_list, count); \ +} \ +\ +static CK_RV \ +fixed ## fixed_index ## _C_GetMechanismInfo (CK_SLOT_ID slot_id, \ + CK_MECHANISM_TYPE type, \ + CK_MECHANISM_INFO_PTR info) \ +{ \ + CK_FUNCTION_LIST *bound; \ + Wrapper *wrapper; \ + CK_X_FUNCTION_LIST *funcs; \ + bound = fixed_closures[fixed_index]; \ + return_val_if_fail (bound != NULL, CKR_GENERAL_ERROR); \ + wrapper = (Wrapper *) bound; \ + funcs = &wrapper->virt->funcs; \ + return funcs->C_GetMechanismInfo (funcs, slot_id, type, info); \ +} \ +\ +static CK_RV \ +fixed ## fixed_index ## _C_InitToken (CK_SLOT_ID slot_id, \ + CK_BYTE_PTR pin, \ + CK_ULONG pin_len, \ + CK_BYTE_PTR label) \ +{ \ + CK_FUNCTION_LIST *bound; \ + Wrapper *wrapper; \ + CK_X_FUNCTION_LIST *funcs; \ + bound = fixed_closures[fixed_index]; \ + return_val_if_fail (bound != NULL, CKR_GENERAL_ERROR); \ + wrapper = (Wrapper *) bound; \ + funcs = &wrapper->virt->funcs; \ + return funcs->C_InitToken (funcs, slot_id, pin, pin_len, label); \ +} \ +\ +static CK_RV \ +fixed ## fixed_index ## _C_InitPIN (CK_SESSION_HANDLE session, \ + CK_BYTE_PTR pin, \ + CK_ULONG pin_len) \ +{ \ + CK_FUNCTION_LIST *bound; \ + Wrapper *wrapper; \ + CK_X_FUNCTION_LIST *funcs; \ + bound = fixed_closures[fixed_index]; \ + return_val_if_fail (bound != NULL, CKR_GENERAL_ERROR); \ + wrapper = (Wrapper *) bound; \ + funcs = &wrapper->virt->funcs; \ + return funcs->C_InitPIN (funcs, session, pin, pin_len); \ +} \ +\ +static CK_RV \ +fixed ## fixed_index ## _C_SetPIN (CK_SESSION_HANDLE session, \ + CK_BYTE_PTR old_pin, \ + CK_ULONG old_len, \ + CK_BYTE_PTR new_pin, \ + CK_ULONG new_len) \ +{ \ + CK_FUNCTION_LIST *bound; \ + Wrapper *wrapper; \ + CK_X_FUNCTION_LIST *funcs; \ + bound = fixed_closures[fixed_index]; \ + return_val_if_fail (bound != NULL, CKR_GENERAL_ERROR); \ + wrapper = (Wrapper *) bound; \ + funcs = &wrapper->virt->funcs; \ + return funcs->C_SetPIN (funcs, session, old_pin, old_len, new_pin, new_len); \ +} \ +\ +static CK_RV \ +fixed ## fixed_index ## _C_OpenSession (CK_SLOT_ID slot_id, \ + CK_FLAGS flags, \ + CK_VOID_PTR application, \ + CK_NOTIFY notify, \ + CK_SESSION_HANDLE_PTR session) \ +{ \ + CK_FUNCTION_LIST *bound; \ + Wrapper *wrapper; \ + CK_X_FUNCTION_LIST *funcs; \ + bound = fixed_closures[fixed_index]; \ + return_val_if_fail (bound != NULL, CKR_GENERAL_ERROR); \ + wrapper = (Wrapper *) bound; \ + funcs = &wrapper->virt->funcs; \ + return funcs->C_OpenSession (funcs, slot_id, flags, application, notify, session); \ +} \ +\ +static CK_RV \ +fixed ## fixed_index ## _C_CloseSession (CK_SESSION_HANDLE session) \ +{ \ + CK_FUNCTION_LIST *bound; \ + Wrapper *wrapper; \ + CK_X_FUNCTION_LIST *funcs; \ + bound = fixed_closures[fixed_index]; \ + return_val_if_fail (bound != NULL, CKR_GENERAL_ERROR); \ + wrapper = (Wrapper *) bound; \ + funcs = &wrapper->virt->funcs; \ + return funcs->C_CloseSession (funcs, session); \ +} \ +\ +static CK_RV \ +fixed ## fixed_index ## _C_CloseAllSessions (CK_SLOT_ID slot_id) \ +{ \ + CK_FUNCTION_LIST *bound; \ + Wrapper *wrapper; \ + CK_X_FUNCTION_LIST *funcs; \ + bound = fixed_closures[fixed_index]; \ + return_val_if_fail (bound != NULL, CKR_GENERAL_ERROR); \ + wrapper = (Wrapper *) bound; \ + funcs = &wrapper->virt->funcs; \ + return funcs->C_CloseAllSessions (funcs, slot_id); \ +} \ +\ +static CK_RV \ +fixed ## fixed_index ## _C_GetSessionInfo (CK_SESSION_HANDLE session, \ + CK_SESSION_INFO_PTR info) \ +{ \ + CK_FUNCTION_LIST *bound; \ + Wrapper *wrapper; \ + CK_X_FUNCTION_LIST *funcs; \ + bound = fixed_closures[fixed_index]; \ + return_val_if_fail (bound != NULL, CKR_GENERAL_ERROR); \ + wrapper = (Wrapper *) bound; \ + funcs = &wrapper->virt->funcs; \ + return funcs->C_GetSessionInfo (funcs, session, info); \ +} \ +\ +static CK_RV \ +fixed ## fixed_index ## _C_GetOperationState (CK_SESSION_HANDLE session, \ + CK_BYTE_PTR operation_state, \ + CK_ULONG_PTR operation_state_len) \ +{ \ + CK_FUNCTION_LIST *bound; \ + Wrapper *wrapper; \ + CK_X_FUNCTION_LIST *funcs; \ + bound = fixed_closures[fixed_index]; \ + return_val_if_fail (bound != NULL, CKR_GENERAL_ERROR); \ + wrapper = (Wrapper *) bound; \ + funcs = &wrapper->virt->funcs; \ + return funcs->C_GetOperationState (funcs, session, operation_state, operation_state_len); \ +} \ +\ +static CK_RV \ +fixed ## fixed_index ## _C_SetOperationState (CK_SESSION_HANDLE session, \ + CK_BYTE_PTR operation_state, \ + CK_ULONG operation_state_len, \ + CK_OBJECT_HANDLE encryption_key, \ + CK_OBJECT_HANDLE authentiation_key) \ +{ \ + CK_FUNCTION_LIST *bound; \ + Wrapper *wrapper; \ + CK_X_FUNCTION_LIST *funcs; \ + bound = fixed_closures[fixed_index]; \ + return_val_if_fail (bound != NULL, CKR_GENERAL_ERROR); \ + wrapper = (Wrapper *) bound; \ + funcs = &wrapper->virt->funcs; \ + return funcs->C_SetOperationState (funcs, session, operation_state, operation_state_len, encryption_key, authentiation_key); \ +} \ +\ +static CK_RV \ +fixed ## fixed_index ## _C_Login (CK_SESSION_HANDLE session, \ + CK_USER_TYPE user_type, \ + CK_BYTE_PTR pin, \ + CK_ULONG pin_len) \ +{ \ + CK_FUNCTION_LIST *bound; \ + Wrapper *wrapper; \ + CK_X_FUNCTION_LIST *funcs; \ + bound = fixed_closures[fixed_index]; \ + return_val_if_fail (bound != NULL, CKR_GENERAL_ERROR); \ + wrapper = (Wrapper *) bound; \ + funcs = &wrapper->virt->funcs; \ + return funcs->C_Login (funcs, session, user_type, pin, pin_len); \ +} \ +\ +static CK_RV \ +fixed ## fixed_index ## _C_Logout (CK_SESSION_HANDLE session) \ +{ \ + CK_FUNCTION_LIST *bound; \ + Wrapper *wrapper; \ + CK_X_FUNCTION_LIST *funcs; \ + bound = fixed_closures[fixed_index]; \ + return_val_if_fail (bound != NULL, CKR_GENERAL_ERROR); \ + wrapper = (Wrapper *) bound; \ + funcs = &wrapper->virt->funcs; \ + return funcs->C_Logout (funcs, session); \ +} \ +\ +static CK_RV \ +fixed ## fixed_index ## _C_CreateObject (CK_SESSION_HANDLE session, \ + CK_ATTRIBUTE_PTR templ, \ + CK_ULONG count, \ + CK_OBJECT_HANDLE_PTR object) \ +{ \ + CK_FUNCTION_LIST *bound; \ + Wrapper *wrapper; \ + CK_X_FUNCTION_LIST *funcs; \ + bound = fixed_closures[fixed_index]; \ + return_val_if_fail (bound != NULL, CKR_GENERAL_ERROR); \ + wrapper = (Wrapper *) bound; \ + funcs = &wrapper->virt->funcs; \ + return funcs->C_CreateObject (funcs, session, templ, count, object); \ +} \ +\ +static CK_RV \ +fixed ## fixed_index ## _C_CopyObject (CK_SESSION_HANDLE session, \ + CK_OBJECT_HANDLE object, \ + CK_ATTRIBUTE_PTR templ, \ + CK_ULONG count, \ + CK_OBJECT_HANDLE_PTR new_object) \ +{ \ + CK_FUNCTION_LIST *bound; \ + Wrapper *wrapper; \ + CK_X_FUNCTION_LIST *funcs; \ + bound = fixed_closures[fixed_index]; \ + return_val_if_fail (bound != NULL, CKR_GENERAL_ERROR); \ + wrapper = (Wrapper *) bound; \ + funcs = &wrapper->virt->funcs; \ + return funcs->C_CopyObject (funcs, session, object, templ, count, new_object); \ +} \ +\ +static CK_RV \ +fixed ## fixed_index ## _C_DestroyObject (CK_SESSION_HANDLE session, \ + CK_OBJECT_HANDLE object) \ +{ \ + CK_FUNCTION_LIST *bound; \ + Wrapper *wrapper; \ + CK_X_FUNCTION_LIST *funcs; \ + bound = fixed_closures[fixed_index]; \ + return_val_if_fail (bound != NULL, CKR_GENERAL_ERROR); \ + wrapper = (Wrapper *) bound; \ + funcs = &wrapper->virt->funcs; \ + return funcs->C_DestroyObject (funcs, session, object); \ +} \ +\ +static CK_RV \ +fixed ## fixed_index ## _C_GetObjectSize (CK_SESSION_HANDLE session, \ + CK_OBJECT_HANDLE object, \ + CK_ULONG_PTR size) \ +{ \ + CK_FUNCTION_LIST *bound; \ + Wrapper *wrapper; \ + CK_X_FUNCTION_LIST *funcs; \ + bound = fixed_closures[fixed_index]; \ + return_val_if_fail (bound != NULL, CKR_GENERAL_ERROR); \ + wrapper = (Wrapper *) bound; \ + funcs = &wrapper->virt->funcs; \ + return funcs->C_GetObjectSize (funcs, session, object, size); \ +} \ +\ +static CK_RV \ +fixed ## fixed_index ## _C_GetAttributeValue (CK_SESSION_HANDLE session, \ + CK_OBJECT_HANDLE object, \ + CK_ATTRIBUTE_PTR templ, \ + CK_ULONG count) \ +{ \ + CK_FUNCTION_LIST *bound; \ + Wrapper *wrapper; \ + CK_X_FUNCTION_LIST *funcs; \ + bound = fixed_closures[fixed_index]; \ + return_val_if_fail (bound != NULL, CKR_GENERAL_ERROR); \ + wrapper = (Wrapper *) bound; \ + funcs = &wrapper->virt->funcs; \ + return funcs->C_GetAttributeValue (funcs, session, object, templ, count); \ +} \ +\ +static CK_RV \ +fixed ## fixed_index ## _C_SetAttributeValue (CK_SESSION_HANDLE session, \ + CK_OBJECT_HANDLE object, \ + CK_ATTRIBUTE_PTR templ, \ + CK_ULONG count) \ +{ \ + CK_FUNCTION_LIST *bound; \ + Wrapper *wrapper; \ + CK_X_FUNCTION_LIST *funcs; \ + bound = fixed_closures[fixed_index]; \ + return_val_if_fail (bound != NULL, CKR_GENERAL_ERROR); \ + wrapper = (Wrapper *) bound; \ + funcs = &wrapper->virt->funcs; \ + return funcs->C_SetAttributeValue (funcs, session, object, templ, count); \ +} \ +\ +static CK_RV \ +fixed ## fixed_index ## _C_FindObjectsInit (CK_SESSION_HANDLE session, \ + CK_ATTRIBUTE_PTR templ, \ + CK_ULONG count) \ +{ \ + CK_FUNCTION_LIST *bound; \ + Wrapper *wrapper; \ + CK_X_FUNCTION_LIST *funcs; \ + bound = fixed_closures[fixed_index]; \ + return_val_if_fail (bound != NULL, CKR_GENERAL_ERROR); \ + wrapper = (Wrapper *) bound; \ + funcs = &wrapper->virt->funcs; \ + return funcs->C_FindObjectsInit (funcs, session, templ, count); \ +} \ +\ +static CK_RV \ +fixed ## fixed_index ## _C_FindObjects (CK_SESSION_HANDLE session, \ + CK_OBJECT_HANDLE_PTR object, \ + CK_ULONG max_object_count, \ + CK_ULONG_PTR object_count) \ +{ \ + CK_FUNCTION_LIST *bound; \ + Wrapper *wrapper; \ + CK_X_FUNCTION_LIST *funcs; \ + bound = fixed_closures[fixed_index]; \ + return_val_if_fail (bound != NULL, CKR_GENERAL_ERROR); \ + wrapper = (Wrapper *) bound; \ + funcs = &wrapper->virt->funcs; \ + return funcs->C_FindObjects (funcs, session, object, max_object_count, object_count); \ +} \ +\ +static CK_RV \ +fixed ## fixed_index ## _C_FindObjectsFinal (CK_SESSION_HANDLE session) \ +{ \ + CK_FUNCTION_LIST *bound; \ + Wrapper *wrapper; \ + CK_X_FUNCTION_LIST *funcs; \ + bound = fixed_closures[fixed_index]; \ + return_val_if_fail (bound != NULL, CKR_GENERAL_ERROR); \ + wrapper = (Wrapper *) bound; \ + funcs = &wrapper->virt->funcs; \ + return funcs->C_FindObjectsFinal (funcs, session); \ +} \ +\ +static CK_RV \ +fixed ## fixed_index ## _C_EncryptInit (CK_SESSION_HANDLE session, \ + CK_MECHANISM_PTR mechanism, \ + CK_OBJECT_HANDLE key) \ +{ \ + CK_FUNCTION_LIST *bound; \ + Wrapper *wrapper; \ + CK_X_FUNCTION_LIST *funcs; \ + bound = fixed_closures[fixed_index]; \ + return_val_if_fail (bound != NULL, CKR_GENERAL_ERROR); \ + wrapper = (Wrapper *) bound; \ + funcs = &wrapper->virt->funcs; \ + return funcs->C_EncryptInit (funcs, session, mechanism, key); \ +} \ +\ +static CK_RV \ +fixed ## fixed_index ## _C_Encrypt (CK_SESSION_HANDLE session, \ + CK_BYTE_PTR data, \ + CK_ULONG data_len, \ + CK_BYTE_PTR encrypted_data, \ + CK_ULONG_PTR encrypted_data_len) \ +{ \ + CK_FUNCTION_LIST *bound; \ + Wrapper *wrapper; \ + CK_X_FUNCTION_LIST *funcs; \ + bound = fixed_closures[fixed_index]; \ + return_val_if_fail (bound != NULL, CKR_GENERAL_ERROR); \ + wrapper = (Wrapper *) bound; \ + funcs = &wrapper->virt->funcs; \ + return funcs->C_Encrypt (funcs, session, data, data_len, encrypted_data, encrypted_data_len); \ +} \ +\ +static CK_RV \ +fixed ## fixed_index ## _C_EncryptUpdate (CK_SESSION_HANDLE session, \ + CK_BYTE_PTR part, \ + CK_ULONG part_len, \ + CK_BYTE_PTR encrypted_part, \ + CK_ULONG_PTR encrypted_part_len) \ +{ \ + CK_FUNCTION_LIST *bound; \ + Wrapper *wrapper; \ + CK_X_FUNCTION_LIST *funcs; \ + bound = fixed_closures[fixed_index]; \ + return_val_if_fail (bound != NULL, CKR_GENERAL_ERROR); \ + wrapper = (Wrapper *) bound; \ + funcs = &wrapper->virt->funcs; \ + return funcs->C_EncryptUpdate (funcs, session, part, part_len, encrypted_part, encrypted_part_len); \ +} \ +\ +static CK_RV \ +fixed ## fixed_index ## _C_EncryptFinal (CK_SESSION_HANDLE session, \ + CK_BYTE_PTR last_encrypted_part, \ + CK_ULONG_PTR last_encrypted_part_len) \ +{ \ + CK_FUNCTION_LIST *bound; \ + Wrapper *wrapper; \ + CK_X_FUNCTION_LIST *funcs; \ + bound = fixed_closures[fixed_index]; \ + return_val_if_fail (bound != NULL, CKR_GENERAL_ERROR); \ + wrapper = (Wrapper *) bound; \ + funcs = &wrapper->virt->funcs; \ + return funcs->C_EncryptFinal (funcs, session, last_encrypted_part, last_encrypted_part_len); \ +} \ +\ +static CK_RV \ +fixed ## fixed_index ## _C_DecryptInit (CK_SESSION_HANDLE session, \ + CK_MECHANISM_PTR mechanism, \ + CK_OBJECT_HANDLE key) \ +{ \ + CK_FUNCTION_LIST *bound; \ + Wrapper *wrapper; \ + CK_X_FUNCTION_LIST *funcs; \ + bound = fixed_closures[fixed_index]; \ + return_val_if_fail (bound != NULL, CKR_GENERAL_ERROR); \ + wrapper = (Wrapper *) bound; \ + funcs = &wrapper->virt->funcs; \ + return funcs->C_DecryptInit (funcs, session, mechanism, key); \ +} \ +\ +static CK_RV \ +fixed ## fixed_index ## _C_Decrypt (CK_SESSION_HANDLE session, \ + CK_BYTE_PTR encrypted_data, \ + CK_ULONG encrypted_data_len, \ + CK_BYTE_PTR data, \ + CK_ULONG_PTR data_len) \ +{ \ + CK_FUNCTION_LIST *bound; \ + Wrapper *wrapper; \ + CK_X_FUNCTION_LIST *funcs; \ + bound = fixed_closures[fixed_index]; \ + return_val_if_fail (bound != NULL, CKR_GENERAL_ERROR); \ + wrapper = (Wrapper *) bound; \ + funcs = &wrapper->virt->funcs; \ + return funcs->C_Decrypt (funcs, session, encrypted_data, encrypted_data_len, data, data_len); \ +} \ +\ +static CK_RV \ +fixed ## fixed_index ## _C_DecryptUpdate (CK_SESSION_HANDLE session, \ + CK_BYTE_PTR encrypted_part, \ + CK_ULONG encrypted_part_len, \ + CK_BYTE_PTR part, \ + CK_ULONG_PTR part_len) \ +{ \ + CK_FUNCTION_LIST *bound; \ + Wrapper *wrapper; \ + CK_X_FUNCTION_LIST *funcs; \ + bound = fixed_closures[fixed_index]; \ + return_val_if_fail (bound != NULL, CKR_GENERAL_ERROR); \ + wrapper = (Wrapper *) bound; \ + funcs = &wrapper->virt->funcs; \ + return funcs->C_DecryptUpdate (funcs, session, encrypted_part, encrypted_part_len, part, part_len); \ +} \ +\ +static CK_RV \ +fixed ## fixed_index ## _C_DecryptFinal (CK_SESSION_HANDLE session, \ + CK_BYTE_PTR last_part, \ + CK_ULONG_PTR last_part_len) \ +{ \ + CK_FUNCTION_LIST *bound; \ + Wrapper *wrapper; \ + CK_X_FUNCTION_LIST *funcs; \ + bound = fixed_closures[fixed_index]; \ + return_val_if_fail (bound != NULL, CKR_GENERAL_ERROR); \ + wrapper = (Wrapper *) bound; \ + funcs = &wrapper->virt->funcs; \ + return funcs->C_DecryptFinal (funcs, session, last_part, last_part_len); \ +} \ +\ +static CK_RV \ +fixed ## fixed_index ## _C_DigestInit (CK_SESSION_HANDLE session, \ + CK_MECHANISM_PTR mechanism) \ +{ \ + CK_FUNCTION_LIST *bound; \ + Wrapper *wrapper; \ + CK_X_FUNCTION_LIST *funcs; \ + bound = fixed_closures[fixed_index]; \ + return_val_if_fail (bound != NULL, CKR_GENERAL_ERROR); \ + wrapper = (Wrapper *) bound; \ + funcs = &wrapper->virt->funcs; \ + return funcs->C_DigestInit (funcs, session, mechanism); \ +} \ +\ +static CK_RV \ +fixed ## fixed_index ## _C_Digest (CK_SESSION_HANDLE session, \ + CK_BYTE_PTR data, \ + CK_ULONG data_len, \ + CK_BYTE_PTR digest, \ + CK_ULONG_PTR digest_len) \ +{ \ + CK_FUNCTION_LIST *bound; \ + Wrapper *wrapper; \ + CK_X_FUNCTION_LIST *funcs; \ + bound = fixed_closures[fixed_index]; \ + return_val_if_fail (bound != NULL, CKR_GENERAL_ERROR); \ + wrapper = (Wrapper *) bound; \ + funcs = &wrapper->virt->funcs; \ + return funcs->C_Digest (funcs, session, data, data_len, digest, digest_len); \ +} \ +\ +static CK_RV \ +fixed ## fixed_index ## _C_DigestUpdate (CK_SESSION_HANDLE session, \ + CK_BYTE_PTR part, \ + CK_ULONG part_len) \ +{ \ + CK_FUNCTION_LIST *bound; \ + Wrapper *wrapper; \ + CK_X_FUNCTION_LIST *funcs; \ + bound = fixed_closures[fixed_index]; \ + return_val_if_fail (bound != NULL, CKR_GENERAL_ERROR); \ + wrapper = (Wrapper *) bound; \ + funcs = &wrapper->virt->funcs; \ + return funcs->C_DigestUpdate (funcs, session, part, part_len); \ +} \ +\ +static CK_RV \ +fixed ## fixed_index ## _C_DigestKey (CK_SESSION_HANDLE session, \ + CK_OBJECT_HANDLE key) \ +{ \ + CK_FUNCTION_LIST *bound; \ + Wrapper *wrapper; \ + CK_X_FUNCTION_LIST *funcs; \ + bound = fixed_closures[fixed_index]; \ + return_val_if_fail (bound != NULL, CKR_GENERAL_ERROR); \ + wrapper = (Wrapper *) bound; \ + funcs = &wrapper->virt->funcs; \ + return funcs->C_DigestKey (funcs, session, key); \ +} \ +\ +static CK_RV \ +fixed ## fixed_index ## _C_DigestFinal (CK_SESSION_HANDLE session, \ + CK_BYTE_PTR digest, \ + CK_ULONG_PTR digest_len) \ +{ \ + CK_FUNCTION_LIST *bound; \ + Wrapper *wrapper; \ + CK_X_FUNCTION_LIST *funcs; \ + bound = fixed_closures[fixed_index]; \ + return_val_if_fail (bound != NULL, CKR_GENERAL_ERROR); \ + wrapper = (Wrapper *) bound; \ + funcs = &wrapper->virt->funcs; \ + return funcs->C_DigestFinal (funcs, session, digest, digest_len); \ +} \ +\ +static CK_RV \ +fixed ## fixed_index ## _C_SignInit (CK_SESSION_HANDLE session, \ + CK_MECHANISM_PTR mechanism, \ + CK_OBJECT_HANDLE key) \ +{ \ + CK_FUNCTION_LIST *bound; \ + Wrapper *wrapper; \ + CK_X_FUNCTION_LIST *funcs; \ + bound = fixed_closures[fixed_index]; \ + return_val_if_fail (bound != NULL, CKR_GENERAL_ERROR); \ + wrapper = (Wrapper *) bound; \ + funcs = &wrapper->virt->funcs; \ + return funcs->C_SignInit (funcs, session, mechanism, key); \ +} \ +\ +static CK_RV \ +fixed ## fixed_index ## _C_Sign (CK_SESSION_HANDLE session, \ + CK_BYTE_PTR data, \ + CK_ULONG data_len, \ + CK_BYTE_PTR signature, \ + CK_ULONG_PTR signature_len) \ +{ \ + CK_FUNCTION_LIST *bound; \ + Wrapper *wrapper; \ + CK_X_FUNCTION_LIST *funcs; \ + bound = fixed_closures[fixed_index]; \ + return_val_if_fail (bound != NULL, CKR_GENERAL_ERROR); \ + wrapper = (Wrapper *) bound; \ + funcs = &wrapper->virt->funcs; \ + return funcs->C_Sign (funcs, session, data, data_len, signature, signature_len); \ +} \ +\ +static CK_RV \ +fixed ## fixed_index ## _C_SignUpdate (CK_SESSION_HANDLE session, \ + CK_BYTE_PTR part, \ + CK_ULONG part_len) \ +{ \ + CK_FUNCTION_LIST *bound; \ + Wrapper *wrapper; \ + CK_X_FUNCTION_LIST *funcs; \ + bound = fixed_closures[fixed_index]; \ + return_val_if_fail (bound != NULL, CKR_GENERAL_ERROR); \ + wrapper = (Wrapper *) bound; \ + funcs = &wrapper->virt->funcs; \ + return funcs->C_SignUpdate (funcs, session, part, part_len); \ +} \ +\ +static CK_RV \ +fixed ## fixed_index ## _C_SignFinal (CK_SESSION_HANDLE session, \ + CK_BYTE_PTR signature, \ + CK_ULONG_PTR signature_len) \ +{ \ + CK_FUNCTION_LIST *bound; \ + Wrapper *wrapper; \ + CK_X_FUNCTION_LIST *funcs; \ + bound = fixed_closures[fixed_index]; \ + return_val_if_fail (bound != NULL, CKR_GENERAL_ERROR); \ + wrapper = (Wrapper *) bound; \ + funcs = &wrapper->virt->funcs; \ + return funcs->C_SignFinal (funcs, session, signature, signature_len); \ +} \ +\ +static CK_RV \ +fixed ## fixed_index ## _C_SignRecoverInit (CK_SESSION_HANDLE session, \ + CK_MECHANISM_PTR mechanism, \ + CK_OBJECT_HANDLE key) \ +{ \ + CK_FUNCTION_LIST *bound; \ + Wrapper *wrapper; \ + CK_X_FUNCTION_LIST *funcs; \ + bound = fixed_closures[fixed_index]; \ + return_val_if_fail (bound != NULL, CKR_GENERAL_ERROR); \ + wrapper = (Wrapper *) bound; \ + funcs = &wrapper->virt->funcs; \ + return funcs->C_SignRecoverInit (funcs, session, mechanism, key); \ +} \ +\ +static CK_RV \ +fixed ## fixed_index ## _C_SignRecover (CK_SESSION_HANDLE session, \ + CK_BYTE_PTR data, \ + CK_ULONG data_len, \ + CK_BYTE_PTR signature, \ + CK_ULONG_PTR signature_len) \ +{ \ + CK_FUNCTION_LIST *bound; \ + Wrapper *wrapper; \ + CK_X_FUNCTION_LIST *funcs; \ + bound = fixed_closures[fixed_index]; \ + return_val_if_fail (bound != NULL, CKR_GENERAL_ERROR); \ + wrapper = (Wrapper *) bound; \ + funcs = &wrapper->virt->funcs; \ + return funcs->C_SignRecover (funcs, session, data, data_len, signature, signature_len); \ +} \ +\ +static CK_RV \ +fixed ## fixed_index ## _C_VerifyInit (CK_SESSION_HANDLE session, \ + CK_MECHANISM_PTR mechanism, \ + CK_OBJECT_HANDLE key) \ +{ \ + CK_FUNCTION_LIST *bound; \ + Wrapper *wrapper; \ + CK_X_FUNCTION_LIST *funcs; \ + bound = fixed_closures[fixed_index]; \ + return_val_if_fail (bound != NULL, CKR_GENERAL_ERROR); \ + wrapper = (Wrapper *) bound; \ + funcs = &wrapper->virt->funcs; \ + return funcs->C_VerifyInit (funcs, session, mechanism, key); \ +} \ +\ +static CK_RV \ +fixed ## fixed_index ## _C_Verify (CK_SESSION_HANDLE session, \ + CK_BYTE_PTR data, \ + CK_ULONG data_len, \ + CK_BYTE_PTR signature, \ + CK_ULONG signature_len) \ +{ \ + CK_FUNCTION_LIST *bound; \ + Wrapper *wrapper; \ + CK_X_FUNCTION_LIST *funcs; \ + bound = fixed_closures[fixed_index]; \ + return_val_if_fail (bound != NULL, CKR_GENERAL_ERROR); \ + wrapper = (Wrapper *) bound; \ + funcs = &wrapper->virt->funcs; \ + return funcs->C_Verify (funcs, session, data, data_len, signature, signature_len); \ +} \ +\ +static CK_RV \ +fixed ## fixed_index ## _C_VerifyUpdate (CK_SESSION_HANDLE session, \ + CK_BYTE_PTR part, \ + CK_ULONG part_len) \ +{ \ + CK_FUNCTION_LIST *bound; \ + Wrapper *wrapper; \ + CK_X_FUNCTION_LIST *funcs; \ + bound = fixed_closures[fixed_index]; \ + return_val_if_fail (bound != NULL, CKR_GENERAL_ERROR); \ + wrapper = (Wrapper *) bound; \ + funcs = &wrapper->virt->funcs; \ + return funcs->C_VerifyUpdate (funcs, session, part, part_len); \ +} \ +\ +static CK_RV \ +fixed ## fixed_index ## _C_VerifyFinal (CK_SESSION_HANDLE session, \ + CK_BYTE_PTR signature, \ + CK_ULONG signature_len) \ +{ \ + CK_FUNCTION_LIST *bound; \ + Wrapper *wrapper; \ + CK_X_FUNCTION_LIST *funcs; \ + bound = fixed_closures[fixed_index]; \ + return_val_if_fail (bound != NULL, CKR_GENERAL_ERROR); \ + wrapper = (Wrapper *) bound; \ + funcs = &wrapper->virt->funcs; \ + return funcs->C_VerifyFinal (funcs, session, signature, signature_len); \ +} \ +\ +static CK_RV \ +fixed ## fixed_index ## _C_VerifyRecoverInit (CK_SESSION_HANDLE session, \ + CK_MECHANISM_PTR mechanism, \ + CK_OBJECT_HANDLE key) \ +{ \ + CK_FUNCTION_LIST *bound; \ + Wrapper *wrapper; \ + CK_X_FUNCTION_LIST *funcs; \ + bound = fixed_closures[fixed_index]; \ + return_val_if_fail (bound != NULL, CKR_GENERAL_ERROR); \ + wrapper = (Wrapper *) bound; \ + funcs = &wrapper->virt->funcs; \ + return funcs->C_VerifyRecoverInit (funcs, session, mechanism, key); \ +} \ +\ +static CK_RV \ +fixed ## fixed_index ## _C_VerifyRecover (CK_SESSION_HANDLE session, \ + CK_BYTE_PTR signature, \ + CK_ULONG signature_len, \ + CK_BYTE_PTR data, \ + CK_ULONG_PTR data_len) \ +{ \ + CK_FUNCTION_LIST *bound; \ + Wrapper *wrapper; \ + CK_X_FUNCTION_LIST *funcs; \ + bound = fixed_closures[fixed_index]; \ + return_val_if_fail (bound != NULL, CKR_GENERAL_ERROR); \ + wrapper = (Wrapper *) bound; \ + funcs = &wrapper->virt->funcs; \ + return funcs->C_VerifyRecover (funcs, session, signature, signature_len, data, data_len); \ +} \ +\ +static CK_RV \ +fixed ## fixed_index ## _C_DigestEncryptUpdate (CK_SESSION_HANDLE session, \ + CK_BYTE_PTR part, \ + CK_ULONG part_len, \ + CK_BYTE_PTR encrypted_part, \ + CK_ULONG_PTR encrypted_part_len) \ +{ \ + CK_FUNCTION_LIST *bound; \ + Wrapper *wrapper; \ + CK_X_FUNCTION_LIST *funcs; \ + bound = fixed_closures[fixed_index]; \ + return_val_if_fail (bound != NULL, CKR_GENERAL_ERROR); \ + wrapper = (Wrapper *) bound; \ + funcs = &wrapper->virt->funcs; \ + return funcs->C_DigestEncryptUpdate (funcs, session, part, part_len, encrypted_part, encrypted_part_len); \ +} \ +\ +static CK_RV \ +fixed ## fixed_index ## _C_DecryptDigestUpdate (CK_SESSION_HANDLE session, \ + CK_BYTE_PTR encrypted_part, \ + CK_ULONG encrypted_part_len, \ + CK_BYTE_PTR part, \ + CK_ULONG_PTR part_len) \ +{ \ + CK_FUNCTION_LIST *bound; \ + Wrapper *wrapper; \ + CK_X_FUNCTION_LIST *funcs; \ + bound = fixed_closures[fixed_index]; \ + return_val_if_fail (bound != NULL, CKR_GENERAL_ERROR); \ + wrapper = (Wrapper *) bound; \ + funcs = &wrapper->virt->funcs; \ + return funcs->C_DecryptDigestUpdate (funcs, session, encrypted_part, encrypted_part_len, part, part_len); \ +} \ +\ +static CK_RV \ +fixed ## fixed_index ## _C_SignEncryptUpdate (CK_SESSION_HANDLE session, \ + CK_BYTE_PTR part, \ + CK_ULONG part_len, \ + CK_BYTE_PTR encrypted_part, \ + CK_ULONG_PTR encrypted_part_len) \ +{ \ + CK_FUNCTION_LIST *bound; \ + Wrapper *wrapper; \ + CK_X_FUNCTION_LIST *funcs; \ + bound = fixed_closures[fixed_index]; \ + return_val_if_fail (bound != NULL, CKR_GENERAL_ERROR); \ + wrapper = (Wrapper *) bound; \ + funcs = &wrapper->virt->funcs; \ + return funcs->C_SignEncryptUpdate (funcs, session, part, part_len, encrypted_part, encrypted_part_len); \ +} \ +\ +static CK_RV \ +fixed ## fixed_index ## _C_DecryptVerifyUpdate (CK_SESSION_HANDLE session, \ + CK_BYTE_PTR encrypted_part, \ + CK_ULONG encrypted_part_len, \ + CK_BYTE_PTR part, \ + CK_ULONG_PTR part_len) \ +{ \ + CK_FUNCTION_LIST *bound; \ + Wrapper *wrapper; \ + CK_X_FUNCTION_LIST *funcs; \ + bound = fixed_closures[fixed_index]; \ + return_val_if_fail (bound != NULL, CKR_GENERAL_ERROR); \ + wrapper = (Wrapper *) bound; \ + funcs = &wrapper->virt->funcs; \ + return funcs->C_DecryptVerifyUpdate (funcs, session, encrypted_part, encrypted_part_len, part, part_len); \ +} \ +\ +static CK_RV \ +fixed ## fixed_index ## _C_GenerateKey (CK_SESSION_HANDLE session, \ + CK_MECHANISM_PTR mechanism, \ + CK_ATTRIBUTE_PTR templ, \ + CK_ULONG count, \ + CK_OBJECT_HANDLE_PTR key) \ +{ \ + CK_FUNCTION_LIST *bound; \ + Wrapper *wrapper; \ + CK_X_FUNCTION_LIST *funcs; \ + bound = fixed_closures[fixed_index]; \ + return_val_if_fail (bound != NULL, CKR_GENERAL_ERROR); \ + wrapper = (Wrapper *) bound; \ + funcs = &wrapper->virt->funcs; \ + return funcs->C_GenerateKey (funcs, session, mechanism, templ, count, key); \ +} \ +\ +static CK_RV \ +fixed ## fixed_index ## _C_GenerateKeyPair (CK_SESSION_HANDLE session, \ + CK_MECHANISM_PTR mechanism, \ + CK_ATTRIBUTE_PTR public_key_template, \ + CK_ULONG public_key_attribute_count, \ + CK_ATTRIBUTE_PTR private_key_template, \ + CK_ULONG private_key_attribute_count, \ + CK_OBJECT_HANDLE_PTR public_key, \ + CK_OBJECT_HANDLE_PTR private_key) \ +{ \ + CK_FUNCTION_LIST *bound; \ + Wrapper *wrapper; \ + CK_X_FUNCTION_LIST *funcs; \ + bound = fixed_closures[fixed_index]; \ + return_val_if_fail (bound != NULL, CKR_GENERAL_ERROR); \ + wrapper = (Wrapper *) bound; \ + funcs = &wrapper->virt->funcs; \ + return funcs->C_GenerateKeyPair (funcs, session, mechanism, public_key_template, public_key_attribute_count, private_key_template, private_key_attribute_count, public_key, private_key); \ +} \ +\ +static CK_RV \ +fixed ## fixed_index ## _C_WrapKey (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_FUNCTION_LIST *bound; \ + Wrapper *wrapper; \ + CK_X_FUNCTION_LIST *funcs; \ + bound = fixed_closures[fixed_index]; \ + return_val_if_fail (bound != NULL, CKR_GENERAL_ERROR); \ + wrapper = (Wrapper *) bound; \ + funcs = &wrapper->virt->funcs; \ + return funcs->C_WrapKey (funcs, session, mechanism, wrapping_key, key, wrapped_key, wrapped_key_len); \ +} \ +\ +static CK_RV \ +fixed ## fixed_index ## _C_UnwrapKey (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 templ, \ + CK_ULONG attribute_count, \ + CK_OBJECT_HANDLE_PTR key) \ +{ \ + CK_FUNCTION_LIST *bound; \ + Wrapper *wrapper; \ + CK_X_FUNCTION_LIST *funcs; \ + bound = fixed_closures[fixed_index]; \ + return_val_if_fail (bound != NULL, CKR_GENERAL_ERROR); \ + wrapper = (Wrapper *) bound; \ + funcs = &wrapper->virt->funcs; \ + return funcs->C_UnwrapKey (funcs, session, mechanism, unwrapping_key, wrapped_key, wrapped_key_len, templ, attribute_count, key); \ +} \ +\ +static CK_RV \ +fixed ## fixed_index ## _C_DeriveKey (CK_SESSION_HANDLE session, \ + CK_MECHANISM_PTR mechanism, \ + CK_OBJECT_HANDLE base_key, \ + CK_ATTRIBUTE_PTR templ, \ + CK_ULONG attribute_count, \ + CK_OBJECT_HANDLE_PTR key) \ +{ \ + CK_FUNCTION_LIST *bound; \ + Wrapper *wrapper; \ + CK_X_FUNCTION_LIST *funcs; \ + bound = fixed_closures[fixed_index]; \ + return_val_if_fail (bound != NULL, CKR_GENERAL_ERROR); \ + wrapper = (Wrapper *) bound; \ + funcs = &wrapper->virt->funcs; \ + return funcs->C_DeriveKey (funcs, session, mechanism, base_key, templ, attribute_count, key); \ +} \ +\ +static CK_RV \ +fixed ## fixed_index ## _C_SeedRandom (CK_SESSION_HANDLE session, \ + CK_BYTE_PTR seed, \ + CK_ULONG seed_len) \ +{ \ + CK_FUNCTION_LIST *bound; \ + Wrapper *wrapper; \ + CK_X_FUNCTION_LIST *funcs; \ + bound = fixed_closures[fixed_index]; \ + return_val_if_fail (bound != NULL, CKR_GENERAL_ERROR); \ + wrapper = (Wrapper *) bound; \ + funcs = &wrapper->virt->funcs; \ + return funcs->C_SeedRandom (funcs, session, seed, seed_len); \ +} \ +\ +static CK_RV \ +fixed ## fixed_index ## _C_GenerateRandom (CK_SESSION_HANDLE session, \ + CK_BYTE_PTR random_data, \ + CK_ULONG random_len) \ +{ \ + CK_FUNCTION_LIST *bound; \ + Wrapper *wrapper; \ + CK_X_FUNCTION_LIST *funcs; \ + bound = fixed_closures[fixed_index]; \ + return_val_if_fail (bound != NULL, CKR_GENERAL_ERROR); \ + wrapper = (Wrapper *) bound; \ + funcs = &wrapper->virt->funcs; \ + return funcs->C_GenerateRandom (funcs, session, random_data, random_len); \ +} \ +\ +static CK_RV \ +fixed ## fixed_index ## _C_WaitForSlotEvent (CK_FLAGS flags, \ + CK_SLOT_ID_PTR slot, \ + CK_VOID_PTR reserved) \ +{ \ + CK_FUNCTION_LIST *bound; \ + Wrapper *wrapper; \ + CK_X_FUNCTION_LIST *funcs; \ + bound = fixed_closures[fixed_index]; \ + return_val_if_fail (bound != NULL, CKR_GENERAL_ERROR); \ + wrapper = (Wrapper *) bound; \ + funcs = &wrapper->virt->funcs; \ + return funcs->C_WaitForSlotEvent (funcs, flags, slot, reserved); \ +} \ +\ +static CK_RV \ +fixed ## fixed_index ## _C_GetFunctionList (CK_FUNCTION_LIST_PTR_PTR list); + +#define P11_VIRTUAL_FIXED_GET_FUNCTION_LIST(fixed_index) \ +static CK_RV \ +fixed ## fixed_index ## _C_GetFunctionList (CK_FUNCTION_LIST_PTR_PTR list) \ +{ \ + if (!list) \ + return CKR_ARGUMENTS_BAD; \ + *list = fixed_closures[fixed_index]; \ + return CKR_OK; \ +} + +#define P11_VIRTUAL_FIXED_INITIALIZER(fixed_index) \ +{ \ + { CRYPTOKI_VERSION_MAJOR, CRYPTOKI_VERSION_MINOR }, /* version */ \ + fixed ## fixed_index ## _C_Initialize, \ + fixed ## fixed_index ## _C_Finalize, \ + fixed ## fixed_index ## _C_GetInfo, \ + fixed ## fixed_index ## _C_GetFunctionList, \ + fixed ## fixed_index ## _C_GetSlotList, \ + fixed ## fixed_index ## _C_GetSlotInfo, \ + fixed ## fixed_index ## _C_GetTokenInfo, \ + fixed ## fixed_index ## _C_GetMechanismList, \ + fixed ## fixed_index ## _C_GetMechanismInfo, \ + fixed ## fixed_index ## _C_InitToken, \ + fixed ## fixed_index ## _C_InitPIN, \ + fixed ## fixed_index ## _C_SetPIN, \ + fixed ## fixed_index ## _C_OpenSession, \ + fixed ## fixed_index ## _C_CloseSession, \ + fixed ## fixed_index ## _C_CloseAllSessions, \ + fixed ## fixed_index ## _C_GetSessionInfo, \ + fixed ## fixed_index ## _C_GetOperationState, \ + fixed ## fixed_index ## _C_SetOperationState, \ + fixed ## fixed_index ## _C_Login, \ + fixed ## fixed_index ## _C_Logout, \ + fixed ## fixed_index ## _C_CreateObject, \ + fixed ## fixed_index ## _C_CopyObject, \ + fixed ## fixed_index ## _C_DestroyObject, \ + fixed ## fixed_index ## _C_GetObjectSize, \ + fixed ## fixed_index ## _C_GetAttributeValue, \ + fixed ## fixed_index ## _C_SetAttributeValue, \ + fixed ## fixed_index ## _C_FindObjectsInit, \ + fixed ## fixed_index ## _C_FindObjects, \ + fixed ## fixed_index ## _C_FindObjectsFinal, \ + fixed ## fixed_index ## _C_EncryptInit, \ + fixed ## fixed_index ## _C_Encrypt, \ + fixed ## fixed_index ## _C_EncryptUpdate, \ + fixed ## fixed_index ## _C_EncryptFinal, \ + fixed ## fixed_index ## _C_DecryptInit, \ + fixed ## fixed_index ## _C_Decrypt, \ + fixed ## fixed_index ## _C_DecryptUpdate, \ + fixed ## fixed_index ## _C_DecryptFinal, \ + fixed ## fixed_index ## _C_DigestInit, \ + fixed ## fixed_index ## _C_Digest, \ + fixed ## fixed_index ## _C_DigestUpdate, \ + fixed ## fixed_index ## _C_DigestKey, \ + fixed ## fixed_index ## _C_DigestFinal, \ + fixed ## fixed_index ## _C_SignInit, \ + fixed ## fixed_index ## _C_Sign, \ + fixed ## fixed_index ## _C_SignUpdate, \ + fixed ## fixed_index ## _C_SignFinal, \ + fixed ## fixed_index ## _C_SignRecoverInit, \ + fixed ## fixed_index ## _C_SignRecover, \ + fixed ## fixed_index ## _C_VerifyInit, \ + fixed ## fixed_index ## _C_Verify, \ + fixed ## fixed_index ## _C_VerifyUpdate, \ + fixed ## fixed_index ## _C_VerifyFinal, \ + fixed ## fixed_index ## _C_VerifyRecoverInit, \ + fixed ## fixed_index ## _C_VerifyRecover, \ + fixed ## fixed_index ## _C_DigestEncryptUpdate, \ + fixed ## fixed_index ## _C_DecryptDigestUpdate, \ + fixed ## fixed_index ## _C_SignEncryptUpdate, \ + fixed ## fixed_index ## _C_DecryptVerifyUpdate, \ + fixed ## fixed_index ## _C_GenerateKey, \ + fixed ## fixed_index ## _C_GenerateKeyPair, \ + fixed ## fixed_index ## _C_WrapKey, \ + fixed ## fixed_index ## _C_UnwrapKey, \ + fixed ## fixed_index ## _C_DeriveKey, \ + fixed ## fixed_index ## _C_SeedRandom, \ + fixed ## fixed_index ## _C_GenerateRandom, \ + short_C_GetFunctionStatus, \ + short_C_CancelFunction, \ + fixed ## fixed_index ## _C_WaitForSlotEvent \ +} diff --git a/p11-kit/virtual.c b/p11-kit/virtual.c index bb0d845..a9eae56 100644 --- a/p11-kit/virtual.c +++ b/p11-kit/virtual.c @@ -40,13 +40,14 @@ #include "debug.h" #include "library.h" #include "virtual.h" +#include "virtual-fixed.h" #include <assert.h> #include <stdarg.h> #include <stdlib.h> #include <string.h> -#ifdef WITH_FFI +#if defined(WITH_FFI) && WITH_FFI /* * We use libffi to build closures. Note that even with libffi certain @@ -62,8 +63,6 @@ #define LIBFFI_FREE_CLOSURES 0 #include "ffi.h" -#ifndef FFI_CLOSURES -#error "FFI_CLOSURES should be checked in configure.ac" #endif /* There are 66 functions in PKCS#11, with a maximum of 8 args */ @@ -78,12 +77,47 @@ typedef struct { p11_virtual *virt; p11_destroyer destroyer; +#if defined(FFI_CLOSURES) && FFI_CLOSURES /* A list of our libffi built closures, for cleanup later */ ffi_closure *ffi_closures[MAX_FUNCTIONS]; ffi_cif ffi_cifs[MAX_FUNCTIONS]; int ffi_used; +#endif /* FFI_CLOSURES */ + + /* The index in fixed_closures, or -1 when libffi closures are used */ + int fixed_index; } Wrapper; +static p11_mutex_t fixed_mutex; +static CK_FUNCTION_LIST *fixed_closures[P11_VIRTUAL_MAX_FIXED]; + +static Wrapper *create_fixed_wrapper (p11_virtual *virt, + size_t index, + p11_destroyer destroyer); +static CK_FUNCTION_LIST * + p11_virtual_wrap_fixed (p11_virtual *virt, + p11_destroyer destroyer); +static void + p11_virtual_unwrap_fixed + (CK_FUNCTION_LIST_PTR module); + +void +p11_virtual_init_fixed (void) +{ + p11_lock (); + p11_mutex_init (&fixed_mutex); + memset (fixed_closures, 0, sizeof (fixed_closures)); + p11_unlock (); +} + +void +p11_virtual_uninit_fixed (void) +{ + p11_lock (); + p11_mutex_uninit (&fixed_mutex); + p11_unlock (); +} + static CK_RV short_C_GetFunctionStatus (CK_SESSION_HANDLE handle) { @@ -96,6 +130,8 @@ short_C_CancelFunction (CK_SESSION_HANDLE handle) return CKR_FUNCTION_NOT_PARALLEL; } +#if defined(FFI_CLOSURES) && FFI_CLOSURES + static void binding_C_GetFunctionList (ffi_cif *cif, CK_RV *ret, @@ -930,7 +966,7 @@ binding_C_GenerateRandom (ffi_cif *cif, *(CK_ULONG *)args[2]); } -#endif /* WITH_FFI */ +#endif /* FFI_CLOSURES */ static CK_RV stack_C_Initialize (CK_X_FUNCTION_LIST *self, @@ -2494,16 +2530,12 @@ p11_virtual_uninit (p11_virtual *virt) (virt->lower_destroy) (virt->lower_module); } -#ifdef WITH_FFI - typedef struct { const char *name; - void *binding_function; void *stack_fallback; size_t virtual_offset; void *base_fallback; size_t module_offset; - ffi_type *types[MAX_ARGS]; } FunctionInfo; #define STRUCT_OFFSET(struct_type, member) \ @@ -2514,77 +2546,77 @@ typedef struct { (*(member_type*) STRUCT_MEMBER_P ((struct_p), (struct_offset))) #define FUNCTION(name) \ - #name, binding_C_##name, \ + #name, \ stack_C_##name, STRUCT_OFFSET (CK_X_FUNCTION_LIST, C_##name), \ base_C_##name, STRUCT_OFFSET (CK_FUNCTION_LIST, C_##name) static const FunctionInfo function_info[] = { - { FUNCTION (Initialize), { &ffi_type_pointer, NULL } }, - { FUNCTION (Finalize), { &ffi_type_pointer, NULL } }, - { FUNCTION (GetInfo), { &ffi_type_pointer, NULL } }, - { FUNCTION (GetSlotList), { &ffi_type_uchar, &ffi_type_pointer, &ffi_type_pointer, NULL } }, - { FUNCTION (GetSlotInfo), { &ffi_type_ulong, &ffi_type_pointer, NULL } }, - { FUNCTION (GetTokenInfo), { &ffi_type_ulong, &ffi_type_pointer, NULL } }, - { FUNCTION (WaitForSlotEvent), { &ffi_type_ulong, &ffi_type_pointer, &ffi_type_pointer, NULL } }, - { FUNCTION (GetMechanismList), { &ffi_type_ulong, &ffi_type_pointer, &ffi_type_pointer, NULL } }, - { FUNCTION (GetMechanismInfo), { &ffi_type_ulong, &ffi_type_ulong, &ffi_type_pointer, NULL } }, - { FUNCTION (InitToken), { &ffi_type_ulong, &ffi_type_pointer, &ffi_type_ulong, &ffi_type_pointer, NULL } }, - { FUNCTION (InitPIN), { &ffi_type_ulong, &ffi_type_pointer, &ffi_type_ulong, NULL } }, - { FUNCTION (SetPIN), { &ffi_type_ulong, &ffi_type_pointer, &ffi_type_ulong, &ffi_type_pointer, &ffi_type_ulong, NULL } }, - { FUNCTION (OpenSession), { &ffi_type_ulong, &ffi_type_ulong, &ffi_type_pointer, &ffi_type_pointer, &ffi_type_pointer, NULL } }, - { FUNCTION (CloseSession), { &ffi_type_ulong, NULL } }, - { FUNCTION (CloseAllSessions), { &ffi_type_ulong, NULL } }, - { FUNCTION (GetSessionInfo), { &ffi_type_ulong, &ffi_type_pointer, NULL } }, - { FUNCTION (GetOperationState), { &ffi_type_ulong, &ffi_type_pointer, &ffi_type_pointer, NULL } }, - { FUNCTION (SetOperationState), { &ffi_type_ulong, &ffi_type_pointer, &ffi_type_ulong, &ffi_type_ulong, &ffi_type_ulong, NULL } }, - { FUNCTION (Login), { &ffi_type_ulong, &ffi_type_ulong, &ffi_type_pointer, &ffi_type_ulong, NULL } }, - { FUNCTION (Logout), { &ffi_type_ulong, NULL } }, - { FUNCTION (CreateObject), { &ffi_type_ulong, &ffi_type_pointer, &ffi_type_ulong, &ffi_type_pointer, NULL } }, - { FUNCTION (CopyObject), { &ffi_type_ulong, &ffi_type_ulong, &ffi_type_pointer, &ffi_type_ulong, &ffi_type_pointer, NULL } }, - { FUNCTION (DestroyObject), { &ffi_type_ulong, &ffi_type_ulong, NULL } }, - { FUNCTION (GetObjectSize), { &ffi_type_ulong, &ffi_type_ulong, &ffi_type_pointer, NULL } }, - { FUNCTION (GetAttributeValue), { &ffi_type_ulong, &ffi_type_ulong, &ffi_type_pointer, &ffi_type_ulong, NULL } }, - { FUNCTION (SetAttributeValue), { &ffi_type_ulong, &ffi_type_ulong, &ffi_type_pointer, &ffi_type_ulong, NULL } }, - { FUNCTION (FindObjectsInit), { &ffi_type_ulong, &ffi_type_pointer, &ffi_type_ulong, NULL } }, - { FUNCTION (FindObjects), { &ffi_type_ulong, &ffi_type_pointer, &ffi_type_ulong, &ffi_type_pointer, NULL } }, - { FUNCTION (FindObjectsFinal), { &ffi_type_ulong, NULL } }, - { FUNCTION (EncryptInit), { &ffi_type_ulong, &ffi_type_pointer, &ffi_type_ulong, NULL } }, - { FUNCTION (Encrypt), { &ffi_type_ulong, &ffi_type_pointer, &ffi_type_ulong, &ffi_type_pointer, &ffi_type_pointer, NULL } }, - { FUNCTION (EncryptUpdate), { &ffi_type_ulong, &ffi_type_pointer, &ffi_type_ulong, &ffi_type_pointer, &ffi_type_pointer, NULL } }, - { FUNCTION (EncryptFinal), { &ffi_type_ulong, &ffi_type_pointer, &ffi_type_pointer, NULL } }, - { FUNCTION (DecryptInit), { &ffi_type_ulong, &ffi_type_pointer, &ffi_type_ulong, NULL } }, - { FUNCTION (Decrypt), { &ffi_type_ulong, &ffi_type_pointer, &ffi_type_ulong, &ffi_type_pointer, &ffi_type_pointer, NULL } }, - { FUNCTION (DecryptUpdate), { &ffi_type_ulong, &ffi_type_pointer, &ffi_type_ulong, &ffi_type_pointer, &ffi_type_pointer, NULL } }, - { FUNCTION (DecryptFinal), { &ffi_type_ulong, &ffi_type_pointer, &ffi_type_pointer, NULL } }, - { FUNCTION (DigestInit), { &ffi_type_ulong, &ffi_type_pointer, NULL } }, - { FUNCTION (Digest), { &ffi_type_ulong, &ffi_type_pointer, &ffi_type_ulong, &ffi_type_pointer, &ffi_type_pointer, NULL } }, - { FUNCTION (DigestUpdate), { &ffi_type_ulong, &ffi_type_pointer, &ffi_type_ulong, NULL } }, - { FUNCTION (DigestKey), { &ffi_type_ulong, &ffi_type_ulong, NULL } }, - { FUNCTION (DigestFinal), { &ffi_type_ulong, &ffi_type_pointer, &ffi_type_pointer, NULL } }, - { FUNCTION (SignInit), { &ffi_type_ulong, &ffi_type_pointer, &ffi_type_ulong, NULL } }, - { FUNCTION (Sign), { &ffi_type_ulong, &ffi_type_pointer, &ffi_type_ulong, &ffi_type_pointer, &ffi_type_pointer, NULL } }, - { FUNCTION (SignUpdate), { &ffi_type_ulong, &ffi_type_pointer, &ffi_type_ulong, NULL } }, - { FUNCTION (SignFinal), { &ffi_type_ulong, &ffi_type_pointer, &ffi_type_pointer, NULL } }, - { FUNCTION (SignRecoverInit), { &ffi_type_ulong, &ffi_type_pointer, &ffi_type_ulong, NULL } }, - { FUNCTION (SignRecover), { &ffi_type_ulong, &ffi_type_pointer, &ffi_type_ulong, &ffi_type_pointer, &ffi_type_pointer, NULL } }, - { FUNCTION (VerifyInit), { &ffi_type_ulong, &ffi_type_pointer, &ffi_type_ulong, NULL } }, - { FUNCTION (Verify), { &ffi_type_ulong, &ffi_type_pointer, &ffi_type_ulong, &ffi_type_pointer, &ffi_type_ulong, NULL } }, - { FUNCTION (VerifyUpdate), { &ffi_type_ulong, &ffi_type_pointer, &ffi_type_ulong, NULL } }, - { FUNCTION (VerifyFinal), { &ffi_type_ulong, &ffi_type_pointer, &ffi_type_ulong, NULL } }, - { FUNCTION (VerifyRecoverInit), { &ffi_type_ulong, &ffi_type_pointer, &ffi_type_ulong, NULL } }, - { FUNCTION (VerifyRecover), { &ffi_type_ulong, &ffi_type_pointer, &ffi_type_ulong, &ffi_type_pointer, &ffi_type_pointer, NULL } }, - { FUNCTION (DigestEncryptUpdate), { &ffi_type_ulong, &ffi_type_pointer, &ffi_type_ulong, &ffi_type_pointer, &ffi_type_pointer, NULL } }, - { FUNCTION (DecryptDigestUpdate), { &ffi_type_ulong, &ffi_type_pointer, &ffi_type_ulong, &ffi_type_pointer, &ffi_type_pointer, NULL } }, - { FUNCTION (SignEncryptUpdate), { &ffi_type_ulong, &ffi_type_pointer, &ffi_type_ulong, &ffi_type_pointer, &ffi_type_pointer, NULL } }, - { FUNCTION (DecryptVerifyUpdate), { &ffi_type_ulong, &ffi_type_pointer, &ffi_type_ulong, &ffi_type_pointer, &ffi_type_pointer, NULL } }, - { FUNCTION (GenerateKey), { &ffi_type_ulong, &ffi_type_pointer, &ffi_type_pointer, &ffi_type_ulong, &ffi_type_pointer, NULL } }, - { FUNCTION (GenerateKeyPair), { &ffi_type_ulong, &ffi_type_pointer, &ffi_type_pointer, &ffi_type_ulong, &ffi_type_pointer, &ffi_type_ulong, &ffi_type_pointer, &ffi_type_pointer, NULL } }, - { FUNCTION (WrapKey), { &ffi_type_ulong, &ffi_type_pointer, &ffi_type_ulong, &ffi_type_ulong, &ffi_type_pointer, &ffi_type_pointer, NULL } }, - { FUNCTION (UnwrapKey), { &ffi_type_ulong, &ffi_type_pointer, &ffi_type_ulong, &ffi_type_pointer, &ffi_type_ulong, &ffi_type_pointer, &ffi_type_ulong, &ffi_type_pointer, NULL } }, - { FUNCTION (DeriveKey), { &ffi_type_ulong, &ffi_type_pointer, &ffi_type_ulong, &ffi_type_pointer, &ffi_type_ulong, &ffi_type_pointer, NULL } }, - { FUNCTION (SeedRandom), { &ffi_type_ulong, &ffi_type_pointer, &ffi_type_ulong, NULL } }, - { FUNCTION (GenerateRandom), { &ffi_type_ulong, &ffi_type_pointer, &ffi_type_ulong, NULL } }, - { 0, } + { FUNCTION (Initialize) }, + { FUNCTION (Finalize) }, + { FUNCTION (GetInfo) }, + { FUNCTION (GetSlotList) }, + { FUNCTION (GetSlotInfo) }, + { FUNCTION (GetTokenInfo) }, + { FUNCTION (GetMechanismList) }, + { FUNCTION (GetMechanismInfo) }, + { FUNCTION (InitToken) }, + { FUNCTION (InitPIN) }, + { FUNCTION (SetPIN) }, + { FUNCTION (OpenSession) }, + { FUNCTION (CloseSession) }, + { FUNCTION (CloseAllSessions) }, + { FUNCTION (GetSessionInfo) }, + { FUNCTION (GetOperationState) }, + { FUNCTION (SetOperationState) }, + { FUNCTION (Login) }, + { FUNCTION (Logout) }, + { FUNCTION (CreateObject) }, + { FUNCTION (CopyObject) }, + { FUNCTION (DestroyObject) }, + { FUNCTION (GetObjectSize) }, + { FUNCTION (GetAttributeValue) }, + { FUNCTION (SetAttributeValue) }, + { FUNCTION (FindObjectsInit) }, + { FUNCTION (FindObjects) }, + { FUNCTION (FindObjectsFinal) }, + { FUNCTION (EncryptInit) }, + { FUNCTION (Encrypt) }, + { FUNCTION (EncryptUpdate) }, + { FUNCTION (EncryptFinal) }, + { FUNCTION (DecryptInit) }, + { FUNCTION (Decrypt) }, + { FUNCTION (DecryptUpdate) }, + { FUNCTION (DecryptFinal) }, + { FUNCTION (DigestInit) }, + { FUNCTION (Digest) }, + { FUNCTION (DigestUpdate) }, + { FUNCTION (DigestKey) }, + { FUNCTION (DigestFinal) }, + { FUNCTION (SignInit) }, + { FUNCTION (Sign) }, + { FUNCTION (SignUpdate) }, + { FUNCTION (SignFinal) }, + { FUNCTION (SignRecoverInit) }, + { FUNCTION (SignRecover) }, + { FUNCTION (VerifyInit) }, + { FUNCTION (Verify) }, + { FUNCTION (VerifyUpdate) }, + { FUNCTION (VerifyFinal) }, + { FUNCTION (VerifyRecoverInit) }, + { FUNCTION (VerifyRecover) }, + { FUNCTION (DigestEncryptUpdate) }, + { FUNCTION (DecryptDigestUpdate) }, + { FUNCTION (SignEncryptUpdate) }, + { FUNCTION (DecryptVerifyUpdate) }, + { FUNCTION (GenerateKey) }, + { FUNCTION (GenerateKeyPair) }, + { FUNCTION (WrapKey) }, + { FUNCTION (UnwrapKey) }, + { FUNCTION (DeriveKey) }, + { FUNCTION (SeedRandom) }, + { FUNCTION (GenerateRandom) }, + { FUNCTION (WaitForSlotEvent) }, + { 0, } }; static bool @@ -2621,6 +2653,82 @@ lookup_fall_through (p11_virtual *virt, return false; } +#if defined(FFI_CLOSURES) && FFI_CLOSURES +typedef struct { + void *function; + ffi_type *types[MAX_ARGS+1]; +} BindingInfo; + +static const BindingInfo binding_info[] = { + { binding_C_Initialize, { &ffi_type_pointer, NULL } }, + { binding_C_Finalize, { &ffi_type_pointer, NULL } }, + { binding_C_GetInfo, { &ffi_type_pointer, NULL } }, + { binding_C_GetSlotList, { &ffi_type_uchar, &ffi_type_pointer, &ffi_type_pointer, NULL } }, + { binding_C_GetSlotInfo, { &ffi_type_ulong, &ffi_type_pointer, NULL } }, + { binding_C_GetTokenInfo, { &ffi_type_ulong, &ffi_type_pointer, NULL } }, + { binding_C_GetMechanismList, { &ffi_type_ulong, &ffi_type_pointer, &ffi_type_pointer, NULL } }, + { binding_C_GetMechanismInfo, { &ffi_type_ulong, &ffi_type_ulong, &ffi_type_pointer, NULL } }, + { binding_C_InitToken, { &ffi_type_ulong, &ffi_type_pointer, &ffi_type_ulong, &ffi_type_pointer, NULL } }, + { binding_C_InitPIN, { &ffi_type_ulong, &ffi_type_pointer, &ffi_type_ulong, NULL } }, + { binding_C_SetPIN, { &ffi_type_ulong, &ffi_type_pointer, &ffi_type_ulong, &ffi_type_pointer, &ffi_type_ulong, NULL } }, + { binding_C_OpenSession, { &ffi_type_ulong, &ffi_type_ulong, &ffi_type_pointer, &ffi_type_pointer, &ffi_type_pointer, NULL } }, + { binding_C_CloseSession, { &ffi_type_ulong, NULL } }, + { binding_C_CloseAllSessions, { &ffi_type_ulong, NULL } }, + { binding_C_GetSessionInfo, { &ffi_type_ulong, &ffi_type_pointer, NULL } }, + { binding_C_GetOperationState, { &ffi_type_ulong, &ffi_type_pointer, &ffi_type_pointer, NULL } }, + { binding_C_SetOperationState, { &ffi_type_ulong, &ffi_type_pointer, &ffi_type_ulong, &ffi_type_ulong, &ffi_type_ulong, NULL } }, + { binding_C_Login, { &ffi_type_ulong, &ffi_type_ulong, &ffi_type_pointer, &ffi_type_ulong, NULL } }, + { binding_C_Logout, { &ffi_type_ulong, NULL } }, + { binding_C_CreateObject, { &ffi_type_ulong, &ffi_type_pointer, &ffi_type_ulong, &ffi_type_pointer, NULL } }, + { binding_C_CopyObject, { &ffi_type_ulong, &ffi_type_ulong, &ffi_type_pointer, &ffi_type_ulong, &ffi_type_pointer, NULL } }, + { binding_C_DestroyObject, { &ffi_type_ulong, &ffi_type_ulong, NULL } }, + { binding_C_GetObjectSize, { &ffi_type_ulong, &ffi_type_ulong, &ffi_type_pointer, NULL } }, + { binding_C_GetAttributeValue, { &ffi_type_ulong, &ffi_type_ulong, &ffi_type_pointer, &ffi_type_ulong, NULL } }, + { binding_C_SetAttributeValue, { &ffi_type_ulong, &ffi_type_ulong, &ffi_type_pointer, &ffi_type_ulong, NULL } }, + { binding_C_FindObjectsInit, { &ffi_type_ulong, &ffi_type_pointer, &ffi_type_ulong, NULL } }, + { binding_C_FindObjects, { &ffi_type_ulong, &ffi_type_pointer, &ffi_type_ulong, &ffi_type_pointer, NULL } }, + { binding_C_FindObjectsFinal, { &ffi_type_ulong, NULL } }, + { binding_C_EncryptInit, { &ffi_type_ulong, &ffi_type_pointer, &ffi_type_ulong, NULL } }, + { binding_C_Encrypt, { &ffi_type_ulong, &ffi_type_pointer, &ffi_type_ulong, &ffi_type_pointer, &ffi_type_pointer, NULL } }, + { binding_C_EncryptUpdate, { &ffi_type_ulong, &ffi_type_pointer, &ffi_type_ulong, &ffi_type_pointer, &ffi_type_pointer, NULL } }, + { binding_C_EncryptFinal, { &ffi_type_ulong, &ffi_type_pointer, &ffi_type_pointer, NULL } }, + { binding_C_DecryptInit, { &ffi_type_ulong, &ffi_type_pointer, &ffi_type_ulong, NULL } }, + { binding_C_Decrypt, { &ffi_type_ulong, &ffi_type_pointer, &ffi_type_ulong, &ffi_type_pointer, &ffi_type_pointer, NULL } }, + { binding_C_DecryptUpdate, { &ffi_type_ulong, &ffi_type_pointer, &ffi_type_ulong, &ffi_type_pointer, &ffi_type_pointer, NULL } }, + { binding_C_DecryptFinal, { &ffi_type_ulong, &ffi_type_pointer, &ffi_type_pointer, NULL } }, + { binding_C_DigestInit, { &ffi_type_ulong, &ffi_type_pointer, NULL } }, + { binding_C_Digest, { &ffi_type_ulong, &ffi_type_pointer, &ffi_type_ulong, &ffi_type_pointer, &ffi_type_pointer, NULL } }, + { binding_C_DigestUpdate, { &ffi_type_ulong, &ffi_type_pointer, &ffi_type_ulong, NULL } }, + { binding_C_DigestKey, { &ffi_type_ulong, &ffi_type_ulong, NULL } }, + { binding_C_DigestFinal, { &ffi_type_ulong, &ffi_type_pointer, &ffi_type_pointer, NULL } }, + { binding_C_SignInit, { &ffi_type_ulong, &ffi_type_pointer, &ffi_type_ulong, NULL } }, + { binding_C_Sign, { &ffi_type_ulong, &ffi_type_pointer, &ffi_type_ulong, &ffi_type_pointer, &ffi_type_pointer, NULL } }, + { binding_C_SignUpdate, { &ffi_type_ulong, &ffi_type_pointer, &ffi_type_ulong, NULL } }, + { binding_C_SignFinal, { &ffi_type_ulong, &ffi_type_pointer, &ffi_type_pointer, NULL } }, + { binding_C_SignRecoverInit, { &ffi_type_ulong, &ffi_type_pointer, &ffi_type_ulong, NULL } }, + { binding_C_SignRecover, { &ffi_type_ulong, &ffi_type_pointer, &ffi_type_ulong, &ffi_type_pointer, &ffi_type_pointer, NULL } }, + { binding_C_VerifyInit, { &ffi_type_ulong, &ffi_type_pointer, &ffi_type_ulong, NULL } }, + { binding_C_Verify, { &ffi_type_ulong, &ffi_type_pointer, &ffi_type_ulong, &ffi_type_pointer, &ffi_type_ulong, NULL } }, + { binding_C_VerifyUpdate, { &ffi_type_ulong, &ffi_type_pointer, &ffi_type_ulong, NULL } }, + { binding_C_VerifyFinal, { &ffi_type_ulong, &ffi_type_pointer, &ffi_type_ulong, NULL } }, + { binding_C_VerifyRecoverInit, { &ffi_type_ulong, &ffi_type_pointer, &ffi_type_ulong, NULL } }, + { binding_C_VerifyRecover, { &ffi_type_ulong, &ffi_type_pointer, &ffi_type_ulong, &ffi_type_pointer, &ffi_type_pointer, NULL } }, + { binding_C_DigestEncryptUpdate, { &ffi_type_ulong, &ffi_type_pointer, &ffi_type_ulong, &ffi_type_pointer, &ffi_type_pointer, NULL } }, + { binding_C_DecryptDigestUpdate, { &ffi_type_ulong, &ffi_type_pointer, &ffi_type_ulong, &ffi_type_pointer, &ffi_type_pointer, NULL } }, + { binding_C_SignEncryptUpdate, { &ffi_type_ulong, &ffi_type_pointer, &ffi_type_ulong, &ffi_type_pointer, &ffi_type_pointer, NULL } }, + { binding_C_DecryptVerifyUpdate, { &ffi_type_ulong, &ffi_type_pointer, &ffi_type_ulong, &ffi_type_pointer, &ffi_type_pointer, NULL } }, + { binding_C_GenerateKey, { &ffi_type_ulong, &ffi_type_pointer, &ffi_type_pointer, &ffi_type_ulong, &ffi_type_pointer, NULL } }, + { binding_C_GenerateKeyPair, { &ffi_type_ulong, &ffi_type_pointer, &ffi_type_pointer, &ffi_type_ulong, &ffi_type_pointer, &ffi_type_ulong, &ffi_type_pointer, &ffi_type_pointer, NULL } }, + { binding_C_WrapKey, { &ffi_type_ulong, &ffi_type_pointer, &ffi_type_ulong, &ffi_type_ulong, &ffi_type_pointer, &ffi_type_pointer, NULL } }, + { binding_C_UnwrapKey, { &ffi_type_ulong, &ffi_type_pointer, &ffi_type_ulong, &ffi_type_pointer, &ffi_type_ulong, &ffi_type_pointer, &ffi_type_ulong, &ffi_type_pointer, NULL } }, + { binding_C_DeriveKey, { &ffi_type_ulong, &ffi_type_pointer, &ffi_type_ulong, &ffi_type_pointer, &ffi_type_ulong, &ffi_type_pointer, NULL } }, + { binding_C_SeedRandom, { &ffi_type_ulong, &ffi_type_pointer, &ffi_type_ulong, NULL } }, + { binding_C_GenerateRandom, { &ffi_type_ulong, &ffi_type_pointer, &ffi_type_ulong, NULL } }, + { binding_C_WaitForSlotEvent, { &ffi_type_ulong, &ffi_type_pointer, &ffi_type_pointer, NULL } }, + { 0, } +}; + + static bool bind_ffi_closure (Wrapper *wrapper, void *binding_data, @@ -2698,9 +2806,10 @@ init_wrapper_funcs (Wrapper *wrapper) * fall through, then this returns the original module function. */ if (!lookup_fall_through (wrapper->virt, info, bound)) { + const BindingInfo *binding = binding_info + i; if (!bind_ffi_closure (wrapper, over, - info->binding_function, - (ffi_type **)info->types, bound)) + binding->function, + (ffi_type **)binding->types, bound)) return_val_if_reached (false); } } @@ -2725,7 +2834,7 @@ init_wrapper_funcs (Wrapper *wrapper) return true; } -#if LIBFFI_FREE_CLOSURES +#if defined(LIBFFI_FREE_CLOSURES) && LIBFFI_FREE_CLOSURES static void uninit_wrapper_funcs (Wrapper *wrapper) { @@ -2753,7 +2862,7 @@ p11_virtual_wrap (p11_virtual *virt, wrapper->bound.version.minor = CRYPTOKI_VERSION_MINOR; if (!init_wrapper_funcs (wrapper)) - return_val_if_reached (NULL); + return p11_virtual_wrap_fixed (virt, destroyer); assert ((void *)wrapper == (void *)&wrapper->bound); assert (p11_virtual_is_wrapper (&wrapper->bound)); @@ -2761,12 +2870,17 @@ p11_virtual_wrap (p11_virtual *virt, return &wrapper->bound; } -bool -p11_virtual_can_wrap (void) +#else /* !FFI_CLOSURES */ + +CK_FUNCTION_LIST * +p11_virtual_wrap (p11_virtual *virt, + p11_destroyer destroyer) { - return TRUE; + return p11_virtual_wrap_fixed (virt, destroyer); } +#endif /* !FFI_CLOSURES */ + bool p11_virtual_is_wrapper (CK_FUNCTION_LIST_PTR module) { @@ -2791,6 +2905,9 @@ p11_virtual_unwrap (CK_FUNCTION_LIST_PTR module) /* The bound CK_FUNCTION_LIST_PTR sits at the front of Context */ wrapper = (Wrapper *)module; + if (wrapper->fixed_index >= 0) + p11_virtual_unwrap_fixed (module); + /* * Make sure that the CK_FUNCTION_LIST_PTR is invalid, and that * p11_virtual_is_wrapper() recognizes this. This is in case the @@ -2801,41 +2918,12 @@ p11_virtual_unwrap (CK_FUNCTION_LIST_PTR module) if (wrapper->destroyer) (wrapper->destroyer) (wrapper->virt); -#if LIBFFI_FREE_CLOSURES +#if defined(LIBFFI_FREE_CLOSURES) && LIBFFI_FREE_CLOSURES uninit_wrapper_funcs (wrapper); #endif free (wrapper); } -#else /* !WITH_FFI */ - -CK_FUNCTION_LIST * -p11_virtual_wrap (p11_virtual *virt, - p11_destroyer destroyer) -{ - assert_not_reached (); -} - -bool -p11_virtual_can_wrap (void) -{ - return FALSE; -} - -bool -p11_virtual_is_wrapper (CK_FUNCTION_LIST_PTR module) -{ - return FALSE; -} - -void -p11_virtual_unwrap (CK_FUNCTION_LIST_PTR module) -{ - assert_not_reached (); -} - -#endif /* !WITH_FFI */ - CK_X_FUNCTION_LIST p11_virtual_stack = { { CRYPTOKI_VERSION_MAJOR, CRYPTOKI_VERSION_MINOR }, /* version */ stack_C_Initialize, @@ -2973,3 +3061,305 @@ CK_X_FUNCTION_LIST p11_virtual_base = { base_C_GenerateRandom, base_C_WaitForSlotEvent }; + +P11_VIRTUAL_FIXED_FUNCTIONS(0) +P11_VIRTUAL_FIXED_FUNCTIONS(1) +P11_VIRTUAL_FIXED_FUNCTIONS(2) +P11_VIRTUAL_FIXED_FUNCTIONS(3) +P11_VIRTUAL_FIXED_FUNCTIONS(4) +P11_VIRTUAL_FIXED_FUNCTIONS(5) +P11_VIRTUAL_FIXED_FUNCTIONS(6) +P11_VIRTUAL_FIXED_FUNCTIONS(7) +P11_VIRTUAL_FIXED_FUNCTIONS(8) +P11_VIRTUAL_FIXED_FUNCTIONS(9) +P11_VIRTUAL_FIXED_FUNCTIONS(10) +P11_VIRTUAL_FIXED_FUNCTIONS(11) +P11_VIRTUAL_FIXED_FUNCTIONS(12) +P11_VIRTUAL_FIXED_FUNCTIONS(13) +P11_VIRTUAL_FIXED_FUNCTIONS(14) +P11_VIRTUAL_FIXED_FUNCTIONS(15) +P11_VIRTUAL_FIXED_FUNCTIONS(16) +P11_VIRTUAL_FIXED_FUNCTIONS(17) +P11_VIRTUAL_FIXED_FUNCTIONS(18) +P11_VIRTUAL_FIXED_FUNCTIONS(19) +P11_VIRTUAL_FIXED_FUNCTIONS(20) +P11_VIRTUAL_FIXED_FUNCTIONS(21) +P11_VIRTUAL_FIXED_FUNCTIONS(22) +P11_VIRTUAL_FIXED_FUNCTIONS(23) +P11_VIRTUAL_FIXED_FUNCTIONS(24) +P11_VIRTUAL_FIXED_FUNCTIONS(25) +P11_VIRTUAL_FIXED_FUNCTIONS(26) +P11_VIRTUAL_FIXED_FUNCTIONS(27) +P11_VIRTUAL_FIXED_FUNCTIONS(28) +P11_VIRTUAL_FIXED_FUNCTIONS(29) +P11_VIRTUAL_FIXED_FUNCTIONS(30) +P11_VIRTUAL_FIXED_FUNCTIONS(31) +P11_VIRTUAL_FIXED_FUNCTIONS(32) +P11_VIRTUAL_FIXED_FUNCTIONS(33) +P11_VIRTUAL_FIXED_FUNCTIONS(34) +P11_VIRTUAL_FIXED_FUNCTIONS(35) +P11_VIRTUAL_FIXED_FUNCTIONS(36) +P11_VIRTUAL_FIXED_FUNCTIONS(37) +P11_VIRTUAL_FIXED_FUNCTIONS(38) +P11_VIRTUAL_FIXED_FUNCTIONS(39) +P11_VIRTUAL_FIXED_FUNCTIONS(40) +P11_VIRTUAL_FIXED_FUNCTIONS(41) +P11_VIRTUAL_FIXED_FUNCTIONS(42) +P11_VIRTUAL_FIXED_FUNCTIONS(43) +P11_VIRTUAL_FIXED_FUNCTIONS(44) +P11_VIRTUAL_FIXED_FUNCTIONS(45) +P11_VIRTUAL_FIXED_FUNCTIONS(46) +P11_VIRTUAL_FIXED_FUNCTIONS(47) +P11_VIRTUAL_FIXED_FUNCTIONS(48) +P11_VIRTUAL_FIXED_FUNCTIONS(49) +P11_VIRTUAL_FIXED_FUNCTIONS(50) +P11_VIRTUAL_FIXED_FUNCTIONS(51) +P11_VIRTUAL_FIXED_FUNCTIONS(52) +P11_VIRTUAL_FIXED_FUNCTIONS(53) +P11_VIRTUAL_FIXED_FUNCTIONS(54) +P11_VIRTUAL_FIXED_FUNCTIONS(55) +P11_VIRTUAL_FIXED_FUNCTIONS(56) +P11_VIRTUAL_FIXED_FUNCTIONS(57) +P11_VIRTUAL_FIXED_FUNCTIONS(58) +P11_VIRTUAL_FIXED_FUNCTIONS(59) +P11_VIRTUAL_FIXED_FUNCTIONS(60) +P11_VIRTUAL_FIXED_FUNCTIONS(61) +P11_VIRTUAL_FIXED_FUNCTIONS(62) +P11_VIRTUAL_FIXED_FUNCTIONS(63) + +CK_FUNCTION_LIST p11_virtual_fixed[P11_VIRTUAL_MAX_FIXED] = { + P11_VIRTUAL_FIXED_INITIALIZER(0), \ + P11_VIRTUAL_FIXED_INITIALIZER(1), \ + P11_VIRTUAL_FIXED_INITIALIZER(2), \ + P11_VIRTUAL_FIXED_INITIALIZER(3), \ + P11_VIRTUAL_FIXED_INITIALIZER(4), \ + P11_VIRTUAL_FIXED_INITIALIZER(5), \ + P11_VIRTUAL_FIXED_INITIALIZER(6), \ + P11_VIRTUAL_FIXED_INITIALIZER(7), \ + P11_VIRTUAL_FIXED_INITIALIZER(8), \ + P11_VIRTUAL_FIXED_INITIALIZER(9), \ + P11_VIRTUAL_FIXED_INITIALIZER(10), \ + P11_VIRTUAL_FIXED_INITIALIZER(11), \ + P11_VIRTUAL_FIXED_INITIALIZER(12), \ + P11_VIRTUAL_FIXED_INITIALIZER(13), \ + P11_VIRTUAL_FIXED_INITIALIZER(14), \ + P11_VIRTUAL_FIXED_INITIALIZER(15), \ + P11_VIRTUAL_FIXED_INITIALIZER(16), \ + P11_VIRTUAL_FIXED_INITIALIZER(17), \ + P11_VIRTUAL_FIXED_INITIALIZER(18), \ + P11_VIRTUAL_FIXED_INITIALIZER(19), \ + P11_VIRTUAL_FIXED_INITIALIZER(20), \ + P11_VIRTUAL_FIXED_INITIALIZER(21), \ + P11_VIRTUAL_FIXED_INITIALIZER(22), \ + P11_VIRTUAL_FIXED_INITIALIZER(23), \ + P11_VIRTUAL_FIXED_INITIALIZER(24), \ + P11_VIRTUAL_FIXED_INITIALIZER(25), \ + P11_VIRTUAL_FIXED_INITIALIZER(26), \ + P11_VIRTUAL_FIXED_INITIALIZER(27), \ + P11_VIRTUAL_FIXED_INITIALIZER(28), \ + P11_VIRTUAL_FIXED_INITIALIZER(29), \ + P11_VIRTUAL_FIXED_INITIALIZER(30), \ + P11_VIRTUAL_FIXED_INITIALIZER(31), \ + P11_VIRTUAL_FIXED_INITIALIZER(32), \ + P11_VIRTUAL_FIXED_INITIALIZER(33), \ + P11_VIRTUAL_FIXED_INITIALIZER(34), \ + P11_VIRTUAL_FIXED_INITIALIZER(35), \ + P11_VIRTUAL_FIXED_INITIALIZER(36), \ + P11_VIRTUAL_FIXED_INITIALIZER(37), \ + P11_VIRTUAL_FIXED_INITIALIZER(38), \ + P11_VIRTUAL_FIXED_INITIALIZER(39), \ + P11_VIRTUAL_FIXED_INITIALIZER(40), \ + P11_VIRTUAL_FIXED_INITIALIZER(41), \ + P11_VIRTUAL_FIXED_INITIALIZER(42), \ + P11_VIRTUAL_FIXED_INITIALIZER(43), \ + P11_VIRTUAL_FIXED_INITIALIZER(44), \ + P11_VIRTUAL_FIXED_INITIALIZER(45), \ + P11_VIRTUAL_FIXED_INITIALIZER(46), \ + P11_VIRTUAL_FIXED_INITIALIZER(47), \ + P11_VIRTUAL_FIXED_INITIALIZER(48), \ + P11_VIRTUAL_FIXED_INITIALIZER(49), \ + P11_VIRTUAL_FIXED_INITIALIZER(50), \ + P11_VIRTUAL_FIXED_INITIALIZER(51), \ + P11_VIRTUAL_FIXED_INITIALIZER(52), \ + P11_VIRTUAL_FIXED_INITIALIZER(53), \ + P11_VIRTUAL_FIXED_INITIALIZER(54), \ + P11_VIRTUAL_FIXED_INITIALIZER(55), \ + P11_VIRTUAL_FIXED_INITIALIZER(56), \ + P11_VIRTUAL_FIXED_INITIALIZER(57), \ + P11_VIRTUAL_FIXED_INITIALIZER(58), \ + P11_VIRTUAL_FIXED_INITIALIZER(59), \ + P11_VIRTUAL_FIXED_INITIALIZER(60), \ + P11_VIRTUAL_FIXED_INITIALIZER(61), \ + P11_VIRTUAL_FIXED_INITIALIZER(62), \ + P11_VIRTUAL_FIXED_INITIALIZER(63) +}; + +P11_VIRTUAL_FIXED_GET_FUNCTION_LIST(0) +P11_VIRTUAL_FIXED_GET_FUNCTION_LIST(1) +P11_VIRTUAL_FIXED_GET_FUNCTION_LIST(2) +P11_VIRTUAL_FIXED_GET_FUNCTION_LIST(3) +P11_VIRTUAL_FIXED_GET_FUNCTION_LIST(4) +P11_VIRTUAL_FIXED_GET_FUNCTION_LIST(5) +P11_VIRTUAL_FIXED_GET_FUNCTION_LIST(6) +P11_VIRTUAL_FIXED_GET_FUNCTION_LIST(7) +P11_VIRTUAL_FIXED_GET_FUNCTION_LIST(8) +P11_VIRTUAL_FIXED_GET_FUNCTION_LIST(9) +P11_VIRTUAL_FIXED_GET_FUNCTION_LIST(10) +P11_VIRTUAL_FIXED_GET_FUNCTION_LIST(11) +P11_VIRTUAL_FIXED_GET_FUNCTION_LIST(12) +P11_VIRTUAL_FIXED_GET_FUNCTION_LIST(13) +P11_VIRTUAL_FIXED_GET_FUNCTION_LIST(14) +P11_VIRTUAL_FIXED_GET_FUNCTION_LIST(15) +P11_VIRTUAL_FIXED_GET_FUNCTION_LIST(16) +P11_VIRTUAL_FIXED_GET_FUNCTION_LIST(17) +P11_VIRTUAL_FIXED_GET_FUNCTION_LIST(18) +P11_VIRTUAL_FIXED_GET_FUNCTION_LIST(19) +P11_VIRTUAL_FIXED_GET_FUNCTION_LIST(20) +P11_VIRTUAL_FIXED_GET_FUNCTION_LIST(21) +P11_VIRTUAL_FIXED_GET_FUNCTION_LIST(22) +P11_VIRTUAL_FIXED_GET_FUNCTION_LIST(23) +P11_VIRTUAL_FIXED_GET_FUNCTION_LIST(24) +P11_VIRTUAL_FIXED_GET_FUNCTION_LIST(25) +P11_VIRTUAL_FIXED_GET_FUNCTION_LIST(26) +P11_VIRTUAL_FIXED_GET_FUNCTION_LIST(27) +P11_VIRTUAL_FIXED_GET_FUNCTION_LIST(28) +P11_VIRTUAL_FIXED_GET_FUNCTION_LIST(29) +P11_VIRTUAL_FIXED_GET_FUNCTION_LIST(30) +P11_VIRTUAL_FIXED_GET_FUNCTION_LIST(31) +P11_VIRTUAL_FIXED_GET_FUNCTION_LIST(32) +P11_VIRTUAL_FIXED_GET_FUNCTION_LIST(33) +P11_VIRTUAL_FIXED_GET_FUNCTION_LIST(34) +P11_VIRTUAL_FIXED_GET_FUNCTION_LIST(35) +P11_VIRTUAL_FIXED_GET_FUNCTION_LIST(36) +P11_VIRTUAL_FIXED_GET_FUNCTION_LIST(37) +P11_VIRTUAL_FIXED_GET_FUNCTION_LIST(38) +P11_VIRTUAL_FIXED_GET_FUNCTION_LIST(39) +P11_VIRTUAL_FIXED_GET_FUNCTION_LIST(40) +P11_VIRTUAL_FIXED_GET_FUNCTION_LIST(41) +P11_VIRTUAL_FIXED_GET_FUNCTION_LIST(42) +P11_VIRTUAL_FIXED_GET_FUNCTION_LIST(43) +P11_VIRTUAL_FIXED_GET_FUNCTION_LIST(44) +P11_VIRTUAL_FIXED_GET_FUNCTION_LIST(45) +P11_VIRTUAL_FIXED_GET_FUNCTION_LIST(46) +P11_VIRTUAL_FIXED_GET_FUNCTION_LIST(47) +P11_VIRTUAL_FIXED_GET_FUNCTION_LIST(48) +P11_VIRTUAL_FIXED_GET_FUNCTION_LIST(49) +P11_VIRTUAL_FIXED_GET_FUNCTION_LIST(50) +P11_VIRTUAL_FIXED_GET_FUNCTION_LIST(51) +P11_VIRTUAL_FIXED_GET_FUNCTION_LIST(52) +P11_VIRTUAL_FIXED_GET_FUNCTION_LIST(53) +P11_VIRTUAL_FIXED_GET_FUNCTION_LIST(54) +P11_VIRTUAL_FIXED_GET_FUNCTION_LIST(55) +P11_VIRTUAL_FIXED_GET_FUNCTION_LIST(56) +P11_VIRTUAL_FIXED_GET_FUNCTION_LIST(57) +P11_VIRTUAL_FIXED_GET_FUNCTION_LIST(58) +P11_VIRTUAL_FIXED_GET_FUNCTION_LIST(59) +P11_VIRTUAL_FIXED_GET_FUNCTION_LIST(60) +P11_VIRTUAL_FIXED_GET_FUNCTION_LIST(61) +P11_VIRTUAL_FIXED_GET_FUNCTION_LIST(62) +P11_VIRTUAL_FIXED_GET_FUNCTION_LIST(63) + +static CK_FUNCTION_LIST * +p11_virtual_wrap_fixed (p11_virtual *virt, + p11_destroyer destroyer) +{ + CK_FUNCTION_LIST *result = NULL; + size_t i; + + p11_mutex_lock (&fixed_mutex); + for (i = 0; i < P11_VIRTUAL_MAX_FIXED; i++) { + if (fixed_closures[i] == NULL) { + Wrapper *wrapper; + wrapper = create_fixed_wrapper (virt, i, destroyer); + result = &wrapper->bound; + fixed_closures[i] = result; + break; + } + } + p11_mutex_unlock (&fixed_mutex); + + return result; +} + +static void +p11_virtual_unwrap_fixed (CK_FUNCTION_LIST_PTR module) +{ + size_t i; + + p11_mutex_lock (&fixed_mutex); + for (i = 0; i < P11_VIRTUAL_MAX_FIXED; i++) { + if (fixed_closures[i] == module) { + fixed_closures[i] = NULL; + break; + } + } + p11_mutex_unlock (&fixed_mutex); +} + +static bool +init_wrapper_funcs_fixed (Wrapper *wrapper, CK_FUNCTION_LIST *fixed) +{ + const FunctionInfo *info; + void **bound_to, **bound_from; + int i; + + for (i = 0; function_info[i].name != NULL; i++) { + info = function_info + i; + + /* Address to where we're placing the bound function */ + bound_to = &STRUCT_MEMBER (void *, &wrapper->bound, info->module_offset); + bound_from = &STRUCT_MEMBER (void *, fixed, info->module_offset); + + /* + * See if we can just shoot straight through to the module function + * without wrapping at all. If all the stacked virtual modules just + * fall through, then this returns the original module function. + */ + if (!lookup_fall_through (wrapper->virt, info, bound_to)) + *bound_to = *bound_from; + } + + /* Always bind the C_GetFunctionList function itself */ + wrapper->bound.C_GetFunctionList = fixed->C_GetFunctionList; + + /* + * These functions are used as a marker to indicate whether this is + * one of our CK_FUNCTION_LIST_PTR sets of functions or not. These + * functions are defined to always have the same standard implementation + * in PKCS#11 2.x so we don't need to call through to the base for + * these guys. + */ + wrapper->bound.C_CancelFunction = short_C_CancelFunction; + wrapper->bound.C_GetFunctionStatus = short_C_GetFunctionStatus; + + return true; +} + +static Wrapper * +create_fixed_wrapper (p11_virtual *virt, + size_t index, + p11_destroyer destroyer) +{ + Wrapper *wrapper; + + return_val_if_fail (virt != NULL, NULL); + + wrapper = calloc (1, sizeof (Wrapper)); + return_val_if_fail (wrapper != NULL, NULL); + + wrapper->virt = virt; + wrapper->destroyer = destroyer; + wrapper->bound.version.major = CRYPTOKI_VERSION_MAJOR; + wrapper->bound.version.minor = CRYPTOKI_VERSION_MINOR; + wrapper->fixed_index = index; + + if (!init_wrapper_funcs_fixed (wrapper, &p11_virtual_fixed[index])) { + free (wrapper); + return NULL; + } + + assert ((void *)wrapper == (void *)&wrapper->bound); + assert (p11_virtual_is_wrapper (&wrapper->bound)); + assert (wrapper->bound.C_GetFunctionList != NULL); + return wrapper; +} diff --git a/p11-kit/virtual.h b/p11-kit/virtual.h index 97d2a7c..8083eb9 100644 --- a/p11-kit/virtual.h +++ b/p11-kit/virtual.h @@ -56,8 +56,6 @@ void p11_virtual_init (p11_virtual *virt, void p11_virtual_uninit (p11_virtual *virt); -bool p11_virtual_can_wrap (void); - CK_FUNCTION_LIST * p11_virtual_wrap (p11_virtual *virt, p11_destroyer destroyer); @@ -65,4 +63,8 @@ bool p11_virtual_is_wrapper (CK_FUNCTION_LIST *module); void p11_virtual_unwrap (CK_FUNCTION_LIST *module); +void p11_virtual_init_fixed (void); +void p11_virtual_uninit_fixed + (void); + #endif /* __P11_VIRTUAL_H__ */ |