diff options
Diffstat (limited to 'p11-kit')
31 files changed, 12243 insertions, 1568 deletions
diff --git a/p11-kit/Makefile.am b/p11-kit/Makefile.am index 1ab3b3d..2e08e84 100644 --- a/p11-kit/Makefile.am +++ b/p11-kit/Makefile.am @@ -5,7 +5,7 @@ SUBDIRS = . tests COMMON = $(top_srcdir)/common -INCLUDES = \ +AM_CPPFLAGS = \ -I$(top_srcdir) \ -I$(COMMON) \ -DP11_KIT_FUTURE_UNSTABLE_API \ @@ -14,6 +14,7 @@ INCLUDES = \ incdir = $(includedir)/p11-kit-1/p11-kit inc_HEADERS = \ + deprecated.h \ iter.h \ p11-kit.h \ pin.h \ @@ -24,14 +25,16 @@ MODULE_SRCS = \ util.c \ conf.c conf.h \ iter.c \ - modules.c \ + log.c log.h \ + modules.c modules.h \ pkcs11.h \ pin.c \ pkcs11.h \ - proxy.c \ + proxy.c proxy.h \ private.h \ messages.c \ uri.c \ + virtual.c virtual.h \ $(inc_HEADERS) lib_LTLIBRARIES = \ @@ -44,6 +47,7 @@ libp11_kit_la_CFLAGS = \ -DP11_USER_CONFIG_FILE=\""$(p11_user_config_file)"\" \ -DP11_USER_CONFIG_MODULES=\""$(p11_user_config_modules)"\" \ -DP11_MODULE_PATH=\""$(p11_module_path)"\" \ + $(LIBFFI_CFLAGS) \ $(NULL) libp11_kit_la_LDFLAGS = \ @@ -54,9 +58,10 @@ libp11_kit_la_LDFLAGS = \ libp11_kit_la_SOURCES = $(MODULE_SRCS) libp11_kit_la_LIBADD = \ - $(LTLIBINTL) \ $(top_builddir)/common/libp11-common.la \ $(top_builddir)/common/libp11-library.la \ + $(LIBFFI_LIBS) \ + $(LTLIBINTL) \ $(NULL) noinst_LTLIBRARIES = \ @@ -75,6 +80,7 @@ libp11_kit_testable_la_CFLAGS = \ -DP11_USER_CONFIG_FILE=\""$(abs_top_srcdir)/p11-kit/tests/files/user-pkcs11.conf"\" \ -DP11_USER_CONFIG_MODULES=\""$(abs_top_srcdir)/p11-kit/tests/files/user-modules/win32"\" \ -DP11_MODULE_PATH=\""$(abs_top_builddir)/p11-kit/tests/.libs"\" \ + $(LIBFFI_CFLAGS) \ $(NULL) else @@ -86,6 +92,7 @@ libp11_kit_testable_la_CFLAGS = \ -DP11_USER_CONFIG_FILE=\""$(abs_top_srcdir)/p11-kit/tests/files/user-pkcs11.conf"\" \ -DP11_USER_CONFIG_MODULES=\""$(abs_top_srcdir)/p11-kit/tests/files/user-modules"\" \ -DP11_MODULE_PATH=\""$(abs_top_builddir)/p11-kit/tests/.libs"\" \ + $(LIBFFI_CFLAGS) \ $(NULL) endif @@ -98,7 +105,9 @@ example_DATA = pkcs11.conf.example EXTRA_DIST = \ p11-kit-1.pc.in \ - pkcs11.conf.example.in + pkcs11.conf.example.in \ + docs.h \ + $(NULL) # Proxy module is actually same as library, so install a link install-exec-hook: diff --git a/p11-kit/deprecated.h b/p11-kit/deprecated.h new file mode 100644 index 0000000..ffe5d9d --- /dev/null +++ b/p11-kit/deprecated.h @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2013 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 <stefw@redhat.com> + */ + +#ifndef __P11_KIT_DEPRECATED_H__ +#define __P11_KIT_DEPRECATED_H__ + +#ifndef __P11_KIT_H__ +#error "Please include <p11-kit/p11-kit.h> instead of this file." +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef P11_KIT_NO_DEPRECATIONS +#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5) +#define P11_KIT_DEPRECATED_FOR(f) __attribute__((deprecated("Use " #f " instead"))) +#elif __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1) +#define P11_KIT_DEPRECATED_FOR(f) __attribute__((__deprecated__)) +#endif +#endif + +#ifndef P11_KIT_DEPRECATED_FOR +#define P11_KIT_DEPRECATED_FOR(f) +#endif + +#ifndef P11_KIT_DISABLE_DEPRECATED + +P11_KIT_DEPRECATED_FOR (p11_kit_modules_load) +CK_RV p11_kit_initialize_registered (void); + +P11_KIT_DEPRECATED_FOR (p11_kit_modules_release) +CK_RV p11_kit_finalize_registered (void); + +P11_KIT_DEPRECATED_FOR (p11_kit_modules_release) +CK_FUNCTION_LIST_PTR * p11_kit_registered_modules (void); + +P11_KIT_DEPRECATED_FOR (p11_kit_module_for_name) +CK_FUNCTION_LIST_PTR p11_kit_registered_name_to_module (const char *name); + +P11_KIT_DEPRECATED_FOR (p11_kit_module_get_name) +char * p11_kit_registered_module_to_name (CK_FUNCTION_LIST_PTR module); + +P11_KIT_DEPRECATED_FOR (p11_kit_config_option) +char * p11_kit_registered_option (CK_FUNCTION_LIST_PTR module, + const char *field); + +P11_KIT_DEPRECATED_FOR (module->C_Initialize) +CK_RV p11_kit_initialize_module (CK_FUNCTION_LIST_PTR module); + +P11_KIT_DEPRECATED_FOR (module->C_Finalize) +CK_RV p11_kit_finalize_module (CK_FUNCTION_LIST_PTR module); + +P11_KIT_DEPRECATED_FOR (p11_kit_module_load) +CK_RV p11_kit_load_initialize_module (const char *module_path, + CK_FUNCTION_LIST_PTR *module); + +#endif /* P11_KIT_DISABLE_DEPRECATED */ + +#undef P11_KIT_DEPRECATED_FOR + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* __P11_KIT_DEPRECATED_H__ */ diff --git a/p11-kit/docs.h b/p11-kit/docs.h new file mode 100644 index 0000000..7b29e3d --- /dev/null +++ b/p11-kit/docs.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2013 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 <stefw@redhat.com> + */ + +/* This header is not used by anything, and merely to help gtk-doc be sane */ + +#define P11_KIT_MODULE_UNMANAGED 1 +#define P11_KIT_MODULE_CRITICAL 1 diff --git a/p11-kit/log.c b/p11-kit/log.c new file mode 100644 index 0000000..19377b2 --- /dev/null +++ b/p11-kit/log.c @@ -0,0 +1,2022 @@ +/* + * Copyright (c) 2007, Stefan Walter + * Copyright (c) 2013, Red Hat Inc. + * + * All rights reserved. + * + * 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. + * + * + * CONTRIBUTORS + * Stef Walter <stef@memberwebs.com> + */ + +#include "config.h" + +#include "attrs.h" +#include "buffer.h" +#include "constants.h" +#include "debug.h" +#include "log.h" +#include "p11-kit.h" +#include "virtual.h" + +#include <sys/types.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <errno.h> +#include <stdarg.h> + +bool p11_log_force = false; +bool p11_log_output = true; + +typedef struct { + p11_virtual virt; + CK_X_FUNCTION_LIST *lower; + p11_destroyer destroyer; +} LogData; + +#define LOG_FLAG(buf, flags, had, flag) \ + if ((flags & flag) == flag) { \ + p11_buffer_add (buf, had ? " | " : " = ", 3); \ + p11_buffer_add (buf, #flag, -1); \ + had++; \ + } + +static void +log_CKM (p11_buffer *buf, + CK_MECHANISM_TYPE v) +{ + char temp[32]; + const char *string; + + string = p11_constant_name (p11_constant_mechanisms, v); + if (string == NULL) { + snprintf (temp, sizeof (temp), "CKM_0x%08lX", v); + p11_buffer_add (buf, temp, -1); + } else { + p11_buffer_add (buf, string, -1); + } +} + +static void +log_CKS (p11_buffer *buf, + CK_STATE v) +{ + char temp[32]; + const char *string; + + string = p11_constant_name (p11_constant_states, v); + if (string == NULL) { + snprintf (temp, sizeof (temp), "CKS_0x%08lX", v); + p11_buffer_add (buf, temp, -1); + } else { + p11_buffer_add (buf, string, -1); + } +} + +static void +log_CKU (p11_buffer *buf, + CK_USER_TYPE v) +{ + char temp[32]; + const char *string; + + string = p11_constant_name (p11_constant_users, v); + if (string == NULL) { + snprintf (temp, sizeof (temp), "CKU_0x%08lX", v); + p11_buffer_add (buf, temp, -1); + } else { + p11_buffer_add (buf, string, -1); + } +} + +static void +log_CKR (p11_buffer *buf, + CK_RV v) +{ + char temp[32]; + const char *string; + + string = p11_constant_name (p11_constant_returns, v); + if (string == NULL) { + snprintf (temp, sizeof (temp), "CKR_0x%08lX", v); + p11_buffer_add (buf, temp, -1); + } else { + p11_buffer_add (buf, string, -1); + } +} + +static void +log_some_bytes (p11_buffer *buf, + CK_BYTE_PTR arr, + CK_ULONG num) +{ + CK_ULONG i; + char temp[128]; + char *p, *e; + CK_BYTE ch; + + if(!arr) { + p11_buffer_add (buf, "NULL", 4); + return; + } else if (num == (CK_ULONG)-1) { + p11_buffer_add (buf, "????", 4); + return; + } + + temp[0] = '\"'; + p = temp + 1; + e = temp + (sizeof (temp) - 8); + + for(i = 0; i < num && p < e; ++i, ++p) { + ch = arr[i]; + if (ch == '\t') { + p[0] = '\\'; p[1] = 't'; + ++p; + } else if (ch == '\n') { + p[0] = '\\'; p[1] = 'n'; + ++p; + } else if (ch == '\r') { + p[0] = '\\'; p[1] = 'r'; + ++p; + } else if (ch >= 32 && ch < 127) { + *p = ch; + } else { + p[0] = '\\'; + p[1] = 'x'; + sprintf(p + 2, "%02X", ch); + p += 3; + } + } + + *p = 0; + if (p >= e) + strcpy (e, "..."); + strcat (p, "\""); + p11_buffer_add (buf, temp, -1); +} + +static void +log_pointer (p11_buffer *buf, + const char *pref, + const char *name, + CK_VOID_PTR val, + CK_RV status) +{ + char temp[32]; + + if (status != CKR_OK) + return; + + p11_buffer_add (buf, pref, -1); + p11_buffer_add (buf, name, -1); + p11_buffer_add (buf, " = ", 3); + if (val == NULL) { + p11_buffer_add (buf, "NULL\n", 5); + } else { + snprintf (temp, sizeof (temp), "0x%08lX\n", (unsigned long)(size_t)val); + p11_buffer_add (buf, temp, -1); + } +} + +static void +log_attribute_types (p11_buffer *buf, + const char *pref, + const char *name, + CK_ATTRIBUTE_PTR arr, + CK_ULONG num, + CK_RV status) +{ + const char *string; + char temp[32]; + CK_ULONG i; + + if (status == CKR_BUFFER_TOO_SMALL) { + arr = NULL; + status = CKR_OK; + } + if (status != CKR_OK) + return; + + p11_buffer_add (buf, pref, -1); + p11_buffer_add (buf, name, -1); + p11_buffer_add (buf, " = ", 3); + if (arr == NULL) { + snprintf (temp, sizeof (temp), "(%lu) NONE\n", num); + p11_buffer_add (buf, temp, -1); + } else { + snprintf (temp, sizeof (temp), "(%lu) [ ", num); + p11_buffer_add (buf, temp, -1); + for (i = 0; i < num; i++) { + if (i > 0) + p11_buffer_add (buf, ", ", 2); + string = p11_constant_name (p11_constant_types, arr[i].type); + if (string != NULL) { + p11_buffer_add (buf, string, -1); + } else { + snprintf (temp, sizeof (temp), "CKA_0x%08lX", arr[i].type); + p11_buffer_add (buf, temp, -1); + } + } + + p11_buffer_add (buf, " ]\n", 3); + } +} + +static void +log_attribute_array (p11_buffer *buf, + const char *pref, + const char *name, + CK_ATTRIBUTE_PTR arr, + CK_ULONG num, + CK_RV status) +{ + char temp[32]; + + if (status == CKR_BUFFER_TOO_SMALL) { + arr = NULL; + status = CKR_OK; + } + if (status != CKR_OK) + return; + + p11_buffer_add (buf, pref, -1); + p11_buffer_add (buf, name, -1); + p11_buffer_add (buf, " = ", 3); + if (arr == NULL) { + snprintf (temp, sizeof (temp), "(%lu) NONE\n", num); + p11_buffer_add (buf, temp, -1); + } else { + p11_attrs_format (buf, arr, num); + p11_buffer_add (buf, "\n", 1); + } +} + +static void +log_bool (p11_buffer *buf, + const char *pref, + const char *name, + CK_BBOOL val, + CK_RV status) +{ + if (status == CKR_OK) { + p11_buffer_add (buf, pref, -1); + p11_buffer_add (buf, name, -1); + p11_buffer_add (buf, " = ", 3); + p11_buffer_add (buf, val ? "CK_TRUE" : "CK_FALSE", -1); + p11_buffer_add (buf, "\n", 1); + } +} + +static void +log_byte_array (p11_buffer *buf, + const char *pref, + const char *name, + CK_BYTE_PTR arr, + CK_ULONG_PTR num, + CK_RV status) +{ + char temp[32]; + + if (status == CKR_BUFFER_TOO_SMALL) { + arr = NULL; + status = CKR_OK; + } + + if (status != CKR_OK) + return; + p11_buffer_add (buf, pref, -1); + p11_buffer_add (buf, name, -1); + p11_buffer_add (buf, " = ", 3); + if (num == NULL) { + p11_buffer_add (buf, "(?) NOTHING\n", -1); + } else if (arr == NULL) { + snprintf (temp, sizeof (temp), "(%lu) NOTHING\n", *num); + p11_buffer_add (buf, temp, -1); + } else { + snprintf (temp, sizeof (temp), "(%lu) ", *num); + p11_buffer_add (buf, temp, -1); + log_some_bytes (buf, arr, *num); + p11_buffer_add (buf, "\n", 1); + } +} + +static void +log_info (p11_buffer *buf, + const char *pref, + const char *name, + CK_INFO_PTR info, + CK_RV status) +{ + char temp[32]; + + if (status != CKR_OK) + return; + if (info == NULL) { + log_pointer (buf, pref, name, info, status); + } else { + p11_buffer_add (buf, pref, -1); + p11_buffer_add (buf, name, -1); + p11_buffer_add (buf, " = {\n", 5); + p11_buffer_add (buf, "\tcryptokiVersion: ", -1); + snprintf (temp, sizeof (temp), "%u.%u", (unsigned int)info->cryptokiVersion.major, + (unsigned int)info->cryptokiVersion.minor); + p11_buffer_add (buf, temp, -1); + p11_buffer_add (buf, "\n\tmanufacturerID: \"", -1); + p11_buffer_add (buf, info->manufacturerID, p11_kit_space_strlen (info->manufacturerID, sizeof (info->manufacturerID))); + p11_buffer_add (buf, "\"\n\tflags: ", -1); + snprintf (temp, sizeof (temp), "%lX", info->flags); + p11_buffer_add (buf, temp, -1); + p11_buffer_add (buf, "\n\tlibraryDescription: \"", -1); + p11_buffer_add (buf, info->libraryDescription, p11_kit_space_strlen (info->libraryDescription, sizeof (info->libraryDescription))); + p11_buffer_add (buf, "\"\n\tlibraryVersion: ", -1); + snprintf (temp, sizeof (temp), "%u.%u", (unsigned int)info->libraryVersion.major, + (unsigned int)info->libraryVersion.minor); + p11_buffer_add (buf, temp, -1); + p11_buffer_add (buf, "\n }\n", -1); + } +} + +static void +log_pInitArgs (p11_buffer *buf, + const char *pref, + const char *name, + CK_VOID_PTR pInitArgs, + CK_RV status) +{ + char temp[32]; + int had = 0; + + if (status != CKR_OK) + return; + if (pInitArgs == NULL) + log_pointer (buf, pref, name, pInitArgs, status); + else { + CK_C_INITIALIZE_ARGS *args = (CK_C_INITIALIZE_ARGS*)pInitArgs; + p11_buffer_add (buf, pref, -1); + p11_buffer_add (buf, name, -1); + p11_buffer_add (buf, " = {\n", 5); + p11_buffer_add (buf, "\tCreateMutex: ", -1); + snprintf (temp, sizeof (temp), "0x%08lX", (unsigned long)(size_t)args->CreateMutex); + p11_buffer_add (buf, temp, -1); + p11_buffer_add (buf, "\n\tDestroyMutex: ", -1); + snprintf (temp, sizeof (temp), "0x%08lX", (unsigned long)(size_t)args->DestroyMutex); + p11_buffer_add (buf, temp, -1); + p11_buffer_add (buf, "\n\tLockMutex: ", -1); + snprintf (temp, sizeof (temp), "0x%08lX", (unsigned long)(size_t)args->LockMutex); + p11_buffer_add (buf, temp, -1); + p11_buffer_add (buf, "\n\tUnlockMutex: ", -1); + snprintf (temp, sizeof (temp), "0x%08lX", (unsigned long)(size_t)args->UnlockMutex); + p11_buffer_add (buf, temp, -1); + p11_buffer_add (buf, "\n\tflags: ", -1); + snprintf (temp, sizeof (temp), "%lX", args->flags); + LOG_FLAG (buf, args->flags, had, CKF_OS_LOCKING_OK); + p11_buffer_add (buf, "\n\treserved: ", -1); + snprintf (temp, sizeof (temp), "0x%08lX", (unsigned long)(size_t)args->pReserved); + p11_buffer_add (buf, temp, -1); + p11_buffer_add (buf, "\n }\n", -1); + } +} + +static void +log_mechanism_info (p11_buffer *buf, + const char *pref, + const char *name, + CK_MECHANISM_INFO_PTR info, + CK_RV status) +{ + char temp[32]; + int had = 0; + + if (status != CKR_OK) + return; + if (info == NULL) { + log_pointer (buf, pref, name, info, status); + } else { + p11_buffer_add (buf, pref, -1); + p11_buffer_add (buf, name, -1); + p11_buffer_add (buf, " = {\n", 5); + p11_buffer_add (buf, "\tulMinKeySize: ", -1); + snprintf (temp, sizeof (temp), "%lu", info->ulMinKeySize); + p11_buffer_add (buf, temp, -1); + p11_buffer_add (buf, "\n\tulMaxKeySize: ", -1); + snprintf (temp, sizeof (temp), "%lu", info->ulMaxKeySize); + p11_buffer_add (buf, temp, -1); + p11_buffer_add (buf, "\n\tflags: ", -1); + snprintf (temp, sizeof (temp), "%lX", info->flags); + p11_buffer_add (buf, temp, -1); + LOG_FLAG (buf, info->flags, had, CKF_HW); + LOG_FLAG (buf, info->flags, had, CKF_ENCRYPT); + LOG_FLAG (buf, info->flags, had, CKF_DECRYPT); + LOG_FLAG (buf, info->flags, had, CKF_DIGEST); + LOG_FLAG (buf, info->flags, had, CKF_SIGN); + LOG_FLAG (buf, info->flags, had, CKF_SIGN_RECOVER); + LOG_FLAG (buf, info->flags, had, CKF_VERIFY); + LOG_FLAG (buf, info->flags, had, CKF_VERIFY_RECOVER); + LOG_FLAG (buf, info->flags, had, CKF_GENERATE); + LOG_FLAG (buf, info->flags, had, CKF_GENERATE_KEY_PAIR); + LOG_FLAG (buf, info->flags, had, CKF_WRAP); + LOG_FLAG (buf, info->flags, had, CKF_UNWRAP); + LOG_FLAG (buf, info->flags, had, CKF_DERIVE); + LOG_FLAG (buf, info->flags, had, CKF_EXTENSION); + p11_buffer_add (buf, "\n }\n", -1); + } +} + +static void +log_mechanism (p11_buffer *buf, + const char *pref, + const char *name, + CK_MECHANISM_PTR mech, + CK_RV status) +{ + char temp[32]; + + if (status != CKR_OK) + return; + p11_buffer_add (buf, pref, -1); + p11_buffer_add (buf, name, -1); + p11_buffer_add (buf, " = {\n", 5); + p11_buffer_add (buf, "\tmechanism: ", -1); + log_CKM (buf, mech->mechanism); + p11_buffer_add (buf, "\n\tpParameter: ", -1); + snprintf (temp, sizeof (temp), "(%lu) ", mech->ulParameterLen); + p11_buffer_add (buf, temp, -1); + log_some_bytes (buf, mech->pParameter, mech->ulParameterLen); + p11_buffer_add (buf, "\n }\n", -1); +} + +static void +log_mechanism_type (p11_buffer *buf, + const char *pref, + const char *name, + CK_MECHANISM_TYPE val, + CK_RV status) +{ + if (status != CKR_OK) + return; + p11_buffer_add (buf, pref, -1); + p11_buffer_add (buf, name, -1); + p11_buffer_add (buf, " = ", 3); + log_CKM (buf, val); + p11_buffer_add (buf, "\n", 1); +} + +static void +log_mechanism_type_array (p11_buffer *buf, + const char *pref, + const char *name, + CK_MECHANISM_TYPE_PTR arr, + CK_ULONG_PTR num, + CK_RV status) +{ + char temp[32]; + CK_ULONG i; + + if (status == CKR_BUFFER_TOO_SMALL) { + arr = NULL; + status = CKR_OK; + } + if (status != CKR_OK) + return; + + p11_buffer_add (buf, pref, -1); + p11_buffer_add (buf, name, -1); + p11_buffer_add (buf, " = ", 3); + if (num == NULL) { + p11_buffer_add (buf, "(?) NO-VALUES\n", -1); + } else if (arr == NULL) { + snprintf (temp, sizeof (temp), "(%lu) NO-VALUES\n", *num); + p11_buffer_add (buf, temp, -1); + } else { + snprintf (temp, sizeof (temp), "(%lu) [ ", *num); + p11_buffer_add (buf, temp, -1); + for(i = 0; i < *num; ++i) { + if (i > 0) + p11_buffer_add (buf, ", ", 2); + log_CKM (buf, arr[i]); + } + p11_buffer_add (buf, " ]\n", 3); + } +} + +static void +log_session_info (p11_buffer *buf, + const char *pref, + const char *name, + CK_SESSION_INFO_PTR info, + CK_RV status) +{ + char temp[32]; + int had = 0; + + if (status != CKR_OK) + return; + if (info == NULL) { + log_pointer (buf, pref, name, info, status); + } else { + p11_buffer_add (buf, pref, -1); + p11_buffer_add (buf, name, -1); + p11_buffer_add (buf, " = {\n", 5); + p11_buffer_add (buf, "\tslotID: ", -1); + snprintf (temp, sizeof (temp), "SL%lu", info->slotID); + p11_buffer_add (buf, temp, -1); + p11_buffer_add (buf, "\n\tstate: ", -1); + log_CKS (buf, info->state); + p11_buffer_add (buf, "\n\tflags: ", -1); + snprintf (temp, sizeof (temp), "%lX", info->flags); + p11_buffer_add (buf, temp, -1); + LOG_FLAG (buf, info->flags, had, CKF_SERIAL_SESSION); + LOG_FLAG (buf, info->flags, had, CKF_RW_SESSION); + p11_buffer_add (buf, "\n\tulDeviceError: ", -1); + snprintf (temp, sizeof (temp), "%lu", info->ulDeviceError); + p11_buffer_add (buf, temp, -1); + p11_buffer_add (buf, "\n }\n", -1); + } +} + +static void +log_slot_info (p11_buffer *buf, + const char *pref, + const char *name, + CK_SLOT_INFO_PTR info, + CK_RV status) +{ + char temp[32]; + int had = 0; + + if (status != CKR_OK) + return; + if (info == NULL) { + log_pointer (buf, pref, name, info, status); + } else { + p11_buffer_add (buf, pref, -1); + p11_buffer_add (buf, name, -1); + p11_buffer_add (buf, " = {\n", 5); + p11_buffer_add (buf, "\tslotDescription: \"", -1); + p11_buffer_add (buf, info->slotDescription, p11_kit_space_strlen (info->slotDescription, sizeof (info->slotDescription))); + p11_buffer_add (buf, "\"\n\tmanufacturerID: \"", -1); + p11_buffer_add (buf, info->manufacturerID, p11_kit_space_strlen (info->manufacturerID, sizeof (info->manufacturerID))); + p11_buffer_add (buf, "\"\n\tflags: ", -1); + snprintf (temp, sizeof (temp), "%lu", info->flags); + p11_buffer_add (buf, temp, -1); + LOG_FLAG (buf, info->flags, had, CKF_TOKEN_PRESENT); + LOG_FLAG (buf, info->flags, had, CKF_REMOVABLE_DEVICE); + LOG_FLAG (buf, info->flags, had, CKF_HW_SLOT); + p11_buffer_add (buf, "\n\thardwareVersion: ", -1); + snprintf (temp, sizeof (temp), "%u.%u", (unsigned int)info->hardwareVersion.major, + (unsigned int)info->hardwareVersion.minor); + p11_buffer_add (buf, temp, -1); + p11_buffer_add (buf, "\n\tfirmwareVersion: ", -1); + snprintf (temp, sizeof (temp), "%u.%u", (unsigned int)info->firmwareVersion.major, + (unsigned int)info->firmwareVersion.minor); + p11_buffer_add (buf, temp, -1); + p11_buffer_add (buf, "\n }\n", -1); + } +} + +static void +log_string (p11_buffer *buf, + const char *pref, + const char *name, + CK_UTF8CHAR_PTR str, + const CK_RV status) +{ + if (status != CKR_OK) + return; + if (str == NULL) { + log_pointer (buf, pref, name, str, status); + } else { + p11_buffer_add (buf, pref, -1); + p11_buffer_add (buf, name, -1); + p11_buffer_add (buf, " = \"", 4); + p11_buffer_add (buf, str, -1); + p11_buffer_add (buf, "\"\n", 2); + } +} + +static void +log_token_number (p11_buffer *buf, + CK_ULONG number) +{ + char temp[32]; + + if (number == 0) { + p11_buffer_add (buf, "CK_UNAVAILABLE_INFORMATION", -1); + } else if (number == (CK_ULONG)-1) { + p11_buffer_add (buf, "CK_EFFECTIVELY_INFINITE", -1); + } else { + snprintf (temp, sizeof (temp), "%lu", number); + p11_buffer_add (buf, temp, -1); + } +} + +static void +log_token_info (p11_buffer *buf, + const char *pref, + const char *name, + CK_TOKEN_INFO_PTR info, + CK_RV status) +{ + char temp[32]; + int had = 0; + + if (status != CKR_OK) + return; + if (info == NULL) { + log_pointer (buf, pref, name, info, status); + } else { + p11_buffer_add (buf, pref, -1); + p11_buffer_add (buf, name, -1); + p11_buffer_add (buf, " = {\n", 5); + p11_buffer_add (buf, "\tlabel: \"", -1); + p11_buffer_add (buf, info->label, p11_kit_space_strlen (info->label, sizeof (info->label))); + p11_buffer_add (buf, "\"\n\tmanufacturerID: \"", -1); + p11_buffer_add (buf, info->manufacturerID, p11_kit_space_strlen (info->manufacturerID, sizeof (info->manufacturerID))); + p11_buffer_add (buf, "\"\n\tmodel: \"", -1); + p11_buffer_add (buf, info->model, p11_kit_space_strlen (info->model, sizeof (info->model))); + p11_buffer_add (buf, "\"\n\tserialNumber: \"", -1); + p11_buffer_add (buf, info->serialNumber, p11_kit_space_strlen (info->serialNumber, sizeof (info->serialNumber))); + p11_buffer_add (buf, "\"\n\tflags: ", -1); + snprintf (temp, sizeof (temp), "%lu", info->flags); + p11_buffer_add (buf, temp, -1); + LOG_FLAG (buf, info->flags, had, CKF_RNG); + LOG_FLAG (buf, info->flags, had, CKF_WRITE_PROTECTED); + LOG_FLAG (buf, info->flags, had, CKF_LOGIN_REQUIRED); + LOG_FLAG (buf, info->flags, had, CKF_USER_PIN_INITIALIZED); + LOG_FLAG (buf, info->flags, had, CKF_RESTORE_KEY_NOT_NEEDED); + LOG_FLAG (buf, info->flags, had, CKF_CLOCK_ON_TOKEN); + LOG_FLAG (buf, info->flags, had, CKF_PROTECTED_AUTHENTICATION_PATH); + LOG_FLAG (buf, info->flags, had, CKF_DUAL_CRYPTO_OPERATIONS); + LOG_FLAG (buf, info->flags, had, CKF_TOKEN_INITIALIZED); + LOG_FLAG (buf, info->flags, had, CKF_SECONDARY_AUTHENTICATION); + LOG_FLAG (buf, info->flags, had, CKF_USER_PIN_COUNT_LOW); + LOG_FLAG (buf, info->flags, had, CKF_USER_PIN_FINAL_TRY); + LOG_FLAG (buf, info->flags, had, CKF_USER_PIN_LOCKED); + LOG_FLAG (buf, info->flags, had, CKF_USER_PIN_TO_BE_CHANGED); + LOG_FLAG (buf, info->flags, had, CKF_SO_PIN_COUNT_LOW); + LOG_FLAG (buf, info->flags, had, CKF_SO_PIN_FINAL_TRY); + LOG_FLAG (buf, info->flags, had, CKF_SO_PIN_LOCKED); + LOG_FLAG (buf, info->flags, had, CKF_SO_PIN_TO_BE_CHANGED); + if (!had) { + snprintf (temp, sizeof (temp), "%lu", info->flags); + p11_buffer_add (buf, temp, -1); + } + + p11_buffer_add (buf, "\n\tulMaxSessionCount: ", -1); + log_token_number (buf, info->ulMaxSessionCount); + p11_buffer_add (buf, "\n\tulSessionCount: ", -1); + snprintf (temp, sizeof (temp), "%lu", info->ulSessionCount); + p11_buffer_add (buf, temp, -1); + p11_buffer_add (buf, "\n\tulMaxRwSessionCount: ", -1); + log_token_number (buf, info->ulMaxSessionCount); + p11_buffer_add (buf, "\n\tulRwSessionCount: ", -1); + snprintf (temp, sizeof (temp), "%lu", info->ulRwSessionCount); + p11_buffer_add (buf, temp, -1); + p11_buffer_add (buf, "\n\tulMaxPinLen: ", -1); + snprintf (temp, sizeof (temp), "%lu", info->ulMaxPinLen); + p11_buffer_add (buf, temp, -1); + p11_buffer_add (buf, "\n\tulMinPinLen: ", -1); + snprintf (temp, sizeof (temp), "%lu", info->ulMinPinLen); + p11_buffer_add (buf, temp, -1); + p11_buffer_add (buf, "\n\tulTotalPublicMemory: ", -1); + log_token_number (buf, info->ulMaxSessionCount); + p11_buffer_add (buf, "\n\tulFreePublicMemory: ", -1); + log_token_number (buf, info->ulMaxSessionCount); + p11_buffer_add (buf, "\n\tulTotalPrivateMemory: ", -1); + log_token_number (buf, info->ulMaxSessionCount); + p11_buffer_add (buf, "\n\tulFreePrivateMemory: ", -1); + log_token_number (buf, info->ulMaxSessionCount); + p11_buffer_add (buf, "\n\tulFreePrivateMemory: ", -1); + log_token_number (buf, info->ulMaxSessionCount); + p11_buffer_add (buf, "\n\thardwareVersion: ", -1); + snprintf (temp, sizeof (temp), "%u.%u", (unsigned int)info->hardwareVersion.major, + (unsigned int)info->hardwareVersion.minor); + p11_buffer_add (buf, temp, -1); + p11_buffer_add (buf, "\n\tfirmwareVersion: ", -1); + snprintf (temp, sizeof (temp), "%u.%u", (unsigned int)info->firmwareVersion.major, + (unsigned int)info->firmwareVersion.minor); + p11_buffer_add (buf, temp, -1); + p11_buffer_add (buf, "\n\tutcTime: ", -1); + p11_buffer_add (buf, (info->flags & CKF_CLOCK_ON_TOKEN) ? (const char*)info->utcTime : "", -1); + p11_buffer_add (buf, "\n }\n", -1); + } +} + +static void +log_ulong (p11_buffer *buf, + const char *pref, + const char *name, + CK_ULONG val, + const char* npref, + CK_RV status) +{ + char temp[32]; + + if (!npref) + npref = ""; + if (status == CKR_OK) { + p11_buffer_add (buf, pref, -1); + p11_buffer_add (buf, name, -1); + p11_buffer_add (buf, " = ", 3); + p11_buffer_add (buf, npref, -1); + snprintf (temp, sizeof (temp), "%lu", val); + p11_buffer_add (buf, temp, -1); + p11_buffer_add (buf, "\n", 1); + } +} + +static void +log_ulong_array (p11_buffer *buf, + const char *pref, + const char *name, + CK_ULONG_PTR arr, + CK_ULONG_PTR num, + const char *npref, + CK_RV status) +{ + char temp[32]; + CK_ULONG i; + + if (status == CKR_BUFFER_TOO_SMALL) { + arr = NULL; + status = CKR_OK; + } + + if (status != CKR_OK) + return; + if (npref == NULL) + npref = ""; + p11_buffer_add (buf, pref, -1); + p11_buffer_add (buf, name, -1); + p11_buffer_add (buf, " = ", 3); + if (num == NULL) { + p11_buffer_add (buf, "(?) NO-VALUES\n", -1); + } else if (arr == NULL) { + snprintf (temp, sizeof (temp), "(%lu) NO-VALUES\n", *num); + p11_buffer_add (buf, temp, -1); + } else { + snprintf (temp, sizeof (temp), "(%lu) [ ", *num); + p11_buffer_add (buf, temp, -1); + for (i = 0; i < *num; ++i) { + if (i > 0) + p11_buffer_add (buf, ", ", 2); + p11_buffer_add (buf, npref, -1); + snprintf (temp, sizeof (temp), "%lu", arr[i]); + p11_buffer_add (buf, temp, -1); + } + p11_buffer_add (buf, " ]\n", 3); + } +} + +static void +log_ulong_pointer (p11_buffer *buf, + const char *pref, + const char *name, + CK_ULONG_PTR val, + const char *npref, + CK_RV status) +{ + char temp[32]; + + if (status != CKR_OK) + return; + if (npref == NULL) + npref = ""; + p11_buffer_add (buf, pref, -1); + p11_buffer_add (buf, name, -1); + p11_buffer_add (buf, " = ", 3); + if (val == NULL) { + p11_buffer_add (buf, "NULL\n", 5); + } else { + snprintf (temp, sizeof (temp), "0x%08lX", (unsigned long)(size_t)val); + p11_buffer_add (buf, temp, -1); + p11_buffer_add (buf, " = ", 3); + p11_buffer_add (buf, npref, -1); + snprintf (temp, sizeof (temp), "%lu", *val); + p11_buffer_add (buf, temp, -1); + p11_buffer_add (buf, "\n", 1); + } +} + +static void +log_user_type (p11_buffer *buf, + const char *pref, + const char *name, + CK_USER_TYPE val, + CK_RV status) +{ + if (status != CKR_OK) + return; + p11_buffer_add (buf, pref, -1); + p11_buffer_add (buf, name, -1); + p11_buffer_add (buf, " = ", 3); + log_CKU (buf, val); + p11_buffer_add (buf, "\n", 1); +} + +static void +flush_buffer (p11_buffer *buf) +{ + if (p11_log_output) { + fwrite (buf->data, 1, buf->len, stderr); + fflush (stderr); + } + p11_buffer_reset (buf, 128); +} + +#define BEGIN_CALL(name) \ + { \ + LogData *_log = (LogData *)self; \ + const char* _name = "C_" #name; \ + p11_buffer _buf; \ + CK_X_##name _func = _log->lower->C_##name; \ + CK_RV _ret = CKR_OK; \ + p11_buffer_init_null (&_buf, 128); \ + return_val_if_fail (_func != NULL, CKR_DEVICE_ERROR); \ + p11_buffer_add (&_buf, _name, -1); \ + p11_buffer_add (&_buf, "\n", 1); \ + self = _log->lower; + +#define PROCESS_CALL(args) \ + flush_buffer (&_buf); \ + _ret = (_func) args; + +#define DONE_CALL \ + p11_buffer_add (&_buf, _name, -1); \ + p11_buffer_add (&_buf, " = ", 3); \ + log_CKR (&_buf, _ret); \ + p11_buffer_add (&_buf, "\n", 1); \ + flush_buffer (&_buf); \ + p11_buffer_uninit (&_buf); \ + return _ret; \ + } + +#define LIN " IN: " +#define LOUT " OUT: " + +#define IN_ATTRIBUTE_ARRAY(a, n) \ + log_attribute_types (&_buf, LIN, #a, a, n, CKR_OK); + +#define IN_BOOL(a) \ + log_bool (&_buf, LIN, #a, a, CKR_OK); + +#define IN_BYTE_ARRAY(a, n) \ + log_byte_array (&_buf, LIN, #a, a, &n, CKR_OK); + +#define IN_HANDLE(a) \ + log_ulong (&_buf, LIN, #a, a, "H", CKR_OK); + +#define IN_INIT_ARGS(a) \ + log_pInitArgs (&_buf, LIN, #a, a, CKR_OK); + +#define IN_POINTER(a) \ + log_pointer (&_buf, LIN, #a, a, CKR_OK); + +#define IN_MECHANISM(a) \ + log_mechanism (&_buf, LIN, #a, a, CKR_OK); + +#define IN_MECHANISM_TYPE(a) \ + log_mechanism_type (&_buf, LIN, #a, a, CKR_OK); + +#define IN_SESSION(a) \ + log_ulong (&_buf, LIN, #a, a, "S", CKR_OK); + +#define IN_SLOT_ID(a) \ + log_ulong (&_buf, LIN, #a, a, "SL", CKR_OK); + +#define IN_STRING(a) \ + log_string (&_buf, LIN, #a, a, CKR_OK); + +#define IN_ULONG(a) \ + log_ulong (&_buf, LIN, #a, a, NULL, CKR_OK); + +#define IN_ULONG_PTR(a) \ + log_ulong_pointer (&_buf, LIN, #a, a, NULL, CKR_OK); + +#define IN_USER_TYPE(a) \ + log_user_type (&_buf, LIN, #a, a, CKR_OK); + +#define OUT_ATTRIBUTE_ARRAY(a, n) \ + log_attribute_array (&_buf, LOUT, #a, a, n, _ret); + +#define OUT_BYTE_ARRAY(a, n) \ + log_byte_array(&_buf, LOUT, #a, a, n, _ret); + +#define OUT_HANDLE(a) \ + log_ulong_pointer (&_buf, LOUT, #a, a, "H", _ret); + +#define OUT_HANDLE_ARRAY(a, n) \ + log_ulong_array (&_buf, LOUT, #a, a, n, "H", _ret); + +#define OUT_INFO(a) \ + log_info (&_buf, LOUT, #a, a, _ret); + +#define OUT_MECHANISM_INFO(a) \ + log_mechanism_info (&_buf, LOUT, #a, a, _ret); + +#define OUT_MECHANISM_TYPE_ARRAY(a, n) \ + log_mechanism_type_array (&_buf, LOUT, #a, a, n, _ret); + +#define OUT_POINTER(a) \ + log_pointer (&_buf, LOUT, #a, a, _ret); + +#define OUT_SESSION(a) \ + log_ulong_pointer (&_buf, LOUT, #a, a, "S", _ret); + +#define OUT_SESSION_INFO(a) \ + log_session_info (&_buf, LOUT, #a, a, _ret); + +#define OUT_SLOT_ID_ARRAY(a, n) \ + log_ulong_array (&_buf, LOUT, #a, a, n, "SL", _ret); + +#define OUT_SLOT_ID(a) \ + log_ulong_pointer (&_buf, LOUT, #a, a, "SL", _ret); + +#define OUT_SLOT_INFO(a) \ + log_slot_info (&_buf, LOUT, #a, a, _ret); + +#define OUT_TOKEN_INFO(a) \ + log_token_info (&_buf, LOUT, #a, a, _ret); + +#define OUT_ULONG(a) \ + log_ulong_pointer (&_buf, LOUT, #a, a, NULL, _ret); + +#define OUT_ULONG_ARRAY(a, n) \ + log_ulong_array (&_buf, LOUT, #a, a, n, NULL, _ret); + + + +/* ---------------------------------------------------------------- */ + +static CK_RV +log_C_Initialize (CK_X_FUNCTION_LIST *self, + CK_VOID_PTR pInitArgs) +{ + BEGIN_CALL (Initialize) + IN_INIT_ARGS (pInitArgs) + PROCESS_CALL ((self, pInitArgs)) + DONE_CALL +} + +static CK_RV +log_C_Finalize (CK_X_FUNCTION_LIST *self, + CK_VOID_PTR pReserved) +{ + BEGIN_CALL (Finalize) + IN_POINTER (pReserved) + PROCESS_CALL ((self, pReserved)) + DONE_CALL +} + +static CK_RV +log_C_GetInfo (CK_X_FUNCTION_LIST *self, + CK_INFO_PTR pInfo) +{ + BEGIN_CALL (GetInfo) + PROCESS_CALL ((self, pInfo)) + OUT_INFO (pInfo) + DONE_CALL +} + +static CK_RV +log_C_GetSlotList (CK_X_FUNCTION_LIST *self, + CK_BBOOL tokenPresent, + CK_SLOT_ID_PTR pSlotList, + CK_ULONG_PTR pulCount) +{ + BEGIN_CALL (GetSlotList) + IN_BOOL (tokenPresent) + IN_ULONG_PTR (pulCount) + PROCESS_CALL ((self, tokenPresent, pSlotList, pulCount)) + OUT_SLOT_ID_ARRAY (pSlotList, pulCount) + DONE_CALL +} + +static CK_RV +log_C_GetSlotInfo (CK_X_FUNCTION_LIST *self, + CK_SLOT_ID slotID, + CK_SLOT_INFO_PTR pInfo) +{ + BEGIN_CALL (GetSlotInfo) + IN_SLOT_ID (slotID) + PROCESS_CALL ((self, slotID, pInfo)) + OUT_SLOT_INFO (pInfo) + DONE_CALL +} + +static CK_RV +log_C_GetTokenInfo (CK_X_FUNCTION_LIST *self, + CK_SLOT_ID slotID, + CK_TOKEN_INFO_PTR pInfo) +{ + BEGIN_CALL (GetTokenInfo) + IN_SLOT_ID (slotID) + PROCESS_CALL ((self, slotID, pInfo)) + OUT_TOKEN_INFO (pInfo) + DONE_CALL +} + +static CK_RV +log_C_GetMechanismList (CK_X_FUNCTION_LIST *self, + CK_SLOT_ID slotID, + CK_MECHANISM_TYPE_PTR pMechanismList, + CK_ULONG_PTR pulCount) +{ + BEGIN_CALL (GetMechanismList) + IN_SLOT_ID (slotID) + IN_ULONG_PTR (pulCount) + PROCESS_CALL ((self, slotID, pMechanismList, pulCount)) + OUT_MECHANISM_TYPE_ARRAY (pMechanismList, pulCount) + DONE_CALL +} + +static CK_RV +log_C_GetMechanismInfo (CK_X_FUNCTION_LIST *self, + CK_SLOT_ID slotID, + CK_MECHANISM_TYPE type, + CK_MECHANISM_INFO_PTR pInfo) +{ + BEGIN_CALL (GetMechanismInfo) + IN_SLOT_ID (slotID) + IN_MECHANISM_TYPE (type) + PROCESS_CALL ((self, slotID, type, pInfo)) + OUT_MECHANISM_INFO (pInfo) + DONE_CALL +} + +static CK_RV +log_C_InitToken (CK_X_FUNCTION_LIST *self, + CK_SLOT_ID slotID, + CK_UTF8CHAR_PTR pPin, + CK_ULONG ulPinLen, + CK_UTF8CHAR_PTR pLabel) +{ + BEGIN_CALL (InitToken) + IN_SLOT_ID (slotID) + IN_BYTE_ARRAY (pPin, ulPinLen) + IN_STRING (pLabel) + PROCESS_CALL ((self, slotID, pPin, ulPinLen, pLabel)) + DONE_CALL +} + +static CK_RV +log_C_WaitForSlotEvent (CK_X_FUNCTION_LIST *self, + CK_FLAGS flags, + CK_SLOT_ID_PTR pSlot, + CK_VOID_PTR pReserved) +{ + char temp[32]; + int had = 0; + + BEGIN_CALL (WaitForSlotEvent) + p11_buffer_add (&_buf, " IN: flags = ", -1); + snprintf (temp, sizeof (temp), "%lu", flags); + p11_buffer_add (&_buf, temp, -1); + LOG_FLAG (&_buf, flags, had, CKF_DONT_BLOCK); + p11_buffer_add (&_buf, "\n", 1); + PROCESS_CALL ((self, flags, pSlot, pReserved)) + OUT_SLOT_ID (pSlot) + OUT_POINTER (pReserved) + DONE_CALL +} + +static CK_RV +log_C_OpenSession (CK_X_FUNCTION_LIST *self, + CK_SLOT_ID slotID, + CK_FLAGS flags, + CK_VOID_PTR pApplication, + CK_NOTIFY Notify, + CK_SESSION_HANDLE_PTR phSession) +{ + char temp[32]; + int had = 0; + + BEGIN_CALL (OpenSession) + IN_SLOT_ID (slotID) + p11_buffer_add (&_buf, " IN: flags = ", -1); + snprintf (temp, sizeof (temp), "%lu", flags); + p11_buffer_add (&_buf, temp, -1); + LOG_FLAG (&_buf, flags, had, CKF_SERIAL_SESSION); + LOG_FLAG (&_buf, flags, had, CKF_RW_SESSION); + p11_buffer_add (&_buf, "\n", 1); + IN_POINTER (pApplication); + IN_POINTER (Notify); + PROCESS_CALL ((self, slotID, flags, pApplication, Notify, phSession)); + OUT_SESSION (phSession) + DONE_CALL +} + +static CK_RV +log_C_CloseSession (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE hSession) +{ + BEGIN_CALL (CloseSession) + IN_SESSION (hSession) + PROCESS_CALL ((self, hSession)) + DONE_CALL +} + +static CK_RV +log_C_CloseAllSessions (CK_X_FUNCTION_LIST *self, + CK_SLOT_ID slotID) +{ + BEGIN_CALL (CloseAllSessions) + IN_SLOT_ID (slotID) + PROCESS_CALL ((self, slotID)) + DONE_CALL +} + +static CK_RV +log_C_GetSessionInfo (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE hSession, + CK_SESSION_INFO_PTR pInfo) +{ + BEGIN_CALL (GetSessionInfo) + IN_SESSION (hSession) + PROCESS_CALL ((self, hSession, pInfo)) + OUT_SESSION_INFO (pInfo) + DONE_CALL +} + +static CK_RV +log_C_InitPIN (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE hSession, + CK_UTF8CHAR_PTR pPin, + CK_ULONG ulPinLen) +{ + BEGIN_CALL (InitPIN) + IN_SESSION (hSession) + IN_BYTE_ARRAY (pPin, ulPinLen) + PROCESS_CALL ((self, hSession, pPin, ulPinLen)) + DONE_CALL +} + +static CK_RV +log_C_SetPIN (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE hSession, + CK_UTF8CHAR_PTR pOldPin, + CK_ULONG ulOldLen, + CK_UTF8CHAR_PTR pNewPin, + CK_ULONG ulNewLen) +{ + BEGIN_CALL (SetPIN) + IN_SESSION (hSession) + IN_BYTE_ARRAY (pOldPin, ulOldLen) + IN_BYTE_ARRAY (pNewPin, ulNewLen); + PROCESS_CALL ((self, hSession, pOldPin, ulOldLen, pNewPin, ulNewLen)) + DONE_CALL +} + +static CK_RV +log_C_GetOperationState (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE hSession, + CK_BYTE_PTR pOperationState, + CK_ULONG_PTR pulOperationStateLen) +{ + BEGIN_CALL (GetOperationState) + IN_SESSION (hSession) + IN_ULONG_PTR (pulOperationStateLen) + PROCESS_CALL ((self, hSession, pOperationState, pulOperationStateLen)) + OUT_BYTE_ARRAY (pOperationState, pulOperationStateLen) + DONE_CALL +} + +static CK_RV +log_C_SetOperationState (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE hSession, + CK_BYTE_PTR pOperationState, + CK_ULONG ulOperationStateLen, + CK_OBJECT_HANDLE hEncryptionKey, + CK_OBJECT_HANDLE hAuthenticationKey) +{ + BEGIN_CALL (SetOperationState) + IN_SESSION (hSession) + IN_BYTE_ARRAY (pOperationState, ulOperationStateLen) + IN_HANDLE (hEncryptionKey) + IN_HANDLE (hAuthenticationKey) + PROCESS_CALL ((self, hSession, pOperationState, ulOperationStateLen, hEncryptionKey, hAuthenticationKey)) + DONE_CALL +} + +static CK_RV +log_C_Login (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE hSession, + CK_USER_TYPE userType, + CK_UTF8CHAR_PTR pPin, + CK_ULONG ulPinLen) +{ + BEGIN_CALL (Login) + IN_SESSION (hSession) + IN_USER_TYPE (userType) + IN_BYTE_ARRAY (pPin, ulPinLen); + PROCESS_CALL ((self, hSession, userType, pPin, ulPinLen)) + DONE_CALL +} + +static CK_RV +log_C_Logout (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE hSession) +{ + BEGIN_CALL (Logout) + IN_SESSION (hSession) + PROCESS_CALL ((self, hSession)) + DONE_CALL +} + +static CK_RV +log_C_CreateObject (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE hSession, + CK_ATTRIBUTE_PTR pTemplate, + CK_ULONG ulCount, + CK_OBJECT_HANDLE_PTR phObject) +{ + BEGIN_CALL (CreateObject) + IN_SESSION (hSession) + IN_ATTRIBUTE_ARRAY (pTemplate, ulCount) + PROCESS_CALL ((self, hSession, pTemplate, ulCount, phObject)) + OUT_HANDLE (phObject) + DONE_CALL +} + +static CK_RV +log_C_CopyObject (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE hSession, + CK_OBJECT_HANDLE hObject, + CK_ATTRIBUTE_PTR pTemplate, + CK_ULONG ulCount, + CK_OBJECT_HANDLE_PTR phNewObject) +{ + BEGIN_CALL (CopyObject) + IN_SESSION (hSession) + IN_HANDLE (hObject) + IN_ATTRIBUTE_ARRAY (pTemplate, ulCount) + PROCESS_CALL ((self, hSession, hObject, pTemplate, ulCount, phNewObject)) + OUT_HANDLE (phNewObject) + DONE_CALL +} + + +static CK_RV +log_C_DestroyObject (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE hSession, + CK_OBJECT_HANDLE hObject) +{ + BEGIN_CALL (DestroyObject); + IN_SESSION (hSession) + IN_HANDLE (hObject) + PROCESS_CALL ((self, hSession, hObject)) + DONE_CALL +} + +static CK_RV +log_C_GetObjectSize (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE hSession, + CK_OBJECT_HANDLE hObject, + CK_ULONG_PTR size) +{ + BEGIN_CALL (GetObjectSize); + IN_SESSION (hSession) + IN_HANDLE (hObject) + PROCESS_CALL ((self, hSession, hObject, size)) + OUT_ULONG (size) + DONE_CALL +} + +static CK_RV +log_C_GetAttributeValue (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE hSession, + CK_OBJECT_HANDLE hObject, + CK_ATTRIBUTE_PTR pTemplate, + CK_ULONG ulCount) +{ + BEGIN_CALL (GetAttributeValue) + IN_SESSION (hSession) + IN_HANDLE (hObject) + IN_ATTRIBUTE_ARRAY (pTemplate, ulCount) + PROCESS_CALL ((self, hSession, hObject, pTemplate, ulCount)) + OUT_ATTRIBUTE_ARRAY (pTemplate, ulCount) + DONE_CALL +} + +static CK_RV +log_C_SetAttributeValue (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE hSession, + CK_OBJECT_HANDLE hObject, + CK_ATTRIBUTE_PTR pTemplate, + CK_ULONG ulCount) +{ + BEGIN_CALL (SetAttributeValue) + IN_SESSION (hSession) + IN_HANDLE (hObject) + IN_ATTRIBUTE_ARRAY (pTemplate, ulCount) + PROCESS_CALL ((self, hSession, hObject, pTemplate, ulCount)) + DONE_CALL +} + +static CK_RV +log_C_FindObjectsInit (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE hSession, + CK_ATTRIBUTE_PTR pTemplate, + CK_ULONG ulCount) +{ + BEGIN_CALL (FindObjectsInit) + IN_SESSION (hSession) + IN_ATTRIBUTE_ARRAY (pTemplate, ulCount) + PROCESS_CALL ((self, hSession, pTemplate, ulCount)) + DONE_CALL +} + +static CK_RV +log_C_FindObjects (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE hSession, + CK_OBJECT_HANDLE_PTR object, + CK_ULONG max_object_count, + CK_ULONG_PTR object_count) +{ + BEGIN_CALL (FindObjects) + IN_SESSION (hSession) + IN_ULONG (max_object_count) + PROCESS_CALL ((self, hSession, object, max_object_count, object_count)) + OUT_HANDLE_ARRAY (object, object_count) + DONE_CALL +} + +static CK_RV +log_C_FindObjectsFinal (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE hSession) +{ + BEGIN_CALL (FindObjectsFinal) + IN_SESSION (hSession) + PROCESS_CALL ((self, hSession)) + DONE_CALL +} + +static CK_RV +log_C_EncryptInit (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE hSession, + CK_MECHANISM_PTR pMechanism, + CK_OBJECT_HANDLE hKey) +{ + BEGIN_CALL (EncryptInit) + IN_SESSION (hSession) + IN_MECHANISM (pMechanism) + IN_HANDLE (hKey) + PROCESS_CALL ((self, hSession, pMechanism, hKey)) + DONE_CALL +} + +static CK_RV +log_C_Encrypt (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE hSession, + CK_BYTE_PTR pData, + CK_ULONG ulDataLen, + CK_BYTE_PTR pEncryptedData, + CK_ULONG_PTR pulEncryptedDataLen) +{ + BEGIN_CALL (Encrypt) + IN_SESSION (hSession) + IN_BYTE_ARRAY (pData, ulDataLen) + PROCESS_CALL ((self, hSession, pData, ulDataLen, pEncryptedData, pulEncryptedDataLen)) + OUT_BYTE_ARRAY (pEncryptedData, pulEncryptedDataLen) + DONE_CALL +} + +static CK_RV +log_C_EncryptUpdate (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE hSession, + CK_BYTE_PTR pPart, + CK_ULONG ulPartLen, + CK_BYTE_PTR pEncryptedPart, + CK_ULONG_PTR pulEncryptedPartLen) +{ + BEGIN_CALL (EncryptUpdate) + IN_SESSION (hSession) + IN_BYTE_ARRAY (pPart, ulPartLen) + PROCESS_CALL ((self, hSession, pPart, ulPartLen, pEncryptedPart, pulEncryptedPartLen)) + OUT_BYTE_ARRAY (pEncryptedPart, pulEncryptedPartLen) + DONE_CALL +} + +static CK_RV +log_C_EncryptFinal (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE hSession, + CK_BYTE_PTR pLastEncryptedPart, + CK_ULONG_PTR pulLastEncryptedPartLen) +{ + BEGIN_CALL (EncryptFinal) + IN_SESSION (hSession) + PROCESS_CALL ((self, hSession, pLastEncryptedPart, pulLastEncryptedPartLen)) + OUT_BYTE_ARRAY (pLastEncryptedPart, pulLastEncryptedPartLen) + DONE_CALL +} + +static CK_RV +log_C_DecryptInit (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE hSession, + CK_MECHANISM_PTR pMechanism, + CK_OBJECT_HANDLE hKey) +{ + BEGIN_CALL (DecryptInit) + IN_SESSION (hSession) + IN_MECHANISM (pMechanism) + IN_HANDLE (hKey) + PROCESS_CALL ((self, hSession, pMechanism, hKey)) + DONE_CALL +} + +static CK_RV +log_C_Decrypt (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE hSession, + CK_BYTE_PTR pEncryptedData, + CK_ULONG ulEncryptedDataLen, + CK_BYTE_PTR pData, + CK_ULONG_PTR pulDataLen) +{ + BEGIN_CALL (Decrypt) + IN_SESSION (hSession) + IN_BYTE_ARRAY (pEncryptedData, ulEncryptedDataLen) + PROCESS_CALL ((self, hSession, pEncryptedData, ulEncryptedDataLen, pData, pulDataLen)) + OUT_BYTE_ARRAY (pData, pulDataLen) + DONE_CALL +} + +static CK_RV +log_C_DecryptUpdate (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE hSession, + CK_BYTE_PTR pEncryptedPart, + CK_ULONG ulEncryptedPartLen, + CK_BYTE_PTR pPart, + CK_ULONG_PTR pulPartLen) +{ + BEGIN_CALL (DecryptUpdate) + IN_SESSION (hSession) + IN_BYTE_ARRAY (pEncryptedPart, ulEncryptedPartLen) + PROCESS_CALL ((self, hSession, pEncryptedPart, ulEncryptedPartLen, pPart, pulPartLen)) + OUT_BYTE_ARRAY (pPart, pulPartLen) + DONE_CALL +} + +static CK_RV +log_C_DecryptFinal (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE hSession, + CK_BYTE_PTR pLastPart, + CK_ULONG_PTR pulLastPartLen) +{ + BEGIN_CALL (DecryptFinal) + IN_SESSION (hSession) + PROCESS_CALL ((self, hSession, pLastPart, pulLastPartLen)) + OUT_BYTE_ARRAY (pLastPart, pulLastPartLen) + DONE_CALL +} + +static CK_RV +log_C_DigestInit (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE hSession, + CK_MECHANISM_PTR pMechanism) +{ + BEGIN_CALL (DigestInit) + IN_SESSION (hSession) + IN_MECHANISM (pMechanism) + PROCESS_CALL ((self, hSession, pMechanism)) + DONE_CALL +} + +static CK_RV +log_C_Digest (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE hSession, + CK_BYTE_PTR pData, + CK_ULONG ulDataLen, + CK_BYTE_PTR pDigest, + CK_ULONG_PTR pulDigestLen) +{ + BEGIN_CALL (Digest) + IN_SESSION (hSession) + IN_BYTE_ARRAY (pData, ulDataLen) + PROCESS_CALL ((self, hSession, pData, ulDataLen, pDigest, pulDigestLen)) + OUT_BYTE_ARRAY (pDigest, pulDigestLen) + DONE_CALL +} + +static CK_RV +log_C_DigestUpdate (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE hSession, + CK_BYTE_PTR pPart, + CK_ULONG ulPartLen) +{ + BEGIN_CALL (DigestUpdate) + IN_SESSION (hSession) + IN_BYTE_ARRAY (pPart, ulPartLen) + PROCESS_CALL ((self, hSession, pPart, ulPartLen)) + DONE_CALL +} + +static CK_RV +log_C_DigestKey (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE hSession, + CK_OBJECT_HANDLE hKey) +{ + BEGIN_CALL (DigestKey) + IN_SESSION (hSession) + IN_HANDLE (hKey) + PROCESS_CALL ((self, hSession, hKey)) + DONE_CALL +} + +static CK_RV +log_C_DigestFinal (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE hSession, + CK_BYTE_PTR pDigest, + CK_ULONG_PTR pulDigestLen) +{ + BEGIN_CALL (DigestFinal) + IN_SESSION (hSession) + PROCESS_CALL ((self, hSession, pDigest, pulDigestLen)) + OUT_BYTE_ARRAY (pDigest, pulDigestLen) + DONE_CALL +} + +static CK_RV +log_C_SignInit (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE hSession, + CK_MECHANISM_PTR pMechanism, + CK_OBJECT_HANDLE hKey) +{ + BEGIN_CALL (SignInit) + IN_SESSION (hSession) + IN_MECHANISM (pMechanism) + IN_HANDLE (hKey) + PROCESS_CALL ((self, hSession, pMechanism, hKey)) + DONE_CALL +} + +static CK_RV +log_C_Sign (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE hSession, + CK_BYTE_PTR pData, + CK_ULONG ulDataLen, + CK_BYTE_PTR pSignature, + CK_ULONG_PTR pulSignatureLen) +{ + BEGIN_CALL (Sign) + IN_SESSION (hSession) + IN_BYTE_ARRAY (pData, ulDataLen) + PROCESS_CALL ((self, hSession, pData, ulDataLen, pSignature, pulSignatureLen)) + OUT_BYTE_ARRAY (pSignature, pulSignatureLen) + DONE_CALL +} + +static CK_RV +log_C_SignUpdate (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE hSession, + CK_BYTE_PTR pPart, + CK_ULONG ulPartLen) +{ + BEGIN_CALL (SignUpdate) + IN_SESSION (hSession) + IN_BYTE_ARRAY (pPart, ulPartLen) + PROCESS_CALL ((self, hSession, pPart, ulPartLen)) + DONE_CALL +} + +static CK_RV +log_C_SignFinal (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE hSession, + CK_BYTE_PTR pSignature, + CK_ULONG_PTR pulSignatureLen) +{ + BEGIN_CALL (SignFinal) + IN_SESSION (hSession) + PROCESS_CALL ((self, hSession, pSignature, pulSignatureLen)) + OUT_BYTE_ARRAY (pSignature, pulSignatureLen) + DONE_CALL +} + +static CK_RV +log_C_SignRecoverInit (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE hSession, + CK_MECHANISM_PTR pMechanism, + CK_OBJECT_HANDLE hKey) +{ + BEGIN_CALL (SignRecoverInit) + IN_SESSION (hSession) + IN_MECHANISM (pMechanism) + IN_HANDLE (hKey) + PROCESS_CALL ((self, hSession, pMechanism, hKey)) + DONE_CALL +} + +static CK_RV +log_C_SignRecover (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE hSession, + CK_BYTE_PTR pData, + CK_ULONG ulDataLen, + CK_BYTE_PTR pSignature, + CK_ULONG_PTR pulSignatureLen) +{ + BEGIN_CALL (SignRecover) + IN_SESSION (hSession) + IN_BYTE_ARRAY (pData, ulDataLen) + PROCESS_CALL ((self, hSession, pData, ulDataLen, pSignature, pulSignatureLen)) + OUT_BYTE_ARRAY (pSignature, pulSignatureLen) + DONE_CALL +} + +static CK_RV +log_C_VerifyInit (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE hSession, + CK_MECHANISM_PTR pMechanism, + CK_OBJECT_HANDLE hKey) +{ + BEGIN_CALL (VerifyInit); + IN_SESSION (hSession) + IN_MECHANISM (pMechanism) + IN_HANDLE (hKey) + PROCESS_CALL ((self, hSession, pMechanism, hKey)) + DONE_CALL +} + +static CK_RV +log_C_Verify (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE hSession, + CK_BYTE_PTR pData, + CK_ULONG ulDataLen, + CK_BYTE_PTR pSignature, + CK_ULONG ulSignatureLen) +{ + BEGIN_CALL (Verify) + IN_SESSION (hSession) + IN_BYTE_ARRAY (pData, ulDataLen) + IN_BYTE_ARRAY (pSignature, ulSignatureLen) + PROCESS_CALL ((self, hSession, pData, ulDataLen, pSignature, ulSignatureLen)) + DONE_CALL +} + +static CK_RV +log_C_VerifyUpdate (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE hSession, + CK_BYTE_PTR pPart, + CK_ULONG ulPartLen) +{ + BEGIN_CALL (VerifyUpdate) + IN_SESSION (hSession) + IN_BYTE_ARRAY (pPart, ulPartLen) + PROCESS_CALL ((self, hSession, pPart, ulPartLen)) + DONE_CALL +} + +static CK_RV +log_C_VerifyFinal (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE hSession, + CK_BYTE_PTR pSignature, + CK_ULONG ulSignatureLen) +{ + BEGIN_CALL (VerifyFinal) + IN_SESSION (hSession) + IN_BYTE_ARRAY (pSignature, ulSignatureLen); + PROCESS_CALL ((self, hSession, pSignature, ulSignatureLen)) + DONE_CALL +} + +static CK_RV +log_C_VerifyRecoverInit (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE hSession, + CK_MECHANISM_PTR pMechanism, + CK_OBJECT_HANDLE hKey) +{ + BEGIN_CALL (VerifyRecoverInit) + IN_SESSION (hSession) + IN_MECHANISM (pMechanism) + IN_HANDLE (hKey) + PROCESS_CALL ((self, hSession, pMechanism, hKey)) + DONE_CALL +} + +static CK_RV +log_C_VerifyRecover (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE hSession, + CK_BYTE_PTR pSignature, + CK_ULONG ulSignatureLen, + CK_BYTE_PTR pData, + CK_ULONG_PTR pulDataLen) +{ + BEGIN_CALL (VerifyRecover) + IN_SESSION (hSession) + IN_BYTE_ARRAY (pSignature, ulSignatureLen) + PROCESS_CALL ((self, hSession, pSignature, ulSignatureLen, pData, pulDataLen)) + OUT_BYTE_ARRAY (pData, pulDataLen) + DONE_CALL +} + +static CK_RV +log_C_DigestEncryptUpdate (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE hSession, + CK_BYTE_PTR pPart, + CK_ULONG ulPartLen, + CK_BYTE_PTR pEncryptedPart, + CK_ULONG_PTR pulEncryptedPartLen) +{ + BEGIN_CALL (DigestEncryptUpdate); + IN_SESSION (hSession) + IN_BYTE_ARRAY (pPart, ulPartLen) + PROCESS_CALL ((self, hSession, pPart, ulPartLen, pEncryptedPart, pulEncryptedPartLen)) + OUT_BYTE_ARRAY (pEncryptedPart, pulEncryptedPartLen) + DONE_CALL +} + +static CK_RV +log_C_DecryptDigestUpdate (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE hSession, + CK_BYTE_PTR pEncryptedPart, + CK_ULONG ulEncryptedPartLen, + CK_BYTE_PTR pPart, + CK_ULONG_PTR pulPartLen) +{ + BEGIN_CALL (DecryptDigestUpdate) + IN_SESSION (hSession) + IN_BYTE_ARRAY (pEncryptedPart, ulEncryptedPartLen) + PROCESS_CALL ((self, hSession, pEncryptedPart, ulEncryptedPartLen, pPart, pulPartLen)) + OUT_BYTE_ARRAY (pPart, pulPartLen) + DONE_CALL +} + +static CK_RV +log_C_SignEncryptUpdate (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE hSession, + CK_BYTE_PTR pPart, + CK_ULONG ulPartLen, + CK_BYTE_PTR pEncryptedPart, + CK_ULONG_PTR pulEncryptedPartLen) +{ + BEGIN_CALL (SignEncryptUpdate) + IN_SESSION (hSession) + IN_BYTE_ARRAY (pPart, ulPartLen) + PROCESS_CALL ((self, hSession, pPart, ulPartLen, pEncryptedPart, pulEncryptedPartLen)) + OUT_BYTE_ARRAY (pEncryptedPart, pulEncryptedPartLen) + DONE_CALL +} + +static CK_RV +log_C_DecryptVerifyUpdate (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE hSession, + CK_BYTE_PTR pEncryptedPart, + CK_ULONG ulEncryptedPartLen, + CK_BYTE_PTR pPart, + CK_ULONG_PTR pulPartLen) +{ + BEGIN_CALL (DecryptVerifyUpdate) + IN_SESSION (hSession) + IN_BYTE_ARRAY (pEncryptedPart, ulEncryptedPartLen) + PROCESS_CALL ((self, hSession, pEncryptedPart, ulEncryptedPartLen, pPart, pulPartLen)) + OUT_BYTE_ARRAY (pPart, pulPartLen) + DONE_CALL +} + +static CK_RV +log_C_GenerateKey (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE hSession, + CK_MECHANISM_PTR pMechanism, + CK_ATTRIBUTE_PTR pTemplate, + CK_ULONG ulCount, + CK_OBJECT_HANDLE_PTR phKey) +{ + BEGIN_CALL (GenerateKey) + IN_SESSION (hSession) + IN_MECHANISM (pMechanism) + IN_ATTRIBUTE_ARRAY (pTemplate, ulCount) + PROCESS_CALL ((self, hSession, pMechanism, pTemplate, ulCount, phKey)) + OUT_HANDLE (phKey) + DONE_CALL +} + +static CK_RV +log_C_GenerateKeyPair (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE hSession, + CK_MECHANISM_PTR pMechanism, + CK_ATTRIBUTE_PTR pPublicKeyTemplate, + CK_ULONG ulPublicKeyAttributeCount, + CK_ATTRIBUTE_PTR pPrivateKeyTemplate, + CK_ULONG ulPrivateKeyAttributeCount, + CK_OBJECT_HANDLE_PTR phPublicKey, + CK_OBJECT_HANDLE_PTR phPrivateKey) +{ + BEGIN_CALL (GenerateKeyPair) + IN_SESSION (hSession) + IN_MECHANISM (pMechanism) + IN_ATTRIBUTE_ARRAY (pPublicKeyTemplate, ulPublicKeyAttributeCount) + IN_ATTRIBUTE_ARRAY (pPrivateKeyTemplate, ulPrivateKeyAttributeCount) + PROCESS_CALL ((self, hSession, pMechanism, pPublicKeyTemplate, ulPublicKeyAttributeCount, + pPrivateKeyTemplate, ulPrivateKeyAttributeCount, phPublicKey, phPrivateKey)) + OUT_HANDLE (phPublicKey) + OUT_HANDLE (phPrivateKey) + DONE_CALL +} + +static CK_RV +log_C_WrapKey (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE hSession, + CK_MECHANISM_PTR pMechanism, + CK_OBJECT_HANDLE hWrappingKey, + CK_OBJECT_HANDLE hKey, + CK_BYTE_PTR pWrappedKey, + CK_ULONG_PTR pulWrappedKeyLen) +{ + BEGIN_CALL (WrapKey) + IN_SESSION (hSession) + IN_MECHANISM (pMechanism) + IN_HANDLE (hWrappingKey) + IN_HANDLE (hKey) + PROCESS_CALL ((self, hSession, pMechanism, hWrappingKey, hKey, pWrappedKey, pulWrappedKeyLen)) + OUT_BYTE_ARRAY (pWrappedKey, pulWrappedKeyLen) + DONE_CALL +} + +static CK_RV +log_C_UnwrapKey (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE hSession, + CK_MECHANISM_PTR pMechanism, + CK_OBJECT_HANDLE hUnwrappingKey, + CK_BYTE_PTR pWrappedKey, + CK_ULONG ulWrappedKeyLen, + CK_ATTRIBUTE_PTR pTemplate, + CK_ULONG ulAttributeCount, + CK_OBJECT_HANDLE_PTR phKey) +{ + BEGIN_CALL (UnwrapKey) + IN_SESSION (hSession) + IN_MECHANISM (pMechanism) + IN_HANDLE (hUnwrappingKey) + IN_BYTE_ARRAY (pWrappedKey, ulWrappedKeyLen) + IN_ATTRIBUTE_ARRAY (pTemplate, ulAttributeCount) + PROCESS_CALL ((self, hSession, pMechanism, hUnwrappingKey, pWrappedKey, + ulWrappedKeyLen, pTemplate, ulAttributeCount, phKey)) + OUT_HANDLE (phKey) + DONE_CALL +} + +static CK_RV +log_C_DeriveKey (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE hSession, + CK_MECHANISM_PTR pMechanism, + CK_OBJECT_HANDLE hBaseKey, + CK_ATTRIBUTE_PTR pTemplate, + CK_ULONG ulAttributeCount, + CK_OBJECT_HANDLE_PTR phObject) +{ + BEGIN_CALL (DeriveKey) + IN_SESSION (hSession) + IN_MECHANISM (pMechanism) + IN_HANDLE (hBaseKey) + IN_ATTRIBUTE_ARRAY (pTemplate, ulAttributeCount) + PROCESS_CALL ((self, hSession, pMechanism, hBaseKey, pTemplate, ulAttributeCount, phObject)) + OUT_HANDLE (phObject) + DONE_CALL +} + +static CK_RV +log_C_SeedRandom (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE hSession, + CK_BYTE_PTR pSeed, + CK_ULONG ulSeedLen) +{ + BEGIN_CALL (SeedRandom) + IN_SESSION (hSession) + IN_BYTE_ARRAY (pSeed, ulSeedLen); + PROCESS_CALL ((self, hSession, pSeed, ulSeedLen)) + DONE_CALL +} + +static CK_RV +log_C_GenerateRandom (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE hSession, + CK_BYTE_PTR pRandomData, + CK_ULONG ulRandomLen) +{ + BEGIN_CALL (GenerateRandom) + IN_SESSION (hSession) + IN_ULONG (ulRandomLen) + PROCESS_CALL ((self, hSession, pRandomData, ulRandomLen)) + OUT_BYTE_ARRAY (pRandomData, &ulRandomLen) + DONE_CALL +} + +static CK_X_FUNCTION_LIST log_functions = { + { -1, -1 }, + log_C_Initialize, + log_C_Finalize, + log_C_GetInfo, + log_C_GetSlotList, + log_C_GetSlotInfo, + log_C_GetTokenInfo, + log_C_GetMechanismList, + log_C_GetMechanismInfo, + log_C_InitToken, + log_C_InitPIN, + log_C_SetPIN, + log_C_OpenSession, + log_C_CloseSession, + log_C_CloseAllSessions, + log_C_GetSessionInfo, + log_C_GetOperationState, + log_C_SetOperationState, + log_C_Login, + log_C_Logout, + log_C_CreateObject, + log_C_CopyObject, + log_C_DestroyObject, + log_C_GetObjectSize, + log_C_GetAttributeValue, + log_C_SetAttributeValue, + log_C_FindObjectsInit, + log_C_FindObjects, + log_C_FindObjectsFinal, + log_C_EncryptInit, + log_C_Encrypt, + log_C_EncryptUpdate, + log_C_EncryptFinal, + log_C_DecryptInit, + log_C_Decrypt, + log_C_DecryptUpdate, + log_C_DecryptFinal, + log_C_DigestInit, + log_C_Digest, + log_C_DigestUpdate, + log_C_DigestKey, + log_C_DigestFinal, + log_C_SignInit, + log_C_Sign, + log_C_SignUpdate, + log_C_SignFinal, + log_C_SignRecoverInit, + log_C_SignRecover, + log_C_VerifyInit, + log_C_Verify, + log_C_VerifyUpdate, + log_C_VerifyFinal, + log_C_VerifyRecoverInit, + log_C_VerifyRecover, + log_C_DigestEncryptUpdate, + log_C_DecryptDigestUpdate, + log_C_SignEncryptUpdate, + log_C_DecryptVerifyUpdate, + log_C_GenerateKey, + log_C_GenerateKeyPair, + log_C_WrapKey, + log_C_UnwrapKey, + log_C_DeriveKey, + log_C_SeedRandom, + log_C_GenerateRandom, + log_C_WaitForSlotEvent, +}; + +void +p11_log_release (void *data) +{ + LogData *log = (LogData *)data; + + return_if_fail (data != NULL); + p11_virtual_uninit (&log->virt); + free (log); +} + +p11_virtual * +p11_log_subclass (p11_virtual *lower, + p11_destroyer destroyer) +{ + LogData *log; + + log = calloc (1, sizeof (LogData)); + return_val_if_fail (log != NULL, NULL); + + p11_virtual_init (&log->virt, &log_functions, lower, destroyer); + log->lower = &lower->funcs; + return &log->virt; +} diff --git a/p11-kit/log.h b/p11-kit/log.h new file mode 100644 index 0000000..d8169e8 --- /dev/null +++ b/p11-kit/log.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2013, Red Hat Inc. + * + * All rights reserved. + * + * 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. + * + * + * CONTRIBUTORS + * Stef Walter <stef@thewalter.net> + */ + +#ifndef P11_LOG_H_ +#define P11_LOG_H_ + +#include "virtual.h" + +p11_virtual * p11_log_subclass (p11_virtual *lower, + p11_destroyer destroyer); + +void p11_log_release (void *logger); + +extern bool p11_log_force; + +extern bool p11_log_output; + +#endif /* P11_LOG_H_ */ diff --git a/p11-kit/modules.c b/p11-kit/modules.c index 19ba895..ef8cea6 100644 --- a/p11-kit/modules.c +++ b/p11-kit/modules.c @@ -35,16 +35,23 @@ #include "config.h" -#include "conf.h" +/* We use and define deprecated functions here */ +#define P11_KIT_NO_DEPRECATIONS #define P11_DEBUG_FLAG P11_DEBUG_LIB + +#include "conf.h" #include "debug.h" #include "dict.h" #include "library.h" +#include "log.h" #include "message.h" +#include "modules.h" #include "path.h" #include "pkcs11.h" #include "p11-kit.h" #include "private.h" +#include "proxy.h" +#include "virtual.h" #include <sys/stat.h> #include <sys/types.h> @@ -70,44 +77,83 @@ * crypto objects (like keys and certificates) and to perform crypto operations. * * In order for applications to behave consistently with regard to the user's - * installed PKCS\#11 modules, each module must be registered so that applications + * installed PKCS\#11 modules, each module must be configured so that applications * or libraries know that they should load it. * - * The functions here provide support for initializing registered modules. The - * p11_kit_initialize_registered() function should be used to load and initialize - * the registered modules. When done, the p11_kit_finalize_registered() function + * When multiple consumers of a module (such as libraries or applications) are + * in the same process, coordination of the initialization and finalization + * of PKCS\#11 modules is required. To do this modules are managed by p11-kit. + * This means that various unsafe methods are coordinated between callers. Unmanaged + * modules are simply the raw PKCS\#11 module pointers without p11-kit getting in the + * way. It is highly recommended that the default managed behavior is used. + * + * The functions here provide support for initializing configured modules. The + * p11_kit_modules_load() function should be used to load and initialize + * the configured modules. When done, the p11_kit_modules_release() function * should be used to release those modules and associated resources. * - * In addition p11_kit_registered_option() can be used to access other parts + * In addition p11_kit_config_option() can be used to access other parts * of the module configuration. * - * When multiple consumers of a module (such as libraries or applications) are - * in the same process, coordination of the initialization and finalization - * of PKCS\#11 modules is required. The functions here automatically provide - * initialization reference counting to make this work. - * * If a consumer wishes to load an arbitrary PKCS\#11 module that's not - * registered, that module should be initialized with p11_kit_initialize_module() - * and finalized with p11_kit_finalize_module(). The module's own - * <code>C_Initialize</code> and <code>C_Finalize</code> methods should not - * be called directly. + * configured use p11_kit_module_load() to do so. And use p11_kit_module_release() + * to later release it. * * Modules are represented by a pointer to their <code>CK_FUNCTION_LIST</code> - * entry points. This means that callers can load modules elsewhere, using - * dlopen() for example, and then still use these methods on them. + * entry points. + */ + +/** + * SECTION:p11-kit-deprecated + * @title: Deprecated + * @short_description: Deprecated functions + * + * These functions have been deprecated from p11-kit and are not recommended for + * general usage. In large part they were deprecated because they did not adequately + * insulate multiple callers of a PKCS\#11 module from another, and could not + * support the 'managed' mode needed to do this. + */ + +/** + * P11_KIT_MODULE_UNMANAGED: + * + * Module is loaded in non 'managed' mode. This is not recommended, + * disables many features, and prevents coordination between multiple + * callers of the same module. + */ + +/** + * P11_KIT_MODULE_CRITICAL: + * + * Flag to load a module in 'critical' mode. Failure to load a critical module + * will prevent all other modules from loading. A failure when loading a + * non-critical module skips that module. */ typedef struct _Module { - CK_FUNCTION_LIST_PTR funcs; + /* + * When using managed modules, this forms the base of the + * virtual stack into which all the other modules call. This is also + * the first field in this structure so we can cast between them. + */ + p11_virtual virt; + + /* The initialize args built from configuration */ CK_C_INITIALIZE_ARGS init_args; int ref_count; + int init_count; /* Registered modules */ char *name; p11_dict *config; + bool critical; - /* Loaded modules */ - dl_module_t dl_module; + /* + * This is a pointer to the actual dl shared module, or perhaps + * the RPC client context. + */ + void *loaded_module; + p11_kit_destroyer loaded_destroy; /* Initialization, mutex must be held */ p11_mutex_t initialize_mutex; @@ -121,6 +167,8 @@ typedef struct _Module { */ static struct _Shared { p11_dict *modules; + p11_dict *unmanaged_by_funcs; + p11_dict *managed_by_closure; p11_dict *config; } gl = { NULL, NULL }; @@ -184,15 +232,19 @@ free_module_unlocked (void *data) assert (mod != NULL); - /* Module must be finalized */ - assert (!mod->initialize_called); - assert (mod->initialize_thread == 0); - /* Module must have no outstanding references */ assert (mod->ref_count == 0); - if (mod->dl_module) - p11_dl_close (mod->dl_module); + if (mod->init_count > 0) { + p11_debug_precond ("module unloaded without C_Finalize having been " + "called for each C_Initialize"); + } else { + assert (!mod->initialize_called); + assert (mod->initialize_thread == 0); + } + + if (mod->loaded_destroy) + mod->loaded_destroy (mod->loaded_module); p11_mutex_uninit (&mod->initialize_mutex); p11_dict_free (mod->config); @@ -215,28 +267,44 @@ alloc_module_unlocked (void) mod->init_args.flags = CKF_OS_LOCKING_OK; p11_mutex_init (&mod->initialize_mutex); + /* + * The default for configured modules is non-critical, but for + * modules loaded explicitly, and not from config, we treat them + * as critical. So this gets overridden for configured modules + * later when the config is loaded. + */ + mod->critical = true; + return mod; } static CK_RV -dlopen_and_get_function_list (Module *mod, const char *path) +dlopen_and_get_function_list (Module *mod, + const char *path, + CK_FUNCTION_LIST **funcs) { CK_C_GetFunctionList gfl; + dl_module_t dl; char *error; CK_RV rv; - assert (mod); - assert (path); + assert (mod != NULL); + assert (path != NULL); + assert (funcs != NULL); - mod->dl_module = p11_dl_open (path); - if (mod->dl_module == NULL) { + dl = p11_dl_open (path); + if (dl == NULL) { error = p11_dl_error (); p11_message ("couldn't load module: %s: %s", path, error); free (error); return CKR_GENERAL_ERROR; } - gfl = p11_dl_symbol (mod->dl_module, "C_GetFunctionList"); + /* When the Module goes away, dlclose the loaded module */ + mod->loaded_destroy = (p11_kit_destroyer)p11_dl_close; + mod->loaded_module = dl; + + gfl = p11_dl_symbol (dl, "C_GetFunctionList"); if (!gfl) { error = p11_dl_error (); p11_message ("couldn't find C_GetFunctionList entry point in module: %s: %s", @@ -245,65 +313,77 @@ dlopen_and_get_function_list (Module *mod, const char *path) return CKR_GENERAL_ERROR; } - rv = gfl (&mod->funcs); + rv = gfl (funcs); if (rv != CKR_OK) { p11_message ("call to C_GetFunctiontList failed in module: %s: %s", path, p11_kit_strerror (rv)); return rv; } + if (p11_proxy_module_check (*funcs)) { + p11_message ("refusing to load the p11-kit-proxy.so module as a registered module"); + return CKR_FUNCTION_FAILED; + } + + p11_virtual_init (&mod->virt, &p11_virtual_base, *funcs, NULL); p11_debug ("opened module: %s", path); return CKR_OK; } static CK_RV -load_module_from_file_unlocked (const char *path, Module **result) +load_module_from_file_inlock (const char *name, + const char *path, + Module **result) { + CK_FUNCTION_LIST *funcs; + char *expand = NULL; Module *mod; Module *prev; CK_RV rv; + assert (path != NULL); + assert (result != NULL); + mod = alloc_module_unlocked (); return_val_if_fail (mod != NULL, CKR_HOST_MEMORY); - rv = dlopen_and_get_function_list (mod, path); + if (!p11_path_absolute (path)) { + p11_debug ("module path is relative, loading from: %s", P11_MODULE_PATH); + path = expand = p11_path_build (P11_MODULE_PATH, path, NULL); + return_val_if_fail (path != NULL, CKR_HOST_MEMORY); + } + + p11_debug ("loading module %s%sfrom path: %s", + name ? name : "", name ? " " : "", path); + + rv = dlopen_and_get_function_list (mod, path, &funcs); + free (expand); + if (rv != CKR_OK) { free_module_unlocked (mod); return rv; } /* Do we have a previous one like this, if so ignore load */ - prev = p11_dict_get (gl.modules, mod->funcs); + prev = p11_dict_get (gl.unmanaged_by_funcs, funcs); + /* If same module was loaded previously, just take over config */ if (prev != NULL) { - p11_debug ("duplicate module %s, using previous", path); + if (!name || prev->name || prev->config) + p11_debug ("duplicate module %s, using previous", path); free_module_unlocked (mod); mod = prev; - } else if (!p11_dict_set (gl.modules, mod->funcs, mod)) { + /* This takes ownership of the module */ + } else if (!p11_dict_set (gl.modules, mod, mod) || + !p11_dict_set (gl.unmanaged_by_funcs, funcs, mod)) { return_val_if_reached (CKR_HOST_MEMORY); } - if (result) - *result= mod; + *result= mod; return CKR_OK; } -static char* -expand_module_path (const char *filename) -{ - char *path; - - if (!p11_path_absolute (filename)) { - p11_debug ("module path is relative, loading from: %s", P11_MODULE_PATH); - path = p11_path_build (P11_MODULE_PATH, filename, NULL); - } else { - path = strdup (filename); - } - - return path; -} - static int is_list_delimiter (char ch) { @@ -360,13 +440,12 @@ is_module_enabled_unlocked (const char *name, } static CK_RV -take_config_and_load_module_unlocked (char **name, - p11_dict **config) +take_config_and_load_module_inlock (char **name, + p11_dict **config, + bool critical) { - Module *mod, *prev; - const char *module_filename; - char *path; - char *key; + const char *filename; + Module *mod; CK_RV rv; assert (name); @@ -377,36 +456,22 @@ take_config_and_load_module_unlocked (char **name, if (!is_module_enabled_unlocked (*name, *config)) return CKR_OK; - module_filename = p11_dict_get (*config, "module"); - if (module_filename == NULL) { + filename = p11_dict_get (*config, "module"); + if (filename == NULL) { p11_debug ("no module path for module, skipping: %s", *name); return CKR_OK; } - path = expand_module_path (module_filename); - return_val_if_fail (path != NULL, CKR_HOST_MEMORY); - - key = strdup ("module"); - return_val_if_fail (key != NULL, CKR_HOST_MEMORY); - - /* The hash map will take ownership of the variable */ - if (!p11_dict_set (*config, key, path)) - return_val_if_reached (CKR_HOST_MEMORY); - - mod = alloc_module_unlocked (); - return_val_if_fail (mod != NULL, CKR_HOST_MEMORY); + rv = load_module_from_file_inlock (*name, filename, &mod); + if (rv != CKR_OK) + return CKR_OK; /* Take ownership of thes evariables */ mod->config = *config; *config = NULL; mod->name = *name; *name = NULL; - - rv = dlopen_and_get_function_list (mod, path); - if (rv != CKR_OK) { - free_module_unlocked (mod); - return rv; - } + mod->critical = critical; /* * We support setting of CK_C_INITIALIZE_ARGS.pReserved from @@ -415,27 +480,6 @@ take_config_and_load_module_unlocked (char **name, */ mod->init_args.pReserved = p11_dict_get (mod->config, "x-init-reserved"); - prev = p11_dict_get (gl.modules, mod->funcs); - - /* If same module was loaded previously, just take over config */ - if (prev && !prev->name && !prev->config) { - prev->name = mod->name; - mod->name = NULL; - prev->config = mod->config; - mod->config = NULL; - free_module_unlocked (mod); - - /* Ignore duplicate module */ - } else if (prev) { - p11_message ("duplicate configured module: %s: %s", mod->name, path); - free_module_unlocked (mod); - - /* Add this new module to our hash table */ - } else { - if (!p11_dict_set (gl.modules, mod->funcs, mod)) - return_val_if_reached (CKR_HOST_MEMORY); - } - return CKR_OK; } @@ -485,8 +529,7 @@ load_registered_modules_unlocked (void) /* Is this a critical module, should abort loading of others? */ critical = _p11_conf_parse_boolean (p11_dict_get (config, "critical"), false); - - rv = take_config_and_load_module_unlocked (&name, &config); + rv = take_config_and_load_module_inlock (&name, &config, critical); /* * These variables will be cleared if ownership is transeferred @@ -510,10 +553,11 @@ load_registered_modules_unlocked (void) } static CK_RV -initialize_module_unlocked_reentrant (Module *mod) +initialize_module_inlock_reentrant (Module *mod) { CK_RV rv = CKR_OK; p11_thread_id_t self; + assert (mod); self = p11_thread_id_self (); @@ -531,23 +575,16 @@ initialize_module_unlocked_reentrant (Module *mod) mod->initialize_thread = self; /* Change over to the module specific mutex */ - p11_mutex_lock (&mod->initialize_mutex); p11_unlock (); + p11_mutex_lock (&mod->initialize_mutex); if (!mod->initialize_called) { - assert (mod->funcs); - - if (mod->funcs == &_p11_proxy_function_list) { - p11_message ("refusing to load the p11-kit-proxy.so module as a registered module"); - rv = CKR_FUNCTION_FAILED; + p11_debug ("C_Initialize: calling"); - } else { - p11_debug ("C_Initialize: calling"); - - rv = mod->funcs->C_Initialize (&mod->init_args); + rv = mod->virt.funcs.C_Initialize (&mod->virt.funcs, + &mod->init_args); - p11_debug ("C_Initialize: result: %lu", rv); - } + p11_debug ("C_Initialize: result: %lu", rv); /* Module was initialized and C_Finalize should be called */ if (rv == CKR_OK) @@ -561,10 +598,14 @@ initialize_module_unlocked_reentrant (Module *mod) p11_mutex_unlock (&mod->initialize_mutex); p11_lock (); - /* Don't claim reference if failed */ - if (rv != CKR_OK) - --mod->ref_count; + if (rv == CKR_OK) { + /* Matches the ref count in finalize_module_inlock_reentrant() */ + if (mod->init_count == 0) + mod->ref_count++; + mod->init_count++; + } + mod->ref_count--; mod->initialize_thread = 0; return rv; } @@ -583,13 +624,13 @@ reinitialize_after_fork (void) if (gl.modules) { p11_dict_iterate (gl.modules, &iter); - while (p11_dict_next (&iter, NULL, (void **)&mod)) + while (p11_dict_next (&iter, (void **)&mod, NULL)) mod->initialize_called = false; } p11_unlock (); - _p11_kit_proxy_after_fork (); + p11_proxy_after_fork (); } #endif /* OS_UNIX */ @@ -600,11 +641,26 @@ init_globals_unlocked (void) static bool once = false; if (!gl.modules) { - gl.modules = p11_dict_new (p11_dict_direct_hash, p11_dict_direct_equal, - NULL, free_module_unlocked); + gl.modules = p11_dict_new (p11_dict_direct_hash, + p11_dict_direct_equal, + free_module_unlocked, NULL); return_val_if_fail (gl.modules != NULL, CKR_HOST_MEMORY); } + if (!gl.unmanaged_by_funcs) { + gl.unmanaged_by_funcs = p11_dict_new (p11_dict_direct_hash, + p11_dict_direct_equal, + NULL, NULL); + return_val_if_fail (gl.unmanaged_by_funcs != NULL, CKR_HOST_MEMORY); + } + + if (!gl.managed_by_closure) { + gl.managed_by_closure = p11_dict_new (p11_dict_direct_hash, + p11_dict_direct_equal, + NULL, NULL); + return_val_if_fail (gl.managed_by_closure != NULL, CKR_HOST_MEMORY); + } + if (once) return CKR_OK; @@ -624,19 +680,26 @@ free_modules_when_no_refs_unlocked (void) /* Check if any modules have a ref count */ p11_dict_iterate (gl.modules, &iter); - while (p11_dict_next (&iter, NULL, (void **)&mod)) { + while (p11_dict_next (&iter, (void **)&mod, NULL)) { if (mod->ref_count) return; } + p11_dict_free (gl.unmanaged_by_funcs); + gl.unmanaged_by_funcs = NULL; + + p11_dict_free (gl.managed_by_closure); + gl.managed_by_closure = NULL; + p11_dict_free (gl.modules); gl.modules = NULL; + p11_dict_free (gl.config); gl.config = NULL; } static CK_RV -finalize_module_unlocked_reentrant (Module *mod) +finalize_module_inlock_reentrant (Module *mod) { assert (mod); @@ -647,7 +710,7 @@ finalize_module_unlocked_reentrant (Module *mod) if (mod->ref_count == 0) return CKR_ARGUMENTS_BAD; - if (--mod->ref_count > 0) + if (--mod->init_count > 0) return CKR_OK; /* @@ -655,78 +718,58 @@ finalize_module_unlocked_reentrant (Module *mod) * the ref count. This prevents module from being freed out * from ounder us. */ - ++mod->ref_count; - p11_mutex_lock (&mod->initialize_mutex); p11_unlock (); + p11_mutex_lock (&mod->initialize_mutex); if (mod->initialize_called) { - - assert (mod->funcs); - mod->funcs->C_Finalize (NULL); - + mod->virt.funcs.C_Finalize (&mod->virt.funcs, NULL); mod->initialize_called = false; } p11_mutex_unlock (&mod->initialize_mutex); p11_lock (); - /* Match the increment above */ - --mod->ref_count; + /* Match the ref increment in initialize_module_inlock_reentrant() */ + mod->ref_count--; free_modules_when_no_refs_unlocked (); return CKR_OK; } -static Module* -find_module_for_name_unlocked (const char *name) +static CK_RV +initialize_registered_inlock_reentrant (void) { - Module *mod; p11_dictiter iter; - - assert (name); - - p11_dict_iterate (gl.modules, &iter); - while (p11_dict_next (&iter, NULL, (void **)&mod)) - if (mod->ref_count && mod->name && strcmp (name, mod->name) == 0) - return mod; - return NULL; -} - -CK_RV -_p11_kit_initialize_registered_unlocked_reentrant (void) -{ Module *mod; - p11_dictiter iter; - int critical; CK_RV rv; + /* + * This is only called by deprecated code. The caller expects all + * configured and enabled modules to be initialized. + */ + rv = init_globals_unlocked (); if (rv != CKR_OK) return rv; rv = load_registered_modules_unlocked (); if (rv == CKR_OK) { - p11_dict_iterate (gl.modules, &iter); - while (p11_dict_next (&iter, NULL, (void **)&mod)) { + p11_dict_iterate (gl.unmanaged_by_funcs, &iter); + while (rv == CKR_OK && p11_dict_next (&iter, NULL, (void **)&mod)) { - /* Skip all modules that aren't registered */ + /* Skip all modules that aren't registered or enabled */ if (mod->name == NULL || !is_module_enabled_unlocked (mod->name, mod->config)) continue; - rv = initialize_module_unlocked_reentrant (mod); - - /* - * Module failed to initialize. If this is a critical module, - * then this, should abort loading of others. - */ + rv = initialize_module_inlock_reentrant (mod); if (rv != CKR_OK) { - p11_message ("failed to initialize module: %s: %s", - mod->name, p11_kit_strerror (rv)); - - critical = _p11_conf_parse_boolean (p11_dict_get (mod->config, "critical"), false); - if (!critical) { - p11_debug ("ignoring failure, non-critical module: %s", mod->name); + if (mod->critical) { + p11_message ("initialization of critical module '%s' failed: %s", + mod->name, p11_kit_strerror (rv)); + } else { + p11_message ("skipping module '%s' whose initialization failed: %s", + mod->name, p11_kit_strerror (rv)); rv = CKR_OK; } } @@ -736,6 +779,27 @@ _p11_kit_initialize_registered_unlocked_reentrant (void) return rv; } +static Module * +module_for_functions_inlock (CK_FUNCTION_LIST *funcs) +{ + if (p11_virtual_is_wrapper (funcs)) + return p11_dict_get (gl.managed_by_closure, funcs); + else + return p11_dict_get (gl.unmanaged_by_funcs, funcs); +} + +static CK_FUNCTION_LIST * +unmanaged_for_module_inlock (Module *mod) +{ + CK_FUNCTION_LIST *funcs; + + funcs = mod->virt.lower_module; + if (p11_dict_get (gl.unmanaged_by_funcs, funcs) == mod) + return funcs; + + return NULL; +} + /** * p11_kit_initialize_registered: * @@ -751,6 +815,8 @@ _p11_kit_initialize_registered_unlocked_reentrant (void) * If this function fails, then an error message will be available via the * p11_kit_message() function. * + * Deprecated: Since: 0.19.0: Use p11_kit_modules_load() instead. + * * Returns: CKR_OK if the initialization succeeded, or an error code. */ CK_RV @@ -768,7 +834,7 @@ p11_kit_initialize_registered (void) p11_message_clear (); /* WARNING: Reentrancy can occur here */ - rv = _p11_kit_initialize_registered_unlocked_reentrant (); + rv = initialize_registered_inlock_reentrant (); _p11_kit_default_message (rv); @@ -782,29 +848,36 @@ p11_kit_initialize_registered (void) return rv; } -CK_RV -_p11_kit_finalize_registered_unlocked_reentrant (void) +static CK_RV +finalize_registered_inlock_reentrant (void) { Module *mod; p11_dictiter iter; Module **to_finalize; int i, count; + /* + * This is only called from deprecated code. The caller expects all + * modules initialized earlier to be finalized (once). If non-critical + * modules failed to initialize, then it is not possible to completely + * guarantee the internal state. + */ + if (!gl.modules) return CKR_CRYPTOKI_NOT_INITIALIZED; /* WARNING: This function must be reentrant */ - to_finalize = calloc (p11_dict_size (gl.modules), sizeof (Module *)); + to_finalize = calloc (p11_dict_size (gl.unmanaged_by_funcs), sizeof (Module *)); if (!to_finalize) return CKR_HOST_MEMORY; count = 0; - p11_dict_iterate (gl.modules, &iter); + p11_dict_iterate (gl.unmanaged_by_funcs, &iter); while (p11_dict_next (&iter, NULL, (void **)&mod)) { /* Skip all modules that aren't registered */ - if (mod->name) + if (mod->name && mod->init_count) to_finalize[count++] = mod; } @@ -812,7 +885,7 @@ _p11_kit_finalize_registered_unlocked_reentrant (void) for (i = 0; i < count; ++i) { /* WARNING: Reentrant calls can occur here */ - finalize_module_unlocked_reentrant (to_finalize[i]); + finalize_module_inlock_reentrant (to_finalize[i]); } free (to_finalize); @@ -837,6 +910,8 @@ _p11_kit_finalize_registered_unlocked_reentrant (void) * If this function fails, then an error message will be available via the * p11_kit_message() function. * + * Deprecated: Since 0.19.0: Use p11_kit_modules_release() instead. + * * Returns: CKR_OK if the finalization succeeded, or an error code. */ @@ -855,7 +930,7 @@ p11_kit_finalize_registered (void) p11_message_clear (); /* WARNING: Reentrant calls can occur here */ - rv = _p11_kit_finalize_registered_unlocked_reentrant (); + rv = finalize_registered_inlock_reentrant (); _p11_kit_default_message (rv); @@ -875,8 +950,8 @@ compar_priority (const void *one, const char *v1, *v2; int o1, o2; - m1 = p11_dict_get (gl.modules, f1); - m2 = p11_dict_get (gl.modules, f2); + m1 = module_for_functions_inlock (f1); + m2 = module_for_functions_inlock (f2); assert (m1 != NULL && m2 != NULL); v1 = p11_dict_get (m1->config, "priority"); @@ -910,20 +985,27 @@ sort_modules_by_priority (CK_FUNCTION_LIST_PTR *modules, qsort (modules, count, sizeof (CK_FUNCTION_LIST_PTR), compar_priority); } -CK_FUNCTION_LIST_PTR_PTR -_p11_kit_registered_modules_unlocked (void) +static CK_FUNCTION_LIST ** +list_registered_modules_inlock (void) { - CK_FUNCTION_LIST_PTR_PTR result = NULL; + CK_FUNCTION_LIST **result = NULL; + CK_FUNCTION_LIST *funcs; Module *mod; p11_dictiter iter; int i = 0; - if (gl.modules) { - result = calloc (p11_dict_size (gl.modules) + 1, sizeof (CK_FUNCTION_LIST_PTR)); + /* + * This is only called by deprecated code. The caller expects to get + * a list of all registered enabled modules that have been initialized. + */ + + if (gl.unmanaged_by_funcs) { + result = calloc (p11_dict_size (gl.unmanaged_by_funcs) + 1, + sizeof (CK_FUNCTION_LIST *)); return_val_if_fail (result != NULL, NULL); - p11_dict_iterate (gl.modules, &iter); - while (p11_dict_next (&iter, NULL, (void **)&mod)) { + p11_dict_iterate (gl.unmanaged_by_funcs, &iter); + while (p11_dict_next (&iter, (void **)&funcs, (void **)&mod)) { /* * We don't include unreferenced modules. We don't include @@ -936,9 +1018,9 @@ _p11_kit_registered_modules_unlocked (void) * having initialized. This is a corner case, but want to make * sure to cover it. */ - if (mod->ref_count && mod->name && + if (mod->ref_count && mod->name && mod->init_count && is_module_enabled_unlocked (mod->name, mod->config)) { - result[i++] = mod->funcs; + result[i++] = funcs; } } @@ -957,6 +1039,10 @@ _p11_kit_registered_modules_unlocked (void) * The returned value is a <code>NULL</code> terminated array of * <code>CK_FUNCTION_LIST_PTR</code> pointers. * + * The returned modules are unmanaged. + * + * Deprecated: Since 0.19.0: Use p11_kit_modules_load() instead. + * * Returns: A list of all the registered modules. Use the free() function to * free the list. */ @@ -971,7 +1057,7 @@ p11_kit_registered_modules (void) p11_message_clear (); - result = _p11_kit_registered_modules_unlocked (); + result = list_registered_modules_inlock (); p11_unlock (); @@ -987,6 +1073,8 @@ p11_kit_registered_modules (void) * You can use p11_kit_registered_modules() to get a list of all the registered * modules. This name is specified by the registered module configuration. * + * Deprecated: Since 0.19.0: Use p11_kit_module_get_name() instead. + * * Returns: A newly allocated string containing the module name, or * <code>NULL</code> if no such registered module exists. Use free() to * free this string. @@ -994,6 +1082,28 @@ p11_kit_registered_modules (void) char* p11_kit_registered_module_to_name (CK_FUNCTION_LIST_PTR module) { + return_val_if_fail (module != NULL, NULL); + return p11_kit_module_get_name (module); +} + +/** + * p11_kit_module_get_name: + * @module: pointer to a loaded module + * + * Get the configured name of the PKCS\#11 module. + * + * Configured modules are loaded by p11_kit_modules_load(). The module + * passed to this function can be either managed or unmanaged. Non + * configured modules will return %NULL. + * + * Use free() to release the return value when you're done with it. + * + * Returns: a newly allocated string containing the module name, or + * <code>NULL</code> if the module is not a configured module + */ +char * +p11_kit_module_get_name (CK_FUNCTION_LIST *module) +{ Module *mod; char *name = NULL; @@ -1005,9 +1115,11 @@ p11_kit_registered_module_to_name (CK_FUNCTION_LIST_PTR module) p11_message_clear (); - mod = module && gl.modules ? p11_dict_get (gl.modules, module) : NULL; - if (mod && mod->name) - name = strdup (mod->name); + if (gl.modules) { + mod = module_for_functions_inlock (module); + if (mod && mod->name) + name = strdup (mod->name); + } p11_unlock (); @@ -1015,12 +1127,60 @@ p11_kit_registered_module_to_name (CK_FUNCTION_LIST_PTR module) } /** + * p11_kit_module_get_flags: + * @module: the module + * + * Get the flags for this module. + * + * The %P11_KIT_MODULE_UNMANAGED flag will be set if the module is not + * managed by p11-kit. It is a raw PKCS\#11 module function list. + * + * The %P11_KIT_MODULE_CRITICAL flag will be set if the module is configured + * to be critical, and not be skipped over if it fails to initialize or + * load. This flag is also set for modules that are not configured, but have + * been loaded in another fashion. + * + * Returns: the flags for the module + */ +int +p11_kit_module_get_flags (CK_FUNCTION_LIST *module) +{ + Module *mod; + int flags = 0; + + return_val_if_fail (module != NULL, 0); + + p11_library_init_once (); + + p11_lock (); + + p11_message_clear (); + + if (gl.modules) { + if (p11_virtual_is_wrapper (module)) { + mod = p11_dict_get (gl.managed_by_closure, module); + } else { + flags |= P11_KIT_MODULE_UNMANAGED; + mod = p11_dict_get (gl.unmanaged_by_funcs, module); + } + if (!mod || mod->critical) + flags |= P11_KIT_MODULE_CRITICAL; + } + + p11_unlock (); + + return flags; +} + +/** * p11_kit_registered_name_to_module: * @name: name of a registered module * * Lookup a registered PKCS\#11 module by its name. This name is specified by * the registered module configuration. * + * Deprecated: Since 0.19.0: Use p11_kit_module_for_name() instead. + * * Returns: a pointer to a PKCS\#11 module, or <code>NULL</code> if this name was * not found. */ @@ -1028,19 +1188,28 @@ CK_FUNCTION_LIST_PTR p11_kit_registered_name_to_module (const char *name) { CK_FUNCTION_LIST_PTR module = NULL; + CK_FUNCTION_LIST_PTR funcs; + p11_dictiter iter; Module *mod; return_val_if_fail (name != NULL, NULL); p11_lock (); - p11_message_clear (); + p11_message_clear (); - if (gl.modules) { - mod = find_module_for_name_unlocked (name); - if (mod != NULL && is_module_enabled_unlocked (name, mod->config)) - module = mod->funcs; + if (gl.modules) { + + assert (name); + + p11_dict_iterate (gl.unmanaged_by_funcs, &iter); + while (p11_dict_next (&iter, (void **)&funcs, (void **)&mod)) { + if (mod->ref_count && mod->name && strcmp (name, mod->name) == 0) { + module = funcs; + break; + } } + } p11_unlock (); @@ -1048,6 +1217,70 @@ p11_kit_registered_name_to_module (const char *name) } /** + * p11_kit_module_for_name: + * @modules: a list of modules to look through + * @name: the name of the module to find + * + * Look through the list of @modules and return the module whose @name + * matches. + * + * Only configured modules have names. Configured modules are loaded by + * p11_kit_modules_load(). The module passed to this function can be either + * managed or unmanaged. + * + * The return value is not copied or duplicated in anyway. It is still + * 'owned' by the @modules list. + * + * Returns: the module which matches the name, or %NULL if no match. + */ +CK_FUNCTION_LIST * +p11_kit_module_for_name (CK_FUNCTION_LIST **modules, + const char *name) +{ + CK_FUNCTION_LIST *ret = NULL; + Module *mod; + int i; + + return_val_if_fail (name != NULL, NULL); + + if (!modules) + return NULL; + + p11_library_init_once (); + + p11_lock (); + + p11_message_clear (); + + for (i = 0; gl.modules && modules[i] != NULL; i++) { + mod = module_for_functions_inlock (modules[i]); + if (mod && mod->name && strcmp (mod->name, name) == 0) { + ret = modules[i]; + break; + } + } + + p11_unlock (); + + return ret; +} + +static const char * +module_get_option_inlock (Module *mod, + const char *option) +{ + p11_dict *config; + + if (mod == NULL) + config = gl.config; + else + config = mod->config; + if (config == NULL) + return NULL; + return p11_dict_get (config, option); +} + +/** * p11_kit_registered_option: * @module: a pointer to a registered module * @field: the name of the option to lookup. @@ -1056,6 +1289,8 @@ p11_kit_registered_name_to_module (const char *name) * <code>NULL</code> module argument is specified, then this will lookup * the configuration option in the global config file. * + * Deprecated: Since 0.19.0: Use p11_kit_config_option() instead. + * * Returns: A newly allocated string containing the option value, or * <code>NULL</code> if the registered module or the option were not found. * Use free() to free the returned string. @@ -1065,7 +1300,7 @@ p11_kit_registered_option (CK_FUNCTION_LIST_PTR module, const char *field) { Module *mod = NULL; char *option = NULL; - p11_dict *config = NULL; + const char *value; return_val_if_fail (field != NULL, NULL); @@ -1075,24 +1310,824 @@ p11_kit_registered_option (CK_FUNCTION_LIST_PTR module, const char *field) p11_message_clear (); - if (module == NULL) { - config = gl.config; + if (module == NULL) + mod = NULL; + else + mod = gl.unmanaged_by_funcs ? p11_dict_get (gl.unmanaged_by_funcs, module) : NULL; + + value = module_get_option_inlock (mod, field); + if (value) + option = strdup (value); + + p11_unlock (); + + return option; +} + +/** + * p11_kit_config_option: + * @module: the module to retrieve the option for, or %NULL for global options + * @option: the option to retrieve + * + * Retrieve the value for a configured option. + * + * If @module is %NULL, then the global option with the given name will + * be retrieved. Otherwise @module should point to a configured loaded module. + * If no such @option or configured @module exists, then %NULL will be returned. + * + * Use free() to release the returned value. + * + * Returns: the option value or %NULL + */ +char * +p11_kit_config_option (CK_FUNCTION_LIST *module, + const char *option) +{ + Module *mod = NULL; + const char *value = NULL; + char *ret = NULL; + + return_val_if_fail (option != NULL, NULL); + + p11_library_init_once (); + + p11_lock (); + + p11_message_clear (); + + if (gl.modules) { + if (module != NULL) { + mod = module_for_functions_inlock (module); + if (mod == NULL) + goto cleanup; + } + + value = module_get_option_inlock (mod, option); + if (value) + ret = strdup (value); + } + +cleanup: + p11_unlock (); + return ret; +} + +typedef struct { + p11_virtual virt; + Module *mod; + bool initialized; + p11_dict *sessions; +} Managed; + +static CK_RV +managed_C_Initialize (CK_X_FUNCTION_LIST *self, + CK_VOID_PTR init_args) +{ + Managed *managed = ((Managed *)self); + p11_dict *sessions; + CK_RV rv; + + p11_debug ("in"); + p11_lock (); + + if (managed->initialized) { + rv = CKR_CRYPTOKI_ALREADY_INITIALIZED; + + } else { + sessions = p11_dict_new (p11_dict_ulongptr_hash, + p11_dict_ulongptr_equal, + free, free); + if (!sessions) + rv = CKR_HOST_MEMORY; + else + rv = initialize_module_inlock_reentrant (managed->mod); + if (rv == CKR_OK) { + managed->sessions = sessions; + managed->initialized = true; } else { - mod = gl.modules ? p11_dict_get (gl.modules, module) : NULL; - if (mod) - config = mod->config; + p11_dict_free (sessions); } + } + + p11_unlock (); + p11_debug ("out: %lu", rv); - if (config && field) { - option = p11_dict_get (config, field); - if (option) - option = strdup (option); + return rv; +} + +static CK_RV +managed_track_session_inlock (p11_dict *sessions, + CK_SLOT_ID slot_id, + CK_SESSION_HANDLE session) +{ + void *key; + void *value; + + key = memdup (&session, sizeof (CK_SESSION_HANDLE)); + return_val_if_fail (key != NULL, CKR_HOST_MEMORY); + + value = memdup (&slot_id, sizeof (CK_SESSION_HANDLE)); + return_val_if_fail (value != NULL, CKR_HOST_MEMORY); + + if (!p11_dict_set (sessions, key, value)) + return_val_if_reached (CKR_HOST_MEMORY); + + return CKR_OK; +} + +static void +managed_untrack_session_inlock (p11_dict *sessions, + CK_SESSION_HANDLE session) +{ + p11_dict_remove (sessions, &session); +} + +static CK_SESSION_HANDLE * +managed_steal_sessions_inlock (p11_dict *sessions, + bool matching_slot_id, + CK_SLOT_ID slot_id, + int *count) +{ + CK_SESSION_HANDLE *stolen; + CK_SESSION_HANDLE *key; + CK_SLOT_ID *value; + p11_dictiter iter; + int at, i; + + assert (sessions != NULL); + assert (count != NULL); + + stolen = calloc (p11_dict_size (sessions), sizeof (CK_SESSION_HANDLE)); + return_val_if_fail (stolen != NULL, NULL); + + at = 0; + p11_dict_iterate (sessions, &iter); + while (p11_dict_next (&iter, (void **)&key, (void **)&value)) { + if (!matching_slot_id || slot_id == *value) + stolen[at++] = *key; + } + + /* Removed them all, clear the whole array */ + if (at == p11_dict_size (sessions)) { + p11_dict_clear (sessions); + + /* Only removed some, go through and remove those */ + } else { + for (i = 0; i < at; i++) { + if (!p11_dict_remove (sessions, stolen + at)) + assert_not_reached (); } + } + + *count = at; + return stolen; +} + +static void +managed_close_sessions (CK_X_FUNCTION_LIST *funcs, + CK_SESSION_HANDLE *stolen, + int count) +{ + CK_RV rv; + int i; + + for (i = 0; i < count; i++) { + rv = funcs->C_CloseSession (funcs, stolen[i]); + if (rv != CKR_OK) + p11_message ("couldn't close session: %s", p11_kit_strerror (rv)); + } +} + +static CK_RV +managed_C_Finalize (CK_X_FUNCTION_LIST *self, + CK_VOID_PTR reserved) +{ + Managed *managed = ((Managed *)self); + CK_SESSION_HANDLE *sessions; + int count; + CK_RV rv; + + p11_debug ("in"); + p11_lock (); + + if (!managed->initialized) { + rv = CKR_CRYPTOKI_NOT_INITIALIZED; + + } else { + sessions = managed_steal_sessions_inlock (managed->sessions, false, 0, &count); + + if (sessions && count) { + /* WARNING: reentrancy can occur here */ + p11_unlock (); + managed_close_sessions (&managed->mod->virt.funcs, sessions, count); + p11_lock (); + } + + free (sessions); + + /* WARNING: reentrancy can occur here */ + rv = finalize_module_inlock_reentrant (managed->mod); + + if (rv == CKR_OK) { + managed->initialized = false; + p11_dict_free (managed->sessions); + managed->sessions = NULL; + } + } p11_unlock (); + p11_debug ("out: %lu", rv); - return option; + return rv; +} + +static CK_RV +managed_C_OpenSession (CK_X_FUNCTION_LIST *self, + CK_SLOT_ID slot_id, + CK_FLAGS flags, + CK_VOID_PTR application, + CK_NOTIFY notify, + CK_SESSION_HANDLE_PTR session) +{ + Managed *managed = ((Managed *)self); + CK_RV rv; + + return_val_if_fail (session != NULL, CKR_ARGUMENTS_BAD); + + self = &managed->mod->virt.funcs; + rv = self->C_OpenSession (self, slot_id, flags, application, notify, session); + + if (rv == CKR_OK) { + p11_lock (); + rv = managed_track_session_inlock (managed->sessions, slot_id, *session); + p11_unlock (); + } + + return rv; +} + +static CK_RV +managed_C_CloseSession (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE session) +{ + Managed *managed = ((Managed *)self); + CK_RV rv; + + self = &managed->mod->virt.funcs; + rv = self->C_CloseSession (self, session); + + if (rv == CKR_OK) { + p11_lock (); + managed_untrack_session_inlock (managed->sessions, session); + p11_unlock (); + } + + return rv; +} + +static CK_RV +managed_C_CloseAllSessions (CK_X_FUNCTION_LIST *self, + CK_SLOT_ID slot_id) +{ + Managed *managed = ((Managed *)self); + CK_SESSION_HANDLE *stolen; + int count; + + p11_lock (); + stolen = managed_steal_sessions_inlock (managed->sessions, true, slot_id, &count); + p11_unlock (); + + self = &managed->mod->virt.funcs; + managed_close_sessions (self, stolen, count); + free (stolen); + + return stolen ? CKR_OK : CKR_GENERAL_ERROR; +} + +static void +managed_free_inlock (void *data) +{ + Managed *managed = data; + managed->mod->ref_count--; + free (managed); +} + +static p11_virtual * +managed_create_inlock (Module *mod) +{ + Managed *managed; + + managed = calloc (1, sizeof (Managed)); + return_val_if_fail (managed != NULL, NULL); + + p11_virtual_init (&managed->virt, &p11_virtual_stack, + &mod->virt, NULL); + managed->virt.funcs.C_Initialize = managed_C_Initialize; + managed->virt.funcs.C_Finalize = managed_C_Finalize; + managed->virt.funcs.C_CloseAllSessions = managed_C_CloseAllSessions; + managed->virt.funcs.C_CloseSession = managed_C_CloseSession; + managed->virt.funcs.C_OpenSession = managed_C_OpenSession; + managed->mod = mod; + mod->ref_count++; + + return &managed->virt; +} + +static bool +lookup_managed_option (Module *mod, + bool supported, + const char *option, + bool def_value) +{ + const char *string; + bool value; + + string = module_get_option_inlock (NULL, option); + if (!string) + string = module_get_option_inlock (mod, option); + if (!string) { + if (!supported) + return false; + return def_value; + } + + 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; + } + + return value; +} + +static CK_RV +release_module_inlock_rentrant (CK_FUNCTION_LIST *module, + const char *caller_func) +{ + Module *mod; + + assert (module != NULL); + + /* See if a managed module, and finalize if so */ + if (p11_virtual_is_wrapper (module)) { + mod = p11_dict_get (gl.managed_by_closure, module); + if (mod != NULL) { + if (!p11_dict_remove (gl.managed_by_closure, module)) + assert_not_reached (); + p11_virtual_unwrap (module); + } + + /* If an unmanaged module then caller should have finalized */ + } else { + mod = p11_dict_get (gl.unmanaged_by_funcs, module); + } + + if (mod == NULL) { + p11_debug_precond ("invalid module pointer passed to %s", caller_func); + return CKR_ARGUMENTS_BAD; + } + + /* Matches the ref in prepare_module_inlock_reentrant() */ + mod->ref_count--; + return CKR_OK; +} + +CK_RV +p11_modules_release_inlock_reentrant (CK_FUNCTION_LIST **modules) +{ + CK_RV ret = CKR_OK; + CK_RV rv; + int i; + + for (i = 0; modules[i] != NULL; i++) { + rv = release_module_inlock_rentrant (modules[i], __PRETTY_FUNCTION__); + if (rv != CKR_OK) + ret = rv; + } + + free (modules); + + /* In case nothing loaded, free up internal memory */ + free_modules_when_no_refs_unlocked (); + + return ret; +} + +static CK_RV +prepare_module_inlock_reentrant (Module *mod, + int flags, + CK_FUNCTION_LIST **module) +{ + p11_destroyer destroyer; + p11_virtual *virt; + bool is_managed; + bool with_log; + + assert (module != NULL); + + if (flags & P11_KIT_MODULE_UNMANAGED) { + is_managed = false; + with_log = false; + } else { + is_managed = lookup_managed_option (mod, p11_virtual_can_wrap (), "managed", true); + with_log = lookup_managed_option (mod, is_managed, "log-calls", false); + } + + if (is_managed) { + virt = managed_create_inlock (mod); + return_val_if_fail (virt != NULL, CKR_HOST_MEMORY); + destroyer = managed_free_inlock; + + /* Add the logger if configured */ + if (p11_log_force || with_log) { + virt = p11_log_subclass (virt, destroyer); + destroyer = p11_log_release; + } + + *module = p11_virtual_wrap (virt, destroyer); + return_val_if_fail (*module != NULL, CKR_GENERAL_ERROR); + + if (!p11_dict_set (gl.managed_by_closure, *module, mod)) + return_val_if_reached (CKR_HOST_MEMORY); + + } else { + *module = unmanaged_for_module_inlock (mod); + if (*module == NULL) + return CKR_FUNCTION_NOT_SUPPORTED; + } + + /* Matches the deref in release_module_inlock_rentrant() */ + mod->ref_count++; + return CKR_OK; +} + +CK_RV +p11_modules_load_inlock_reentrant (int flags, + CK_FUNCTION_LIST ***results) +{ + CK_FUNCTION_LIST **modules; + Module *mod; + p11_dictiter iter; + CK_RV rv; + int at; + + rv = init_globals_unlocked (); + if (rv != CKR_OK) + return rv; + + rv = load_registered_modules_unlocked (); + if (rv != CKR_OK) + return rv; + + modules = calloc (p11_dict_size (gl.modules) + 1, sizeof (CK_FUNCTION_LIST *)); + return_val_if_fail (modules != NULL, CKR_HOST_MEMORY); + + at = 0; + rv = CKR_OK; + + p11_dict_iterate (gl.modules, &iter); + while (p11_dict_next (&iter, NULL, (void **)&mod)) { + + /* + * We don't include unreferenced modules. We don't include + * modules that have been initialized but aren't in the + * registry. These have a NULL name. + * + * In addition we check again that the module isn't disabled + * using enable-in or disable-in. This is because a caller + * can change the progname we recognize the process as after + * having initialized. This is a corner case, but want to make + * sure to cover it. + */ + if (!mod->name || !is_module_enabled_unlocked (mod->name, mod->config)) + continue; + + rv = prepare_module_inlock_reentrant (mod, flags, modules + at); + if (rv == CKR_OK) + at++; + else if (rv != CKR_FUNCTION_NOT_SUPPORTED) + break; + } + + modules[at] = NULL; + + if (rv != CKR_OK) { + p11_modules_release_inlock_reentrant (modules); + return rv; + } + + sort_modules_by_priority (modules, at); + *results = modules; + return CKR_OK; +} + +/** + * p11_kit_modules_load: + * @reserved: set to %NULL + * @flags: flags to use to load the module + * + * Load the configured PKCS\#11 modules. + * + * If @flags contains the %P11_KIT_MODULE_UNMANAGED flag, then the + * modules will be not be loaded in 'managed' mode regardless of its + * configuration. This is not recommended for general usage. + * + * If @flags contains the %P11_KIT_MODULE_CRITICAL flag then the + * modules will all be treated as 'critical', regardless of the module + * configuration. This means that a failure to load any module will + * cause this funtion to fail. + * + * For unmanaged modules there is no guarantee to the state of the + * modules. Other callers may be using the modules. Using unmanaged + * modules haphazardly is not recommended for this reason. Some + * modules (such as those configured with RPC) cannot be loaded in + * unmanaged mode, and will be skipped. + * + * Use p11_kit_modules_release() to release the modules returned by + * this function. + * + * If this function fails, then an error message will be available via the + * p11_kit_message() function. + * + * Returns: a null terminated list of modules represented as PKCS\#11 + * function lists, or %NULL on failure + */ +CK_FUNCTION_LIST ** +p11_kit_modules_load (const char *reserved, + int flags) +{ + CK_FUNCTION_LIST **modules; + CK_RV rv; + + /* progname attribute not implemented yet */ + return_val_if_fail (reserved == NULL, NULL); + + p11_library_init_once (); + + /* WARNING: This function must be reentrant */ + p11_debug ("in"); + + p11_lock (); + + p11_message_clear (); + + /* WARNING: Reentrancy can occur here */ + rv = p11_modules_load_inlock_reentrant (flags, &modules); + + p11_unlock (); + + if (rv != CKR_OK) + modules = NULL; + + p11_debug ("out: %s", modules ? "success" : "fail"); + return modules; +} + +/** + * p11_kit_modules_initialize: + * @modules: a %NULL terminated list of modules + * @failure_callback: called with modules that fail to initialize + * + * Initialize all the modules in the @modules list by calling their + * <literal>C_Initialize</literal> function. + * + * For managed modules the <literal>C_Initialize</literal> function + * is overridden so that multiple callers can initialize the same + * modules. In addition for managed modules multiple callers can + * initialize from different threads, and still guarantee consistent + * thread-safe behavior. + * + * For unmanaged modules if multiple callers try to initialize + * a module, then one of the calls will return + * <literal>CKR_CRYPTOKI_ALREADY_INITIALIZED</literal> according to the + * PKCS\#11 specification. In addition there are no guarantees that + * thread-safe behavior will occur if multiple callers initialize from + * different threads. + * + * When a module fails to initialize it is removed from the @modules list. + * If the @failure_callback is not %NULL then it is called with the modules that + * fail to initialize. For example, you may pass p11_kit_module_release() + * as a @failure_callback if the @modules list was loaded wit p11_kit_modules_load(). + * + * The return value will return the failure code of the last critical + * module that failed to initialize. Non-critical module failures do not affect + * the return value. If no critical modules failed to initialize then the + * return value will be <literal>CKR_OK</literal>. + * + * When modules are removed, the list will be %NULL terminated at the + * appropriate place so it can continue to be used as a modules list. + * + * This function does not accept a <code>CK_C_INITIALIZE_ARGS</code> argument. + * Custom initialization arguments cannot be supported when multiple consumers + * load the same module. + * + * Returns: <literal>CKR_OK</literal> or the failure code of the last critical + * module that failed to initialize. + */ +CK_RV +p11_kit_modules_initialize (CK_FUNCTION_LIST **modules, + p11_kit_destroyer failure_callback) +{ + CK_RV ret = CKR_OK; + CK_RV rv; + bool critical; + char *name; + int i, out; + + return_val_if_fail (modules != NULL, CKR_ARGUMENTS_BAD); + + for (i = 0, out = 0; modules[i] != NULL; i++, out++) { + rv = modules[i]->C_Initialize (NULL); + if (rv != CKR_OK) { + name = p11_kit_module_get_name (modules[i]); + if (name == NULL) + name = strdup ("(unknown)"); + return_val_if_fail (name != NULL, CKR_HOST_MEMORY); + critical = (p11_kit_module_get_flags (modules[i]) & P11_KIT_MODULE_CRITICAL); + p11_message ("%s: module failed to initialize%s: %s", + name, critical ? "" : ", skipping", p11_kit_strerror (rv)); + if (critical) + ret = rv; + if (failure_callback) + failure_callback (modules[i]); + out--; + free (name); + } + } + + /* NULL terminate after above changes */ + modules[out] = NULL; + return ret; +} + +/** + * p11_kit_modules_load_and_initialize: + * @flags: flags to use to load the modules + * + * Load and initialize configured modules. + * + * If a critical module fails to load or initialize then the function will + * return <literal>NULL</literal>. Non-critical modules will be skipped + * and not included in the returned module list. + * + * Use p11_kit_modules_finalize_and_release() when you're done with the + * modules returned by this function. + * + * Returns: a <literal>NULL</literal> terminated list of modules, or + * <literal>NULL</literal> on failure + */ +CK_FUNCTION_LIST ** +p11_kit_modules_load_and_initialize (int flags) +{ + CK_FUNCTION_LIST **modules; + CK_RV rv; + + modules = p11_kit_modules_load (NULL, flags); + if (modules == NULL) + return NULL; + + rv = p11_kit_modules_initialize (modules, (p11_destroyer)p11_kit_module_release); + if (rv != CKR_OK) { + p11_kit_modules_release (modules); + modules = NULL; + } + + return modules; +} + +/** + * p11_kit_modules_finalize: + * @modules: a <literal>NULL</literal> terminated list of modules + * + * Finalize each module in the @modules list by calling its + * <literal>C_Finalize</literal> function. Regardless of failures, all + * @modules will have their <literal>C_Finalize</literal> function called. + * + * If a module returns a failure from its <literal>C_Finalize</literal> + * method it will be returned. If multiple modules fail, the last failure + * will be returned. + * + * For managed modules the <literal>C_Finalize</literal> function + * is overridden so that multiple callers can finalize the same + * modules. In addition for managed modules multiple callers can + * finalize from different threads, and still guarantee consistent + * thread-safe behavior. + * + * For unmanaged modules if multiple callers try to finalize + * a module, then one of the calls will return + * <literal>CKR_CRYPTOKI_NOT_INITIALIZED</literal> according to the + * PKCS\#11 specification. In addition there are no guarantees that + * thread-safe behavior will occur if multiple callers finalize from + * different threads. + * + * Returns: <literal>CKR_OK</literal> or the failure code of the last + * module that failed to finalize + */ +CK_RV +p11_kit_modules_finalize (CK_FUNCTION_LIST **modules) +{ + CK_RV ret = CKR_OK; + CK_RV rv; + char *name; + int i; + + return_val_if_fail (modules != NULL, CKR_ARGUMENTS_BAD); + + for (i = 0; modules[i] != NULL; i++) { + rv = modules[i]->C_Finalize (NULL); + if (rv != CKR_OK) { + name = p11_kit_module_get_name (modules[i]); + p11_message ("%s: module failed to finalize: %s", + name ? name : "(unknown)", p11_kit_strerror (rv)); + free (name); + ret = rv; + } + } + + return ret; +} + +/** + * p11_kit_modules_release: + * @modules: the modules to release + * + * Release the a set of loaded PKCS\#11 modules. + * + * The modules may be either managed or unmanaged. The array containing + * the module pointers is also freed by this function. + * + * Managed modules will not be actually released until all + * callers using them have done so. If the modules were initialized, they + * should have been finalized first. + */ +void +p11_kit_modules_release (CK_FUNCTION_LIST **modules) +{ + p11_library_init_once (); + + return_if_fail (modules != NULL); + + /* WARNING: This function must be reentrant */ + p11_debug ("in"); + + p11_lock (); + + p11_message_clear (); + p11_modules_release_inlock_reentrant (modules); + + p11_unlock (); + + p11_debug ("out"); +} + +/** + * p11_kit_modules_finalize_and_release: + * @modules: the modules to release + * + * Finalize and then release the a set of loaded PKCS\#11 modules. + * + * The modules may be either managed or unmanaged. The array containing + * the module pointers is also freed by this function. + * + * Modules are released even if their finalization returns an error code. + * Managed modules will not be actually finalized or released until all + * callers using them have done so. + * + * For managed modules the <literal>C_Finalize</literal> function + * is overridden so that multiple callers can finalize the same + * modules. In addition for managed modules multiple callers can + * finalize from different threads, and still guarantee consistent + * thread-safe behavior. + * + * For unmanaged modules if multiple callers try to finalize + * a module, then one of the calls will return + * <literal>CKR_CRYPTOKI_NOT_INITIALIZED</literal> according to the + * PKCS\#11 specification. In addition there are no guarantees that + * thread-safe behavior will occur if multiple callers initialize from + * different threads. + */ +void +p11_kit_modules_finalize_and_release (CK_FUNCTION_LIST **modules) +{ + return_if_fail (modules != NULL); + p11_kit_modules_finalize (modules); + p11_kit_modules_release (modules); } /** @@ -1123,14 +2158,17 @@ p11_kit_registered_option (CK_FUNCTION_LIST_PTR module, const char *field) * If this function fails, then an error message will be available via the * p11_kit_message() function. * + * Deprecated: Since 0.19.0: Use p11_kit_module_initialize() instead. + * * Returns: CKR_OK if the initialization was successful. */ CK_RV p11_kit_initialize_module (CK_FUNCTION_LIST_PTR module) { - Module *allocated = NULL; + CK_FUNCTION_LIST_PTR result; Module *mod; - CK_RV rv = CKR_OK; + int flags; + CK_RV rv; return_val_if_fail (module != NULL, CKR_ARGUMENTS_BAD); @@ -1143,34 +2181,132 @@ p11_kit_initialize_module (CK_FUNCTION_LIST_PTR module) p11_message_clear (); - rv = init_globals_unlocked (); - if (rv == CKR_OK) { + flags = P11_KIT_MODULE_CRITICAL | P11_KIT_MODULE_UNMANAGED; + rv = p11_module_load_inlock_reentrant (module, flags, &result); - mod = p11_dict_get (gl.modules, module); - if (mod == NULL) { - p11_debug ("allocating new module"); - allocated = mod = alloc_module_unlocked (); - if (mod == NULL) - rv = CKR_HOST_MEMORY; - else - mod->funcs = module; - } + /* An unmanaged module should return the same pointer */ + assert (rv != CKR_OK || result == module); - /* If this was newly allocated, add it to the list */ - if (rv == CKR_OK && allocated) { - if (p11_dict_set (gl.modules, allocated->funcs, allocated)) - allocated = NULL; - else - rv = CKR_HOST_MEMORY; + if (rv == CKR_OK) { + mod = p11_dict_get (gl.unmanaged_by_funcs, module); + assert (mod != NULL); + rv = initialize_module_inlock_reentrant (mod); + if (rv != CKR_OK) { + p11_message ("module initialization failed: %s", p11_kit_strerror (rv)); + p11_module_release_inlock_reentrant (module); } + } + + p11_unlock (); + + p11_debug ("out: %lu", rv); + return rv; +} + +CK_RV +p11_module_load_inlock_reentrant (CK_FUNCTION_LIST *module, + int flags, + CK_FUNCTION_LIST **result) +{ + Module *allocated = NULL; + Module *mod; + CK_RV rv = CKR_OK; + + rv = init_globals_unlocked (); + if (rv == CKR_OK) { + + mod = p11_dict_get (gl.unmanaged_by_funcs, module); + if (mod == NULL) { + p11_debug ("allocating new module"); + allocated = mod = alloc_module_unlocked (); + return_val_if_fail (mod != NULL, CKR_HOST_MEMORY); + p11_virtual_init (&mod->virt, &p11_virtual_base, module, NULL); + } + + /* If this was newly allocated, add it to the list */ + if (rv == CKR_OK && allocated) { + if (!p11_dict_set (gl.modules, allocated, allocated) || + !p11_dict_set (gl.unmanaged_by_funcs, module, allocated)) + return_val_if_reached (CKR_HOST_MEMORY); + allocated = NULL; + } + + if (rv == CKR_OK) { + /* WARNING: Reentrancy can occur here */ + rv = prepare_module_inlock_reentrant (mod, flags, result); + } + + free (allocated); + } + + /* + * If initialization failed, we may need to cleanup. + * If we added this module above, then this will + * clean things up as expected. + */ + if (rv != CKR_OK) + free_modules_when_no_refs_unlocked (); + + _p11_kit_default_message (rv); + return rv; +} + +/** + * p11_kit_module_load: + * @module_path: full file path of module library + * @flags: flags to use when loading the module + * + * Load an arbitrary PKCS\#11 module from a dynamic library file, and + * initialize it. Normally using the p11_kit_modules_load() function + * is preferred. + * + * Using this function to load modules allows coordination between multiple + * callers of the same module in a single process. If @flags contains the + * %P11_KIT_MODULE_UNMANAGED flag, then the modules will be not be loaded + * in 'managed' mode and not be coordinated. This is not recommended + * for general usage. + * + * Subsequent calls to this function for the same module will result in an + * initialization count being incremented for the module. It is safe (although + * usually unnecessary) to use this function on registered modules. + * + * The module should be released with p11_kit_module_release(). + * + * If this function fails, then an error message will be available via the + * p11_kit_message() function. + * + * Returns: the loaded module PKCS\#11 functions or %NULL on failure + */ +CK_FUNCTION_LIST * +p11_kit_module_load (const char *module_path, + int flags) +{ + CK_FUNCTION_LIST *module = NULL; + CK_RV rv; + Module *mod; + + return_val_if_fail (module_path != NULL, NULL); + p11_library_init_once (); + + /* WARNING: This function must be reentrant for the same arguments */ + p11_debug ("in: %s", module_path); + + p11_lock (); + + p11_message_clear (); + + rv = init_globals_unlocked (); + if (rv == CKR_OK) { + + rv = load_module_from_file_inlock (NULL, module_path, &mod); if (rv == CKR_OK) { /* WARNING: Reentrancy can occur here */ - rv = initialize_module_unlocked_reentrant (mod); + rv = prepare_module_inlock_reentrant (mod, flags, &module); + if (rv != CKR_OK) + module = NULL; } - - free (allocated); } /* @@ -1181,12 +2317,11 @@ p11_kit_initialize_module (CK_FUNCTION_LIST_PTR module) if (rv != CKR_OK) free_modules_when_no_refs_unlocked (); - _p11_kit_default_message (rv); - p11_unlock (); - p11_debug ("out: %lu", rv); - return rv; + p11_debug ("out: %s", module ? "success" : "fail"); + return module; + } /** @@ -1198,7 +2333,7 @@ p11_kit_initialize_module (CK_FUNCTION_LIST_PTR module) * p11_kit_finalize_registered() instead of this function. * * Using this function to finalize modules allows coordination between - * multiple users of the same module in a single process. The caller should + * multiple users of the same module in a single process. The caller should not * call the module's <code>C_Finalize</code> method. This function will call * <code>C_Finalize</code> as necessary. * @@ -1211,10 +2346,13 @@ p11_kit_initialize_module (CK_FUNCTION_LIST_PTR module) * If this function fails, then an error message will be available via the * p11_kit_message() function. * + * Deprecated: Since 0.19.0: Use p11_kit_module_finalize() and + * p11_kit_module_release() instead. + * * Returns: CKR_OK if the finalization was successful. */ CK_RV -p11_kit_finalize_module (CK_FUNCTION_LIST_PTR module) +p11_kit_finalize_module (CK_FUNCTION_LIST *module) { Module *mod; CK_RV rv = CKR_OK; @@ -1230,13 +2368,13 @@ p11_kit_finalize_module (CK_FUNCTION_LIST_PTR module) p11_message_clear (); - mod = gl.modules ? p11_dict_get (gl.modules, module) : NULL; + mod = gl.unmanaged_by_funcs ? p11_dict_get (gl.unmanaged_by_funcs, module) : NULL; if (mod == NULL) { p11_debug ("module not found"); rv = CKR_ARGUMENTS_BAD; } else { /* WARNING: Rentrancy can occur here */ - rv = finalize_module_unlocked_reentrant (mod); + rv = finalize_module_inlock_reentrant (mod); } _p11_kit_default_message (rv); @@ -1248,6 +2386,130 @@ p11_kit_finalize_module (CK_FUNCTION_LIST_PTR module) } /** + * p11_kit_module_initialize: + * @module: the module to initialize + * + * Initialize a PKCS\#11 module by calling its <literal>C_Initialize</literal> + * function. + * + * For managed modules the <literal>C_Initialize</literal> function + * is overridden so that multiple callers can initialize the same + * modules. In addition for managed modules multiple callers can + * initialize from different threads, and still guarantee consistent + * thread-safe behavior. + * + * For unmanaged modules if multiple callers try to initialize + * a module, then one of the calls will return + * <literal>CKR_CRYPTOKI_ALREADY_INITIALIZED</literal> according to the + * PKCS\#11 specification. In addition there are no guarantees that + * thread-safe behavior will occur if multiple callers initialize from + * different threads. + * + * This function does not accept a <code>CK_C_INITIALIZE_ARGS</code> argument. + * Custom initialization arguments cannot be supported when multiple consumers + * load the same module. + * + * Returns: <literal>CKR_OK</literal> or a failure code + */ +CK_RV +p11_kit_module_initialize (CK_FUNCTION_LIST *module) +{ + char *name; + CK_RV rv; + + return_val_if_fail (module != NULL, CKR_ARGUMENTS_BAD); + + rv = module->C_Initialize (NULL); + if (rv != CKR_OK) { + name = p11_kit_module_get_name (module); + p11_message ("%s: module failed to initialize: %s", + name ? name : "(unknown)", p11_kit_strerror (rv)); + free (name); + } + + return rv; +} + +/** + * p11_kit_module_finalize: + * @module: the module to finalize + * + * Finalize a PKCS\#11 module by calling its <literal>C_Finalize</literal> + * function. + * + * For managed modules the <literal>C_Finalize</literal> function + * is overridden so that multiple callers can finalize the same + * modules. In addition for managed modules multiple callers can + * finalize from different threads, and still guarantee consistent + * thread-safe behavior. + * + * For unmanaged modules if multiple callers try to finalize + * a module, then one of the calls will return + * <literal>CKR_CRYPTOKI_NOT_INITIALIZED</literal> according to the + * PKCS\#11 specification. In addition there are no guarantees that + * thread-safe behavior will occur if multiple callers finalize from + * different threads. + * + * Returns: <literal>CKR_OK</literal> or a failure code + */ +CK_RV +p11_kit_module_finalize (CK_FUNCTION_LIST *module) +{ + char *name; + CK_RV rv; + + return_val_if_fail (module != NULL, CKR_ARGUMENTS_BAD); + + rv = module->C_Finalize (NULL); + if (rv != CKR_OK) { + name = p11_kit_module_get_name (module); + p11_message ("%s: module failed to finalize: %s", + name ? name : "(unknown)", p11_kit_strerror (rv)); + free (name); + } + + return rv; + +} + + +/** + * p11_kit_module_release: + * @module: the module to release + * + * Release the a loaded PKCS\#11 modules. + * + * The module may be either managed or unmanaged. The <literal>C_Finalize</literal> + * function will be called if no other callers are using this module. + */ +void +p11_kit_module_release (CK_FUNCTION_LIST *module) +{ + return_if_fail (module != NULL); + + p11_library_init_once (); + + /* WARNING: This function must be reentrant for the same arguments */ + p11_debug ("in"); + + p11_lock (); + + p11_message_clear (); + + release_module_inlock_rentrant (module, __PRETTY_FUNCTION__); + + p11_unlock (); + + p11_debug ("out"); +} + +CK_RV +p11_module_release_inlock_reentrant (CK_FUNCTION_LIST *module) +{ + return release_module_inlock_rentrant (module, __PRETTY_FUNCTION__); +} + +/** * p11_kit_load_initialize_module: * @module_path: full file path of module library * @module: location to place loaded module pointer @@ -1278,6 +2540,8 @@ p11_kit_finalize_module (CK_FUNCTION_LIST_PTR module) * If this function fails, then an error message will be available via the * p11_kit_message() function. * + * Deprecated: Since 0.19.0: Use p11_kit_module_load() instead. + * * Returns: CKR_OK if the initialization was successful. */ CK_RV @@ -1302,16 +2566,18 @@ p11_kit_load_initialize_module (const char *module_path, rv = init_globals_unlocked (); if (rv == CKR_OK) { - rv = load_module_from_file_unlocked (module_path, &mod); + rv = load_module_from_file_inlock (NULL, module_path, &mod); if (rv == CKR_OK) { /* WARNING: Reentrancy can occur here */ - rv = initialize_module_unlocked_reentrant (mod); + rv = initialize_module_inlock_reentrant (mod); } } - if (rv == CKR_OK && module) - *module = mod->funcs; + if (rv == CKR_OK && module) { + *module = unmanaged_for_module_inlock (mod); + assert (*module != NULL); + } /* * If initialization failed, we may need to cleanup. diff --git a/p11-kit/modules.h b/p11-kit/modules.h new file mode 100644 index 0000000..ca8dac3 --- /dev/null +++ b/p11-kit/modules.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2013 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 <stefw@redhat.com> + */ + +#ifndef __P11_MODULES_H__ +#define __P11_MODULES_H__ + +#include "pkcs11.h" + +CK_RV p11_modules_load_inlock_reentrant (int flags, + CK_FUNCTION_LIST_PTR **results); + +CK_RV p11_modules_release_inlock_reentrant (CK_FUNCTION_LIST_PTR *modules); + +CK_RV p11_module_load_inlock_reentrant (CK_FUNCTION_LIST_PTR module, + int flags, + CK_FUNCTION_LIST_PTR *result); + +CK_RV p11_module_release_inlock_reentrant (CK_FUNCTION_LIST_PTR module); + +#endif /* __P11_MODULES_H__ */ diff --git a/p11-kit/p11-kit.h b/p11-kit/p11-kit.h index f83cbd0..a07bf40 100644 --- a/p11-kit/p11-kit.h +++ b/p11-kit/p11-kit.h @@ -44,54 +44,75 @@ #ifdef CRYPTOKI_GNU typedef ck_rv_t CK_RV; typedef struct ck_function_list* CK_FUNCTION_LIST_PTR; +typedef struct ck_function_list CK_FUNCTION_LIST; #endif +#include "p11-kit/deprecated.h" + #ifdef __cplusplus extern "C" { #endif -CK_RV p11_kit_initialize_registered (void); +enum { + P11_KIT_MODULE_UNMANAGED = 1 << 0, + P11_KIT_MODULE_CRITICAL = 1 << 1, +}; -CK_RV p11_kit_finalize_registered (void); +typedef void (* p11_kit_destroyer) (void *data); -CK_FUNCTION_LIST_PTR* p11_kit_registered_modules (void); +CK_FUNCTION_LIST ** p11_kit_modules_load (const char *reserved, + int flags); -char* p11_kit_registered_module_to_name (CK_FUNCTION_LIST_PTR module); +CK_RV p11_kit_modules_initialize (CK_FUNCTION_LIST **modules, + p11_kit_destroyer failure_callback); -CK_FUNCTION_LIST_PTR p11_kit_registered_name_to_module (const char *name); +CK_FUNCTION_LIST ** p11_kit_modules_load_and_initialize (int flags); -char* p11_kit_registered_option (CK_FUNCTION_LIST_PTR module, - const char *field); +CK_RV p11_kit_modules_finalize (CK_FUNCTION_LIST **modules); -CK_RV p11_kit_initialize_module (CK_FUNCTION_LIST_PTR module); +void p11_kit_modules_release (CK_FUNCTION_LIST **modules); -CK_RV p11_kit_finalize_module (CK_FUNCTION_LIST_PTR module); +void p11_kit_modules_finalize_and_release (CK_FUNCTION_LIST **modules); -CK_RV p11_kit_load_initialize_module (const char *module_path, - CK_FUNCTION_LIST_PTR *module); +CK_FUNCTION_LIST * p11_kit_module_for_name (CK_FUNCTION_LIST **modules, + const char *name); -const char* p11_kit_strerror (CK_RV rv); +char * p11_kit_module_get_name (CK_FUNCTION_LIST *module); -size_t p11_kit_space_strlen (const unsigned char *string, - size_t max_length); +int p11_kit_module_get_flags (CK_FUNCTION_LIST *module); -char* p11_kit_space_strdup (const unsigned char *string, - size_t max_length); +CK_FUNCTION_LIST * p11_kit_module_load (const char *module_path, + int flags); -#ifdef P11_KIT_FUTURE_UNSTABLE_API +CK_RV p11_kit_module_initialize (CK_FUNCTION_LIST *module); + +CK_RV p11_kit_module_finalize (CK_FUNCTION_LIST *module); -void p11_kit_set_progname (const char *progname); +void p11_kit_module_release (CK_FUNCTION_LIST *module); -void p11_kit_be_quiet (void); +char * p11_kit_config_option (CK_FUNCTION_LIST *module, + const char *option); -void p11_kit_be_loud (void); +const char* p11_kit_strerror (CK_RV rv); -const char* p11_kit_message (void); +size_t p11_kit_space_strlen (const unsigned char *string, + size_t max_length); -typedef void (* p11_kit_destroyer) (void *data); +char* p11_kit_space_strdup (const unsigned char *string, + size_t max_length); + +#ifdef P11_KIT_FUTURE_UNSTABLE_API + +void p11_kit_set_progname (const char *progname); + +void p11_kit_be_quiet (void); + +void p11_kit_be_loud (void); #endif +const char * p11_kit_message (void); + #ifdef __cplusplus } /* extern "C" */ #endif diff --git a/p11-kit/private.h b/p11-kit/private.h index f862975..0fa221b 100644 --- a/p11-kit/private.h +++ b/p11-kit/private.h @@ -38,16 +38,6 @@ #include "compat.h" #include "pkcs11.h" -extern CK_FUNCTION_LIST _p11_proxy_function_list; - -CK_FUNCTION_LIST_PTR_PTR _p11_kit_registered_modules_unlocked (void); - -CK_RV _p11_kit_initialize_registered_unlocked_reentrant (void); - -CK_RV _p11_kit_finalize_registered_unlocked_reentrant (void); - -void _p11_kit_proxy_after_fork (void); - CK_RV _p11_load_config_files_unlocked (const char *system_conf, const char *user_conf, int *user_mode); diff --git a/p11-kit/proxy.c b/p11-kit/proxy.c index 1908d34..36a43a1 100644 --- a/p11-kit/proxy.c +++ b/p11-kit/proxy.c @@ -35,15 +35,21 @@ #include "config.h" +#include "compat.h" #define P11_DEBUG_FLAG P11_DEBUG_PROXY +#define CRYPTOKI_EXPORTS + #include "debug.h" #include "dict.h" #include "library.h" #include "message.h" -#define CRYPTOKI_EXPORTS +#include "modules.h" #include "pkcs11.h" +#include "pkcs11x.h" #include "p11-kit.h" #include "private.h" +#include "proxy.h" +#include "virtual.h" #include <sys/types.h> #include <assert.h> @@ -70,17 +76,24 @@ typedef struct _Session { CK_SLOT_ID wrap_slot; } Session; -/* - * Shared data between threads, protected by the mutex, a structure so - * we can audit thread safety easier. - */ -static struct _Shared { +typedef struct { + int refs; Mapping *mappings; unsigned int n_mappings; - int mappings_refs; p11_dict *sessions; + CK_FUNCTION_LIST **modules; +} Proxy; + +typedef struct _State { + p11_virtual virt; + struct _State *next; + CK_FUNCTION_LIST *wrapped; CK_ULONG last_handle; -} gl = { NULL, 0, 0, NULL, FIRST_HANDLE }; + Proxy *px; +} State; + +static State *all_instances = NULL; +static State global = { { { { -1, -1 }, NULL, }, }, NULL, NULL, FIRST_HANDLE, NULL }; #define MANUFACTURER_ID "PKCS#11 Kit " #define LIBRARY_DESCRIPTION "PKCS#11 Kit Proxy Module " @@ -92,36 +105,42 @@ static struct _Shared { */ static CK_RV -map_slot_unlocked (CK_SLOT_ID slot, Mapping *mapping) +map_slot_unlocked (Proxy *px, + CK_SLOT_ID slot, + Mapping *mapping) { - assert (mapping); + assert (px != NULL); + assert (mapping != NULL); if (slot < MAPPING_OFFSET) return CKR_SLOT_ID_INVALID; slot -= MAPPING_OFFSET; - if (slot > gl.n_mappings) { + if (slot > px->n_mappings) { return CKR_SLOT_ID_INVALID; } else { - assert (gl.mappings); - memcpy (mapping, &gl.mappings[slot], sizeof (Mapping)); + assert (px->mappings); + memcpy (mapping, &px->mappings[slot], sizeof (Mapping)); return CKR_OK; } } static CK_RV -map_slot_to_real (CK_SLOT_ID_PTR slot, Mapping *mapping) +map_slot_to_real (Proxy *px, + CK_SLOT_ID_PTR slot, + Mapping *mapping) { CK_RV rv; - assert (mapping); + assert (px != NULL); + assert (mapping != NULL); p11_lock (); - if (!gl.mappings) + if (!px) rv = CKR_CRYPTOKI_NOT_INITIALIZED; else - rv = map_slot_unlocked (*slot, mapping); + rv = map_slot_unlocked (px, *slot, mapping); if (rv == CKR_OK) *slot = mapping->real_slot; @@ -131,24 +150,28 @@ map_slot_to_real (CK_SLOT_ID_PTR slot, Mapping *mapping) } static CK_RV -map_session_to_real (CK_SESSION_HANDLE_PTR handle, Mapping *mapping, Session *session) +map_session_to_real (Proxy *px, + CK_SESSION_HANDLE_PTR handle, + Mapping *mapping, + Session *session) { CK_RV rv = CKR_OK; Session *sess; - assert (handle); - assert (mapping); + assert (px != NULL); + assert (handle != NULL); + assert (mapping != NULL); p11_lock (); - if (!gl.sessions) { + if (!px) { rv = CKR_CRYPTOKI_NOT_INITIALIZED; } else { - assert (gl.sessions); - sess = p11_dict_get (gl.sessions, handle); + assert (px->sessions); + sess = p11_dict_get (px->sessions, handle); if (sess != NULL) { *handle = sess->real_session; - rv = map_slot_unlocked (sess->wrap_slot, mapping); + rv = map_slot_unlocked (px, sess->wrap_slot, mapping); if (session != NULL) memcpy (session, sess, sizeof (Session)); } else { @@ -162,45 +185,57 @@ map_session_to_real (CK_SESSION_HANDLE_PTR handle, Mapping *mapping, Session *se } static void -finalize_mappings_unlocked (void) +proxy_free (Proxy *py) { - assert (gl.mappings_refs); - - if (--gl.mappings_refs) - return; - - /* No more mappings */ - free (gl.mappings); - gl.mappings = NULL; - gl.n_mappings = 0; - - /* no more sessions */ - p11_dict_free (gl.sessions); - gl.sessions = NULL; + if (py) { + p11_kit_modules_finalize_and_release (py->modules); + p11_dict_free (py->sessions); + free (py->mappings); + free (py); + } } void -_p11_kit_proxy_after_fork (void) +p11_proxy_after_fork (void) { + p11_array *array; + State *state; + unsigned int i; + /* * After a fork the callers are supposed to call C_Initialize and all. * In addition the underlying libraries may change their state so free * up any mappings and all */ + array = p11_array_new (NULL); + p11_lock (); - gl.mappings_refs = 1; - finalize_mappings_unlocked (); - assert (!gl.mappings); + if (global.px) + p11_array_push (array, global.px); + global.px = NULL; + + for (state = all_instances; state != NULL; state = state->next) { + if (state->px) + p11_array_push (array, state->px); + state->px = NULL; + } p11_unlock (); + + for (i = 0; i < array->num; i++) + proxy_free (array->elem[i]); + p11_array_free (array); } static CK_RV -proxy_C_Finalize (CK_VOID_PTR reserved) +proxy_C_Finalize (CK_X_FUNCTION_LIST *self, + CK_VOID_PTR reserved) { - CK_RV rv; + Proxy *py = NULL; + State *state = (State *)self; + CK_RV rv = CKR_OK; p11_debug ("in"); @@ -212,17 +247,16 @@ proxy_C_Finalize (CK_VOID_PTR reserved) } else { p11_lock (); - /* WARNING: Reentrancy can occur here */ - rv = _p11_kit_finalize_registered_unlocked_reentrant (); - - /* - * If modules are all gone, then this was the last - * finalize, so cleanup our mappings - */ - if (gl.mappings_refs) - finalize_mappings_unlocked (); + if (!state->px) { + rv = CKR_CRYPTOKI_NOT_INITIALIZED; + } else if (state->px->refs-- == 1) { + py = state->px; + state->px = NULL; + } p11_unlock (); + + proxy_free (py); } p11_debug ("out: %lu", rv); @@ -230,35 +264,50 @@ proxy_C_Finalize (CK_VOID_PTR reserved) } static CK_RV -initialize_mappings_unlocked_reentrant (void) +proxy_create (Proxy **res) { - CK_FUNCTION_LIST_PTR *funcss, *f; + CK_FUNCTION_LIST_PTR *f; CK_FUNCTION_LIST_PTR funcs; - Mapping *mappings = NULL; - int n_mappings = 0; CK_SLOT_ID_PTR slots; CK_ULONG i, count; CK_RV rv = CKR_OK; + Proxy *py; - assert (!gl.mappings); + py = calloc (1, sizeof (Proxy)); + return_val_if_fail (py != NULL, CKR_HOST_MEMORY); - funcss = _p11_kit_registered_modules_unlocked (); - for (f = funcss; *f; ++f) { - funcs = *f; + p11_lock (); - assert (funcs); - slots = NULL; + /* WARNING: Reentrancy can occur here */ + rv = p11_modules_load_inlock_reentrant (0, &py->modules); - p11_unlock (); + p11_unlock (); - /* Ask module for its slots */ - rv = (funcs->C_GetSlotList) (FALSE, NULL, &count); - if (rv == CKR_OK && count) { - slots = calloc (sizeof (CK_SLOT_ID), count); - rv = (funcs->C_GetSlotList) (FALSE, slots, &count); - } + if (rv != CKR_OK) { + proxy_free (py); + free (py); + return rv; + } - p11_lock (); + rv = p11_kit_modules_initialize (py->modules, (p11_destroyer)p11_kit_module_release); + if (rv != CKR_OK) { + p11_kit_modules_release (py->modules); + free (py); + return rv; + } + + for (f = py->modules; *f; ++f) { + funcs = *f; + + assert (funcs != NULL); + slots = NULL; + + /* Ask module for its slots */ + rv = (funcs->C_GetSlotList) (FALSE, NULL, &count); + if (rv == CKR_OK && count) { + slots = calloc (sizeof (CK_SLOT_ID), count); + rv = (funcs->C_GetSlotList) (FALSE, slots, &count); + } if (rv != CKR_OK) { free (slots); @@ -267,41 +316,40 @@ initialize_mappings_unlocked_reentrant (void) return_val_if_fail (count == 0 || slots != NULL, CKR_GENERAL_ERROR); - mappings = realloc (mappings, sizeof (Mapping) * (n_mappings + count)); - return_val_if_fail (mappings != NULL, CKR_HOST_MEMORY); + py->mappings = realloc (py->mappings, sizeof (Mapping) * (py->n_mappings + count)); + return_val_if_fail (py->mappings != NULL, CKR_HOST_MEMORY); /* And now add a mapping for each of those slots */ for (i = 0; i < count; ++i) { - mappings[n_mappings].funcs = funcs; - mappings[n_mappings].wrap_slot = n_mappings + MAPPING_OFFSET; - mappings[n_mappings].real_slot = slots[i]; - ++n_mappings; + py->mappings[py->n_mappings].funcs = funcs; + py->mappings[py->n_mappings].wrap_slot = py->n_mappings + MAPPING_OFFSET; + py->mappings[py->n_mappings].real_slot = slots[i]; + ++py->n_mappings; } free (slots); } - free (funcss); - - /* Another thread raced us here due to above reentrancy */ - if (gl.mappings) { - free (mappings); - return CKR_OK; + if (rv != CKR_OK) { + proxy_free (py); + return rv; } - assert (!gl.sessions); - gl.mappings = mappings; - gl.n_mappings = n_mappings; - gl.sessions = p11_dict_new (p11_dict_ulongptr_hash, p11_dict_ulongptr_equal, NULL, free); - ++gl.mappings_refs; + py->sessions = p11_dict_new (p11_dict_ulongptr_hash, p11_dict_ulongptr_equal, NULL, free); + return_val_if_fail (py->sessions != NULL, CKR_HOST_MEMORY); + py->refs = 1; - /* Any cleanup necessary for failure will happen at caller */ - return rv; + *res = py; + return CKR_OK; } static CK_RV -proxy_C_Initialize (CK_VOID_PTR init_args) +proxy_C_Initialize (CK_X_FUNCTION_LIST *self, + CK_VOID_PTR init_args) { + State *state = (State *)self; + bool initialize = false; + Proxy *py; CK_RV rv; p11_library_init_once (); @@ -312,27 +360,43 @@ proxy_C_Initialize (CK_VOID_PTR init_args) p11_lock (); - /* WARNING: Reentrancy can occur here */ - rv = _p11_kit_initialize_registered_unlocked_reentrant (); - - /* WARNING: Reentrancy can occur here */ - if (rv == CKR_OK && gl.mappings_refs == 0) - rv = initialize_mappings_unlocked_reentrant (); + if (state->px == NULL) + initialize = true; + else + state->px->refs++; p11_unlock (); - p11_debug ("here"); + if (!initialize) { + p11_debug ("out: already: %lu", CKR_OK); + return CKR_OK; + } - if (rv != CKR_OK) - proxy_C_Finalize (NULL); + rv = proxy_create (&py); + if (rv != CKR_OK) { + p11_debug ("out: %lu", rv); + return rv; + } - p11_debug ("out: %lu", rv); + p11_lock (); + + if (state->px == NULL) { + state->px = py; + py = NULL; + } + + p11_unlock (); + + proxy_free (py); + p11_debug ("out: 0"); return rv; } static CK_RV -proxy_C_GetInfo (CK_INFO_PTR info) +proxy_C_GetInfo (CK_X_FUNCTION_LIST *self, + CK_INFO_PTR info) { + State *state = (State *)self; CK_RV rv = CKR_OK; p11_library_init_once (); @@ -341,7 +405,7 @@ proxy_C_GetInfo (CK_INFO_PTR info) p11_lock (); - if (!gl.mappings) + if (!state->px) rv = CKR_CRYPTOKI_NOT_INITIALIZED; p11_unlock (); @@ -349,6 +413,7 @@ proxy_C_GetInfo (CK_INFO_PTR info) if (rv != CKR_OK) return rv; + memset (info, 0, sizeof (CK_INFO)); info->cryptokiVersion.major = CRYPTOKI_VERSION_MAJOR; info->cryptokiVersion.minor = CRYPTOKI_VERSION_MINOR; info->libraryVersion.major = LIBRARY_VERSION_MAJOR; @@ -360,19 +425,12 @@ proxy_C_GetInfo (CK_INFO_PTR info) } static CK_RV -proxy_C_GetFunctionList (CK_FUNCTION_LIST_PTR_PTR list) -{ - /* Can be called before C_Initialize */ - - return_val_if_fail (list != NULL, CKR_ARGUMENTS_BAD); - *list = &_p11_proxy_function_list; - return CKR_OK; -} - -static CK_RV -proxy_C_GetSlotList (CK_BBOOL token_present, CK_SLOT_ID_PTR slot_list, - CK_ULONG_PTR count) +proxy_C_GetSlotList (CK_X_FUNCTION_LIST *self, + CK_BBOOL token_present, + CK_SLOT_ID_PTR slot_list, + CK_ULONG_PTR count) { + State *state = (State *)self; CK_SLOT_INFO info; Mapping *mapping; CK_ULONG index; @@ -383,14 +441,14 @@ proxy_C_GetSlotList (CK_BBOOL token_present, CK_SLOT_ID_PTR slot_list, p11_lock (); - if (!gl.mappings) { + if (!state->px) { rv = CKR_CRYPTOKI_NOT_INITIALIZED; } else { index = 0; /* Go through and build up a map */ - for (i = 0; i < gl.n_mappings; ++i) { - mapping = &gl.mappings[i]; + for (i = 0; i < state->px->n_mappings; ++i) { + mapping = &state->px->mappings[i]; /* Skip ones without a token if requested */ if (token_present) { @@ -420,84 +478,109 @@ proxy_C_GetSlotList (CK_BBOOL token_present, CK_SLOT_ID_PTR slot_list, } static CK_RV -proxy_C_GetSlotInfo (CK_SLOT_ID id, CK_SLOT_INFO_PTR info) +proxy_C_GetSlotInfo (CK_X_FUNCTION_LIST *self, + CK_SLOT_ID id, + CK_SLOT_INFO_PTR info) { + State *state = (State *)self; Mapping map; CK_RV rv; - rv = map_slot_to_real (&id, &map); + rv = map_slot_to_real (state->px, &id, &map); if (rv != CKR_OK) return rv; return (map.funcs->C_GetSlotInfo) (id, info); } static CK_RV -proxy_C_GetTokenInfo (CK_SLOT_ID id, CK_TOKEN_INFO_PTR info) +proxy_C_GetTokenInfo (CK_X_FUNCTION_LIST *self, + CK_SLOT_ID id, + CK_TOKEN_INFO_PTR info) { + State *state = (State *)self; Mapping map; CK_RV rv; - rv = map_slot_to_real (&id, &map); + rv = map_slot_to_real (state->px, &id, &map); if (rv != CKR_OK) return rv; return (map.funcs->C_GetTokenInfo) (id, info); } static CK_RV -proxy_C_GetMechanismList (CK_SLOT_ID id, CK_MECHANISM_TYPE_PTR mechanism_list, +proxy_C_GetMechanismList (CK_X_FUNCTION_LIST *self, + CK_SLOT_ID id, + CK_MECHANISM_TYPE_PTR mechanism_list, CK_ULONG_PTR count) { + State *state = (State *)self; Mapping map; CK_RV rv; - rv = map_slot_to_real (&id, &map); + rv = map_slot_to_real (state->px, &id, &map); if (rv != CKR_OK) return rv; return (map.funcs->C_GetMechanismList) (id, mechanism_list, count); } static CK_RV -proxy_C_GetMechanismInfo (CK_SLOT_ID id, CK_MECHANISM_TYPE type, +proxy_C_GetMechanismInfo (CK_X_FUNCTION_LIST *self, + CK_SLOT_ID id, + CK_MECHANISM_TYPE type, CK_MECHANISM_INFO_PTR info) { + State *state = (State *)self; Mapping map; CK_RV rv; - rv = map_slot_to_real (&id, &map); + rv = map_slot_to_real (state->px, &id, &map); if (rv != CKR_OK) return rv; return (map.funcs->C_GetMechanismInfo) (id, type, info); } static CK_RV -proxy_C_InitToken (CK_SLOT_ID id, CK_UTF8CHAR_PTR pin, CK_ULONG pin_len, CK_UTF8CHAR_PTR label) +proxy_C_InitToken (CK_X_FUNCTION_LIST *self, + CK_SLOT_ID id, + CK_UTF8CHAR_PTR pin, + CK_ULONG pin_len, + CK_UTF8CHAR_PTR label) { + State *state = (State *)self; Mapping map; CK_RV rv; - rv = map_slot_to_real (&id, &map); + rv = map_slot_to_real (state->px, &id, &map); if (rv != CKR_OK) return rv; return (map.funcs->C_InitToken) (id, pin, pin_len, label); } static CK_RV -proxy_C_WaitForSlotEvent (CK_FLAGS flags, CK_SLOT_ID_PTR slot, CK_VOID_PTR reserved) +proxy_C_WaitForSlotEvent (CK_X_FUNCTION_LIST *self, + CK_FLAGS flags, + CK_SLOT_ID_PTR slot, + CK_VOID_PTR reserved) { return CKR_FUNCTION_NOT_SUPPORTED; } static CK_RV -proxy_C_OpenSession (CK_SLOT_ID id, CK_FLAGS flags, CK_VOID_PTR user_data, - CK_NOTIFY callback, CK_SESSION_HANDLE_PTR handle) +proxy_C_OpenSession (CK_X_FUNCTION_LIST *self, + CK_SLOT_ID id, + CK_FLAGS flags, + CK_VOID_PTR user_data, + CK_NOTIFY callback, + CK_SESSION_HANDLE_PTR handle) { + State *state = (State *)self; Session *sess; Mapping map; CK_RV rv; return_val_if_fail (handle != NULL, CKR_ARGUMENTS_BAD); - rv = map_slot_to_real (&id, &map); + rv = map_slot_to_real (state->px, &id, &map); if (rv != CKR_OK) return rv; @@ -506,7 +589,7 @@ proxy_C_OpenSession (CK_SLOT_ID id, CK_FLAGS flags, CK_VOID_PTR user_data, if (rv == CKR_OK) { p11_lock (); - if (!gl.sessions) { + if (!state->px) { /* * The underlying module should have returned an error, so this * code should never be reached with properly behaving modules. @@ -519,8 +602,8 @@ proxy_C_OpenSession (CK_SLOT_ID id, CK_FLAGS flags, CK_VOID_PTR user_data, sess = calloc (1, sizeof (Session)); sess->wrap_slot = map.wrap_slot; sess->real_session = *handle; - sess->wrap_session = ++gl.last_handle; /* TODO: Handle wrapping, and then collisions */ - p11_dict_set (gl.sessions, &sess->wrap_session, sess); + sess->wrap_session = ++state->last_handle; /* TODO: Handle wrapping, and then collisions */ + p11_dict_set (state->px->sessions, &sess->wrap_session, sess); *handle = sess->wrap_session; } @@ -531,14 +614,16 @@ proxy_C_OpenSession (CK_SLOT_ID id, CK_FLAGS flags, CK_VOID_PTR user_data, } static CK_RV -proxy_C_CloseSession (CK_SESSION_HANDLE handle) +proxy_C_CloseSession (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE handle) { + State *state = (State *)self; CK_SESSION_HANDLE key; Mapping map; CK_RV rv; key = handle; - rv = map_session_to_real (&handle, &map, NULL); + rv = map_session_to_real (state->px, &handle, &map, NULL); if (rv != CKR_OK) return rv; rv = (map.funcs->C_CloseSession) (handle); @@ -546,8 +631,8 @@ proxy_C_CloseSession (CK_SESSION_HANDLE handle) if (rv == CKR_OK) { p11_lock (); - if (gl.sessions) - p11_dict_remove (gl.sessions, &key); + if (state->px) + p11_dict_remove (state->px->sessions, &key); p11_unlock (); } @@ -556,8 +641,10 @@ proxy_C_CloseSession (CK_SESSION_HANDLE handle) } static CK_RV -proxy_C_CloseAllSessions (CK_SLOT_ID id) +proxy_C_CloseAllSessions (CK_X_FUNCTION_LIST *self, + CK_SLOT_ID id) { + State *state = (State *)self; CK_SESSION_HANDLE_PTR to_close; CK_RV rv = CKR_OK; Session *sess; @@ -566,14 +653,15 @@ proxy_C_CloseAllSessions (CK_SLOT_ID id) p11_lock (); - if (!gl.sessions) { + if (!state->px) { rv = CKR_CRYPTOKI_NOT_INITIALIZED; } else { - to_close = calloc (sizeof (CK_SESSION_HANDLE), p11_dict_size (gl.sessions)); + assert (state->px->sessions != NULL); + to_close = calloc (sizeof (CK_SESSION_HANDLE), p11_dict_size (state->px->sessions)); if (!to_close) { rv = CKR_HOST_MEMORY; } else { - p11_dict_iterate (gl.sessions, &iter); + p11_dict_iterate (state->px->sessions, &iter); count = 0; while (p11_dict_next (&iter, NULL, (void**)&sess)) { if (sess->wrap_slot == id && to_close) @@ -588,46 +676,53 @@ proxy_C_CloseAllSessions (CK_SLOT_ID id) return rv; for (i = 0; i < count; ++i) - proxy_C_CloseSession (to_close[i]); + proxy_C_CloseSession (self, to_close[i]); free (to_close); return CKR_OK; } static CK_RV -proxy_C_GetFunctionStatus (CK_SESSION_HANDLE handle) +proxy_C_GetFunctionStatus (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE handle) { + State *state = (State *)self; Mapping map; CK_RV rv; - rv = map_session_to_real (&handle, &map, NULL); + rv = map_session_to_real (state->px, &handle, &map, NULL); if (rv != CKR_OK) return rv; return (map.funcs->C_GetFunctionStatus) (handle); } static CK_RV -proxy_C_CancelFunction (CK_SESSION_HANDLE handle) +proxy_C_CancelFunction (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE handle) { + State *state = (State *)self; Mapping map; CK_RV rv; - rv = map_session_to_real (&handle, &map, NULL); + rv = map_session_to_real (state->px, &handle, &map, NULL); if (rv != CKR_OK) return rv; return (map.funcs->C_CancelFunction) (handle); } static CK_RV -proxy_C_GetSessionInfo (CK_SESSION_HANDLE handle, CK_SESSION_INFO_PTR info) +proxy_C_GetSessionInfo (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE handle, + CK_SESSION_INFO_PTR info) { + State *state = (State *)self; Mapping map; CK_RV rv; if (info == NULL) return CKR_ARGUMENTS_BAD; - rv = map_session_to_real (&handle, &map, NULL); + rv = map_session_to_real (state->px, &handle, &map, NULL); if (rv != CKR_OK) return rv; @@ -639,12 +734,16 @@ proxy_C_GetSessionInfo (CK_SESSION_HANDLE handle, CK_SESSION_INFO_PTR info) } static CK_RV -proxy_C_InitPIN (CK_SESSION_HANDLE handle, CK_UTF8CHAR_PTR pin, CK_ULONG pin_len) +proxy_C_InitPIN (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE handle, + CK_UTF8CHAR_PTR pin, + CK_ULONG pin_len) { + State *state = (State *)self; Mapping map; CK_RV rv; - rv = map_session_to_real (&handle, &map, NULL); + rv = map_session_to_real (state->px, &handle, &map, NULL); if (rv != CKR_OK) return rv; @@ -652,13 +751,18 @@ proxy_C_InitPIN (CK_SESSION_HANDLE handle, CK_UTF8CHAR_PTR pin, CK_ULONG pin_len } static CK_RV -proxy_C_SetPIN (CK_SESSION_HANDLE handle, CK_UTF8CHAR_PTR old_pin, CK_ULONG old_pin_len, - CK_UTF8CHAR_PTR new_pin, CK_ULONG new_pin_len) +proxy_C_SetPIN (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE handle, + CK_UTF8CHAR_PTR old_pin, + CK_ULONG old_pin_len, + CK_UTF8CHAR_PTR new_pin, + CK_ULONG new_pin_len) { + State *state = (State *)self; Mapping map; CK_RV rv; - rv = map_session_to_real (&handle, &map, NULL); + rv = map_session_to_real (state->px, &handle, &map, NULL); if (rv != CKR_OK) return rv; @@ -666,39 +770,51 @@ proxy_C_SetPIN (CK_SESSION_HANDLE handle, CK_UTF8CHAR_PTR old_pin, CK_ULONG old_ } static CK_RV -proxy_C_GetOperationState (CK_SESSION_HANDLE handle, CK_BYTE_PTR operation_state, CK_ULONG_PTR operation_state_len) +proxy_C_GetOperationState (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE handle, + CK_BYTE_PTR operation_state, + CK_ULONG_PTR operation_state_len) { + State *state = (State *)self; Mapping map; CK_RV rv; - rv = map_session_to_real (&handle, &map, NULL); + rv = map_session_to_real (state->px, &handle, &map, NULL); if (rv != CKR_OK) return rv; return (map.funcs->C_GetOperationState) (handle, operation_state, operation_state_len); } static CK_RV -proxy_C_SetOperationState (CK_SESSION_HANDLE handle, CK_BYTE_PTR operation_state, - CK_ULONG operation_state_len, CK_OBJECT_HANDLE encryption_key, +proxy_C_SetOperationState (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE handle, + CK_BYTE_PTR operation_state, + CK_ULONG operation_state_len, + CK_OBJECT_HANDLE encryption_key, CK_OBJECT_HANDLE authentication_key) { + State *state = (State *)self; Mapping map; CK_RV rv; - rv = map_session_to_real (&handle, &map, NULL); + rv = map_session_to_real (state->px, &handle, &map, NULL); if (rv != CKR_OK) return rv; return (map.funcs->C_SetOperationState) (handle, operation_state, operation_state_len, encryption_key, authentication_key); } static CK_RV -proxy_C_Login (CK_SESSION_HANDLE handle, CK_USER_TYPE user_type, - CK_UTF8CHAR_PTR pin, CK_ULONG pin_len) +proxy_C_Login (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE handle, + CK_USER_TYPE user_type, + CK_UTF8CHAR_PTR pin, + CK_ULONG pin_len) { + State *state = (State *)self; Mapping map; CK_RV rv; - rv = map_session_to_real (&handle, &map, NULL); + rv = map_session_to_real (state->px, &handle, &map, NULL); if (rv != CKR_OK) return rv; @@ -706,25 +822,31 @@ proxy_C_Login (CK_SESSION_HANDLE handle, CK_USER_TYPE user_type, } static CK_RV -proxy_C_Logout (CK_SESSION_HANDLE handle) +proxy_C_Logout (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE handle) { + State *state = (State *)self; Mapping map; CK_RV rv; - rv = map_session_to_real (&handle, &map, NULL); + rv = map_session_to_real (state->px, &handle, &map, NULL); if (rv != CKR_OK) return rv; return (map.funcs->C_Logout) (handle); } static CK_RV -proxy_C_CreateObject (CK_SESSION_HANDLE handle, CK_ATTRIBUTE_PTR template, - CK_ULONG count, CK_OBJECT_HANDLE_PTR new_object) +proxy_C_CreateObject (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE handle, + CK_ATTRIBUTE_PTR template, + CK_ULONG count, + CK_OBJECT_HANDLE_PTR new_object) { + State *state = (State *)self; Mapping map; CK_RV rv; - rv = map_session_to_real (&handle, &map, NULL); + rv = map_session_to_real (state->px, &handle, &map, NULL); if (rv != CKR_OK) return rv; @@ -732,592 +854,1447 @@ proxy_C_CreateObject (CK_SESSION_HANDLE handle, CK_ATTRIBUTE_PTR template, } static CK_RV -proxy_C_CopyObject (CK_SESSION_HANDLE handle, CK_OBJECT_HANDLE object, - CK_ATTRIBUTE_PTR template, CK_ULONG count, +proxy_C_CopyObject (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE handle, + CK_OBJECT_HANDLE object, + CK_ATTRIBUTE_PTR template, + CK_ULONG count, CK_OBJECT_HANDLE_PTR new_object) { + State *state = (State *)self; Mapping map; CK_RV rv; - rv = map_session_to_real (&handle, &map, NULL); + rv = map_session_to_real (state->px, &handle, &map, NULL); if (rv != CKR_OK) return rv; return (map.funcs->C_CopyObject) (handle, object, template, count, new_object); } static CK_RV -proxy_C_DestroyObject (CK_SESSION_HANDLE handle, CK_OBJECT_HANDLE object) +proxy_C_DestroyObject (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE handle, + CK_OBJECT_HANDLE object) { + State *state = (State *)self; Mapping map; CK_RV rv; - rv = map_session_to_real (&handle, &map, NULL); + rv = map_session_to_real (state->px, &handle, &map, NULL); if (rv != CKR_OK) return rv; return (map.funcs->C_DestroyObject) (handle, object); } static CK_RV -proxy_C_GetObjectSize (CK_SESSION_HANDLE handle, CK_OBJECT_HANDLE object, +proxy_C_GetObjectSize (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE handle, + CK_OBJECT_HANDLE object, CK_ULONG_PTR size) { + State *state = (State *)self; Mapping map; CK_RV rv; - rv = map_session_to_real (&handle, &map, NULL); + rv = map_session_to_real (state->px, &handle, &map, NULL); if (rv != CKR_OK) return rv; return (map.funcs->C_GetObjectSize) (handle, object, size); } static CK_RV -proxy_C_GetAttributeValue (CK_SESSION_HANDLE handle, CK_OBJECT_HANDLE object, - CK_ATTRIBUTE_PTR template, CK_ULONG count) +proxy_C_GetAttributeValue (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE handle, + CK_OBJECT_HANDLE object, + CK_ATTRIBUTE_PTR template, + CK_ULONG count) { + State *state = (State *)self; Mapping map; CK_RV rv; - rv = map_session_to_real (&handle, &map, NULL); + rv = map_session_to_real (state->px, &handle, &map, NULL); if (rv != CKR_OK) return rv; return (map.funcs->C_GetAttributeValue) (handle, object, template, count); } static CK_RV -proxy_C_SetAttributeValue (CK_SESSION_HANDLE handle, CK_OBJECT_HANDLE object, - CK_ATTRIBUTE_PTR template, CK_ULONG count) +proxy_C_SetAttributeValue (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE handle, + CK_OBJECT_HANDLE object, + CK_ATTRIBUTE_PTR template, + CK_ULONG count) { + State *state = (State *)self; Mapping map; CK_RV rv; - rv = map_session_to_real (&handle, &map, NULL); + rv = map_session_to_real (state->px, &handle, &map, NULL); if (rv != CKR_OK) return rv; return (map.funcs->C_SetAttributeValue) (handle, object, template, count); } static CK_RV -proxy_C_FindObjectsInit (CK_SESSION_HANDLE handle, CK_ATTRIBUTE_PTR template, +proxy_C_FindObjectsInit (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE handle, + CK_ATTRIBUTE_PTR template, CK_ULONG count) { + State *state = (State *)self; Mapping map; CK_RV rv; - rv = map_session_to_real (&handle, &map, NULL); + rv = map_session_to_real (state->px, &handle, &map, NULL); if (rv != CKR_OK) return rv; return (map.funcs->C_FindObjectsInit) (handle, template, count); } static CK_RV -proxy_C_FindObjects (CK_SESSION_HANDLE handle, CK_OBJECT_HANDLE_PTR objects, - CK_ULONG max_count, CK_ULONG_PTR count) +proxy_C_FindObjects (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE handle, + CK_OBJECT_HANDLE_PTR objects, + CK_ULONG max_count, + CK_ULONG_PTR count) { + State *state = (State *)self; Mapping map; CK_RV rv; - rv = map_session_to_real (&handle, &map, NULL); + rv = map_session_to_real (state->px, &handle, &map, NULL); if (rv != CKR_OK) return rv; return (map.funcs->C_FindObjects) (handle, objects, max_count, count); } static CK_RV -proxy_C_FindObjectsFinal (CK_SESSION_HANDLE handle) +proxy_C_FindObjectsFinal (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE handle) { + State *state = (State *)self; Mapping map; CK_RV rv; - rv = map_session_to_real (&handle, &map, NULL); + rv = map_session_to_real (state->px, &handle, &map, NULL); if (rv != CKR_OK) return rv; return (map.funcs->C_FindObjectsFinal) (handle); } static CK_RV -proxy_C_EncryptInit (CK_SESSION_HANDLE handle, CK_MECHANISM_PTR mechanism, +proxy_C_EncryptInit (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE handle, + CK_MECHANISM_PTR mechanism, CK_OBJECT_HANDLE key) { + State *state = (State *)self; Mapping map; CK_RV rv; - rv = map_session_to_real (&handle, &map, NULL); + rv = map_session_to_real (state->px, &handle, &map, NULL); if (rv != CKR_OK) return rv; return (map.funcs->C_EncryptInit) (handle, mechanism, key); } static CK_RV -proxy_C_Encrypt (CK_SESSION_HANDLE handle, CK_BYTE_PTR data, CK_ULONG data_len, - CK_BYTE_PTR encrypted_data, CK_ULONG_PTR encrypted_data_len) +proxy_C_Encrypt (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE handle, + CK_BYTE_PTR input, + CK_ULONG input_len, + CK_BYTE_PTR encrypted_data, + CK_ULONG_PTR encrypted_data_len) { + State *state = (State *)self; Mapping map; CK_RV rv; - rv = map_session_to_real (&handle, &map, NULL); + rv = map_session_to_real (state->px, &handle, &map, NULL); if (rv != CKR_OK) return rv; - return (map.funcs->C_Encrypt) (handle, data, data_len, encrypted_data, encrypted_data_len); + return (map.funcs->C_Encrypt) (handle, input, input_len, encrypted_data, encrypted_data_len); } static CK_RV -proxy_C_EncryptUpdate (CK_SESSION_HANDLE handle, CK_BYTE_PTR part, - CK_ULONG part_len, CK_BYTE_PTR encrypted_part, +proxy_C_EncryptUpdate (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE handle, + CK_BYTE_PTR part, + CK_ULONG part_len, + CK_BYTE_PTR encrypted_part, CK_ULONG_PTR encrypted_part_len) { + State *state = (State *)self; Mapping map; CK_RV rv; - rv = map_session_to_real (&handle, &map, NULL); + rv = map_session_to_real (state->px, &handle, &map, NULL); if (rv != CKR_OK) return rv; return (map.funcs->C_EncryptUpdate) (handle, part, part_len, encrypted_part, encrypted_part_len); } static CK_RV -proxy_C_EncryptFinal (CK_SESSION_HANDLE handle, CK_BYTE_PTR last_part, +proxy_C_EncryptFinal (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE handle, + CK_BYTE_PTR last_part, CK_ULONG_PTR last_part_len) { + State *state = (State *)self; Mapping map; CK_RV rv; - rv = map_session_to_real (&handle, &map, NULL); + rv = map_session_to_real (state->px, &handle, &map, NULL); if (rv != CKR_OK) return rv; return (map.funcs->C_EncryptFinal) (handle, last_part, last_part_len); } static CK_RV -proxy_C_DecryptInit (CK_SESSION_HANDLE handle, CK_MECHANISM_PTR mechanism, +proxy_C_DecryptInit (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE handle, + CK_MECHANISM_PTR mechanism, CK_OBJECT_HANDLE key) { + State *state = (State *)self; Mapping map; CK_RV rv; - rv = map_session_to_real (&handle, &map, NULL); + rv = map_session_to_real (state->px, &handle, &map, NULL); if (rv != CKR_OK) return rv; return (map.funcs->C_DecryptInit) (handle, mechanism, key); } static CK_RV -proxy_C_Decrypt (CK_SESSION_HANDLE handle, CK_BYTE_PTR enc_data, - CK_ULONG enc_data_len, CK_BYTE_PTR data, CK_ULONG_PTR data_len) +proxy_C_Decrypt (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE handle, + CK_BYTE_PTR enc_data, + CK_ULONG enc_data_len, + CK_BYTE_PTR output, + CK_ULONG_PTR output_len) { + State *state = (State *)self; Mapping map; CK_RV rv; - rv = map_session_to_real (&handle, &map, NULL); + rv = map_session_to_real (state->px, &handle, &map, NULL); if (rv != CKR_OK) return rv; - return (map.funcs->C_Decrypt) (handle, enc_data, enc_data_len, data, data_len); + return (map.funcs->C_Decrypt) (handle, enc_data, enc_data_len, output, output_len); } static CK_RV -proxy_C_DecryptUpdate (CK_SESSION_HANDLE handle, CK_BYTE_PTR enc_part, - CK_ULONG enc_part_len, CK_BYTE_PTR part, CK_ULONG_PTR part_len) +proxy_C_DecryptUpdate (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE handle, + CK_BYTE_PTR enc_part, + CK_ULONG enc_part_len, + CK_BYTE_PTR part, + CK_ULONG_PTR part_len) { + State *state = (State *)self; Mapping map; CK_RV rv; - rv = map_session_to_real (&handle, &map, NULL); + rv = map_session_to_real (state->px, &handle, &map, NULL); if (rv != CKR_OK) return rv; return (map.funcs->C_DecryptUpdate) (handle, enc_part, enc_part_len, part, part_len); } static CK_RV -proxy_C_DecryptFinal (CK_SESSION_HANDLE handle, CK_BYTE_PTR last_part, +proxy_C_DecryptFinal (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE handle, + CK_BYTE_PTR last_part, CK_ULONG_PTR last_part_len) { + State *state = (State *)self; Mapping map; CK_RV rv; - rv = map_session_to_real (&handle, &map, NULL); + rv = map_session_to_real (state->px, &handle, &map, NULL); if (rv != CKR_OK) return rv; return (map.funcs->C_DecryptFinal) (handle, last_part, last_part_len); } static CK_RV -proxy_C_DigestInit (CK_SESSION_HANDLE handle, CK_MECHANISM_PTR mechanism) +proxy_C_DigestInit (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE handle, + CK_MECHANISM_PTR mechanism) { + State *state = (State *)self; Mapping map; CK_RV rv; - rv = map_session_to_real (&handle, &map, NULL); + rv = map_session_to_real (state->px, &handle, &map, NULL); if (rv != CKR_OK) return rv; return (map.funcs->C_DigestInit) (handle, mechanism); } static CK_RV -proxy_C_Digest (CK_SESSION_HANDLE handle, CK_BYTE_PTR data, CK_ULONG data_len, - CK_BYTE_PTR digest, CK_ULONG_PTR digest_len) +proxy_C_Digest (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE handle, + CK_BYTE_PTR input, + CK_ULONG input_len, + CK_BYTE_PTR digest, + CK_ULONG_PTR digest_len) { + State *state = (State *)self; Mapping map; CK_RV rv; - rv = map_session_to_real (&handle, &map, NULL); + rv = map_session_to_real (state->px, &handle, &map, NULL); if (rv != CKR_OK) return rv; - return (map.funcs->C_Digest) (handle, data, data_len, digest, digest_len); + return (map.funcs->C_Digest) (handle, input, input_len, digest, digest_len); } static CK_RV -proxy_C_DigestUpdate (CK_SESSION_HANDLE handle, CK_BYTE_PTR part, CK_ULONG part_len) +proxy_C_DigestUpdate (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE handle, + CK_BYTE_PTR part, + CK_ULONG part_len) { + State *state = (State *)self; Mapping map; CK_RV rv; - rv = map_session_to_real (&handle, &map, NULL); + rv = map_session_to_real (state->px, &handle, &map, NULL); if (rv != CKR_OK) return rv; return (map.funcs->C_DigestUpdate) (handle, part, part_len); } static CK_RV -proxy_C_DigestKey (CK_SESSION_HANDLE handle, CK_OBJECT_HANDLE key) +proxy_C_DigestKey (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE handle, + CK_OBJECT_HANDLE key) { + State *state = (State *)self; Mapping map; CK_RV rv; - rv = map_session_to_real (&handle, &map, NULL); + rv = map_session_to_real (state->px, &handle, &map, NULL); if (rv != CKR_OK) return rv; return (map.funcs->C_DigestKey) (handle, key); } static CK_RV -proxy_C_DigestFinal (CK_SESSION_HANDLE handle, CK_BYTE_PTR digest, +proxy_C_DigestFinal (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE handle, + CK_BYTE_PTR digest, CK_ULONG_PTR digest_len) { + State *state = (State *)self; Mapping map; CK_RV rv; - rv = map_session_to_real (&handle, &map, NULL); + rv = map_session_to_real (state->px, &handle, &map, NULL); if (rv != CKR_OK) return rv; return (map.funcs->C_DigestFinal) (handle, digest, digest_len); } static CK_RV -proxy_C_SignInit (CK_SESSION_HANDLE handle, CK_MECHANISM_PTR mechanism, +proxy_C_SignInit (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE handle, + CK_MECHANISM_PTR mechanism, CK_OBJECT_HANDLE key) { + State *state = (State *)self; Mapping map; CK_RV rv; - rv = map_session_to_real (&handle, &map, NULL); + rv = map_session_to_real (state->px, &handle, &map, NULL); if (rv != CKR_OK) return rv; return (map.funcs->C_SignInit) (handle, mechanism, key); } static CK_RV -proxy_C_Sign (CK_SESSION_HANDLE handle, CK_BYTE_PTR data, CK_ULONG data_len, - CK_BYTE_PTR signature, CK_ULONG_PTR signature_len) +proxy_C_Sign (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE handle, + CK_BYTE_PTR input, + CK_ULONG input_len, + CK_BYTE_PTR signature, + CK_ULONG_PTR signature_len) { + State *state = (State *)self; Mapping map; CK_RV rv; - rv = map_session_to_real (&handle, &map, NULL); + rv = map_session_to_real (state->px, &handle, &map, NULL); if (rv != CKR_OK) return rv; - return (map.funcs->C_Sign) (handle, data, data_len, signature, signature_len); + return (map.funcs->C_Sign) (handle, input, input_len, signature, signature_len); } static CK_RV -proxy_C_SignUpdate (CK_SESSION_HANDLE handle, CK_BYTE_PTR part, CK_ULONG part_len) +proxy_C_SignUpdate (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE handle, + CK_BYTE_PTR part, + CK_ULONG part_len) { + State *state = (State *)self; Mapping map; CK_RV rv; - rv = map_session_to_real (&handle, &map, NULL); + rv = map_session_to_real (state->px, &handle, &map, NULL); if (rv != CKR_OK) return rv; return (map.funcs->C_SignUpdate) (handle, part, part_len); } static CK_RV -proxy_C_SignFinal (CK_SESSION_HANDLE handle, CK_BYTE_PTR signature, +proxy_C_SignFinal (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE handle, + CK_BYTE_PTR signature, CK_ULONG_PTR signature_len) { + State *state = (State *)self; Mapping map; CK_RV rv; - rv = map_session_to_real (&handle, &map, NULL); + rv = map_session_to_real (state->px, &handle, &map, NULL); if (rv != CKR_OK) return rv; return (map.funcs->C_SignFinal) (handle, signature, signature_len); } static CK_RV -proxy_C_SignRecoverInit (CK_SESSION_HANDLE handle, CK_MECHANISM_PTR mechanism, +proxy_C_SignRecoverInit (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE handle, + CK_MECHANISM_PTR mechanism, CK_OBJECT_HANDLE key) { + State *state = (State *)self; Mapping map; CK_RV rv; - rv = map_session_to_real (&handle, &map, NULL); + rv = map_session_to_real (state->px, &handle, &map, NULL); if (rv != CKR_OK) return rv; return (map.funcs->C_SignRecoverInit) (handle, mechanism, key); } static CK_RV -proxy_C_SignRecover (CK_SESSION_HANDLE handle, CK_BYTE_PTR data, CK_ULONG data_len, - CK_BYTE_PTR signature, CK_ULONG_PTR signature_len) +proxy_C_SignRecover (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE handle, + CK_BYTE_PTR input, + CK_ULONG input_len, + CK_BYTE_PTR signature, + CK_ULONG_PTR signature_len) { + State *state = (State *)self; Mapping map; CK_RV rv; - rv = map_session_to_real (&handle, &map, NULL); + rv = map_session_to_real (state->px, &handle, &map, NULL); if (rv != CKR_OK) return rv; - return (map.funcs->C_SignRecover) (handle, data, data_len, signature, signature_len); + return (map.funcs->C_SignRecover) (handle, input, input_len, signature, signature_len); } static CK_RV -proxy_C_VerifyInit (CK_SESSION_HANDLE handle, CK_MECHANISM_PTR mechanism, +proxy_C_VerifyInit (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE handle, + CK_MECHANISM_PTR mechanism, CK_OBJECT_HANDLE key) { + State *state = (State *)self; Mapping map; CK_RV rv; - rv = map_session_to_real (&handle, &map, NULL); + rv = map_session_to_real (state->px, &handle, &map, NULL); if (rv != CKR_OK) return rv; return (map.funcs->C_VerifyInit) (handle, mechanism, key); } static CK_RV -proxy_C_Verify (CK_SESSION_HANDLE handle, CK_BYTE_PTR data, CK_ULONG data_len, - CK_BYTE_PTR signature, CK_ULONG signature_len) +proxy_C_Verify (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE handle, + CK_BYTE_PTR input, + CK_ULONG input_len, + CK_BYTE_PTR signature, + CK_ULONG signature_len) { + State *state = (State *)self; Mapping map; CK_RV rv; - rv = map_session_to_real (&handle, &map, NULL); + rv = map_session_to_real (state->px, &handle, &map, NULL); if (rv != CKR_OK) return rv; - return (map.funcs->C_Verify) (handle, data, data_len, signature, signature_len); + return (map.funcs->C_Verify) (handle, input, input_len, signature, signature_len); } static CK_RV -proxy_C_VerifyUpdate (CK_SESSION_HANDLE handle, CK_BYTE_PTR part, CK_ULONG part_len) +proxy_C_VerifyUpdate (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE handle, + CK_BYTE_PTR part, + CK_ULONG part_len) { + State *state = (State *)self; Mapping map; CK_RV rv; - rv = map_session_to_real (&handle, &map, NULL); + rv = map_session_to_real (state->px, &handle, &map, NULL); if (rv != CKR_OK) return rv; return (map.funcs->C_VerifyUpdate) (handle, part, part_len); } static CK_RV -proxy_C_VerifyFinal (CK_SESSION_HANDLE handle, CK_BYTE_PTR signature, +proxy_C_VerifyFinal (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE handle, + CK_BYTE_PTR signature, CK_ULONG signature_len) { + State *state = (State *)self; Mapping map; CK_RV rv; - rv = map_session_to_real (&handle, &map, NULL); + rv = map_session_to_real (state->px, &handle, &map, NULL); if (rv != CKR_OK) return rv; return (map.funcs->C_VerifyFinal) (handle, signature, signature_len); } static CK_RV -proxy_C_VerifyRecoverInit (CK_SESSION_HANDLE handle, CK_MECHANISM_PTR mechanism, +proxy_C_VerifyRecoverInit (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE handle, + CK_MECHANISM_PTR mechanism, CK_OBJECT_HANDLE key) { + State *state = (State *)self; Mapping map; CK_RV rv; - rv = map_session_to_real (&handle, &map, NULL); + rv = map_session_to_real (state->px, &handle, &map, NULL); if (rv != CKR_OK) return rv; return (map.funcs->C_VerifyRecoverInit) (handle, mechanism, key); } static CK_RV -proxy_C_VerifyRecover (CK_SESSION_HANDLE handle, CK_BYTE_PTR signature, - CK_ULONG signature_len, CK_BYTE_PTR data, CK_ULONG_PTR data_len) +proxy_C_VerifyRecover (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE handle, + CK_BYTE_PTR signature, + CK_ULONG signature_len, + CK_BYTE_PTR output, + CK_ULONG_PTR output_len) { + State *state = (State *)self; Mapping map; CK_RV rv; - rv = map_session_to_real (&handle, &map, NULL); + rv = map_session_to_real (state->px, &handle, &map, NULL); if (rv != CKR_OK) return rv; - return (map.funcs->C_VerifyRecover) (handle, signature, signature_len, data, data_len); + return (map.funcs->C_VerifyRecover) (handle, signature, signature_len, output, output_len); } static CK_RV -proxy_C_DigestEncryptUpdate (CK_SESSION_HANDLE handle, CK_BYTE_PTR part, - CK_ULONG part_len, CK_BYTE_PTR enc_part, +proxy_C_DigestEncryptUpdate (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE handle, + CK_BYTE_PTR part, + CK_ULONG part_len, + CK_BYTE_PTR enc_part, CK_ULONG_PTR enc_part_len) { + State *state = (State *)self; Mapping map; CK_RV rv; - rv = map_session_to_real (&handle, &map, NULL); + rv = map_session_to_real (state->px, &handle, &map, NULL); if (rv != CKR_OK) return rv; return (map.funcs->C_DigestEncryptUpdate) (handle, part, part_len, enc_part, enc_part_len); } static CK_RV -proxy_C_DecryptDigestUpdate (CK_SESSION_HANDLE handle, CK_BYTE_PTR enc_part, - CK_ULONG enc_part_len, CK_BYTE_PTR part, +proxy_C_DecryptDigestUpdate (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE handle, + CK_BYTE_PTR enc_part, + CK_ULONG enc_part_len, + CK_BYTE_PTR part, CK_ULONG_PTR part_len) { + State *state = (State *)self; Mapping map; CK_RV rv; - rv = map_session_to_real (&handle, &map, NULL); + rv = map_session_to_real (state->px, &handle, &map, NULL); if (rv != CKR_OK) return rv; return (map.funcs->C_DecryptDigestUpdate) (handle, enc_part, enc_part_len, part, part_len); } static CK_RV -proxy_C_SignEncryptUpdate (CK_SESSION_HANDLE handle, CK_BYTE_PTR part, - CK_ULONG part_len, CK_BYTE_PTR enc_part, +proxy_C_SignEncryptUpdate (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE handle, + CK_BYTE_PTR part, + CK_ULONG part_len, + CK_BYTE_PTR enc_part, CK_ULONG_PTR enc_part_len) { + State *state = (State *)self; Mapping map; CK_RV rv; - rv = map_session_to_real (&handle, &map, NULL); + rv = map_session_to_real (state->px, &handle, &map, NULL); if (rv != CKR_OK) return rv; return (map.funcs->C_SignEncryptUpdate) (handle, part, part_len, enc_part, enc_part_len); } static CK_RV -proxy_C_DecryptVerifyUpdate (CK_SESSION_HANDLE handle, CK_BYTE_PTR enc_part, - CK_ULONG enc_part_len, CK_BYTE_PTR part, +proxy_C_DecryptVerifyUpdate (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE handle, + CK_BYTE_PTR enc_part, + CK_ULONG enc_part_len, + CK_BYTE_PTR part, CK_ULONG_PTR part_len) { + State *state = (State *)self; Mapping map; CK_RV rv; - rv = map_session_to_real (&handle, &map, NULL); + rv = map_session_to_real (state->px, &handle, &map, NULL); if (rv != CKR_OK) return rv; return (map.funcs->C_DecryptVerifyUpdate) (handle, enc_part, enc_part_len, part, part_len); } static CK_RV -proxy_C_GenerateKey (CK_SESSION_HANDLE handle, CK_MECHANISM_PTR mechanism, - CK_ATTRIBUTE_PTR template, CK_ULONG count, +proxy_C_GenerateKey (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE handle, + CK_MECHANISM_PTR mechanism, + CK_ATTRIBUTE_PTR template, + CK_ULONG count, CK_OBJECT_HANDLE_PTR key) { + State *state = (State *)self; Mapping map; CK_RV rv; - rv = map_session_to_real (&handle, &map, NULL); + rv = map_session_to_real (state->px, &handle, &map, NULL); if (rv != CKR_OK) return rv; return (map.funcs->C_GenerateKey) (handle, mechanism, template, count, key); } static CK_RV -proxy_C_GenerateKeyPair (CK_SESSION_HANDLE handle, CK_MECHANISM_PTR mechanism, - CK_ATTRIBUTE_PTR pub_template, CK_ULONG pub_count, - CK_ATTRIBUTE_PTR priv_template, CK_ULONG priv_count, - CK_OBJECT_HANDLE_PTR pub_key, CK_OBJECT_HANDLE_PTR priv_key) +proxy_C_GenerateKeyPair (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE handle, + CK_MECHANISM_PTR mechanism, + CK_ATTRIBUTE_PTR pub_template, + CK_ULONG pub_count, + CK_ATTRIBUTE_PTR priv_template, + CK_ULONG priv_count, + CK_OBJECT_HANDLE_PTR pub_key, + CK_OBJECT_HANDLE_PTR priv_key) { + State *state = (State *)self; Mapping map; CK_RV rv; - rv = map_session_to_real (&handle, &map, NULL); + rv = map_session_to_real (state->px, &handle, &map, NULL); if (rv != CKR_OK) return rv; return (map.funcs->C_GenerateKeyPair) (handle, mechanism, pub_template, pub_count, priv_template, priv_count, pub_key, priv_key); } static CK_RV -proxy_C_WrapKey (CK_SESSION_HANDLE handle, CK_MECHANISM_PTR mechanism, - CK_OBJECT_HANDLE wrapping_key, CK_OBJECT_HANDLE key, - CK_BYTE_PTR wrapped_key, CK_ULONG_PTR wrapped_key_len) +proxy_C_WrapKey (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE handle, + CK_MECHANISM_PTR mechanism, + CK_OBJECT_HANDLE wrapping_key, + CK_OBJECT_HANDLE key, + CK_BYTE_PTR wrapped_key, + CK_ULONG_PTR wrapped_key_len) { + State *state = (State *)self; Mapping map; CK_RV rv; - rv = map_session_to_real (&handle, &map, NULL); + rv = map_session_to_real (state->px, &handle, &map, NULL); if (rv != CKR_OK) return rv; return (map.funcs->C_WrapKey) (handle, mechanism, wrapping_key, key, wrapped_key, wrapped_key_len); } static CK_RV -proxy_C_UnwrapKey (CK_SESSION_HANDLE handle, CK_MECHANISM_PTR mechanism, - CK_OBJECT_HANDLE unwrapping_key, CK_BYTE_PTR wrapped_key, - CK_ULONG wrapped_key_len, CK_ATTRIBUTE_PTR template, - CK_ULONG count, CK_OBJECT_HANDLE_PTR key) +proxy_C_UnwrapKey (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE handle, + CK_MECHANISM_PTR mechanism, + CK_OBJECT_HANDLE unwrapping_key, + CK_BYTE_PTR wrapped_key, + CK_ULONG wrapped_key_len, + CK_ATTRIBUTE_PTR template, + CK_ULONG count, + CK_OBJECT_HANDLE_PTR key) { + State *state = (State *)self; Mapping map; CK_RV rv; - rv = map_session_to_real (&handle, &map, NULL); + rv = map_session_to_real (state->px, &handle, &map, NULL); if (rv != CKR_OK) return rv; return (map.funcs->C_UnwrapKey) (handle, mechanism, unwrapping_key, wrapped_key, wrapped_key_len, template, count, key); } static CK_RV -proxy_C_DeriveKey (CK_SESSION_HANDLE handle, CK_MECHANISM_PTR mechanism, - CK_OBJECT_HANDLE base_key, CK_ATTRIBUTE_PTR template, - CK_ULONG count, CK_OBJECT_HANDLE_PTR key) +proxy_C_DeriveKey (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE handle, + CK_MECHANISM_PTR mechanism, + CK_OBJECT_HANDLE base_key, + CK_ATTRIBUTE_PTR template, + CK_ULONG count, + CK_OBJECT_HANDLE_PTR key) { + State *state = (State *)self; Mapping map; CK_RV rv; - rv = map_session_to_real (&handle, &map, NULL); + rv = map_session_to_real (state->px, &handle, &map, NULL); if (rv != CKR_OK) return rv; return (map.funcs->C_DeriveKey) (handle, mechanism, base_key, template, count, key); } static CK_RV -proxy_C_SeedRandom (CK_SESSION_HANDLE handle, CK_BYTE_PTR seed, CK_ULONG seed_len) +proxy_C_SeedRandom (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE handle, + CK_BYTE_PTR seed, + CK_ULONG seed_len) { + State *state = (State *)self; Mapping map; CK_RV rv; - rv = map_session_to_real (&handle, &map, NULL); + rv = map_session_to_real (state->px, &handle, &map, NULL); if (rv != CKR_OK) return rv; return (map.funcs->C_SeedRandom) (handle, seed, seed_len); } static CK_RV -proxy_C_GenerateRandom (CK_SESSION_HANDLE handle, CK_BYTE_PTR random_data, - CK_ULONG random_len) +proxy_C_GenerateRandom (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE handle, + CK_BYTE_PTR random_data, + CK_ULONG random_len) { + State *state = (State *)self; Mapping map; CK_RV rv; - rv = map_session_to_real (&handle, &map, NULL); + rv = map_session_to_real (state->px, &handle, &map, NULL); if (rv != CKR_OK) return rv; return (map.funcs->C_GenerateRandom) (handle, random_data, random_len); } /* -------------------------------------------------------------------- + * Global module functions + */ + +static CK_FUNCTION_LIST module_functions; + +static CK_RV +module_C_Initialize (CK_VOID_PTR init_args) +{ + return proxy_C_Initialize (&global.virt.funcs, init_args); +} + +static CK_RV +module_C_Finalize (CK_VOID_PTR reserved) +{ + return proxy_C_Finalize (&global.virt.funcs, reserved); +} + +static CK_RV +module_C_GetInfo (CK_INFO_PTR info) +{ + return proxy_C_GetInfo (&global.virt.funcs, info); +} + +static CK_RV +module_C_GetFunctionList (CK_FUNCTION_LIST_PTR_PTR list) +{ + return_val_if_fail (list != NULL, CKR_ARGUMENTS_BAD); + *list = &module_functions; + return CKR_OK; +} + +static CK_RV +module_C_GetSlotList (CK_BBOOL token_present, + CK_SLOT_ID_PTR slot_list, + CK_ULONG_PTR count) +{ + return proxy_C_GetSlotList (&global.virt.funcs, token_present, slot_list, count); +} + +static CK_RV +module_C_GetSlotInfo (CK_SLOT_ID id, + CK_SLOT_INFO_PTR info) +{ + return proxy_C_GetSlotInfo (&global.virt.funcs, id, info); +} + +static CK_RV +module_C_GetTokenInfo (CK_SLOT_ID id, + CK_TOKEN_INFO_PTR info) +{ + return proxy_C_GetTokenInfo (&global.virt.funcs, id, info); +} + +static CK_RV +module_C_GetMechanismList (CK_SLOT_ID id, + CK_MECHANISM_TYPE_PTR mechanism_list, + CK_ULONG_PTR count) +{ + return proxy_C_GetMechanismList (&global.virt.funcs, id, mechanism_list, count); +} + +static CK_RV +module_C_GetMechanismInfo (CK_SLOT_ID id, + CK_MECHANISM_TYPE type, + CK_MECHANISM_INFO_PTR info) +{ + return proxy_C_GetMechanismInfo (&global.virt.funcs, id, type, info); +} + +static CK_RV +module_C_InitToken (CK_SLOT_ID id, + CK_UTF8CHAR_PTR pin, + CK_ULONG pin_len, + CK_UTF8CHAR_PTR label) +{ + return proxy_C_InitToken (&global.virt.funcs, id, pin, pin_len, label); +} + +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); +} + +static CK_RV +module_C_OpenSession (CK_SLOT_ID id, + CK_FLAGS flags, + CK_VOID_PTR user_data, + CK_NOTIFY callback, + CK_SESSION_HANDLE_PTR handle) +{ + return proxy_C_OpenSession (&global.virt.funcs, id, flags, user_data, callback, + handle); +} + +static CK_RV +module_C_CloseSession (CK_SESSION_HANDLE handle) +{ + return proxy_C_CloseSession (&global.virt.funcs, handle); +} + +static CK_RV +module_C_CloseAllSessions (CK_SLOT_ID id) +{ + return proxy_C_CloseAllSessions (&global.virt.funcs, id); +} + +static CK_RV +module_C_GetFunctionStatus (CK_SESSION_HANDLE handle) +{ + return proxy_C_GetFunctionStatus (&global.virt.funcs, handle); +} + +static CK_RV +module_C_CancelFunction (CK_SESSION_HANDLE handle) +{ + return proxy_C_CancelFunction (&global.virt.funcs, handle); +} + +static CK_RV +module_C_GetSessionInfo (CK_SESSION_HANDLE handle, + CK_SESSION_INFO_PTR info) +{ + return proxy_C_GetSessionInfo (&global.virt.funcs, handle, info); +} + +static CK_RV +module_C_InitPIN (CK_SESSION_HANDLE handle, + CK_UTF8CHAR_PTR pin, + CK_ULONG pin_len) +{ + return proxy_C_InitPIN (&global.virt.funcs, handle, pin, pin_len); +} + +static CK_RV +module_C_SetPIN (CK_SESSION_HANDLE handle, + CK_UTF8CHAR_PTR old_pin, + CK_ULONG old_pin_len, + CK_UTF8CHAR_PTR new_pin, + CK_ULONG new_pin_len) +{ + return proxy_C_SetPIN (&global.virt.funcs, handle, old_pin, old_pin_len, new_pin, + new_pin_len); +} + +static CK_RV +module_C_GetOperationState (CK_SESSION_HANDLE handle, + CK_BYTE_PTR operation_state, + CK_ULONG_PTR operation_state_len) +{ + return proxy_C_GetOperationState (&global.virt.funcs, handle, operation_state, + operation_state_len); +} + +static CK_RV +module_C_SetOperationState (CK_SESSION_HANDLE handle, + CK_BYTE_PTR operation_state, + CK_ULONG operation_state_len, + CK_OBJECT_HANDLE encryption_key, + CK_OBJECT_HANDLE authentication_key) +{ + return proxy_C_SetOperationState (&global.virt.funcs, handle, operation_state, + operation_state_len, encryption_key, + authentication_key); +} + +static CK_RV +module_C_Login (CK_SESSION_HANDLE handle, + CK_USER_TYPE user_type, + CK_UTF8CHAR_PTR pin, + CK_ULONG pin_len) +{ + return proxy_C_Login (&global.virt.funcs, handle, user_type, pin, pin_len); +} + +static CK_RV +module_C_Logout (CK_SESSION_HANDLE handle) +{ + return proxy_C_Logout (&global.virt.funcs, handle); +} + +static CK_RV +module_C_CreateObject (CK_SESSION_HANDLE handle, + CK_ATTRIBUTE_PTR template, + CK_ULONG count, + CK_OBJECT_HANDLE_PTR new_object) +{ + return proxy_C_CreateObject (&global.virt.funcs, handle, template, count, + new_object); +} + +static CK_RV +module_C_CopyObject (CK_SESSION_HANDLE handle, + CK_OBJECT_HANDLE object, + CK_ATTRIBUTE_PTR template, + CK_ULONG count, + CK_OBJECT_HANDLE_PTR new_object) +{ + return proxy_C_CopyObject (&global.virt.funcs, handle, object, template, count, + new_object); +} + +static CK_RV +module_C_DestroyObject (CK_SESSION_HANDLE handle, + CK_OBJECT_HANDLE object) +{ + return proxy_C_DestroyObject (&global.virt.funcs, handle, object); +} + +static CK_RV +module_C_GetObjectSize (CK_SESSION_HANDLE handle, + CK_OBJECT_HANDLE object, + CK_ULONG_PTR size) +{ + return proxy_C_GetObjectSize (&global.virt.funcs, handle, object, size); +} + +static CK_RV +module_C_GetAttributeValue (CK_SESSION_HANDLE handle, + CK_OBJECT_HANDLE object, + CK_ATTRIBUTE_PTR template, + CK_ULONG count) +{ + return proxy_C_GetAttributeValue (&global.virt.funcs, handle, object, template, + count); +} + +static CK_RV +module_C_SetAttributeValue (CK_SESSION_HANDLE handle, + CK_OBJECT_HANDLE object, + CK_ATTRIBUTE_PTR template, + CK_ULONG count) +{ + return proxy_C_SetAttributeValue (&global.virt.funcs, handle, object, template, + count); +} + +static CK_RV +module_C_FindObjectsInit (CK_SESSION_HANDLE handle, + CK_ATTRIBUTE_PTR template, + CK_ULONG count) +{ + return proxy_C_FindObjectsInit (&global.virt.funcs, handle, template, count); +} + +static CK_RV +module_C_FindObjects (CK_SESSION_HANDLE handle, + CK_OBJECT_HANDLE_PTR objects, + CK_ULONG max_count, + CK_ULONG_PTR count) +{ + return proxy_C_FindObjects (&global.virt.funcs, handle, objects, max_count, count); +} + +static CK_RV +module_C_FindObjectsFinal (CK_SESSION_HANDLE handle) +{ + return proxy_C_FindObjectsFinal (&global.virt.funcs, handle); +} + +static CK_RV +module_C_EncryptInit (CK_SESSION_HANDLE handle, + CK_MECHANISM_PTR mechanism, + CK_OBJECT_HANDLE key) +{ + return proxy_C_EncryptInit (&global.virt.funcs, handle, mechanism, key); +} + +static CK_RV +module_C_Encrypt (CK_SESSION_HANDLE handle, + CK_BYTE_PTR data, + CK_ULONG data_len, + CK_BYTE_PTR encrypted_data, + CK_ULONG_PTR encrypted_data_len) +{ + return proxy_C_Encrypt (&global.virt.funcs, handle, data, data_len, + encrypted_data, encrypted_data_len); +} + +static CK_RV +module_C_EncryptUpdate (CK_SESSION_HANDLE handle, + CK_BYTE_PTR part, + CK_ULONG part_len, + CK_BYTE_PTR encrypted_part, + CK_ULONG_PTR encrypted_part_len) +{ + return proxy_C_EncryptUpdate (&global.virt.funcs, handle, part, part_len, + encrypted_part, encrypted_part_len); +} + +static CK_RV +module_C_EncryptFinal (CK_SESSION_HANDLE handle, + CK_BYTE_PTR last_part, + CK_ULONG_PTR last_part_len) +{ + return proxy_C_EncryptFinal (&global.virt.funcs, handle, last_part, last_part_len); +} + +static CK_RV +module_C_DecryptInit (CK_SESSION_HANDLE handle, + CK_MECHANISM_PTR mechanism, + CK_OBJECT_HANDLE key) +{ + return proxy_C_DecryptInit (&global.virt.funcs, handle, mechanism, key); +} + +static CK_RV +module_C_Decrypt (CK_SESSION_HANDLE handle, + CK_BYTE_PTR enc_data, + CK_ULONG enc_data_len, + CK_BYTE_PTR data, + CK_ULONG_PTR data_len) +{ + return proxy_C_Decrypt (&global.virt.funcs, handle, enc_data, enc_data_len, + data, data_len); +} + +static CK_RV +module_C_DecryptUpdate (CK_SESSION_HANDLE handle, + CK_BYTE_PTR enc_part, + CK_ULONG enc_part_len, + CK_BYTE_PTR part, + CK_ULONG_PTR part_len) +{ + return proxy_C_DecryptUpdate (&global.virt.funcs, handle, enc_part, enc_part_len, + part, part_len); +} + +static CK_RV +module_C_DecryptFinal (CK_SESSION_HANDLE handle, + CK_BYTE_PTR last_part, + CK_ULONG_PTR last_part_len) +{ + return proxy_C_DecryptFinal (&global.virt.funcs, handle, last_part, last_part_len); +} + +static CK_RV +module_C_DigestInit (CK_SESSION_HANDLE handle, + CK_MECHANISM_PTR mechanism) +{ + return proxy_C_DigestInit (&global.virt.funcs, handle, mechanism); +} + +static CK_RV +module_C_Digest (CK_SESSION_HANDLE handle, + CK_BYTE_PTR data, + CK_ULONG data_len, + CK_BYTE_PTR digest, + CK_ULONG_PTR digest_len) +{ + return proxy_C_Digest (&global.virt.funcs, handle, data, data_len, digest, + digest_len); +} + +static CK_RV +module_C_DigestUpdate (CK_SESSION_HANDLE handle, + CK_BYTE_PTR part, + CK_ULONG part_len) +{ + return proxy_C_DigestUpdate (&global.virt.funcs, handle, part, part_len); +} + +static CK_RV +module_C_DigestKey (CK_SESSION_HANDLE handle, + CK_OBJECT_HANDLE key) +{ + return proxy_C_DigestKey (&global.virt.funcs, handle, key); +} + +static CK_RV +module_C_DigestFinal (CK_SESSION_HANDLE handle, + CK_BYTE_PTR digest, + CK_ULONG_PTR digest_len) +{ + return proxy_C_DigestFinal (&global.virt.funcs, handle, digest, digest_len); +} + +static CK_RV +module_C_SignInit (CK_SESSION_HANDLE handle, + CK_MECHANISM_PTR mechanism, + CK_OBJECT_HANDLE key) +{ + return proxy_C_SignInit (&global.virt.funcs, handle, mechanism, key); +} + +static CK_RV +module_C_Sign (CK_SESSION_HANDLE handle, + CK_BYTE_PTR data, + CK_ULONG data_len, + CK_BYTE_PTR signature, + CK_ULONG_PTR signature_len) +{ + return proxy_C_Sign (&global.virt.funcs, handle, data, data_len, signature, + signature_len); +} + +static CK_RV +module_C_SignUpdate (CK_SESSION_HANDLE handle, + CK_BYTE_PTR part, + CK_ULONG part_len) +{ + return proxy_C_SignUpdate (&global.virt.funcs, handle, part, part_len); +} + +static CK_RV +module_C_SignFinal (CK_SESSION_HANDLE handle, + CK_BYTE_PTR signature, + CK_ULONG_PTR signature_len) +{ + return proxy_C_SignFinal (&global.virt.funcs, handle, signature, signature_len); +} + +static CK_RV +module_C_SignRecoverInit (CK_SESSION_HANDLE handle, + CK_MECHANISM_PTR mechanism, + CK_OBJECT_HANDLE key) +{ + return proxy_C_SignRecoverInit (&global.virt.funcs, handle, mechanism, key); +} + +static CK_RV +module_C_SignRecover (CK_SESSION_HANDLE handle, + CK_BYTE_PTR data, + CK_ULONG data_len, + CK_BYTE_PTR signature, + CK_ULONG_PTR signature_len) +{ + return proxy_C_SignRecover (&global.virt.funcs, handle, data, data_len, + signature, signature_len); +} + +static CK_RV +module_C_VerifyInit (CK_SESSION_HANDLE handle, + CK_MECHANISM_PTR mechanism, + CK_OBJECT_HANDLE key) +{ + return proxy_C_VerifyInit (&global.virt.funcs, handle, mechanism, key); +} + +static CK_RV +module_C_Verify (CK_SESSION_HANDLE handle, + CK_BYTE_PTR data, + CK_ULONG data_len, + CK_BYTE_PTR signature, + CK_ULONG signature_len) +{ + return proxy_C_Verify (&global.virt.funcs, handle, data, data_len, signature, + signature_len); +} + +static CK_RV +module_C_VerifyUpdate (CK_SESSION_HANDLE handle, + CK_BYTE_PTR part, + CK_ULONG part_len) +{ + return proxy_C_VerifyUpdate (&global.virt.funcs, handle, part, part_len); +} + +static CK_RV +module_C_VerifyFinal (CK_SESSION_HANDLE handle, + CK_BYTE_PTR signature, + CK_ULONG signature_len) +{ + return proxy_C_VerifyFinal (&global.virt.funcs, handle, signature, signature_len); +} + +static CK_RV +module_C_VerifyRecoverInit (CK_SESSION_HANDLE handle, + CK_MECHANISM_PTR mechanism, + CK_OBJECT_HANDLE key) +{ + return proxy_C_VerifyRecoverInit (&global.virt.funcs, handle, mechanism, key); +} + +static CK_RV +module_C_VerifyRecover (CK_SESSION_HANDLE handle, + CK_BYTE_PTR signature, + CK_ULONG signature_len, + CK_BYTE_PTR data, + CK_ULONG_PTR data_len) +{ + return proxy_C_VerifyRecover (&global.virt.funcs, handle, signature, signature_len, + data, data_len); +} + +static CK_RV +module_C_DigestEncryptUpdate (CK_SESSION_HANDLE handle, + CK_BYTE_PTR part, + CK_ULONG part_len, + CK_BYTE_PTR enc_part, + CK_ULONG_PTR enc_part_len) +{ + return proxy_C_DigestEncryptUpdate (&global.virt.funcs, handle, part, part_len, + enc_part, enc_part_len); +} + +static CK_RV +module_C_DecryptDigestUpdate (CK_SESSION_HANDLE handle, + CK_BYTE_PTR enc_part, + CK_ULONG enc_part_len, + CK_BYTE_PTR part, + CK_ULONG_PTR part_len) +{ + return proxy_C_DecryptDigestUpdate (&global.virt.funcs, handle, enc_part, + enc_part_len, part, part_len); +} + +static CK_RV +module_C_SignEncryptUpdate (CK_SESSION_HANDLE handle, + CK_BYTE_PTR part, + CK_ULONG part_len, + CK_BYTE_PTR enc_part, + CK_ULONG_PTR enc_part_len) +{ + return proxy_C_SignEncryptUpdate (&global.virt.funcs, handle, part, part_len, + enc_part, enc_part_len); +} + +static CK_RV +module_C_DecryptVerifyUpdate (CK_SESSION_HANDLE handle, + CK_BYTE_PTR enc_part, + CK_ULONG enc_part_len, + CK_BYTE_PTR part, + CK_ULONG_PTR part_len) +{ + return proxy_C_DecryptVerifyUpdate (&global.virt.funcs, handle, enc_part, + enc_part_len, part, part_len); +} + +static CK_RV +module_C_GenerateKey (CK_SESSION_HANDLE handle, + CK_MECHANISM_PTR mechanism, + CK_ATTRIBUTE_PTR template, + CK_ULONG count, + CK_OBJECT_HANDLE_PTR key) +{ + return proxy_C_GenerateKey (&global.virt.funcs, handle, mechanism, template, count, + key); +} + +static CK_RV +module_C_GenerateKeyPair (CK_SESSION_HANDLE handle, + CK_MECHANISM_PTR mechanism, + CK_ATTRIBUTE_PTR pub_template, + CK_ULONG pub_count, + CK_ATTRIBUTE_PTR priv_template, + CK_ULONG priv_count, + CK_OBJECT_HANDLE_PTR pub_key, + CK_OBJECT_HANDLE_PTR priv_key) +{ + return proxy_C_GenerateKeyPair (&global.virt.funcs, handle, mechanism, pub_template, + pub_count, priv_template, priv_count, + pub_key, priv_key); +} + +static CK_RV +module_C_WrapKey (CK_SESSION_HANDLE handle, + CK_MECHANISM_PTR mechanism, + CK_OBJECT_HANDLE wrapping_key, + CK_OBJECT_HANDLE key, + CK_BYTE_PTR wrapped_key, + CK_ULONG_PTR wrapped_key_len) +{ + return proxy_C_WrapKey (&global.virt.funcs, handle, mechanism, wrapping_key, + key, wrapped_key, wrapped_key_len); +} + +static CK_RV +module_C_UnwrapKey (CK_SESSION_HANDLE handle, + CK_MECHANISM_PTR mechanism, + CK_OBJECT_HANDLE unwrapping_key, + CK_BYTE_PTR wrapped_key, + CK_ULONG wrapped_key_len, + CK_ATTRIBUTE_PTR template, + CK_ULONG count, + CK_OBJECT_HANDLE_PTR key) +{ + return proxy_C_UnwrapKey (&global.virt.funcs, handle, mechanism, unwrapping_key, + wrapped_key, wrapped_key_len, template, + count, key); +} + +static CK_RV +module_C_DeriveKey (CK_SESSION_HANDLE handle, + CK_MECHANISM_PTR mechanism, + CK_OBJECT_HANDLE base_key, + CK_ATTRIBUTE_PTR template, + CK_ULONG count, + CK_OBJECT_HANDLE_PTR key) +{ + return proxy_C_DeriveKey (&global.virt.funcs, handle, mechanism, base_key, + template, count, key); +} + +static CK_RV +module_C_SeedRandom (CK_SESSION_HANDLE handle, + CK_BYTE_PTR seed, + CK_ULONG seed_len) +{ + return proxy_C_SeedRandom (&global.virt.funcs, handle, seed, seed_len); +} + +static CK_RV +module_C_GenerateRandom (CK_SESSION_HANDLE handle, + CK_BYTE_PTR random_data, + CK_ULONG random_len) +{ + return proxy_C_GenerateRandom (&global.virt.funcs, handle, random_data, random_len); +} + +/* -------------------------------------------------------------------- * MODULE ENTRY POINT */ -CK_FUNCTION_LIST _p11_proxy_function_list = { - { CRYPTOKI_VERSION_MAJOR, CRYPTOKI_VERSION_MINOR }, /* version */ +static CK_FUNCTION_LIST module_functions = { + { CRYPTOKI_VERSION_MAJOR, CRYPTOKI_VERSION_MINOR }, + module_C_Initialize, + module_C_Finalize, + module_C_GetInfo, + module_C_GetFunctionList, + module_C_GetSlotList, + module_C_GetSlotInfo, + module_C_GetTokenInfo, + module_C_GetMechanismList, + module_C_GetMechanismInfo, + module_C_InitToken, + module_C_InitPIN, + module_C_SetPIN, + module_C_OpenSession, + module_C_CloseSession, + module_C_CloseAllSessions, + module_C_GetSessionInfo, + module_C_GetOperationState, + module_C_SetOperationState, + module_C_Login, + module_C_Logout, + module_C_CreateObject, + module_C_CopyObject, + module_C_DestroyObject, + module_C_GetObjectSize, + module_C_GetAttributeValue, + module_C_SetAttributeValue, + module_C_FindObjectsInit, + module_C_FindObjects, + module_C_FindObjectsFinal, + module_C_EncryptInit, + module_C_Encrypt, + module_C_EncryptUpdate, + module_C_EncryptFinal, + module_C_DecryptInit, + module_C_Decrypt, + module_C_DecryptUpdate, + module_C_DecryptFinal, + module_C_DigestInit, + module_C_Digest, + module_C_DigestUpdate, + module_C_DigestKey, + module_C_DigestFinal, + module_C_SignInit, + module_C_Sign, + module_C_SignUpdate, + module_C_SignFinal, + module_C_SignRecoverInit, + module_C_SignRecover, + module_C_VerifyInit, + module_C_Verify, + module_C_VerifyUpdate, + module_C_VerifyFinal, + module_C_VerifyRecoverInit, + module_C_VerifyRecover, + module_C_DigestEncryptUpdate, + module_C_DecryptDigestUpdate, + module_C_SignEncryptUpdate, + module_C_DecryptVerifyUpdate, + module_C_GenerateKey, + module_C_GenerateKeyPair, + module_C_WrapKey, + module_C_UnwrapKey, + module_C_DeriveKey, + module_C_SeedRandom, + module_C_GenerateRandom, + module_C_GetFunctionStatus, + module_C_CancelFunction, + module_C_WaitForSlotEvent +}; + +static CK_X_FUNCTION_LIST proxy_functions = { + { CRYPTOKI_VERSION_MAJOR, CRYPTOKI_VERSION_MINOR }, proxy_C_Initialize, proxy_C_Finalize, proxy_C_GetInfo, - proxy_C_GetFunctionList, proxy_C_GetSlotList, proxy_C_GetSlotInfo, proxy_C_GetTokenInfo, @@ -1379,18 +2356,73 @@ CK_FUNCTION_LIST _p11_proxy_function_list = { proxy_C_DeriveKey, proxy_C_SeedRandom, proxy_C_GenerateRandom, - proxy_C_GetFunctionStatus, - proxy_C_CancelFunction, - proxy_C_WaitForSlotEvent + proxy_C_WaitForSlotEvent, }; #ifdef OS_WIN32 __declspec(dllexport) #endif - CK_RV C_GetFunctionList (CK_FUNCTION_LIST_PTR_PTR list) { + CK_FUNCTION_LIST_PTR module = NULL; + State *state; + CK_RV rv = CKR_OK; + p11_library_init_once (); - return proxy_C_GetFunctionList (list); + p11_lock (); + + if (p11_virtual_can_wrap ()) { + state = calloc (1, sizeof (State)); + if (!state) { + rv = CKR_HOST_MEMORY; + + } else { + p11_virtual_init (&state->virt, &proxy_functions, state, NULL); + state->last_handle = FIRST_HANDLE; + + module = p11_virtual_wrap (&state->virt, free); + if (module == NULL) { + rv = CKR_GENERAL_ERROR; + + } else { + state->wrapped = module; + state->next = all_instances; + all_instances = state; + } + } + } + + if (rv == CKR_OK) { + if (module == NULL) + module = &module_functions; + + /* We use this as a check below */ + module->C_WaitForSlotEvent = module_C_WaitForSlotEvent; + *list = module; + } + + p11_unlock (); + + return rv; +} + +void +p11_proxy_module_cleanup (void) +{ + State *state, *next; + + state = all_instances; + all_instances = NULL; + + for (; state != NULL; state = next) { + next = state->next; + p11_virtual_unwrap (state->wrapped); + } +} + +bool +p11_proxy_module_check (CK_FUNCTION_LIST_PTR module) +{ + return (module->C_WaitForSlotEvent == module_C_WaitForSlotEvent); } diff --git a/p11-kit/proxy.h b/p11-kit/proxy.h new file mode 100644 index 0000000..df05be0 --- /dev/null +++ b/p11-kit/proxy.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2013 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 <stefw@redhat.com> + */ + +#ifndef __P11_PROXY_H__ +#define __P11_PROXY_H__ + +void p11_proxy_after_fork (void); + +bool p11_proxy_module_check (CK_FUNCTION_LIST_PTR module); + +void p11_proxy_module_cleanup (void); + + +#endif /* __P11_PROXY_H__ */ diff --git a/p11-kit/tests/Makefile.am b/p11-kit/tests/Makefile.am index c7b87ae..6963850 100644 --- a/p11-kit/tests/Makefile.am +++ b/p11-kit/tests/Makefile.am @@ -3,29 +3,41 @@ include $(top_srcdir)/build/Makefile.tests COMMON = $(top_srcdir)/common -INCLUDES = \ +AM_CPPFLAGS = \ -I$(top_srcdir) \ -I$(srcdir)/.. \ -I$(COMMON) \ - $(CUTEST_CFLAGS) + $(TEST_CFLAGS) LDADD = \ $(top_builddir)/p11-kit/libp11-kit-testable.la \ - $(top_builddir)/common/libp11-mock.la \ + $(top_builddir)/common/libp11-test.la \ $(top_builddir)/common/libp11-common.la \ $(CUTEST_LIBS) \ $(LTLIBINTL) CHECK_PROGS = \ - progname-test \ - conf-test \ - uri-test \ - pin-test \ + test-progname \ + test-conf \ + test-uri \ + test-pin \ test-init \ test-modules \ + test-deprecated \ + test-proxy \ test-iter \ $(NULL) +if WITH_FFI + +CHECK_PROGS += \ + test-virtual \ + test-managed \ + test-log \ + $(NULL) + +endif + noinst_PROGRAMS = \ print-messages \ $(CHECK_PROGS) @@ -45,7 +57,7 @@ mock_one_la_CFLAGS = \ $(AM_CFLAGS) mock_one_la_LIBADD = \ - $(top_builddir)/common/libp11-mock.la \ + $(top_builddir)/common/libp11-test.la \ $(top_builddir)/common/libp11-common.la \ $(NULL) @@ -68,4 +80,6 @@ mock_four_la_LDFLAGS = $(mock_one_la_LDFLAGS) mock_four_la_LIBADD = $(mock_one_la_LIBADD) EXTRA_DIST = \ - files + files \ + test-mock.c \ + $(NULL) diff --git a/p11-kit/tests/files/system-pkcs11.conf b/p11-kit/tests/files/system-pkcs11.conf index 20741e7..a3aa273 100644 --- a/p11-kit/tests/files/system-pkcs11.conf +++ b/p11-kit/tests/files/system-pkcs11.conf @@ -1,3 +1,6 @@ # Merge in user config -user-config: merge
\ No newline at end of file +user-config: merge + +# Another option +new: world
\ No newline at end of file diff --git a/p11-kit/tests/files/user-modules/one.module b/p11-kit/tests/files/user-modules/one.module index c371e4a..6f1a2e8 100644 --- a/p11-kit/tests/files/user-modules/one.module +++ b/p11-kit/tests/files/user-modules/one.module @@ -1,2 +1,3 @@ -setting: user1
\ No newline at end of file +setting: user1 +managed: yes
\ No newline at end of file diff --git a/p11-kit/tests/conf-test.c b/p11-kit/tests/test-conf.c index d259cf8..c214bac 100644 --- a/p11-kit/tests/conf-test.c +++ b/p11-kit/tests/test-conf.c @@ -33,7 +33,7 @@ */ #include "config.h" -#include "CuTest.h" +#include "test.h" #include <errno.h> #include <stdlib.h> @@ -47,54 +47,54 @@ #include "private.h" static void -test_parse_conf_1 (CuTest *tc) +test_parse_conf_1 (void) { p11_dict *map; const char *value; map = _p11_conf_parse_file (SRCDIR "/files/test-1.conf", 0); - CuAssertPtrNotNull (tc, map); + assert_ptr_not_null (map); value = p11_dict_get (map, "key1"); - CuAssertStrEquals (tc, "value1", value); + assert_str_eq ("value1", value); value = p11_dict_get (map, "with-colon"); - CuAssertStrEquals (tc, "value-of-colon", value); + assert_str_eq ("value-of-colon", value); value = p11_dict_get (map, "with-whitespace"); - CuAssertStrEquals (tc, "value-with-whitespace", value); + assert_str_eq ("value-with-whitespace", value); value = p11_dict_get (map, "embedded-comment"); - CuAssertStrEquals (tc, "this is # not a comment", value); + assert_str_eq ("this is # not a comment", value); p11_dict_free (map); } static void -test_parse_ignore_missing (CuTest *tc) +test_parse_ignore_missing (void) { p11_dict *map; map = _p11_conf_parse_file (SRCDIR "/files/non-existant.conf", CONF_IGNORE_MISSING); - CuAssertPtrNotNull (tc, map); + assert_ptr_not_null (map); - CuAssertIntEquals (tc, 0, p11_dict_size (map)); - CuAssertPtrEquals (tc, NULL, (void*)p11_message_last ()); + assert_num_eq (0, p11_dict_size (map)); + assert (p11_message_last () == NULL); p11_dict_free (map); } static void -test_parse_fail_missing (CuTest *tc) +test_parse_fail_missing (void) { p11_dict *map; map = _p11_conf_parse_file (SRCDIR "/files/non-existant.conf", 0); - CuAssertPtrEquals (tc, map, NULL); - CuAssertPtrNotNull (tc, p11_message_last ()); + assert (map == NULL); + assert_ptr_not_null (p11_message_last ()); } static void -test_merge_defaults (CuTest *tc) +test_merge_defaults (void) { p11_dict *values; p11_dict *defaults; @@ -109,19 +109,19 @@ test_merge_defaults (CuTest *tc) p11_dict_set (defaults, strdup ("three"), strdup ("default3")); if (!_p11_conf_merge_defaults (values, defaults)) - CuFail (tc, "should not be reached"); + assert_not_reached (); p11_dict_free (defaults); - CuAssertStrEquals (tc, p11_dict_get (values, "one"), "real1"); - CuAssertStrEquals (tc, p11_dict_get (values, "two"), "real2"); - CuAssertStrEquals (tc, p11_dict_get (values, "three"), "default3"); + assert_str_eq (p11_dict_get (values, "one"), "real1"); + assert_str_eq (p11_dict_get (values, "two"), "real2"); + assert_str_eq (p11_dict_get (values, "three"), "default3"); p11_dict_free (values); } static void -test_load_globals_merge (CuTest *tc) +test_load_globals_merge (void) { int user_mode = -1; p11_dict *config; @@ -131,19 +131,19 @@ test_load_globals_merge (CuTest *tc) config = _p11_conf_load_globals (SRCDIR "/files/test-system-merge.conf", SRCDIR "/files/test-user.conf", &user_mode); - CuAssertPtrNotNull (tc, config); - CuAssertStrEquals (tc, NULL, p11_message_last ()); - CuAssertIntEquals (tc, CONF_USER_MERGE, user_mode); + assert_ptr_not_null (config); + assert (NULL == p11_message_last ()); + assert_num_eq (CONF_USER_MERGE, user_mode); - CuAssertStrEquals (tc, p11_dict_get (config, "key1"), "system1"); - CuAssertStrEquals (tc, p11_dict_get (config, "key2"), "user2"); - CuAssertStrEquals (tc, p11_dict_get (config, "key3"), "user3"); + assert_str_eq (p11_dict_get (config, "key1"), "system1"); + assert_str_eq (p11_dict_get (config, "key2"), "user2"); + assert_str_eq (p11_dict_get (config, "key3"), "user3"); p11_dict_free (config); } static void -test_load_globals_no_user (CuTest *tc) +test_load_globals_no_user (void) { int user_mode = -1; p11_dict *config; @@ -153,19 +153,19 @@ test_load_globals_no_user (CuTest *tc) config = _p11_conf_load_globals (SRCDIR "/files/test-system-none.conf", SRCDIR "/files/test-user.conf", &user_mode); - CuAssertPtrNotNull (tc, config); - CuAssertStrEquals (tc, NULL, p11_message_last ()); - CuAssertIntEquals (tc, CONF_USER_NONE, user_mode); + assert_ptr_not_null (config); + assert (NULL == p11_message_last ()); + assert_num_eq (CONF_USER_NONE, user_mode); - CuAssertStrEquals (tc, p11_dict_get (config, "key1"), "system1"); - CuAssertStrEquals (tc, p11_dict_get (config, "key2"), "system2"); - CuAssertStrEquals (tc, p11_dict_get (config, "key3"), "system3"); + assert_str_eq (p11_dict_get (config, "key1"), "system1"); + assert_str_eq (p11_dict_get (config, "key2"), "system2"); + assert_str_eq (p11_dict_get (config, "key3"), "system3"); p11_dict_free (config); } static void -test_load_globals_user_sets_only (CuTest *tc) +test_load_globals_user_sets_only (void) { int user_mode = -1; p11_dict *config; @@ -175,19 +175,19 @@ test_load_globals_user_sets_only (CuTest *tc) config = _p11_conf_load_globals (SRCDIR "/files/test-system-merge.conf", SRCDIR "/files/test-user-only.conf", &user_mode); - CuAssertPtrNotNull (tc, config); - CuAssertStrEquals (tc, NULL, p11_message_last ()); - CuAssertIntEquals (tc, CONF_USER_ONLY, user_mode); + assert_ptr_not_null (config); + assert (NULL == p11_message_last ()); + assert_num_eq (CONF_USER_ONLY, user_mode); - CuAssertStrEquals (tc, p11_dict_get (config, "key1"), NULL); - CuAssertStrEquals (tc, p11_dict_get (config, "key2"), "user2"); - CuAssertStrEquals (tc, p11_dict_get (config, "key3"), "user3"); + assert (p11_dict_get (config, "key1") == NULL); + assert_str_eq (p11_dict_get (config, "key2"), "user2"); + assert_str_eq (p11_dict_get (config, "key3"), "user3"); p11_dict_free (config); } static void -test_load_globals_system_sets_only (CuTest *tc) +test_load_globals_system_sets_only (void) { int user_mode = -1; p11_dict *config; @@ -197,19 +197,19 @@ test_load_globals_system_sets_only (CuTest *tc) config = _p11_conf_load_globals (SRCDIR "/files/test-system-only.conf", SRCDIR "/files/test-user.conf", &user_mode); - CuAssertPtrNotNull (tc, config); - CuAssertStrEquals (tc, NULL, p11_message_last ()); - CuAssertIntEquals (tc, CONF_USER_ONLY, user_mode); + assert_ptr_not_null (config); + assert (NULL == p11_message_last ()); + assert_num_eq (CONF_USER_ONLY, user_mode); - CuAssertStrEquals (tc, p11_dict_get (config, "key1"), NULL); - CuAssertStrEquals (tc, p11_dict_get (config, "key2"), "user2"); - CuAssertStrEquals (tc, p11_dict_get (config, "key3"), "user3"); + assert (p11_dict_get (config, "key1") == NULL); + assert_str_eq (p11_dict_get (config, "key2"), "user2"); + assert_str_eq (p11_dict_get (config, "key3"), "user3"); p11_dict_free (config); } static void -test_load_globals_system_sets_invalid (CuTest *tc) +test_load_globals_system_sets_invalid (void) { int user_mode = -1; p11_dict *config; @@ -221,15 +221,15 @@ test_load_globals_system_sets_invalid (CuTest *tc) SRCDIR "/files/non-existant.conf", &user_mode); error = errno; - CuAssertPtrEquals (tc, NULL, config); - CuAssertIntEquals (tc, EINVAL, error); - CuAssertPtrNotNull (tc, p11_message_last ()); + assert_ptr_eq (NULL, config); + assert_num_eq (EINVAL, error); + assert_ptr_not_null (p11_message_last ()); p11_dict_free (config); } static void -test_load_globals_user_sets_invalid (CuTest *tc) +test_load_globals_user_sets_invalid (void) { int user_mode = -1; p11_dict *config; @@ -241,9 +241,9 @@ test_load_globals_user_sets_invalid (CuTest *tc) SRCDIR "/files/test-user-invalid.conf", &user_mode); error = errno; - CuAssertPtrEquals (tc, NULL, config); - CuAssertIntEquals (tc, EINVAL, error); - CuAssertPtrNotNull (tc, p11_message_last ()); + assert_ptr_eq (NULL, config); + assert_num_eq (EINVAL, error); + assert_ptr_not_null (p11_message_last ()); p11_dict_free (config); } @@ -256,7 +256,7 @@ assert_msg_contains (const char *msg, } static void -test_load_modules_merge (CuTest *tc) +test_load_modules_merge (void) { p11_dict *configs; p11_dict *config; @@ -267,29 +267,29 @@ test_load_modules_merge (CuTest *tc) SRCDIR "/files/package-modules", SRCDIR "/files/system-modules", SRCDIR "/files/user-modules"); - CuAssertPtrNotNull (tc, configs); - CuAssertTrue (tc, assert_msg_contains (p11_message_last (), "invalid config filename")); + assert_ptr_not_null (configs); + assert (assert_msg_contains (p11_message_last (), "invalid config filename")); config = p11_dict_get (configs, "one"); - CuAssertPtrNotNull (tc, config); - CuAssertStrEquals (tc, "mock-one.so", p11_dict_get (config, "module")); - CuAssertStrEquals (tc, p11_dict_get (config, "setting"), "user1"); + assert_ptr_not_null (config); + assert_str_eq ("mock-one.so", p11_dict_get (config, "module")); + assert_str_eq (p11_dict_get (config, "setting"), "user1"); config = p11_dict_get (configs, "two.badname"); - CuAssertPtrNotNull (tc, config); - CuAssertStrEquals (tc, "mock-two.so", p11_dict_get (config, "module")); - CuAssertStrEquals (tc, p11_dict_get (config, "setting"), "system2"); + assert_ptr_not_null (config); + assert_str_eq ("mock-two.so", p11_dict_get (config, "module")); + assert_str_eq (p11_dict_get (config, "setting"), "system2"); config = p11_dict_get (configs, "three"); - CuAssertPtrNotNull (tc, config); - CuAssertStrEquals (tc, "mock-three.so", p11_dict_get (config, "module")); - CuAssertStrEquals (tc, p11_dict_get (config, "setting"), "user3"); + assert_ptr_not_null (config); + assert_str_eq ("mock-three.so", p11_dict_get (config, "module")); + assert_str_eq (p11_dict_get (config, "setting"), "user3"); p11_dict_free (configs); } static void -test_load_modules_user_none (CuTest *tc) +test_load_modules_user_none (void) { p11_dict *configs; p11_dict *config; @@ -300,27 +300,27 @@ test_load_modules_user_none (CuTest *tc) SRCDIR "/files/package-modules", SRCDIR "/files/system-modules", SRCDIR "/files/user-modules"); - CuAssertPtrNotNull (tc, configs); - CuAssertTrue (tc, assert_msg_contains (p11_message_last (), "invalid config filename")); + assert_ptr_not_null (configs); + assert (assert_msg_contains (p11_message_last (), "invalid config filename")); config = p11_dict_get (configs, "one"); - CuAssertPtrNotNull (tc, config); - CuAssertStrEquals (tc, "mock-one.so", p11_dict_get (config, "module")); - CuAssertStrEquals (tc, p11_dict_get (config, "setting"), "system1"); + assert_ptr_not_null (config); + assert_str_eq ("mock-one.so", p11_dict_get (config, "module")); + assert_str_eq (p11_dict_get (config, "setting"), "system1"); config = p11_dict_get (configs, "two.badname"); - CuAssertPtrNotNull (tc, config); - CuAssertStrEquals (tc, "mock-two.so", p11_dict_get (config, "module")); - CuAssertStrEquals (tc, p11_dict_get (config, "setting"), "system2"); + assert_ptr_not_null (config); + assert_str_eq ("mock-two.so", p11_dict_get (config, "module")); + assert_str_eq (p11_dict_get (config, "setting"), "system2"); config = p11_dict_get (configs, "three"); - CuAssertPtrEquals (tc, NULL, config); + assert_ptr_eq (NULL, config); p11_dict_free (configs); } static void -test_load_modules_user_only (CuTest *tc) +test_load_modules_user_only (void) { p11_dict *configs; p11_dict *config; @@ -331,27 +331,27 @@ test_load_modules_user_only (CuTest *tc) SRCDIR "/files/package-modules", SRCDIR "/files/system-modules", SRCDIR "/files/user-modules"); - CuAssertPtrNotNull (tc, configs); - CuAssertPtrEquals (tc, NULL, (void *)p11_message_last ()); + assert_ptr_not_null (configs); + assert_ptr_eq (NULL, (void *)p11_message_last ()); config = p11_dict_get (configs, "one"); - CuAssertPtrNotNull (tc, config); - CuAssertStrEquals (tc, p11_dict_get (config, "module"), NULL); - CuAssertStrEquals (tc, p11_dict_get (config, "setting"), "user1"); + assert_ptr_not_null (config); + assert (p11_dict_get (config, "module") == NULL); + assert_str_eq (p11_dict_get (config, "setting"), "user1"); config = p11_dict_get (configs, "two.badname"); - CuAssertPtrEquals (tc, NULL, config); + assert_ptr_eq (NULL, config); config = p11_dict_get (configs, "three"); - CuAssertPtrNotNull (tc, config); - CuAssertStrEquals (tc, "mock-three.so", p11_dict_get (config, "module")); - CuAssertStrEquals (tc, p11_dict_get (config, "setting"), "user3"); + assert_ptr_not_null (config); + assert_str_eq ("mock-three.so", p11_dict_get (config, "module")); + assert_str_eq (p11_dict_get (config, "setting"), "user3"); p11_dict_free (configs); } static void -test_load_modules_no_user (CuTest *tc) +test_load_modules_no_user (void) { p11_dict *configs; p11_dict *config; @@ -362,67 +362,53 @@ test_load_modules_no_user (CuTest *tc) SRCDIR "/files/package-modules", SRCDIR "/files/system-modules", SRCDIR "/files/non-existant"); - CuAssertPtrNotNull (tc, configs); - CuAssertTrue (tc, assert_msg_contains (p11_message_last (), "invalid config filename")); + assert_ptr_not_null (configs); + assert (assert_msg_contains (p11_message_last (), "invalid config filename")); config = p11_dict_get (configs, "one"); - CuAssertPtrNotNull (tc, config); - CuAssertStrEquals (tc, "mock-one.so", p11_dict_get (config, "module")); - CuAssertStrEquals (tc, p11_dict_get (config, "setting"), "system1"); + assert_ptr_not_null (config); + assert_str_eq ("mock-one.so", p11_dict_get (config, "module")); + assert_str_eq (p11_dict_get (config, "setting"), "system1"); config = p11_dict_get (configs, "two.badname"); - CuAssertPtrNotNull (tc, config); - CuAssertStrEquals (tc, "mock-two.so", p11_dict_get (config, "module")); - CuAssertStrEquals (tc, p11_dict_get (config, "setting"), "system2"); + assert_ptr_not_null (config); + assert_str_eq ("mock-two.so", p11_dict_get (config, "module")); + assert_str_eq (p11_dict_get (config, "setting"), "system2"); config = p11_dict_get (configs, "three"); - CuAssertPtrEquals (tc, NULL, config); + assert_ptr_eq (NULL, config); p11_dict_free (configs); } static void -test_parse_boolean (CuTest *tc) +test_parse_boolean (void) { p11_message_quiet (); - CuAssertIntEquals (tc, true, _p11_conf_parse_boolean ("yes", false)); - CuAssertIntEquals (tc, false, _p11_conf_parse_boolean ("no", true)); - CuAssertIntEquals (tc, true, _p11_conf_parse_boolean ("!!!", true)); + assert_num_eq (true, _p11_conf_parse_boolean ("yes", false)); + assert_num_eq (false, _p11_conf_parse_boolean ("no", true)); + assert_num_eq (true, _p11_conf_parse_boolean ("!!!", true)); } int -main (void) +main (int argc, + char *argv[]) { - CuString *output = CuStringNew (); - CuSuite* suite = CuSuiteNew (); - int ret; - - putenv ("P11_KIT_STRICT=1"); - p11_debug_init (); - - SUITE_ADD_TEST (suite, test_parse_conf_1); - SUITE_ADD_TEST (suite, test_parse_ignore_missing); - SUITE_ADD_TEST (suite, test_parse_fail_missing); - SUITE_ADD_TEST (suite, test_merge_defaults); - SUITE_ADD_TEST (suite, test_load_globals_merge); - SUITE_ADD_TEST (suite, test_load_globals_no_user); - SUITE_ADD_TEST (suite, test_load_globals_system_sets_only); - SUITE_ADD_TEST (suite, test_load_globals_user_sets_only); - SUITE_ADD_TEST (suite, test_load_globals_system_sets_invalid); - SUITE_ADD_TEST (suite, test_load_globals_user_sets_invalid); - SUITE_ADD_TEST (suite, test_load_modules_merge); - SUITE_ADD_TEST (suite, test_load_modules_no_user); - SUITE_ADD_TEST (suite, test_load_modules_user_only); - SUITE_ADD_TEST (suite, test_load_modules_user_none); - SUITE_ADD_TEST (suite, test_parse_boolean); - - CuSuiteRun (suite); - CuSuiteSummary (suite, output); - CuSuiteDetails (suite, output); - printf ("%s\n", output->buffer); - ret = suite->failCount; - CuSuiteDelete (suite); - CuStringDelete (output); - return ret; + p11_test (test_parse_conf_1, "/conf/test_parse_conf_1"); + p11_test (test_parse_ignore_missing, "/conf/test_parse_ignore_missing"); + p11_test (test_parse_fail_missing, "/conf/test_parse_fail_missing"); + p11_test (test_merge_defaults, "/conf/test_merge_defaults"); + p11_test (test_load_globals_merge, "/conf/test_load_globals_merge"); + p11_test (test_load_globals_no_user, "/conf/test_load_globals_no_user"); + p11_test (test_load_globals_system_sets_only, "/conf/test_load_globals_system_sets_only"); + p11_test (test_load_globals_user_sets_only, "/conf/test_load_globals_user_sets_only"); + p11_test (test_load_globals_system_sets_invalid, "/conf/test_load_globals_system_sets_invalid"); + p11_test (test_load_globals_user_sets_invalid, "/conf/test_load_globals_user_sets_invalid"); + p11_test (test_load_modules_merge, "/conf/test_load_modules_merge"); + p11_test (test_load_modules_no_user, "/conf/test_load_modules_no_user"); + p11_test (test_load_modules_user_only, "/conf/test_load_modules_user_only"); + p11_test (test_load_modules_user_none, "/conf/test_load_modules_user_none"); + p11_test (test_parse_boolean, "/conf/test_parse_boolean"); + return p11_test_run (argc, argv); } diff --git a/p11-kit/tests/test-deprecated.c b/p11-kit/tests/test-deprecated.c new file mode 100644 index 0000000..7ea8260 --- /dev/null +++ b/p11-kit/tests/test-deprecated.c @@ -0,0 +1,508 @@ +/* + * Copyright (c) 2011, Collabora Ltd. + * Copyright (c) 2012 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 <stefw@redhat.com> + */ + +#define P11_KIT_NO_DEPRECATIONS + +#include "config.h" +#include "test.h" + +#include "dict.h" +#include "library.h" +#include "p11-kit.h" +#include "private.h" +#include "mock.h" + +#include <sys/types.h> + +#include <assert.h> +#include <errno.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <time.h> +#include <unistd.h> + +static CK_FUNCTION_LIST_PTR_PTR +initialize_and_get_modules (void) +{ + CK_FUNCTION_LIST_PTR_PTR modules; + CK_RV rv; + + rv = p11_kit_initialize_registered (); + assert_num_eq (CKR_OK, rv); + modules = p11_kit_registered_modules (); + assert (modules != NULL && modules[0] != NULL); + + return modules; +} + +static void +finalize_and_free_modules (CK_FUNCTION_LIST_PTR_PTR modules) +{ + CK_RV rv; + + free (modules); + rv = p11_kit_finalize_registered (); + assert_num_eq (CKR_OK, rv); + +} + +static void +test_no_duplicates (void) +{ + CK_FUNCTION_LIST_PTR_PTR modules; + p11_dict *paths; + p11_dict *funcs; + char *path; + int i; + + modules = initialize_and_get_modules (); + paths = p11_dict_new (p11_dict_str_hash, p11_dict_str_equal, NULL, NULL); + funcs = p11_dict_new (p11_dict_direct_hash, p11_dict_direct_equal, NULL, NULL); + + /* The loaded modules should not contain duplicates */ + for (i = 0; modules[i] != NULL; i++) { + path = p11_kit_registered_option (modules[i], "module"); + + if (p11_dict_get (funcs, modules[i])) + assert_fail ("found duplicate function list pointer", NULL); + if (p11_dict_get (paths, path)) + assert_fail ("found duplicate path name", NULL); + + if (!p11_dict_set (funcs, modules[i], "")) + assert_not_reached (); + if (!p11_dict_set (paths, path, "")) + assert_not_reached (); + + free (path); + } + + p11_dict_free (paths); + p11_dict_free (funcs); + finalize_and_free_modules (modules); +} + +static CK_FUNCTION_LIST_PTR +lookup_module_with_name (CK_FUNCTION_LIST_PTR_PTR modules, + const char *name) +{ + CK_FUNCTION_LIST_PTR match = NULL; + CK_FUNCTION_LIST_PTR module; + char *module_name; + int i; + + for (i = 0; match == NULL && modules[i] != NULL; i++) { + module_name = p11_kit_registered_module_to_name (modules[i]); + assert_ptr_not_null (module_name); + if (strcmp (module_name, name) == 0) + match = modules[i]; + free (module_name); + } + + /* + * As a side effect, we should check that the results of this function + * matches the above search. + */ + module = p11_kit_registered_name_to_module (name); + if (module != match) + assert_fail ("different result from p11_kit_registered_name_to_module()", NULL); + + return match; +} + +static void +test_disable (void) +{ + CK_FUNCTION_LIST_PTR_PTR modules; + + /* + * The module four should be present, as we don't match any prognames + * that it has disabled. + */ + + modules = initialize_and_get_modules (); + assert (lookup_module_with_name (modules, "four") != NULL); + finalize_and_free_modules (modules); + + /* + * The module two shouldn't have been loaded, because in its config + * file we have: + * + * disable-in: test-disable + */ + + p11_kit_set_progname ("test-disable"); + + modules = initialize_and_get_modules (); + assert (lookup_module_with_name (modules, "four") == NULL); + finalize_and_free_modules (modules); + + p11_kit_set_progname (NULL); +} + +static void +test_disable_later (void) +{ + CK_FUNCTION_LIST_PTR_PTR modules; + CK_RV rv; + + /* + * The module two shouldn't be matched, because in its config + * file we have: + * + * disable-in: test-disable + */ + + rv = p11_kit_initialize_registered (); + assert_num_eq (CKR_OK, rv); + + p11_kit_set_progname ("test-disable"); + + modules = p11_kit_registered_modules (); + assert (modules != NULL && modules[0] != NULL); + + assert (lookup_module_with_name (modules, "two") == NULL); + finalize_and_free_modules (modules); + + p11_kit_set_progname (NULL); +} + +static void +test_enable (void) +{ + CK_FUNCTION_LIST_PTR_PTR modules; + + /* + * The module three should not be present, as we don't match the current + * program. + */ + + modules = initialize_and_get_modules (); + assert (lookup_module_with_name (modules, "three") == NULL); + finalize_and_free_modules (modules); + + /* + * The module three should be loaded here , because in its config + * file we have: + * + * enable-in: test-enable + */ + + p11_kit_set_progname ("test-enable"); + + modules = initialize_and_get_modules (); + assert (lookup_module_with_name (modules, "three") != NULL); + finalize_and_free_modules (modules); + + p11_kit_set_progname (NULL); +} + +CK_FUNCTION_LIST module; + +#ifdef OS_UNIX + +#include <sys/wait.h> + +static CK_RV +mock_C_Initialize__with_fork (CK_VOID_PTR init_args) +{ + struct timespec ts = { 0, 100 * 1000 * 1000 }; + CK_RV rv; + pid_t child; + pid_t ret; + int status; + + rv = mock_C_Initialize (init_args); + assert (rv == CKR_OK); + + /* Fork during the initialization */ + child = fork (); + if (child == 0) { + nanosleep (&ts, NULL); + exit (66); + } + + ret = waitpid (child, &status, 0); + assert (ret == child); + assert (WIFEXITED (status)); + assert (WEXITSTATUS (status) == 66); + + return CKR_OK; +} + +static void +test_fork_initialization (void) +{ + CK_RV rv; + + assert (!mock_module_initialized ()); + + /* Build up our own function list */ + memcpy (&module, &mock_module_no_slots, sizeof (CK_FUNCTION_LIST)); + module.C_Initialize = mock_C_Initialize__with_fork; + + rv = p11_kit_initialize_module (&module); + assert (rv == CKR_OK); + + rv = p11_kit_finalize_module (&module); + assert (rv == CKR_OK); + + assert (!mock_module_initialized ()); +} + +#endif /* OS_UNIX */ + +static CK_RV +mock_C_Initialize__with_recursive (CK_VOID_PTR init_args) +{ + /* Recursively initialize, this is broken */ + return p11_kit_initialize_module (&module); +} + +static void +test_recursive_initialization (void) +{ + CK_RV rv; + + assert (!mock_module_initialized ()); + + /* Build up our own function list */ + memcpy (&module, &mock_module_no_slots, sizeof (CK_FUNCTION_LIST)); + module.C_Initialize = mock_C_Initialize__with_recursive; + + rv = p11_kit_initialize_module (&module); + assert (rv == CKR_FUNCTION_FAILED); + + assert (!mock_module_initialized ()); +} + +static p11_mutex_t race_mutex; +static int initialization_count = 0; +static int finalization_count = 0; + +static CK_RV +mock_C_Initialize__threaded_race (CK_VOID_PTR init_args) +{ + /* Atomically increment value */ + p11_mutex_lock (&race_mutex); + initialization_count += 1; + p11_mutex_unlock (&race_mutex); + + p11_sleep_ms (100); + return CKR_OK; +} + +static CK_RV +mock_C_Finalize__threaded_race (CK_VOID_PTR reserved) +{ + /* Atomically increment value */ + p11_mutex_lock (&race_mutex); + finalization_count += 1; + p11_mutex_unlock (&race_mutex); + + p11_sleep_ms (100); + return CKR_OK; +} + +static void * +initialization_thread (void *data) +{ + CK_RV rv; + + assert_str_eq (data, "thread-data"); + rv = p11_kit_initialize_module (&module); + assert (rv == CKR_OK); + + return "thread-data"; +} + +static void * +finalization_thread (void *data) +{ + CK_RV rv; + + assert_str_eq (data, "thread-data"); + rv = p11_kit_finalize_module (&module); + assert (rv == CKR_OK); + + return "thread-data"; +} + +static void +test_threaded_initialization (void) +{ + static const int num_threads = 2; + p11_thread_t threads[num_threads]; + int ret; + int i; + + assert (!mock_module_initialized ()); + + /* Build up our own function list */ + memcpy (&module, &mock_module_no_slots, sizeof (CK_FUNCTION_LIST)); + module.C_Initialize = mock_C_Initialize__threaded_race; + module.C_Finalize = mock_C_Finalize__threaded_race; + + initialization_count = 0; + finalization_count = 0; + + for (i = 0; i < num_threads; i++) { + ret = p11_thread_create (&threads[i], initialization_thread, "thread-data"); + assert_num_eq (0, ret); + assert (threads[i] != 0); + } + + for (i = 0; i < num_threads; i++) { + ret = p11_thread_join (threads[i]); + assert_num_eq (0, ret); + threads[i] = 0; + } + + for (i = 0; i < num_threads; i++) { + ret = p11_thread_create (&threads[i], finalization_thread, "thread-data"); + assert_num_eq (0, ret); + assert (threads[i] != 0); + } + + for (i = 0; i < num_threads; i++) { + ret = p11_thread_join (threads[i]); + assert_num_eq (0, ret); + threads[i] = 0; + } + + /* C_Initialize should have been called exactly once */ + assert_num_eq (1, initialization_count); + assert_num_eq (1, finalization_count); + + assert (!mock_module_initialized ()); +} + +static CK_RV +mock_C_Initialize__test_mutexes (CK_VOID_PTR args) +{ + CK_C_INITIALIZE_ARGS_PTR init_args; + void *mutex = NULL; + CK_RV rv; + + rv = mock_C_Initialize (NULL); + if (rv != CKR_OK) + return rv; + + assert (args != NULL); + init_args = args; + + rv = (init_args->CreateMutex) (&mutex); + assert (rv == CKR_OK); + + rv = (init_args->LockMutex) (mutex); + assert (rv == CKR_OK); + + rv = (init_args->UnlockMutex) (mutex); + assert (rv == CKR_OK); + + rv = (init_args->DestroyMutex) (mutex); + assert (rv == CKR_OK); + + return CKR_OK; +} + +static void +test_mutexes (void) +{ + CK_RV rv; + + assert (!mock_module_initialized ()); + + /* Build up our own function list */ + memcpy (&module, &mock_module_no_slots, sizeof (CK_FUNCTION_LIST)); + module.C_Initialize = mock_C_Initialize__test_mutexes; + + rv = p11_kit_initialize_module (&module); + assert (rv == CKR_OK); + + rv = p11_kit_finalize_module (&module); + assert (rv == CKR_OK); + + assert (!mock_module_initialized ()); +} + +static void +test_load_and_initialize (void) +{ + CK_FUNCTION_LIST_PTR module; + CK_INFO info; + CK_RV rv; + int ret; + + rv = p11_kit_load_initialize_module (BUILDDIR "/.libs/mock-one" SHLEXT, &module); + assert (rv == CKR_OK); + assert (module != NULL); + + rv = (module->C_GetInfo) (&info); + assert (rv == CKR_OK); + + ret = memcmp (info.manufacturerID, "MOCK MANUFACTURER ", 32); + assert (ret == 0); + + rv = p11_kit_finalize_module (module); + assert (ret == CKR_OK); +} + +int +main (int argc, + char *argv[]) +{ + p11_mutex_init (&race_mutex); + mock_module_init (); + p11_library_init (); + + p11_test (test_no_duplicates, "/deprecated/test_no_duplicates"); + p11_test (test_disable, "/deprecated/test_disable"); + p11_test (test_disable_later, "/deprecated/test_disable_later"); + p11_test (test_enable, "/deprecated/test_enable"); + +#ifdef OS_UNIX + p11_test (test_fork_initialization, "/deprecated/test_fork_initialization"); +#endif + + p11_test (test_recursive_initialization, "/deprecated/test_recursive_initialization"); + p11_test (test_threaded_initialization, "/deprecated/test_threaded_initialization"); + p11_test (test_mutexes, "/deprecated/test_mutexes"); + p11_test (test_load_and_initialize, "/deprecated/test_load_and_initialize"); + + p11_kit_be_quiet (); + + return p11_test_run (argc, argv); +} diff --git a/p11-kit/tests/test-init.c b/p11-kit/tests/test-init.c index 7df4be9..76805ee 100644 --- a/p11-kit/tests/test-init.c +++ b/p11-kit/tests/test-init.c @@ -33,11 +33,16 @@ */ #include "config.h" -#include "CuTest.h" +#include "test.h" #include <sys/types.h> #include "library.h" +#include "mock.h" +#include "modules.h" +#include "p11-kit.h" +#include "private.h" +#include "virtual.h" #include <assert.h> #include <stdio.h> @@ -46,11 +51,8 @@ #include <time.h> #include <unistd.h> -#include "p11-kit/p11-kit.h" - -#include "mock.h" - -CK_FUNCTION_LIST module; +static CK_FUNCTION_LIST module; +static p11_mutex_t race_mutex; #ifdef OS_UNIX @@ -84,23 +86,42 @@ mock_C_Initialize__with_fork (CK_VOID_PTR init_args) } static void -test_fork_initialization (CuTest *tc) +test_fork_initialization (void) { + CK_FUNCTION_LIST_PTR result; CK_RV rv; + mock_module_reset (); + /* Build up our own function list */ memcpy (&module, &mock_module_no_slots, sizeof (CK_FUNCTION_LIST)); module.C_Initialize = mock_C_Initialize__with_fork; - rv = p11_kit_initialize_module (&module); - CuAssertTrue (tc, rv == CKR_OK); + p11_lock (); + + rv = p11_module_load_inlock_reentrant (&module, 0, &result); + assert (rv == CKR_OK); + + p11_unlock (); + + rv = p11_kit_module_initialize (result); + assert (rv == CKR_OK); + + rv = p11_kit_module_finalize (result); + assert (rv == CKR_OK); - rv = p11_kit_finalize_module (&module); - CuAssertTrue (tc, rv == CKR_OK); + p11_lock (); + + rv = p11_module_release_inlock_reentrant (result); + assert (rv == CKR_OK); + + p11_unlock (); } #endif /* OS_UNIX */ +static CK_FUNCTION_LIST *recursive_managed; + static CK_RV mock_C_Initialize__with_recursive (CK_VOID_PTR init_args) { @@ -109,12 +130,11 @@ mock_C_Initialize__with_recursive (CK_VOID_PTR init_args) rv = mock_C_Initialize (init_args); assert (rv == CKR_OK); - /* Recursively initialize, this is broken */ - return p11_kit_initialize_module (&module); + return p11_kit_module_initialize (recursive_managed); } static void -test_recursive_initialization (CuTest *tc) +test_recursive_initialization (void) { CK_RV rv; @@ -122,16 +142,31 @@ test_recursive_initialization (CuTest *tc) memcpy (&module, &mock_module_no_slots, sizeof (CK_FUNCTION_LIST)); module.C_Initialize = mock_C_Initialize__with_recursive; - rv = p11_kit_initialize_module (&module); - CuAssertTrue (tc, rv == CKR_FUNCTION_FAILED); + p11_kit_be_quiet (); + + p11_lock (); + + rv = p11_module_load_inlock_reentrant (&module, 0, &recursive_managed); + assert (rv == CKR_OK); + + p11_unlock (); + + rv = p11_kit_module_initialize (recursive_managed); + assert_num_eq (CKR_FUNCTION_FAILED, rv); + + p11_lock (); + + rv = p11_module_release_inlock_reentrant (recursive_managed); + assert (rv == CKR_OK); + + p11_unlock (); + + p11_kit_be_loud (); } -static p11_mutex_t race_mutex; static int initialization_count = 0; static int finalization_count = 0; -#include "private.h" - static CK_RV mock_C_Initialize__threaded_race (CK_VOID_PTR init_args) { @@ -159,32 +194,36 @@ mock_C_Finalize__threaded_race (CK_VOID_PTR reserved) static void * initialization_thread (void *data) { - CuTest *tc = data; + CK_FUNCTION_LIST *module = data; CK_RV rv; - rv = p11_kit_initialize_module (&module); - CuAssertTrue (tc, rv == CKR_OK); + assert (module != NULL); + rv = p11_kit_module_initialize (module); + assert_num_eq (rv, CKR_OK); - return tc; + return module; } static void * finalization_thread (void *data) { - CuTest *tc = data; + CK_FUNCTION_LIST *module = data; CK_RV rv; - rv = p11_kit_finalize_module (&module); - CuAssertTrue (tc, rv == CKR_OK); + assert (module != NULL); + rv = p11_kit_module_finalize (module); + assert_num_eq (rv, CKR_OK); - return tc; + return module; } static void -test_threaded_initialization (CuTest *tc) +test_threaded_initialization (void) { - static const int num_threads = 2; + static const int num_threads = 1; + CK_FUNCTION_LIST *data[num_threads]; p11_thread_t threads[num_threads]; + CK_RV rv; int ret; int i; @@ -193,36 +232,57 @@ test_threaded_initialization (CuTest *tc) module.C_Initialize = mock_C_Initialize__threaded_race; module.C_Finalize = mock_C_Finalize__threaded_race; + memset (&data, 0, sizeof (data)); initialization_count = 0; finalization_count = 0; + p11_lock (); + + for (i = 0; i < num_threads; i++) { + assert (data[i] == NULL); + rv = p11_module_load_inlock_reentrant (&module, 0, &data[i]); + assert (rv == CKR_OK); + } + + p11_unlock (); + for (i = 0; i < num_threads; i++) { - ret = p11_thread_create (&threads[i], initialization_thread, tc); - CuAssertIntEquals (tc, 0, ret); - CuAssertTrue (tc, threads[i] != 0); + ret = p11_thread_create (&threads[i], initialization_thread, data[i]); + assert_num_eq (0, ret); + assert (threads[i] != 0); } for (i = 0; i < num_threads; i++) { ret = p11_thread_join (threads[i]); - CuAssertIntEquals (tc, 0, ret); + assert_num_eq (0, ret); threads[i] = 0; } for (i = 0; i < num_threads; i++) { - ret = p11_thread_create (&threads[i], finalization_thread, tc); - CuAssertIntEquals (tc, 0, ret); - CuAssertTrue (tc, threads[i] != 0); + ret = p11_thread_create (&threads[i], finalization_thread, data[i]); + assert_num_eq (0, ret); + assert (threads[i] != 0); } for (i = 0; i < num_threads; i++) { ret = p11_thread_join (threads[i]); - CuAssertIntEquals (tc, 0, ret); + assert_num_eq (0, ret); threads[i] = 0; } + p11_lock (); + + for (i = 0; i < num_threads; i++) { + assert (data[i] != NULL); + rv = p11_module_release_inlock_reentrant (data[i]); + assert (rv == CKR_OK); + } + + p11_unlock (); + /* C_Initialize should have been called exactly once */ - CuAssertIntEquals (tc, 1, initialization_count); - CuAssertIntEquals (tc, 1, finalization_count); + assert_num_eq (1, initialization_count); + assert_num_eq (1, finalization_count); } static CK_RV @@ -251,71 +311,106 @@ mock_C_Initialize__test_mutexes (CK_VOID_PTR args) } static void -test_mutexes (CuTest *tc) +test_mutexes (void) { + CK_FUNCTION_LIST_PTR result; CK_RV rv; /* Build up our own function list */ memcpy (&module, &mock_module_no_slots, sizeof (CK_FUNCTION_LIST)); module.C_Initialize = mock_C_Initialize__test_mutexes; - rv = p11_kit_initialize_module (&module); - CuAssertTrue (tc, rv == CKR_OK); + p11_lock (); + + rv = p11_module_load_inlock_reentrant (&module, 0, &result); + assert (rv == CKR_OK); + + rv = p11_module_release_inlock_reentrant (result); + assert (rv == CKR_OK); - rv = p11_kit_finalize_module (&module); - CuAssertTrue (tc, rv == CKR_OK); + p11_unlock (); } static void -test_load_and_initialize (CuTest *tc) +test_load_and_initialize (void) { CK_FUNCTION_LIST_PTR module; CK_INFO info; CK_RV rv; int ret; - rv = p11_kit_load_initialize_module (BUILDDIR "/.libs/mock-one" SHLEXT, &module); - CuAssertTrue (tc, rv == CKR_OK); - CuAssertTrue (tc, module != NULL); + module = p11_kit_module_load (BUILDDIR "/.libs/mock-one" SHLEXT, 0); + assert (module != NULL); + + rv = p11_kit_module_initialize (module); + assert (rv == CKR_OK); rv = (module->C_GetInfo) (&info); - CuAssertTrue (tc, rv == CKR_OK); + assert (rv == CKR_OK); ret = memcmp (info.manufacturerID, "MOCK MANUFACTURER ", 32); - CuAssertTrue (tc, ret == 0); + assert (ret == 0); - rv = p11_kit_finalize_module (module); - CuAssertTrue (tc, ret == CKR_OK); + rv = p11_kit_module_finalize (module); + assert (rv == CKR_OK); + + p11_kit_module_release (module); } -int -main (void) +static void +test_initalize_fail (void) +{ + CK_FUNCTION_LIST failer; + CK_FUNCTION_LIST *modules[3] = { &mock_module_no_slots, &failer, NULL }; + CK_RV rv; + + memcpy (&failer, &mock_module, sizeof (CK_FUNCTION_LIST)); + failer.C_Initialize = mock_C_Initialize__fails; + + mock_module_reset (); + p11_kit_be_quiet (); + + rv = p11_kit_modules_initialize (modules, NULL); + assert_num_eq (CKR_FUNCTION_FAILED, rv); + + p11_kit_be_loud (); + + /* Failed modules get removed from the list */ + assert_ptr_eq (&mock_module_no_slots, modules[0]); + assert_ptr_eq (NULL, modules[1]); + assert_ptr_eq (NULL, modules[2]); + + p11_kit_modules_finalize (modules); +} + +static void +test_finalize_fail (void) { - CuString *output = CuStringNew (); - CuSuite* suite = CuSuiteNew (); - int ret; - putenv ("P11_KIT_STRICT=1"); +} + +int +main (int argc, + char *argv[]) +{ p11_mutex_init (&race_mutex); mock_module_init (); 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"); + #ifdef OS_UNIX - SUITE_ADD_TEST (suite, test_fork_initialization); + p11_test (test_fork_initialization, "/init/test_fork_initialization"); #endif + } - SUITE_ADD_TEST (suite, test_recursive_initialization); - SUITE_ADD_TEST (suite, test_threaded_initialization); - SUITE_ADD_TEST (suite, test_mutexes); - SUITE_ADD_TEST (suite, test_load_and_initialize); - - CuSuiteRun (suite); - CuSuiteSummary (suite, output); - CuSuiteDetails (suite, output); - printf ("%s\n", output->buffer); - ret = suite->failCount; - CuSuiteDelete (suite); - CuStringDelete (output); + p11_test (test_initalize_fail, "/init/test_initalize_fail"); + p11_test (test_finalize_fail, "/init/test_finalize_fail"); - return ret; + return p11_test_run (argc, argv); } diff --git a/p11-kit/tests/test-iter.c b/p11-kit/tests/test-iter.c index 08e43b3..18b5ed6 100644 --- a/p11-kit/tests/test-iter.c +++ b/p11-kit/tests/test-iter.c @@ -33,7 +33,7 @@ */ #include "config.h" -#include "CuTest.h" +#include "test.h" #define P11_KIT_FUTURE_UNSTABLE_API 1 @@ -49,17 +49,14 @@ #include <stdlib.h> static CK_FUNCTION_LIST_PTR_PTR -initialize_and_get_modules (CuTest *tc) +initialize_and_get_modules (void) { CK_FUNCTION_LIST_PTR_PTR modules; - CK_RV rv; p11_message_quiet (); - rv = p11_kit_initialize_registered (); - CuAssertIntEquals (tc, CKR_OK, rv); - modules = p11_kit_registered_modules (); - CuAssertTrue (tc, modules != NULL && modules[0] != NULL); + modules = p11_kit_modules_load_and_initialize (0); + assert (modules != NULL && modules[0] != NULL); p11_message_loud (); @@ -67,14 +64,10 @@ initialize_and_get_modules (CuTest *tc) } static void -finalize_and_free_modules (CuTest *tc, - CK_FUNCTION_LIST_PTR_PTR modules) +finalize_and_free_modules (CK_FUNCTION_LIST_PTR_PTR modules) { - CK_RV rv; - - free (modules); - rv = p11_kit_finalize_registered (); - CuAssertIntEquals (tc, CKR_OK, rv); + p11_kit_modules_finalize (modules); + p11_kit_modules_release (modules); } static int @@ -93,7 +86,7 @@ has_handle (CK_ULONG *objects, static void -test_all (CuTest *tc) +test_all (void) { CK_OBJECT_HANDLE objects[128]; CK_FUNCTION_LIST_PTR *modules; @@ -104,59 +97,60 @@ test_all (CuTest *tc) CK_RV rv; int at; - modules = initialize_and_get_modules (tc); + modules = initialize_and_get_modules (); iter = p11_kit_iter_new (NULL); p11_kit_iter_begin (iter, modules); at = 0; while ((rv = p11_kit_iter_next (iter)) == CKR_OK) { - CuAssertTrue (tc, at < 128); + assert (at < 128); objects[at] = p11_kit_iter_get_object (iter); module = p11_kit_iter_get_module (iter); - CuAssertPtrNotNull (tc, module); + assert_ptr_not_null (module); session = p11_kit_iter_get_session (iter); - CuAssertTrue (tc, session != 0); + assert (session != 0); /* Do something with the object */ size = 0; rv = (module->C_GetObjectSize) (session, objects[at], &size); - CuAssertTrue (tc, rv == CKR_OK); - CuAssertTrue (tc, size > 0); + assert (rv == CKR_OK); + assert (size > 0); at++; } - CuAssertTrue (tc, rv == CKR_CANCEL); + assert (rv == CKR_CANCEL); /* Three modules, each with 1 slot, and 3 public objects */ - CuAssertIntEquals (tc, 9, at); + assert_num_eq (9, at); - CuAssertTrue (tc, has_handle (objects, at, MOCK_DATA_OBJECT)); - CuAssertTrue (tc, !has_handle (objects, at, MOCK_PRIVATE_KEY_CAPITALIZE)); - CuAssertTrue (tc, has_handle (objects, at, MOCK_PUBLIC_KEY_CAPITALIZE)); - CuAssertTrue (tc, !has_handle (objects, at, MOCK_PRIVATE_KEY_PREFIX)); - CuAssertTrue (tc, has_handle (objects, at, MOCK_PUBLIC_KEY_PREFIX)); + assert (has_handle (objects, at, MOCK_DATA_OBJECT)); + assert (!has_handle (objects, at, MOCK_PRIVATE_KEY_CAPITALIZE)); + assert (has_handle (objects, at, MOCK_PUBLIC_KEY_CAPITALIZE)); + assert (!has_handle (objects, at, MOCK_PRIVATE_KEY_PREFIX)); + assert (has_handle (objects, at, MOCK_PUBLIC_KEY_PREFIX)); p11_kit_iter_free (iter); - finalize_and_free_modules (tc, modules); + finalize_and_free_modules (modules); } static CK_RV on_iter_callback (P11KitIter *iter, - CK_BBOOL *matches, - void *data) + CK_BBOOL *matches, + void *data) { - CuTest *tc = data; CK_OBJECT_HANDLE object; CK_FUNCTION_LIST_PTR module; CK_SESSION_HANDLE session; CK_ULONG size; CK_RV rv; + assert_str_eq (data, "callback"); + object = p11_kit_iter_get_object (iter); if (object != MOCK_PUBLIC_KEY_CAPITALIZE && object != MOCK_PUBLIC_KEY_PREFIX) { *matches = CK_FALSE; @@ -164,22 +158,22 @@ on_iter_callback (P11KitIter *iter, } module = p11_kit_iter_get_module (iter); - CuAssertPtrNotNull (tc, module); + assert_ptr_not_null (module); session = p11_kit_iter_get_session (iter); - CuAssertTrue (tc, session != 0); + assert (session != 0); /* Do something with the object */ size = 0; rv = (module->C_GetObjectSize) (session, object, &size); - CuAssertTrue (tc, rv == CKR_OK); - CuAssertTrue (tc, size > 0); + assert (rv == CKR_OK); + assert (size > 0); return CKR_OK; } static void -test_callback (CuTest *tc) +test_callback (void) { CK_OBJECT_HANDLE objects[128]; CK_FUNCTION_LIST_PTR *modules; @@ -187,33 +181,33 @@ test_callback (CuTest *tc) CK_RV rv; int at; - modules = initialize_and_get_modules (tc); + modules = initialize_and_get_modules (); iter = p11_kit_iter_new (NULL); - p11_kit_iter_add_callback (iter, on_iter_callback, tc, NULL); + p11_kit_iter_add_callback (iter, on_iter_callback, "callback", NULL); p11_kit_iter_begin (iter, modules); at= 0; while ((rv = p11_kit_iter_next (iter)) == CKR_OK) { - CuAssertTrue (tc, at < 128); + assert (at < 128); objects[at] = p11_kit_iter_get_object (iter); at++; } - CuAssertTrue (tc, rv == CKR_CANCEL); + assert (rv == CKR_CANCEL); /* Three modules, each with 1 slot, and 2 public keys */ - CuAssertIntEquals (tc, 6, at); + assert_num_eq (6, at); - CuAssertTrue (tc, !has_handle (objects, at, MOCK_DATA_OBJECT)); - CuAssertTrue (tc, !has_handle (objects, at, MOCK_PRIVATE_KEY_CAPITALIZE)); - CuAssertTrue (tc, has_handle (objects, at, MOCK_PUBLIC_KEY_CAPITALIZE)); - CuAssertTrue (tc, !has_handle (objects, at, MOCK_PRIVATE_KEY_PREFIX)); - CuAssertTrue (tc, has_handle (objects, at, MOCK_PUBLIC_KEY_PREFIX)); + assert (!has_handle (objects, at, MOCK_DATA_OBJECT)); + assert (!has_handle (objects, at, MOCK_PRIVATE_KEY_CAPITALIZE)); + assert (has_handle (objects, at, MOCK_PUBLIC_KEY_CAPITALIZE)); + assert (!has_handle (objects, at, MOCK_PRIVATE_KEY_PREFIX)); + assert (has_handle (objects, at, MOCK_PUBLIC_KEY_PREFIX)); p11_kit_iter_free (iter); - finalize_and_free_modules (tc, modules); + finalize_and_free_modules (modules); } static CK_RV @@ -225,30 +219,30 @@ on_callback_fail (P11KitIter *iter, } static void -test_callback_fails (CuTest *tc) +test_callback_fails (void) { CK_FUNCTION_LIST_PTR *modules; P11KitIter *iter; CK_RV rv; int at; - modules = initialize_and_get_modules (tc); + modules = initialize_and_get_modules (); iter = p11_kit_iter_new (NULL); - p11_kit_iter_add_callback (iter, on_callback_fail, tc, NULL); + p11_kit_iter_add_callback (iter, on_callback_fail, "callback", NULL); p11_kit_iter_begin (iter, modules); at= 0; while ((rv = p11_kit_iter_next (iter)) == CKR_OK) at++; - CuAssertTrue (tc, rv == CKR_DATA_INVALID); + assert (rv == CKR_DATA_INVALID); /* Shouldn't have succeeded at all */ - CuAssertIntEquals (tc, 0, at); + assert_num_eq (0, at); p11_kit_iter_free (iter); - finalize_and_free_modules (tc, modules); + finalize_and_free_modules (modules); } static void @@ -259,7 +253,7 @@ on_destroy_increment (void *data) } static void -test_callback_destroyer (CuTest *tc) +test_callback_destroyer (void) { P11KitIter *iter; int value = 1; @@ -268,11 +262,11 @@ test_callback_destroyer (CuTest *tc) p11_kit_iter_add_callback (iter, on_callback_fail, &value, on_destroy_increment); p11_kit_iter_free (iter); - CuAssertIntEquals (tc, 2, value); + assert_num_eq (2, value); } static void -test_with_session (CuTest *tc) +test_with_session (void) { CK_OBJECT_HANDLE objects[128]; CK_SESSION_HANDLE session; @@ -282,53 +276,54 @@ test_with_session (CuTest *tc) CK_RV rv; int at; - rv = p11_kit_initialize_module (&mock_module); - CuAssertTrue (tc, rv == CKR_OK); + mock_module_reset (); + rv = mock_module.C_Initialize (NULL); + assert (rv == CKR_OK); rv = mock_C_OpenSession (MOCK_SLOT_ONE_ID, CKF_SERIAL_SESSION, NULL, NULL, &session); - CuAssertTrue (tc, rv == CKR_OK); + assert (rv == CKR_OK); iter = p11_kit_iter_new (NULL); p11_kit_iter_begin_with (iter, &mock_module, 0, session); at= 0; while ((rv = p11_kit_iter_next (iter)) == CKR_OK) { - CuAssertTrue (tc, at < 128); + assert (at < 128); objects[at] = p11_kit_iter_get_object (iter); slot = p11_kit_iter_get_slot (iter); - CuAssertTrue (tc, slot == MOCK_SLOT_ONE_ID); + assert (slot == MOCK_SLOT_ONE_ID); module = p11_kit_iter_get_module (iter); - CuAssertPtrEquals (tc, module, &mock_module); + assert_ptr_eq (module, &mock_module); - CuAssertTrue (tc, session == p11_kit_iter_get_session (iter)); + assert (session == p11_kit_iter_get_session (iter)); at++; } - CuAssertTrue (tc, rv == CKR_CANCEL); + assert (rv == CKR_CANCEL); /* 1 modules, each with 1 slot, and 3 public objects */ - CuAssertIntEquals (tc, 3, at); + assert_num_eq (3, at); - CuAssertTrue (tc, has_handle (objects, at, MOCK_DATA_OBJECT)); - CuAssertTrue (tc, !has_handle (objects, at, MOCK_PRIVATE_KEY_CAPITALIZE)); - CuAssertTrue (tc, has_handle (objects, at, MOCK_PUBLIC_KEY_CAPITALIZE)); - CuAssertTrue (tc, !has_handle (objects, at, MOCK_PRIVATE_KEY_PREFIX)); - CuAssertTrue (tc, has_handle (objects, at, MOCK_PUBLIC_KEY_PREFIX)); + assert (has_handle (objects, at, MOCK_DATA_OBJECT)); + assert (!has_handle (objects, at, MOCK_PRIVATE_KEY_CAPITALIZE)); + assert (has_handle (objects, at, MOCK_PUBLIC_KEY_CAPITALIZE)); + assert (!has_handle (objects, at, MOCK_PRIVATE_KEY_PREFIX)); + assert (has_handle (objects, at, MOCK_PUBLIC_KEY_PREFIX)); p11_kit_iter_free (iter); /* The session is still valid ... */ rv = mock_module.C_CloseSession (session); - CuAssertTrue (tc, rv == CKR_OK); + assert (rv == CKR_OK); - rv = p11_kit_finalize_module (&mock_module); - CuAssertTrue (tc, rv == CKR_OK); + rv = mock_module.C_Finalize (NULL); + assert (rv == CKR_OK); } static void -test_with_slot (CuTest *tc) +test_with_slot (void) { CK_OBJECT_HANDLE objects[128]; CK_FUNCTION_LIST_PTR module; @@ -337,44 +332,45 @@ test_with_slot (CuTest *tc) CK_RV rv; int at; - rv = p11_kit_initialize_module (&mock_module); - CuAssertTrue (tc, rv == CKR_OK); + mock_module_reset (); + rv = mock_module.C_Initialize (NULL); + assert (rv == CKR_OK); iter = p11_kit_iter_new (NULL); p11_kit_iter_begin_with (iter, &mock_module, MOCK_SLOT_ONE_ID, 0); at= 0; while ((rv = p11_kit_iter_next (iter)) == CKR_OK) { - CuAssertTrue (tc, at < 128); + assert (at < 128); objects[at] = p11_kit_iter_get_object (iter); slot = p11_kit_iter_get_slot (iter); - CuAssertTrue (tc, slot == MOCK_SLOT_ONE_ID); + assert (slot == MOCK_SLOT_ONE_ID); module = p11_kit_iter_get_module (iter); - CuAssertPtrEquals (tc, module, &mock_module); + assert_ptr_eq (module, &mock_module); at++; } - CuAssertTrue (tc, rv == CKR_CANCEL); + assert (rv == CKR_CANCEL); /* 1 modules, each with 1 slot, and 3 public objects */ - CuAssertIntEquals (tc, 3, at); + assert_num_eq (3, at); - CuAssertTrue (tc, has_handle (objects, at, MOCK_DATA_OBJECT)); - CuAssertTrue (tc, !has_handle (objects, at, MOCK_PRIVATE_KEY_CAPITALIZE)); - CuAssertTrue (tc, has_handle (objects, at, MOCK_PUBLIC_KEY_CAPITALIZE)); - CuAssertTrue (tc, !has_handle (objects, at, MOCK_PRIVATE_KEY_PREFIX)); - CuAssertTrue (tc, has_handle (objects, at, MOCK_PUBLIC_KEY_PREFIX)); + assert (has_handle (objects, at, MOCK_DATA_OBJECT)); + assert (!has_handle (objects, at, MOCK_PRIVATE_KEY_CAPITALIZE)); + assert (has_handle (objects, at, MOCK_PUBLIC_KEY_CAPITALIZE)); + assert (!has_handle (objects, at, MOCK_PRIVATE_KEY_PREFIX)); + assert (has_handle (objects, at, MOCK_PUBLIC_KEY_PREFIX)); p11_kit_iter_free (iter); - rv = p11_kit_finalize_module (&mock_module); - CuAssertTrue (tc, rv == CKR_OK); + rv = (mock_module.C_Finalize) (NULL); + assert (rv == CKR_OK); } static void -test_with_module (CuTest *tc) +test_with_module (void) { CK_OBJECT_HANDLE objects[128]; CK_FUNCTION_LIST_PTR module; @@ -382,68 +378,70 @@ test_with_module (CuTest *tc) CK_RV rv; int at; - rv = p11_kit_initialize_module (&mock_module); - CuAssertTrue (tc, rv == CKR_OK); + mock_module_reset (); + rv = mock_module.C_Initialize (NULL); + assert (rv == CKR_OK); iter = p11_kit_iter_new (NULL); p11_kit_iter_begin_with (iter, &mock_module, 0, 0); at= 0; while ((rv = p11_kit_iter_next (iter)) == CKR_OK) { - CuAssertTrue (tc, at < 128); + assert (at < 128); objects[at] = p11_kit_iter_get_object (iter); module = p11_kit_iter_get_module (iter); - CuAssertPtrEquals (tc, module, &mock_module); + assert_ptr_eq (module, &mock_module); at++; } - CuAssertTrue (tc, rv == CKR_CANCEL); + assert (rv == CKR_CANCEL); /* 1 modules, each with 1 slot, and 3 public objects */ - CuAssertIntEquals (tc, 3, at); + assert_num_eq (3, at); - CuAssertTrue (tc, has_handle (objects, at, MOCK_DATA_OBJECT)); - CuAssertTrue (tc, !has_handle (objects, at, MOCK_PRIVATE_KEY_CAPITALIZE)); - CuAssertTrue (tc, has_handle (objects, at, MOCK_PUBLIC_KEY_CAPITALIZE)); - CuAssertTrue (tc, !has_handle (objects, at, MOCK_PRIVATE_KEY_PREFIX)); - CuAssertTrue (tc, has_handle (objects, at, MOCK_PUBLIC_KEY_PREFIX)); + assert (has_handle (objects, at, MOCK_DATA_OBJECT)); + assert (!has_handle (objects, at, MOCK_PRIVATE_KEY_CAPITALIZE)); + assert (has_handle (objects, at, MOCK_PUBLIC_KEY_CAPITALIZE)); + assert (!has_handle (objects, at, MOCK_PRIVATE_KEY_PREFIX)); + assert (has_handle (objects, at, MOCK_PUBLIC_KEY_PREFIX)); p11_kit_iter_free (iter); - rv = p11_kit_finalize_module (&mock_module); - CuAssertTrue (tc, rv == CKR_OK); + rv = mock_module.C_Finalize (NULL); + assert (rv == CKR_OK); } static void -test_keep_session (CuTest *tc) +test_keep_session (void) { CK_SESSION_HANDLE session; P11KitIter *iter; CK_RV rv; - rv = p11_kit_initialize_module (&mock_module); - CuAssertTrue (tc, rv == CKR_OK); + mock_module_reset (); + rv = mock_module.C_Initialize (NULL); + assert (rv == CKR_OK); iter = p11_kit_iter_new (NULL); p11_kit_iter_begin_with (iter, &mock_module, 0, 0); rv = p11_kit_iter_next (iter); - CuAssertTrue (tc, rv == CKR_OK); + assert (rv == CKR_OK); session = p11_kit_iter_keep_session (iter); p11_kit_iter_free (iter); /* The session is still valid ... */ rv = mock_module.C_CloseSession (session); - CuAssertTrue (tc, rv == CKR_OK); + assert (rv == CKR_OK); - rv = p11_kit_finalize_module (&mock_module); - CuAssertTrue (tc, rv == CKR_OK); + rv = mock_module.C_Finalize (NULL); + assert (rv == CKR_OK); } static void -test_unrecognized (CuTest *tc) +test_unrecognized (void) { CK_FUNCTION_LIST_PTR *modules; P11KitIter *iter; @@ -451,7 +449,7 @@ test_unrecognized (CuTest *tc) CK_RV rv; int count; - modules = initialize_and_get_modules (tc); + modules = initialize_and_get_modules (); uri = p11_kit_uri_new (); p11_kit_uri_set_unrecognized (uri, 1); @@ -464,18 +462,18 @@ test_unrecognized (CuTest *tc) while ((rv = p11_kit_iter_next (iter)) == CKR_OK) count++; - CuAssertTrue (tc, rv == CKR_CANCEL); + assert (rv == CKR_CANCEL); /* Nothing should have matched */ - CuAssertIntEquals (tc, 0, count); + assert_num_eq (0, count); p11_kit_iter_free (iter); - finalize_and_free_modules (tc, modules); + finalize_and_free_modules (modules); } static void -test_uri_with_type (CuTest *tc) +test_uri_with_type (void) { CK_OBJECT_HANDLE objects[128]; CK_FUNCTION_LIST_PTR *modules; @@ -485,11 +483,11 @@ test_uri_with_type (CuTest *tc) int at; int ret; - modules = initialize_and_get_modules (tc); + modules = initialize_and_get_modules (); uri = p11_kit_uri_new (); ret = p11_kit_uri_parse ("pkcs11:object-type=public", P11_KIT_URI_FOR_OBJECT, uri); - CuAssertIntEquals (tc, ret, P11_KIT_URI_OK); + assert_num_eq (ret, P11_KIT_URI_OK); iter = p11_kit_iter_new (uri); p11_kit_uri_free (uri); @@ -498,29 +496,29 @@ test_uri_with_type (CuTest *tc) at = 0; while ((rv = p11_kit_iter_next (iter)) == CKR_OK) { - CuAssertTrue (tc, at < 128); + assert (at < 128); objects[at] = p11_kit_iter_get_object (iter); at++; } - CuAssertTrue (tc, rv == CKR_CANCEL); + assert (rv == CKR_CANCEL); /* Three modules, each with 1 slot, and 2 public keys */ - CuAssertIntEquals (tc, 6, at); + assert_num_eq (6, at); - CuAssertTrue (tc, !has_handle (objects, at, MOCK_DATA_OBJECT)); - CuAssertTrue (tc, !has_handle (objects, at, MOCK_PRIVATE_KEY_CAPITALIZE)); - CuAssertTrue (tc, has_handle (objects, at, MOCK_PUBLIC_KEY_CAPITALIZE)); - CuAssertTrue (tc, !has_handle (objects, at, MOCK_PRIVATE_KEY_PREFIX)); - CuAssertTrue (tc, has_handle (objects, at, MOCK_PUBLIC_KEY_PREFIX)); + assert (!has_handle (objects, at, MOCK_DATA_OBJECT)); + assert (!has_handle (objects, at, MOCK_PRIVATE_KEY_CAPITALIZE)); + assert (has_handle (objects, at, MOCK_PUBLIC_KEY_CAPITALIZE)); + assert (!has_handle (objects, at, MOCK_PRIVATE_KEY_PREFIX)); + assert (has_handle (objects, at, MOCK_PUBLIC_KEY_PREFIX)); p11_kit_iter_free (iter); - finalize_and_free_modules (tc, modules); + finalize_and_free_modules (modules); } static void -test_filter (CuTest *tc) +test_filter (void) { CK_OBJECT_HANDLE objects[128]; CK_FUNCTION_LIST_PTR *modules; @@ -535,7 +533,7 @@ test_filter (CuTest *tc) { CKA_CLASS, &public_key, sizeof (public_key) }, }; - modules = initialize_and_get_modules (tc); + modules = initialize_and_get_modules (); iter = p11_kit_iter_new (NULL); p11_kit_iter_add_filter (iter, attrs, 2); @@ -544,29 +542,29 @@ test_filter (CuTest *tc) at = 0; while ((rv = p11_kit_iter_next (iter)) == CKR_OK) { - CuAssertTrue (tc, at < 128); + assert (at < 128); objects[at] = p11_kit_iter_get_object (iter); at++; } - CuAssertTrue (tc, rv == CKR_CANCEL); + assert (rv == CKR_CANCEL); /* Three modules, each with 1 slot, and 2 public keys */ - CuAssertIntEquals (tc, 6, at); + assert_num_eq (6, at); - CuAssertTrue (tc, !has_handle (objects, at, MOCK_DATA_OBJECT)); - CuAssertTrue (tc, !has_handle (objects, at, MOCK_PRIVATE_KEY_CAPITALIZE)); - CuAssertTrue (tc, has_handle (objects, at, MOCK_PUBLIC_KEY_CAPITALIZE)); - CuAssertTrue (tc, !has_handle (objects, at, MOCK_PRIVATE_KEY_PREFIX)); - CuAssertTrue (tc, has_handle (objects, at, MOCK_PUBLIC_KEY_PREFIX)); + assert (!has_handle (objects, at, MOCK_DATA_OBJECT)); + assert (!has_handle (objects, at, MOCK_PRIVATE_KEY_CAPITALIZE)); + assert (has_handle (objects, at, MOCK_PUBLIC_KEY_CAPITALIZE)); + assert (!has_handle (objects, at, MOCK_PRIVATE_KEY_PREFIX)); + assert (has_handle (objects, at, MOCK_PUBLIC_KEY_PREFIX)); p11_kit_iter_free (iter); - finalize_and_free_modules (tc, modules); + finalize_and_free_modules (modules); } static void -test_session_flags (CuTest *tc) +test_session_flags (void) { CK_FUNCTION_LIST_PTR *modules; CK_FUNCTION_LIST_PTR module; @@ -575,7 +573,7 @@ test_session_flags (CuTest *tc) P11KitIter *iter; CK_RV rv; - modules = initialize_and_get_modules (tc); + modules = initialize_and_get_modules (); iter = p11_kit_iter_new (NULL); p11_kit_iter_set_session_flags (iter, CKF_RW_SESSION); @@ -584,26 +582,26 @@ test_session_flags (CuTest *tc) while ((rv = p11_kit_iter_next (iter)) == CKR_OK) { module = p11_kit_iter_get_module (iter); - CuAssertPtrNotNull (tc, module); + assert_ptr_not_null (module); session = p11_kit_iter_get_session (iter); - CuAssertTrue (tc, session != 0); + assert (session != 0); rv = (module->C_GetSessionInfo) (session, &info); - CuAssertTrue (tc, rv == CKR_OK); + assert (rv == CKR_OK); - CuAssertIntEquals (tc, CKS_RW_PUBLIC_SESSION, info.state); + assert_num_eq (CKS_RW_PUBLIC_SESSION, info.state); } - CuAssertTrue (tc, rv == CKR_CANCEL); + assert (rv == CKR_CANCEL); p11_kit_iter_free (iter); - finalize_and_free_modules (tc, modules); + finalize_and_free_modules (modules); } static void -test_module_match (CuTest *tc) +test_module_match (void) { CK_FUNCTION_LIST_PTR *modules; P11KitIter *iter; @@ -612,11 +610,11 @@ test_module_match (CuTest *tc) int count; int ret; - modules = initialize_and_get_modules (tc); + modules = initialize_and_get_modules (); uri = p11_kit_uri_new (); ret = p11_kit_uri_parse ("pkcs11:library-description=MOCK%20LIBRARY", P11_KIT_URI_FOR_MODULE, uri); - CuAssertIntEquals (tc, P11_KIT_URI_OK, ret); + assert_num_eq (P11_KIT_URI_OK, ret); iter = p11_kit_iter_new (uri); p11_kit_uri_free (uri); @@ -627,18 +625,18 @@ test_module_match (CuTest *tc) while ((rv = p11_kit_iter_next (iter)) == CKR_OK) count++; - CuAssertTrue (tc, rv == CKR_CANCEL); + assert (rv == CKR_CANCEL); /* Three modules, each with 1 slot, and 3 public objects */ - CuAssertIntEquals (tc, 9, count); + assert_num_eq (9, count); p11_kit_iter_free (iter); - finalize_and_free_modules (tc, modules); + finalize_and_free_modules (modules); } static void -test_module_mismatch (CuTest *tc) +test_module_mismatch (void) { CK_FUNCTION_LIST_PTR *modules; P11KitIter *iter; @@ -647,11 +645,11 @@ test_module_mismatch (CuTest *tc) int count; int ret; - modules = initialize_and_get_modules (tc); + modules = initialize_and_get_modules (); uri = p11_kit_uri_new (); ret = p11_kit_uri_parse ("pkcs11:library-description=blah", P11_KIT_URI_FOR_MODULE, uri); - CuAssertIntEquals (tc, P11_KIT_URI_OK, ret); + assert_num_eq (P11_KIT_URI_OK, ret); iter = p11_kit_iter_new (uri); p11_kit_uri_free (uri); @@ -662,18 +660,18 @@ test_module_mismatch (CuTest *tc) while ((rv = p11_kit_iter_next (iter)) == CKR_OK) count++; - CuAssertTrue (tc, rv == CKR_CANCEL); + assert (rv == CKR_CANCEL); /* Nothing should have matched */ - CuAssertIntEquals (tc, 0, count); + assert_num_eq (0, count); p11_kit_iter_free (iter); - finalize_and_free_modules (tc, modules); + finalize_and_free_modules (modules); } static void -test_token_match (CuTest *tc) +test_token_match (void) { CK_FUNCTION_LIST_PTR *modules; P11KitIter *iter; @@ -682,11 +680,11 @@ test_token_match (CuTest *tc) int count; int ret; - modules = initialize_and_get_modules (tc); + modules = initialize_and_get_modules (); uri = p11_kit_uri_new (); ret = p11_kit_uri_parse ("pkcs11:manufacturer=TEST%20MANUFACTURER", P11_KIT_URI_FOR_TOKEN, uri); - CuAssertIntEquals (tc, P11_KIT_URI_OK, ret); + assert_num_eq (P11_KIT_URI_OK, ret); iter = p11_kit_iter_new (uri); p11_kit_uri_free (uri); @@ -697,18 +695,18 @@ test_token_match (CuTest *tc) while ((rv = p11_kit_iter_next (iter)) == CKR_OK) count++; - CuAssertTrue (tc, rv == CKR_CANCEL); + assert (rv == CKR_CANCEL); /* Three modules, each with 1 slot, and 3 public objects */ - CuAssertIntEquals (tc, 9, count); + assert_num_eq (9, count); p11_kit_iter_free (iter); - finalize_and_free_modules (tc, modules); + finalize_and_free_modules (modules); } static void -test_token_mismatch (CuTest *tc) +test_token_mismatch (void) { CK_FUNCTION_LIST_PTR *modules; P11KitIter *iter; @@ -717,11 +715,11 @@ test_token_mismatch (CuTest *tc) int count; int ret; - modules = initialize_and_get_modules (tc); + modules = initialize_and_get_modules (); uri = p11_kit_uri_new (); ret = p11_kit_uri_parse ("pkcs11:manufacturer=blah", P11_KIT_URI_FOR_TOKEN, uri); - CuAssertIntEquals (tc, P11_KIT_URI_OK, ret); + assert_num_eq (P11_KIT_URI_OK, ret); iter = p11_kit_iter_new (uri); p11_kit_uri_free (uri); @@ -732,26 +730,27 @@ test_token_mismatch (CuTest *tc) while ((rv = p11_kit_iter_next (iter)) == CKR_OK) count++; - CuAssertTrue (tc, rv == CKR_CANCEL); + assert (rv == CKR_CANCEL); /* Nothing should have matched */ - CuAssertIntEquals (tc, 0, count); + assert_num_eq (0, count); p11_kit_iter_free (iter); - finalize_and_free_modules (tc, modules); + finalize_and_free_modules (modules); } static void -test_getslotlist_fail_first (CuTest *tc) +test_getslotlist_fail_first (void) { CK_FUNCTION_LIST module; P11KitIter *iter; CK_RV rv; int at; - rv = p11_kit_initialize_module (&mock_module); - CuAssertTrue (tc, rv == CKR_OK); + mock_module_reset (); + rv = mock_module.C_Initialize (NULL); + assert (rv == CKR_OK); memcpy (&module, &mock_module, sizeof (CK_FUNCTION_LIST)); module.C_GetSlotList = mock_C_GetSlotList__fail_first; @@ -763,27 +762,28 @@ test_getslotlist_fail_first (CuTest *tc) while ((rv = p11_kit_iter_next (iter)) == CKR_OK) at++; - CuAssertTrue (tc, rv == CKR_VENDOR_DEFINED); + assert (rv == CKR_VENDOR_DEFINED); /* Should fail on the first iteration */ - CuAssertIntEquals (tc, 0, at); + assert_num_eq (0, at); p11_kit_iter_free (iter); - rv = p11_kit_finalize_module (&mock_module); - CuAssertTrue (tc, rv == CKR_OK); + rv = mock_module.C_Finalize (NULL); + assert (rv == CKR_OK); } static void -test_getslotlist_fail_late (CuTest *tc) +test_getslotlist_fail_late (void) { CK_FUNCTION_LIST module; P11KitIter *iter; CK_RV rv; int at; - rv = p11_kit_initialize_module (&mock_module); - CuAssertTrue (tc, rv == CKR_OK); + mock_module_reset (); + rv = mock_module.C_Initialize (NULL); + assert (rv == CKR_OK); memcpy (&module, &mock_module, sizeof (CK_FUNCTION_LIST)); module.C_GetSlotList = mock_C_GetSlotList__fail_late; @@ -795,27 +795,28 @@ test_getslotlist_fail_late (CuTest *tc) while ((rv = p11_kit_iter_next (iter)) == CKR_OK) at++; - CuAssertTrue (tc, rv == CKR_VENDOR_DEFINED); + assert (rv == CKR_VENDOR_DEFINED); /* Should fail on the first iteration */ - CuAssertIntEquals (tc, 0, at); + assert_num_eq (0, at); p11_kit_iter_free (iter); - rv = p11_kit_finalize_module (&mock_module); - CuAssertTrue (tc, rv == CKR_OK); + rv = mock_module.C_Finalize (NULL); + assert (rv == CKR_OK); } static void -test_open_session_fail (CuTest *tc) +test_open_session_fail (void) { CK_FUNCTION_LIST module; P11KitIter *iter; CK_RV rv; int at; - rv = p11_kit_initialize_module (&mock_module); - CuAssertTrue (tc, rv == CKR_OK); + mock_module_reset (); + rv = mock_module.C_Initialize (NULL); + assert (rv == CKR_OK); memcpy (&module, &mock_module, sizeof (CK_FUNCTION_LIST)); module.C_OpenSession = mock_C_OpenSession__fails; @@ -827,27 +828,28 @@ test_open_session_fail (CuTest *tc) while ((rv = p11_kit_iter_next (iter)) == CKR_OK) at++; - CuAssertTrue (tc, rv == CKR_DEVICE_ERROR); + assert (rv == CKR_DEVICE_ERROR); /* Should fail on the first iteration */ - CuAssertIntEquals (tc, 0, at); + assert_num_eq (0, at); p11_kit_iter_free (iter); - rv = p11_kit_finalize_module (&mock_module); - CuAssertTrue (tc, rv == CKR_OK); + rv = mock_module.C_Finalize (NULL); + assert (rv == CKR_OK); } static void -test_find_init_fail (CuTest *tc) +test_find_init_fail (void) { CK_FUNCTION_LIST module; P11KitIter *iter; CK_RV rv; int at; - rv = p11_kit_initialize_module (&mock_module); - CuAssertTrue (tc, rv == CKR_OK); + mock_module_reset (); + rv = mock_module.C_Initialize (NULL); + assert (rv == CKR_OK); memcpy (&module, &mock_module, sizeof (CK_FUNCTION_LIST)); module.C_FindObjectsInit = mock_C_FindObjectsInit__fails; @@ -859,27 +861,28 @@ test_find_init_fail (CuTest *tc) while ((rv = p11_kit_iter_next (iter)) == CKR_OK) at++; - CuAssertTrue (tc, rv == CKR_DEVICE_MEMORY); + assert (rv == CKR_DEVICE_MEMORY); /* Should fail on the first iteration */ - CuAssertIntEquals (tc, 0, at); + assert_num_eq (0, at); p11_kit_iter_free (iter); - rv = p11_kit_finalize_module (&mock_module); - CuAssertTrue (tc, rv == CKR_OK); + rv = mock_module.C_Finalize (NULL); + assert (rv == CKR_OK); } static void -test_find_objects_fail (CuTest *tc) +test_find_objects_fail (void) { CK_FUNCTION_LIST module; P11KitIter *iter; CK_RV rv; int at; - rv = p11_kit_initialize_module (&mock_module); - CuAssertTrue (tc, rv == CKR_OK); + mock_module_reset (); + rv = mock_module.C_Initialize (NULL); + assert (rv == CKR_OK); memcpy (&module, &mock_module, sizeof (CK_FUNCTION_LIST)); module.C_FindObjects = mock_C_FindObjects__fails; @@ -891,19 +894,19 @@ test_find_objects_fail (CuTest *tc) while ((rv = p11_kit_iter_next (iter)) == CKR_OK) at++; - CuAssertTrue (tc, rv == CKR_DEVICE_REMOVED); + assert (rv == CKR_DEVICE_REMOVED); /* Should fail on the first iteration */ - CuAssertIntEquals (tc, 0, at); + assert_num_eq (0, at); p11_kit_iter_free (iter); - rv = p11_kit_finalize_module (&mock_module); - CuAssertTrue (tc, rv == CKR_OK); + rv = mock_module.C_Finalize (NULL); + assert (rv == CKR_OK); } static void -test_load_attributes (CuTest *tc) +test_load_attributes (void) { CK_FUNCTION_LIST_PTR *modules; P11KitIter *iter; @@ -918,7 +921,7 @@ test_load_attributes (CuTest *tc) { CKA_LABEL }, }; - modules = initialize_and_get_modules (tc); + modules = initialize_and_get_modules (); iter = p11_kit_iter_new (NULL); p11_kit_iter_begin (iter, modules); @@ -928,24 +931,24 @@ test_load_attributes (CuTest *tc) at = 0; while ((rv = p11_kit_iter_next (iter)) == CKR_OK) { rv = p11_kit_iter_load_attributes (iter, attrs, 2); - CuAssertTrue (tc, rv == CKR_OK); + assert (rv == CKR_OK); object = p11_kit_iter_get_object (iter); switch (object) { case MOCK_DATA_OBJECT: - CuAssertTrue (tc, p11_attrs_find_ulong (attrs, CKA_CLASS, &ulong) && ulong == CKO_DATA); - CuAssertTrue (tc, p11_attr_match_value (p11_attrs_find (attrs, CKA_LABEL), "TEST LABEL", -1)); + assert (p11_attrs_find_ulong (attrs, CKA_CLASS, &ulong) && ulong == CKO_DATA); + assert (p11_attr_match_value (p11_attrs_find (attrs, CKA_LABEL), "TEST LABEL", -1)); break; case MOCK_PUBLIC_KEY_CAPITALIZE: - CuAssertTrue (tc, p11_attrs_find_ulong (attrs, CKA_CLASS, &ulong) && ulong == CKO_PUBLIC_KEY); - CuAssertTrue (tc, p11_attr_match_value (p11_attrs_find (attrs, CKA_LABEL), "Public Capitalize Key", -1)); + assert (p11_attrs_find_ulong (attrs, CKA_CLASS, &ulong) && ulong == CKO_PUBLIC_KEY); + assert (p11_attr_match_value (p11_attrs_find (attrs, CKA_LABEL), "Public Capitalize Key", -1)); break; case MOCK_PUBLIC_KEY_PREFIX: - CuAssertTrue (tc, p11_attrs_find_ulong (attrs, CKA_CLASS, &ulong) && ulong == CKO_PUBLIC_KEY); - CuAssertTrue (tc, p11_attr_match_value (p11_attrs_find (attrs, CKA_LABEL), "Public prefix key", -1)); + assert (p11_attrs_find_ulong (attrs, CKA_CLASS, &ulong) && ulong == CKO_PUBLIC_KEY); + assert (p11_attr_match_value (p11_attrs_find (attrs, CKA_LABEL), "Public prefix key", -1)); break; default: - CuFail (tc, "Unknown object matched"); + assert_fail ("Unknown object matched", NULL); break; } @@ -954,26 +957,27 @@ test_load_attributes (CuTest *tc) p11_attrs_free (attrs); - CuAssertTrue (tc, rv == CKR_CANCEL); + assert (rv == CKR_CANCEL); /* Three modules, each with 1 slot, and 3 public objects */ - CuAssertIntEquals (tc, 9, at); + assert_num_eq (9, at); p11_kit_iter_free (iter); - finalize_and_free_modules (tc, modules); + finalize_and_free_modules (modules); } static void -test_load_attributes_none (CuTest *tc) +test_load_attributes_none (void) { CK_FUNCTION_LIST module; P11KitIter *iter; CK_ATTRIBUTE *attrs; CK_RV rv; - rv = p11_kit_initialize_module (&mock_module); - CuAssertTrue (tc, rv == CKR_OK); + mock_module_reset (); + rv = mock_module.C_Initialize (NULL); + assert (rv == CKR_OK); memcpy (&module, &mock_module, sizeof (CK_FUNCTION_LIST)); @@ -983,20 +987,20 @@ test_load_attributes_none (CuTest *tc) while ((rv = p11_kit_iter_next (iter)) == CKR_OK) { attrs = p11_attrs_buildn (NULL, NULL, 0); rv = p11_kit_iter_load_attributes (iter, attrs, 0); - CuAssertTrue (tc, rv == CKR_OK); + assert (rv == CKR_OK); p11_attrs_free (attrs); } - CuAssertTrue (tc, rv == CKR_CANCEL); + assert (rv == CKR_CANCEL); p11_kit_iter_free (iter); - rv = p11_kit_finalize_module (&mock_module); - CuAssertTrue (tc, rv == CKR_OK); + rv = mock_module.C_Finalize (NULL); + assert (rv == CKR_OK); } static void -test_load_attributes_fail_first (CuTest *tc) +test_load_attributes_fail_first (void) { CK_ATTRIBUTE label = { CKA_LABEL, }; CK_FUNCTION_LIST module; @@ -1004,8 +1008,9 @@ test_load_attributes_fail_first (CuTest *tc) CK_ATTRIBUTE *attrs; CK_RV rv; - rv = p11_kit_initialize_module (&mock_module); - CuAssertTrue (tc, rv == CKR_OK); + mock_module_reset (); + rv = mock_module.C_Initialize (NULL); + assert (rv == CKR_OK); memcpy (&module, &mock_module, sizeof (CK_FUNCTION_LIST)); module.C_GetAttributeValue = mock_C_GetAttributeValue__fail_first; @@ -1016,20 +1021,20 @@ test_load_attributes_fail_first (CuTest *tc) while ((rv = p11_kit_iter_next (iter)) == CKR_OK) { attrs = p11_attrs_build (NULL, &label, NULL); rv = p11_kit_iter_load_attributes (iter, attrs, 1); - CuAssertTrue (tc, rv == CKR_FUNCTION_REJECTED); + assert (rv == CKR_FUNCTION_REJECTED); p11_attrs_free (attrs); } - CuAssertTrue (tc, rv == CKR_CANCEL); + assert (rv == CKR_CANCEL); p11_kit_iter_free (iter); - rv = p11_kit_finalize_module (&mock_module); - CuAssertTrue (tc, rv == CKR_OK); + rv = mock_module.C_Finalize (NULL); + assert (rv == CKR_OK); } static void -test_load_attributes_fail_late (CuTest *tc) +test_load_attributes_fail_late (void) { CK_ATTRIBUTE label = { CKA_LABEL, }; CK_FUNCTION_LIST module; @@ -1037,8 +1042,9 @@ test_load_attributes_fail_late (CuTest *tc) CK_ATTRIBUTE *attrs; CK_RV rv; - rv = p11_kit_initialize_module (&mock_module); - CuAssertTrue (tc, rv == CKR_OK); + mock_module_reset (); + rv = mock_module.C_Initialize (NULL); + assert (rv == CKR_OK); memcpy (&module, &mock_module, sizeof (CK_FUNCTION_LIST)); module.C_GetAttributeValue = mock_C_GetAttributeValue__fail_late; @@ -1049,61 +1055,50 @@ test_load_attributes_fail_late (CuTest *tc) while ((rv = p11_kit_iter_next (iter)) == CKR_OK) { attrs = p11_attrs_build (NULL, &label, NULL); rv = p11_kit_iter_load_attributes (iter, attrs, 1); - CuAssertTrue (tc, rv == CKR_FUNCTION_FAILED); + assert (rv == CKR_FUNCTION_FAILED); p11_attrs_free (attrs); } - CuAssertTrue (tc, rv == CKR_CANCEL); + assert (rv == CKR_CANCEL); p11_kit_iter_free (iter); - rv = p11_kit_finalize_module (&mock_module); - CuAssertTrue (tc, rv == CKR_OK); + rv = mock_module.C_Finalize (NULL); + assert (rv == CKR_OK); } int -main (void) +main (int argc, + char *argv[]) { - CuString *output = CuStringNew (); - CuSuite* suite = CuSuiteNew (); - int ret; - - putenv ("P11_KIT_STRICT=1"); p11_library_init (); mock_module_init (); - SUITE_ADD_TEST (suite, test_all); - SUITE_ADD_TEST (suite, test_unrecognized); - SUITE_ADD_TEST (suite, test_uri_with_type); - SUITE_ADD_TEST (suite, test_session_flags); - SUITE_ADD_TEST (suite, test_callback); - SUITE_ADD_TEST (suite, test_callback_fails); - SUITE_ADD_TEST (suite, test_callback_destroyer); - SUITE_ADD_TEST (suite, test_filter); - SUITE_ADD_TEST (suite, test_with_session); - SUITE_ADD_TEST (suite, test_with_slot); - SUITE_ADD_TEST (suite, test_with_module); - SUITE_ADD_TEST (suite, test_keep_session); - SUITE_ADD_TEST (suite, test_token_match); - SUITE_ADD_TEST (suite, test_token_mismatch); - SUITE_ADD_TEST (suite, test_module_match); - SUITE_ADD_TEST (suite, test_module_mismatch); - SUITE_ADD_TEST (suite, test_getslotlist_fail_first); - SUITE_ADD_TEST (suite, test_getslotlist_fail_late); - SUITE_ADD_TEST (suite, test_open_session_fail); - SUITE_ADD_TEST (suite, test_find_init_fail); - SUITE_ADD_TEST (suite, test_find_objects_fail); - SUITE_ADD_TEST (suite, test_load_attributes); - SUITE_ADD_TEST (suite, test_load_attributes_none); - SUITE_ADD_TEST (suite, test_load_attributes_fail_first); - SUITE_ADD_TEST (suite, test_load_attributes_fail_late); - - CuSuiteRun (suite); - CuSuiteSummary (suite, output); - CuSuiteDetails (suite, output); - printf ("%s\n", output->buffer); - ret = suite->failCount; - CuSuiteDelete (suite); - CuStringDelete (output); - return ret; + p11_test (test_all, "/iter/test_all"); + p11_test (test_unrecognized, "/iter/test_unrecognized"); + p11_test (test_uri_with_type, "/iter/test_uri_with_type"); + p11_test (test_session_flags, "/iter/test_session_flags"); + p11_test (test_callback, "/iter/test_callback"); + p11_test (test_callback_fails, "/iter/test_callback_fails"); + p11_test (test_callback_destroyer, "/iter/test_callback_destroyer"); + p11_test (test_filter, "/iter/test_filter"); + p11_test (test_with_session, "/iter/test_with_session"); + p11_test (test_with_slot, "/iter/test_with_slot"); + p11_test (test_with_module, "/iter/test_with_module"); + p11_test (test_keep_session, "/iter/test_keep_session"); + p11_test (test_token_match, "/iter/test_token_match"); + p11_test (test_token_mismatch, "/iter/test_token_mismatch"); + p11_test (test_module_match, "/iter/test_module_match"); + p11_test (test_module_mismatch, "/iter/test_module_mismatch"); + p11_test (test_getslotlist_fail_first, "/iter/test_getslotlist_fail_first"); + p11_test (test_getslotlist_fail_late, "/iter/test_getslotlist_fail_late"); + p11_test (test_open_session_fail, "/iter/test_open_session_fail"); + p11_test (test_find_init_fail, "/iter/test_find_init_fail"); + p11_test (test_find_objects_fail, "/iter/test_find_objects_fail"); + p11_test (test_load_attributes, "/iter/test_load_attributes"); + p11_test (test_load_attributes_none, "/iter/test_load_attributes_none"); + p11_test (test_load_attributes_fail_first, "/iter/test_load_attributes_fail_first"); + p11_test (test_load_attributes_fail_late, "/iter/test_load_attributes_fail_late"); + + return p11_test_run (argc, argv); } diff --git a/p11-kit/tests/test-log.c b/p11-kit/tests/test-log.c new file mode 100644 index 0000000..e7dab70 --- /dev/null +++ b/p11-kit/tests/test-log.c @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2013 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 <stefw@redhat.com> + */ + +#include "config.h" +#include "test.h" + +#include "dict.h" +#include "library.h" +#include "log.h" +#include "mock.h" +#include "modules.h" +#include "p11-kit.h" +#include "virtual.h" + +#include <errno.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +static CK_FUNCTION_LIST_PTR +setup_mock_module (CK_SESSION_HANDLE *session) +{ + CK_FUNCTION_LIST_PTR module; + CK_RV rv; + + p11_lock (); + p11_log_force = true; + + rv = p11_module_load_inlock_reentrant (&mock_module, 0, &module); + assert (rv == CKR_OK); + assert_ptr_not_null (module); + assert (p11_virtual_is_wrapper (module)); + + p11_unlock (); + + rv = p11_kit_module_initialize (module); + assert (rv == CKR_OK); + + if (session) { + rv = (module->C_OpenSession) (MOCK_SLOT_ONE_ID, + CKF_RW_SESSION | CKF_SERIAL_SESSION, + NULL, NULL, session); + assert (rv == CKR_OK); + } + + return module; +} + +static void +teardown_mock_module (CK_FUNCTION_LIST_PTR module) +{ + CK_RV rv; + + rv = p11_kit_module_finalize (module); + assert (rv == CKR_OK); + + p11_lock (); + + rv = p11_module_release_inlock_reentrant (module); + assert (rv == CKR_OK); + + p11_unlock (); +} + +/* Bring in all the mock module tests */ +#include "test-mock.c" + +int +main (int argc, + char *argv[]) +{ + p11_library_init (); + mock_module_init (); + + test_mock_add_tests ("/log"); + + p11_kit_be_quiet (); + p11_log_output = false; + + return p11_test_run (argc, argv); +} diff --git a/p11-kit/tests/test-managed.c b/p11-kit/tests/test-managed.c new file mode 100644 index 0000000..9fc9ffb --- /dev/null +++ b/p11-kit/tests/test-managed.c @@ -0,0 +1,215 @@ +/* + * Copyright (c) 2012 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 <stefw@redhat.com> + */ + +#include "config.h" +#include "test.h" + +#include "dict.h" +#include "library.h" +#include "mock.h" +#include "modules.h" +#include "p11-kit.h" +#include "virtual.h" + +#include <errno.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +static CK_FUNCTION_LIST_PTR +setup_mock_module (CK_SESSION_HANDLE *session) +{ + CK_FUNCTION_LIST_PTR module; + CK_RV rv; + + p11_lock (); + + rv = p11_module_load_inlock_reentrant (&mock_module, 0, &module); + assert (rv == CKR_OK); + assert_ptr_not_null (module); + assert (p11_virtual_is_wrapper (module)); + + p11_unlock (); + + rv = p11_kit_module_initialize (module); + assert (rv == CKR_OK); + + if (session) { + rv = (module->C_OpenSession) (MOCK_SLOT_ONE_ID, + CKF_RW_SESSION | CKF_SERIAL_SESSION, + NULL, NULL, session); + assert (rv == CKR_OK); + } + + return module; +} + +static void +teardown_mock_module (CK_FUNCTION_LIST_PTR module) +{ + CK_RV rv; + + rv = p11_kit_module_finalize (module); + assert (rv == CKR_OK); + + p11_lock (); + + rv = p11_module_release_inlock_reentrant (module); + assert (rv == CKR_OK); + + p11_unlock (); +} + +static CK_RV +fail_C_Initialize (void *init_reserved) +{ + return CKR_FUNCTION_FAILED; +} + +static void +test_initialize_finalize (void) +{ + CK_FUNCTION_LIST_PTR module; + CK_RV rv; + + p11_lock (); + + rv = p11_module_load_inlock_reentrant (&mock_module, 0, &module); + assert (rv == CKR_OK); + assert_ptr_not_null (module); + assert (p11_virtual_is_wrapper (module)); + + p11_unlock (); + + rv = module->C_Initialize (NULL); + assert (rv == CKR_OK); + + rv = module->C_Initialize (NULL); + assert (rv == CKR_CRYPTOKI_ALREADY_INITIALIZED); + + rv = module->C_Finalize (NULL); + assert (rv == CKR_OK); + + rv = module->C_Finalize (NULL); + assert (rv == CKR_CRYPTOKI_NOT_INITIALIZED); + + p11_lock (); + + rv = p11_module_release_inlock_reentrant (module); + assert (rv == CKR_OK); + + p11_unlock (); +} + +static void +test_initialize_fail (void) +{ + CK_FUNCTION_LIST_PTR module; + CK_FUNCTION_LIST base; + CK_RV rv; + + memcpy (&base, &mock_module, sizeof (CK_FUNCTION_LIST)); + base.C_Initialize = fail_C_Initialize; + + p11_lock (); + + rv = p11_module_load_inlock_reentrant (&base, 0, &module); + assert (rv == CKR_OK); + + p11_unlock (); + + rv = p11_kit_module_initialize (module); + assert (rv == CKR_FUNCTION_FAILED); +} + +static void +test_separate_close_all_sessions (void) +{ + CK_FUNCTION_LIST *first; + CK_FUNCTION_LIST *second; + CK_SESSION_HANDLE s1; + CK_SESSION_HANDLE s2; + CK_SESSION_INFO info; + CK_RV rv; + + first = setup_mock_module (&s1); + second = setup_mock_module (&s2); + + rv = first->C_GetSessionInfo (s1, &info); + assert (rv == CKR_OK); + + rv = second->C_GetSessionInfo (s2, &info); + assert (rv == CKR_OK); + + first->C_CloseAllSessions (MOCK_SLOT_ONE_ID); + assert (rv == CKR_OK); + + rv = first->C_GetSessionInfo (s1, &info); + assert (rv == CKR_SESSION_HANDLE_INVALID); + + rv = second->C_GetSessionInfo (s2, &info); + assert (rv == CKR_OK); + + second->C_CloseAllSessions (MOCK_SLOT_ONE_ID); + assert (rv == CKR_OK); + + rv = first->C_GetSessionInfo (s1, &info); + assert (rv == CKR_SESSION_HANDLE_INVALID); + + rv = second->C_GetSessionInfo (s2, &info); + assert (rv == CKR_SESSION_HANDLE_INVALID); + + teardown_mock_module (first); + teardown_mock_module (second); +} + +/* Bring in all the mock module tests */ +#include "test-mock.c" + +int +main (int argc, + char *argv[]) +{ + mock_module_init (); + p11_library_init (); + + p11_test (test_initialize_finalize, "/managed/test_initialize_finalize"); + p11_test (test_initialize_fail, "/managed/test_initialize_fail"); + p11_test (test_separate_close_all_sessions, "/managed/test_separate_close_all_sessions"); + test_mock_add_tests ("/managed"); + + p11_kit_be_quiet (); + + return p11_test_run (argc, argv); +} diff --git a/p11-kit/tests/test-mock.c b/p11-kit/tests/test-mock.c new file mode 100644 index 0000000..5fba7ec --- /dev/null +++ b/p11-kit/tests/test-mock.c @@ -0,0 +1,1679 @@ +/* + * Copyright (c) 2012 Stefan Walter + * Copyright (c) 2012-2013 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> + */ + +#include "test.h" + +#include "library.h" +#include "mock.h" +#include "p11-kit.h" + +#include <sys/types.h> +#include <assert.h> +#include <string.h> +#include <stdio.h> +#include <stdlib.h> + +static void +test_get_info (void) +{ + CK_FUNCTION_LIST_PTR module; + CK_INFO info; + CK_RV rv; + + module = setup_mock_module (NULL); + + rv = (module->C_GetInfo) (&info); + assert (rv == CKR_OK); + assert (memcmp (&info, &MOCK_INFO, sizeof (CK_INFO)) == 0); + + teardown_mock_module (module); +} + +static void +test_get_slot_list (void) +{ + CK_FUNCTION_LIST_PTR module; + CK_SLOT_ID slot_list[8]; + CK_ULONG count = 0; + CK_RV rv; + + module = setup_mock_module (NULL); + + /* Normal module has 2 slots, one with token present */ + rv = (module->C_GetSlotList) (CK_TRUE, NULL, &count); + assert (rv == CKR_OK); + assert_num_eq (MOCK_SLOTS_PRESENT, count); + rv = (module->C_GetSlotList) (CK_FALSE, NULL, &count); + assert (rv == CKR_OK); + assert_num_eq (MOCK_SLOTS_ALL, count); + + count = 8; + rv = (module->C_GetSlotList) (CK_TRUE, slot_list, &count); + assert (rv == CKR_OK); + assert_num_eq (MOCK_SLOTS_PRESENT, count); + assert_num_eq (MOCK_SLOT_ONE_ID, slot_list[0]); + + count = 8; + rv = (module->C_GetSlotList) (CK_FALSE, slot_list, &count); + assert (rv == CKR_OK); + assert_num_eq (MOCK_SLOTS_ALL, count); + assert_num_eq (MOCK_SLOT_ONE_ID, slot_list[0]); + assert_num_eq (MOCK_SLOT_TWO_ID, slot_list[1]); + + teardown_mock_module (module); +} + +static void +test_get_slot_info (void) +{ + CK_FUNCTION_LIST_PTR module; + CK_SLOT_INFO info; + char *string; + CK_RV rv; + + module = setup_mock_module (NULL); + + rv = (module->C_GetSlotInfo) (MOCK_SLOT_ONE_ID, &info); + assert (rv == CKR_OK); + string = p11_kit_space_strdup (info.slotDescription, sizeof (info.slotDescription)); + assert_str_eq ("TEST SLOT", string); + free (string); + string = p11_kit_space_strdup (info.manufacturerID, sizeof (info.manufacturerID)); + assert_str_eq ("TEST MANUFACTURER", string); + free (string); + assert_num_eq (CKF_TOKEN_PRESENT | CKF_REMOVABLE_DEVICE, info.flags); + assert_num_eq (55, info.hardwareVersion.major); + assert_num_eq (155, info.hardwareVersion.minor); + assert_num_eq (65, info.firmwareVersion.major); + assert_num_eq (165, info.firmwareVersion.minor); + + rv = (module->C_GetSlotInfo) (MOCK_SLOT_TWO_ID, &info); + assert (rv == CKR_OK); + assert_num_eq (CKF_REMOVABLE_DEVICE, info.flags); + + rv = (module->C_GetSlotInfo) (0, &info); + assert (rv == CKR_SLOT_ID_INVALID); + + teardown_mock_module (module); +} + +static void +test_get_token_info (void) +{ + CK_FUNCTION_LIST_PTR module; + CK_TOKEN_INFO info; + char *string; + CK_RV rv; + + module = setup_mock_module (NULL); + + rv = (module->C_GetTokenInfo) (MOCK_SLOT_ONE_ID, &info); + assert (rv == CKR_OK); + + string = p11_kit_space_strdup (info.label, sizeof (info.label)); + assert_str_eq ("TEST LABEL", string); + free (string); + string = p11_kit_space_strdup (info.manufacturerID, sizeof (info.manufacturerID)); + assert_str_eq ("TEST MANUFACTURER", string); + free (string); + string = p11_kit_space_strdup (info.model, sizeof (info.model)); + assert_str_eq ("TEST MODEL", string); + free (string); + string = p11_kit_space_strdup (info.serialNumber, sizeof (info.serialNumber)); + assert_str_eq ("TEST SERIAL", string); + free (string); + assert_num_eq (CKF_LOGIN_REQUIRED | CKF_USER_PIN_INITIALIZED | CKF_CLOCK_ON_TOKEN | CKF_TOKEN_INITIALIZED, info.flags); + assert_num_eq (1, info.ulMaxSessionCount); + assert_num_eq (2, info.ulSessionCount); + assert_num_eq (3, info.ulMaxRwSessionCount); + assert_num_eq (4, info.ulRwSessionCount); + assert_num_eq (5, info.ulMaxPinLen); + assert_num_eq (6, info.ulMinPinLen); + assert_num_eq (7, info.ulTotalPublicMemory); + assert_num_eq (8, info.ulFreePublicMemory); + assert_num_eq (9, info.ulTotalPrivateMemory); + assert_num_eq (10, info.ulFreePrivateMemory); + assert_num_eq (75, info.hardwareVersion.major); + assert_num_eq (175, info.hardwareVersion.minor); + assert_num_eq (85, info.firmwareVersion.major); + assert_num_eq (185, info.firmwareVersion.minor); + assert (memcmp (info.utcTime, "1999052509195900", sizeof (info.utcTime)) == 0); + + rv = (module->C_GetTokenInfo) (MOCK_SLOT_TWO_ID, &info); + assert (rv == CKR_TOKEN_NOT_PRESENT); + + rv = (module->C_GetTokenInfo) (0, &info); + assert (rv == CKR_SLOT_ID_INVALID); + + teardown_mock_module (module); +} + +static void +test_get_mechanism_list (void) +{ + CK_FUNCTION_LIST_PTR module; + CK_MECHANISM_TYPE mechs[8]; + CK_ULONG count = 0; + CK_RV rv; + + module = setup_mock_module (NULL); + + rv = (module->C_GetMechanismList) (MOCK_SLOT_ONE_ID, NULL, &count); + assert (rv == CKR_OK); + assert_num_eq (2, count); + rv = (module->C_GetMechanismList) (MOCK_SLOT_TWO_ID, NULL, &count); + assert (rv == CKR_TOKEN_NOT_PRESENT); + rv = (module->C_GetMechanismList) (0, NULL, &count); + assert (rv == CKR_SLOT_ID_INVALID); + + count = 8; + rv = (module->C_GetMechanismList) (MOCK_SLOT_ONE_ID, mechs, &count); + assert (rv == CKR_OK); + assert_num_eq (2, count); + assert_num_eq (mechs[0], CKM_MOCK_CAPITALIZE); + assert_num_eq (mechs[1], CKM_MOCK_PREFIX); + + teardown_mock_module (module); +} + +static void +test_get_mechanism_info (void) +{ + CK_FUNCTION_LIST_PTR module; + CK_MECHANISM_INFO info; + CK_RV rv; + + module = setup_mock_module (NULL); + + rv = (module->C_GetMechanismInfo) (MOCK_SLOT_ONE_ID, CKM_MOCK_CAPITALIZE, &info); + assert (rv == CKR_OK); + assert_num_eq (512, info.ulMinKeySize); + assert_num_eq (4096, info.ulMaxKeySize); + assert_num_eq (CKF_ENCRYPT | CKF_DECRYPT, info.flags); + + rv = (module->C_GetMechanismInfo) (MOCK_SLOT_ONE_ID, CKM_MOCK_PREFIX, &info); + assert (rv == CKR_OK); + assert_num_eq (2048, info.ulMinKeySize); + assert_num_eq (2048, info.ulMaxKeySize); + assert_num_eq (CKF_SIGN | CKF_VERIFY, info.flags); + + rv = (module->C_GetMechanismInfo) (MOCK_SLOT_TWO_ID, CKM_MOCK_PREFIX, &info); + assert (rv == CKR_TOKEN_NOT_PRESENT); + rv = (module->C_GetMechanismInfo) (MOCK_SLOT_ONE_ID, 0, &info); + assert (rv == CKR_MECHANISM_INVALID); + rv = (module->C_GetMechanismInfo) (0, CKM_MOCK_PREFIX, &info); + assert (rv == CKR_SLOT_ID_INVALID); + + teardown_mock_module (module); +} + +static void +test_init_token (void) +{ + CK_FUNCTION_LIST_PTR module; + CK_RV rv; + + module = setup_mock_module (NULL); + + rv = (module->C_InitToken) (MOCK_SLOT_ONE_ID, (CK_UTF8CHAR_PTR)"TEST PIN", 8, (CK_UTF8CHAR_PTR)"TEST LABEL"); + assert (rv == CKR_OK); + + rv = (module->C_InitToken) (MOCK_SLOT_ONE_ID, (CK_UTF8CHAR_PTR)"OTHER", 5, (CK_UTF8CHAR_PTR)"TEST LABEL"); + assert (rv == CKR_PIN_INVALID); + rv = (module->C_InitToken) (MOCK_SLOT_TWO_ID, (CK_UTF8CHAR_PTR)"TEST PIN", 8, (CK_UTF8CHAR_PTR)"TEST LABEL"); + assert (rv == CKR_TOKEN_NOT_PRESENT); + rv = (module->C_InitToken) (0, (CK_UTF8CHAR_PTR)"TEST PIN", 8, (CK_UTF8CHAR_PTR)"TEST LABEL"); + assert (rv == CKR_SLOT_ID_INVALID); + + teardown_mock_module (module); +} + +static void +test_wait_for_slot_event (void) +{ + CK_FUNCTION_LIST_PTR module; + CK_SLOT_ID slot; + CK_RV rv; + +#ifdef MOCK_SKIP_WAIT_TEST + return; +#endif + + module = setup_mock_module (NULL); + + rv = (module->C_WaitForSlotEvent) (0, &slot, NULL); + assert (rv == CKR_OK); + assert_num_eq (slot, MOCK_SLOT_TWO_ID); + + rv = (module->C_WaitForSlotEvent) (CKF_DONT_BLOCK, &slot, NULL); + assert (rv == CKR_NO_EVENT); + + teardown_mock_module (module); +} + +static void +test_open_close_session (void) +{ + CK_FUNCTION_LIST_PTR module; + CK_SESSION_HANDLE session = 0; + CK_RV rv; + + module = setup_mock_module (NULL); + + rv = (module->C_OpenSession) (MOCK_SLOT_TWO_ID, CKF_SERIAL_SESSION, NULL, NULL, &session); + assert (rv == CKR_TOKEN_NOT_PRESENT); + rv = (module->C_OpenSession) (0, CKF_SERIAL_SESSION, NULL, NULL, &session); + assert (rv == CKR_SLOT_ID_INVALID); + + rv = (module->C_OpenSession) (MOCK_SLOT_ONE_ID, CKF_SERIAL_SESSION, NULL, NULL, &session); + assert (rv == CKR_OK); + assert (session != 0); + + rv = (module->C_CloseSession) (session); + assert (rv == CKR_OK); + + rv = (module->C_CloseSession) (session); + assert (rv == CKR_SESSION_HANDLE_INVALID); + + teardown_mock_module (module); +} + +static void +test_close_all_sessions (void) +{ + CK_FUNCTION_LIST_PTR module; + CK_SESSION_HANDLE session = 0; + CK_RV rv; + + module = setup_mock_module (NULL); + + rv = (module->C_OpenSession) (MOCK_SLOT_ONE_ID, CKF_SERIAL_SESSION, NULL, NULL, &session); + assert (rv == CKR_OK); + assert (session != 0); + + rv = (module->C_CloseAllSessions) (MOCK_SLOT_ONE_ID); + assert (rv == CKR_OK); + + rv = (module->C_CloseSession) (session); + assert (rv == CKR_SESSION_HANDLE_INVALID); + + teardown_mock_module (module); +} + +static void +test_get_function_status (void) +{ + CK_FUNCTION_LIST_PTR module; + CK_SESSION_HANDLE session = 0; + CK_RV rv; + + module = setup_mock_module (&session); + + rv = (module->C_GetFunctionStatus) (session); + assert (rv == CKR_FUNCTION_NOT_PARALLEL); + + teardown_mock_module (module); +} + +static void +test_cancel_function (void) +{ + CK_FUNCTION_LIST_PTR module; + CK_SESSION_HANDLE session = 0; + CK_RV rv; + + module = setup_mock_module (&session); + + rv = (module->C_CancelFunction) (session); + assert (rv == CKR_FUNCTION_NOT_PARALLEL); + + teardown_mock_module (module); +} + +static void +test_get_session_info (void) +{ + CK_FUNCTION_LIST_PTR module; + CK_SESSION_HANDLE session = 0; + CK_SESSION_INFO info; + CK_RV rv; + + module = setup_mock_module (NULL); + + rv = (module->C_GetSessionInfo) (0, &info); + assert (rv == CKR_SESSION_HANDLE_INVALID); + + rv = (module->C_OpenSession) (MOCK_SLOT_ONE_ID, CKF_SERIAL_SESSION, NULL, NULL, &session); + assert (rv == CKR_OK); + assert (session != 0); + + rv = (module->C_GetSessionInfo) (session, &info); + assert (rv == CKR_OK); + assert_num_eq (MOCK_SLOT_ONE_ID, info.slotID); + assert_num_eq (CKS_RO_PUBLIC_SESSION, info.state); + assert_num_eq (CKF_SERIAL_SESSION, info.flags); + assert_num_eq (1414, info.ulDeviceError); + + rv = (module->C_OpenSession) (MOCK_SLOT_ONE_ID, CKF_RW_SESSION | CKF_SERIAL_SESSION, NULL, NULL, &session); + assert (rv == CKR_OK); + assert (session != 0); + + rv = (module->C_GetSessionInfo) (session, &info); + assert (rv == CKR_OK); + assert_num_eq (MOCK_SLOT_ONE_ID, info.slotID); + assert_num_eq (CKS_RW_PUBLIC_SESSION, info.state); + assert_num_eq (CKF_SERIAL_SESSION | CKF_RW_SESSION, info.flags); + assert_num_eq (1414, info.ulDeviceError); + + teardown_mock_module (module); +} + +static void +test_init_pin (void) +{ + CK_FUNCTION_LIST_PTR module; + CK_SESSION_HANDLE session = 0; + CK_RV rv; + + module = setup_mock_module (&session); + + rv = (module->C_InitPIN) (0, (CK_UTF8CHAR_PTR)"TEST PIN", 8); + assert (rv == CKR_SESSION_HANDLE_INVALID); + + rv = (module->C_InitPIN) (session, (CK_UTF8CHAR_PTR)"TEST PIN", 8); + assert (rv == CKR_OK); + + rv = (module->C_InitPIN) (session, (CK_UTF8CHAR_PTR)"OTHER", 5); + assert (rv == CKR_PIN_INVALID); + + teardown_mock_module (module); +} + +static void +test_set_pin (void) +{ + CK_FUNCTION_LIST_PTR module; + CK_SESSION_HANDLE session = 0; + CK_RV rv; + + module = setup_mock_module (&session); + + rv = (module->C_SetPIN) (0, (CK_UTF8CHAR_PTR)"booo", 4, (CK_UTF8CHAR_PTR)"TEST PIN", 8); + assert (rv == CKR_SESSION_HANDLE_INVALID); + + rv = (module->C_SetPIN) (session, (CK_UTF8CHAR_PTR)"booo", 4, (CK_UTF8CHAR_PTR)"TEST PIN", 8); + assert (rv == CKR_OK); + + rv = (module->C_SetPIN) (session, (CK_UTF8CHAR_PTR)"other", 5, (CK_UTF8CHAR_PTR)"OTHER", 5); + assert (rv == CKR_PIN_INCORRECT); + + teardown_mock_module (module); +} + +static void +test_operation_state (void) +{ + CK_FUNCTION_LIST_PTR module; + CK_BYTE state[128]; + CK_ULONG state_len; + CK_SESSION_HANDLE session = 0; + CK_RV rv; + + module = setup_mock_module (&session); + + state_len = sizeof (state); + rv = (module->C_GetOperationState) (0, state, &state_len); + assert (rv == CKR_SESSION_HANDLE_INVALID); + + state_len = sizeof (state); + rv = (module->C_GetOperationState) (session, state, &state_len); + assert (rv == CKR_OK); + + rv = (module->C_SetOperationState) (session, state, state_len, 355, 455); + assert (rv == CKR_OK); + + rv = (module->C_SetOperationState) (0, state, state_len, 355, 455); + assert (rv == CKR_SESSION_HANDLE_INVALID); + + teardown_mock_module (module); +} + +static void +test_login_logout (void) +{ + CK_FUNCTION_LIST_PTR module; + CK_SESSION_HANDLE session = 0; + CK_RV rv; + + module = setup_mock_module (&session); + + rv = (module->C_Login) (0, CKU_USER, (CK_UTF8CHAR_PTR)"booo", 4); + assert (rv == CKR_SESSION_HANDLE_INVALID); + + rv = (module->C_Login) (session, CKU_USER, (CK_UTF8CHAR_PTR)"bo", 2); + assert (rv == CKR_PIN_INCORRECT); + + rv = (module->C_Login) (session, CKU_USER, (CK_UTF8CHAR_PTR)"booo", 4); + assert (rv == CKR_OK); + + rv = (module->C_Logout) (session); + assert (rv == CKR_OK); + + rv = (module->C_Logout) (session); + assert (rv == CKR_USER_NOT_LOGGED_IN); + + teardown_mock_module (module); +} + +static void +test_get_attribute_value (void) +{ + CK_FUNCTION_LIST_PTR module; + CK_SESSION_HANDLE session = 0; + CK_ATTRIBUTE attrs[8]; + char label[32]; + CK_OBJECT_CLASS klass; + CK_RV rv; + + module = setup_mock_module (&session); + + attrs[0].type = CKA_CLASS; + attrs[0].pValue = &klass; + attrs[0].ulValueLen = sizeof (klass); + attrs[1].type = CKA_LABEL; + attrs[1].pValue = label; + attrs[1].ulValueLen = 2; /* too small */ + attrs[2].type = CKA_BITS_PER_PIXEL; + attrs[2].pValue = NULL; + attrs[2].ulValueLen = 0; + + rv = (module->C_GetAttributeValue) (session, MOCK_PRIVATE_KEY_CAPITALIZE, attrs, 3); + assert (rv == CKR_USER_NOT_LOGGED_IN); + + rv = (module->C_GetAttributeValue) (session, MOCK_PUBLIC_KEY_CAPITALIZE, attrs, 2); + assert (rv == CKR_BUFFER_TOO_SMALL); + + /* Get right size */ + attrs[1].pValue = NULL; + attrs[1].ulValueLen = 0; + + rv = (module->C_GetAttributeValue) (session, MOCK_PUBLIC_KEY_CAPITALIZE, attrs, 2); + assert (rv == CKR_OK); + + rv = (module->C_GetAttributeValue) (session, MOCK_PUBLIC_KEY_CAPITALIZE, attrs, 3); + assert (rv == CKR_ATTRIBUTE_TYPE_INVALID); + + assert_num_eq (CKO_PUBLIC_KEY, klass); + assert_num_eq (21, attrs[1].ulValueLen); + assert_ptr_eq (NULL, attrs[1].pValue); + attrs[1].pValue = label; + attrs[1].ulValueLen = sizeof (label); + assert ((CK_ULONG)-1 == attrs[2].ulValueLen); + assert_ptr_eq (NULL, attrs[2].pValue); + + rv = (module->C_GetAttributeValue) (session, MOCK_PUBLIC_KEY_CAPITALIZE, attrs, 3); + assert (rv == CKR_ATTRIBUTE_TYPE_INVALID); + + assert_num_eq (CKO_PUBLIC_KEY, klass); + assert_num_eq (21, attrs[1].ulValueLen); + assert_ptr_eq (label, attrs[1].pValue); + assert (memcmp (label, "Public Capitalize Key", attrs[1].ulValueLen) == 0); + assert ((CK_ULONG)-1 == attrs[2].ulValueLen); + assert_ptr_eq (NULL, attrs[2].pValue); + + teardown_mock_module (module); +} + +static void +test_set_attribute_value (void) +{ + CK_FUNCTION_LIST_PTR module; + CK_SESSION_HANDLE session = 0; + CK_ATTRIBUTE attrs[8]; + char label[32]; + CK_ULONG bits; + CK_RV rv; + + module = setup_mock_module (&session); + + strcpy (label, "Blahooo"); + bits = 1555; + + attrs[0].type = CKA_LABEL; + attrs[0].pValue = label; + attrs[0].ulValueLen = strlen (label); + attrs[1].type = CKA_BITS_PER_PIXEL; + attrs[1].pValue = &bits; + attrs[1].ulValueLen = sizeof (bits); + + rv = (module->C_SetAttributeValue) (session, MOCK_PRIVATE_KEY_CAPITALIZE, attrs, 2); + assert (rv == CKR_USER_NOT_LOGGED_IN); + + rv = (module->C_SetAttributeValue) (session, MOCK_PUBLIC_KEY_CAPITALIZE, attrs, 2); + assert (rv == CKR_OK); + + memset (label, 0, sizeof (label)); + bits = 0; + + rv = (module->C_GetAttributeValue) (session, MOCK_PUBLIC_KEY_CAPITALIZE, attrs, 2); + assert (rv == CKR_OK); + + assert_num_eq (bits, 1555); + assert_num_eq (7, attrs[0].ulValueLen); + assert (memcmp (label, "Blahooo", attrs[0].ulValueLen) == 0); + + teardown_mock_module (module); +} + +static void +test_create_object (void) +{ + CK_FUNCTION_LIST_PTR module; + CK_SESSION_HANDLE session = 0; + CK_OBJECT_HANDLE object; + CK_ATTRIBUTE attrs[8]; + char label[32]; + CK_ULONG bits; + CK_RV rv; + + module = setup_mock_module (&session); + + strcpy (label, "Blahooo"); + bits = 1555; + + attrs[0].type = CKA_LABEL; + attrs[0].pValue = label; + attrs[0].ulValueLen = strlen (label); + attrs[1].type = CKA_BITS_PER_PIXEL; + attrs[1].pValue = &bits; + attrs[1].ulValueLen = sizeof (bits); + + rv = (module->C_CreateObject) (0, attrs, 2, &object); + assert (rv == CKR_SESSION_HANDLE_INVALID); + + rv = (module->C_CreateObject) (session, attrs, 2, &object); + assert (rv == CKR_OK); + + attrs[0].ulValueLen = sizeof (label); + memset (label, 0, sizeof (label)); + bits = 0; + + rv = (module->C_GetAttributeValue) (session, object, attrs, 2); + assert (rv == CKR_OK); + + assert_num_eq (bits, 1555); + assert_num_eq (7, attrs[0].ulValueLen); + assert (memcmp (label, "Blahooo", attrs[0].ulValueLen) == 0); + + teardown_mock_module (module); +} + +static void +test_copy_object (void) +{ + CK_FUNCTION_LIST_PTR module; + CK_SESSION_HANDLE session = 0; + CK_OBJECT_HANDLE object; + CK_ATTRIBUTE attrs[8]; + char label[32]; + CK_ULONG bits; + CK_RV rv; + + module = setup_mock_module (&session); + + bits = 1555; + + attrs[0].type = CKA_BITS_PER_PIXEL; + attrs[0].pValue = &bits; + attrs[0].ulValueLen = sizeof (bits); + + rv = (module->C_CopyObject) (session, 1333, attrs, 1, &object); + assert (rv == CKR_OBJECT_HANDLE_INVALID); + + rv = (module->C_CopyObject) (session, MOCK_PUBLIC_KEY_CAPITALIZE, attrs, 1, &object); + assert (rv == CKR_OK); + + attrs[1].type = CKA_LABEL; + attrs[1].pValue = label; + attrs[1].ulValueLen = sizeof (label); + bits = 0; + + rv = (module->C_GetAttributeValue) (session, object, attrs, 2); + assert (rv == CKR_OK); + + assert_num_eq (bits, 1555); + assert_num_eq (21, attrs[1].ulValueLen); + assert (memcmp (label, "Public Capitalize Key", attrs[1].ulValueLen) == 0); + + teardown_mock_module (module); +} + +static void +test_destroy_object (void) +{ + CK_FUNCTION_LIST_PTR module; + CK_SESSION_HANDLE session = 0; + CK_ATTRIBUTE attrs[8]; + char label[32]; + CK_RV rv; + + module = setup_mock_module (&session); + + attrs[0].type = CKA_LABEL; + attrs[0].pValue = label; + attrs[0].ulValueLen = sizeof (label); + + rv = (module->C_GetAttributeValue) (session, MOCK_PUBLIC_KEY_CAPITALIZE, attrs, 1); + assert (rv == CKR_OK); + + rv = (module->C_DestroyObject) (0, MOCK_PUBLIC_KEY_CAPITALIZE); + assert (rv == CKR_SESSION_HANDLE_INVALID); + + rv = (module->C_DestroyObject) (session, MOCK_PUBLIC_KEY_CAPITALIZE); + assert (rv == CKR_OK); + + rv = (module->C_GetAttributeValue) (session, MOCK_PUBLIC_KEY_CAPITALIZE, attrs, 1); + assert (rv == CKR_OBJECT_HANDLE_INVALID); + + teardown_mock_module (module); +} + +static void +test_get_object_size (void) +{ + CK_FUNCTION_LIST_PTR module; + CK_SESSION_HANDLE session = 0; + CK_ULONG size; + CK_RV rv; + + module = setup_mock_module (&session); + + rv = (module->C_GetObjectSize) (session, 1333, &size); + assert (rv == CKR_OBJECT_HANDLE_INVALID); + + rv = (module->C_GetObjectSize) (session, MOCK_PUBLIC_KEY_CAPITALIZE, &size); + assert (rv == CKR_OK); + + /* The number here is the length of all attributes added up */ + assert_num_eq (sizeof (CK_ULONG) == 8 ? 44 : 36, size); + + teardown_mock_module (module); +} + +static void +test_find_objects (void) +{ + CK_FUNCTION_LIST_PTR module; + CK_SESSION_HANDLE session = 0; + CK_OBJECT_CLASS klass = CKO_PUBLIC_KEY; + CK_ATTRIBUTE attr = { CKA_CLASS, &klass, sizeof (klass) }; + CK_OBJECT_HANDLE objects[16]; + CK_ULONG count; + CK_ULONG i; + CK_RV rv; + + module = setup_mock_module (&session); + + rv = (module->C_FindObjectsInit) (0, &attr, 1); + assert (rv == CKR_SESSION_HANDLE_INVALID); + + rv = (module->C_FindObjectsInit) (session, &attr, 1); + assert (rv == CKR_OK); + + rv = (module->C_FindObjects) (0, objects, 16, &count); + assert (rv == CKR_SESSION_HANDLE_INVALID); + + rv = (module->C_FindObjects) (session, objects, 16, &count); + assert (rv == CKR_OK); + + assert (count < 16); + + /* Make sure we get the capitalize public key */ + for (i = 0; i < count; i++) { + if (objects[i] == MOCK_PUBLIC_KEY_CAPITALIZE) + break; + } + assert (i != count); + + /* Make sure we get the prefix public key */ + for (i = 0; i < count; i++) { + if (objects[i] == MOCK_PUBLIC_KEY_PREFIX) + break; + } + assert (i != count); + + /* Make sure all public keys */ + for (i = 0; i < count; i++) { + klass = (CK_ULONG)-1; + rv = (module->C_GetAttributeValue) (session, objects[i], &attr, 1); + assert (rv == CKR_OK); + assert_num_eq (CKO_PUBLIC_KEY, klass); + } + + rv = (module->C_FindObjectsFinal) (session); + assert (rv == CKR_OK); + + rv = (module->C_FindObjectsFinal) (session); + assert (rv == CKR_OPERATION_NOT_INITIALIZED); + + teardown_mock_module (module); +} + +static void +test_encrypt (void) +{ + CK_FUNCTION_LIST_PTR module; + CK_SESSION_HANDLE session = 0; + CK_MECHANISM mech = { CKM_MOCK_CAPITALIZE, NULL, 0 }; + CK_BYTE data[128]; + CK_ULONG length; + CK_RV rv; + + module = setup_mock_module (&session); + + rv = (module->C_EncryptInit) (session, &mech, MOCK_PUBLIC_KEY_PREFIX); + assert (rv == CKR_KEY_HANDLE_INVALID); + + rv = (module->C_EncryptInit) (session, &mech, MOCK_PUBLIC_KEY_CAPITALIZE); + assert (rv == CKR_OK); + + length = sizeof (data); + rv = (module->C_Encrypt) (0, (CK_BYTE_PTR)"blah", 4, data, &length); + assert (rv == CKR_SESSION_HANDLE_INVALID); + + length = sizeof (data); + rv = (module->C_Encrypt) (session, (CK_BYTE_PTR)"blah", 4, data, &length); + assert (rv == CKR_OK); + + assert_num_eq (4, length); + assert (memcmp (data, "BLAH", 4) == 0); + + rv = (module->C_EncryptInit) (session, &mech, MOCK_PUBLIC_KEY_CAPITALIZE); + assert (rv == CKR_OK); + + length = sizeof (data); + rv = (module->C_EncryptUpdate) (0, (CK_BYTE_PTR)"blah", 4, data, &length); + assert (rv == CKR_SESSION_HANDLE_INVALID); + + length = sizeof (data); + rv = (module->C_EncryptUpdate) (session, (CK_BYTE_PTR)"sLurm", 5, data, &length); + assert (rv == CKR_OK); + + assert_num_eq (5, length); + assert (memcmp (data, "SLURM", 5) == 0); + + length = sizeof (data); + rv = (module->C_EncryptFinal) (0, data, &length); + assert (rv == CKR_SESSION_HANDLE_INVALID); + + length = sizeof (data); + rv = (module->C_EncryptFinal) (session, data, &length); + assert (rv == CKR_OK); + + teardown_mock_module (module); +} + +static void +test_decrypt (void) +{ + CK_FUNCTION_LIST_PTR module; + CK_SESSION_HANDLE session = 0; + CK_MECHANISM mech = { CKM_MOCK_CAPITALIZE, NULL, 0 }; + CK_BYTE data[128]; + CK_ULONG length; + CK_RV rv; + + module = setup_mock_module (&session); + + rv = (module->C_Login) (session, CKU_USER, (CK_BYTE_PTR)"booo", 4); + assert (rv == CKR_OK); + + rv = (module->C_DecryptInit) (session, &mech, MOCK_PRIVATE_KEY_PREFIX); + assert (rv == CKR_KEY_HANDLE_INVALID); + + rv = (module->C_DecryptInit) (session, &mech, MOCK_PRIVATE_KEY_CAPITALIZE); + assert (rv == CKR_OK); + + length = sizeof (data); + rv = (module->C_Decrypt) (0, (CK_BYTE_PTR)"bLAH", 4, data, &length); + assert (rv == CKR_SESSION_HANDLE_INVALID); + + length = sizeof (data); + rv = (module->C_Decrypt) (session, (CK_BYTE_PTR)"BLAh", 4, data, &length); + assert (rv == CKR_OK); + + assert_num_eq (4, length); + assert (memcmp (data, "blah", 4) == 0); + + rv = (module->C_DecryptInit) (session, &mech, MOCK_PRIVATE_KEY_CAPITALIZE); + assert (rv == CKR_OK); + + length = sizeof (data); + rv = (module->C_DecryptUpdate) (0, (CK_BYTE_PTR)"blah", 4, data, &length); + assert (rv == CKR_SESSION_HANDLE_INVALID); + + length = sizeof (data); + rv = (module->C_DecryptUpdate) (session, (CK_BYTE_PTR)"sLuRM", 5, data, &length); + assert (rv == CKR_OK); + + assert_num_eq (5, length); + assert (memcmp (data, "slurm", 5) == 0); + + length = sizeof (data); + rv = (module->C_DecryptFinal) (0, data, &length); + assert (rv == CKR_SESSION_HANDLE_INVALID); + + length = sizeof (data); + rv = (module->C_DecryptFinal) (session, data, &length); + assert (rv == CKR_OK); + + teardown_mock_module (module); +} + +static void +test_digest (void) +{ + CK_FUNCTION_LIST_PTR module; + CK_SESSION_HANDLE session = 0; + CK_MECHANISM mech = { CKM_MOCK_COUNT, NULL, 0 }; + CK_BYTE digest[128]; + CK_ULONG length; + CK_RV rv; + + module = setup_mock_module (&session); + + rv = (module->C_DigestInit) (0, &mech); + assert (rv == CKR_SESSION_HANDLE_INVALID); + + rv = (module->C_DigestInit) (session, &mech); + assert (rv == CKR_OK); + + length = sizeof (digest); + rv = (module->C_Digest) (0, (CK_BYTE_PTR)"bLAH", 4, digest, &length); + assert (rv == CKR_SESSION_HANDLE_INVALID); + + length = sizeof (digest); + rv = (module->C_Digest) (session, (CK_BYTE_PTR)"BLAh", 4, digest, &length); + assert (rv == CKR_OK); + + assert_num_eq (1, length); + assert (memcmp (digest, "4", 1) == 0); + + rv = (module->C_DigestInit) (session, &mech); + assert (rv == CKR_OK); + + rv = (module->C_DigestUpdate) (0, (CK_BYTE_PTR)"blah", 4); + assert (rv == CKR_SESSION_HANDLE_INVALID); + + rv = (module->C_DigestUpdate) (session, (CK_BYTE_PTR)"sLuRM", 5); + assert (rv == CKR_OK); + + /* Adds the the value of object handle to hash: 6 */ + assert_num_eq (6, MOCK_PUBLIC_KEY_PREFIX); + rv = (module->C_DigestKey) (session, MOCK_PUBLIC_KEY_PREFIX); + assert (rv == CKR_OK); + + rv = (module->C_DigestUpdate) (session, (CK_BYTE_PTR)"Other", 5); + assert (rv == CKR_OK); + + length = sizeof (digest); + rv = (module->C_DigestFinal) (0, digest, &length); + assert (rv == CKR_SESSION_HANDLE_INVALID); + + length = sizeof (digest); + rv = (module->C_DigestFinal) (session, digest, &length); + assert (rv == CKR_OK); + + assert_num_eq (2, length); + assert (memcmp (digest, "16", 2) == 0); + + teardown_mock_module (module); +} + +static void +test_sign (void) +{ + CK_FUNCTION_LIST_PTR module; + CK_SESSION_HANDLE session = 0; + CK_MECHANISM mech = { CKM_MOCK_PREFIX, "prefix:", 7 }; + CK_BYTE signature[128]; + CK_ULONG length; + CK_RV rv; + + module = setup_mock_module (&session); + + rv = (module->C_Login) (session, CKU_USER, (CK_BYTE_PTR)"booo", 4); + assert (rv == CKR_OK); + + rv = (module->C_SignInit) (0, &mech, MOCK_PRIVATE_KEY_PREFIX); + assert (rv == CKR_SESSION_HANDLE_INVALID); + + rv = (module->C_SignInit) (session, &mech, MOCK_PRIVATE_KEY_PREFIX); + assert (rv == CKR_OK); + + rv = (module->C_Login) (session, CKU_CONTEXT_SPECIFIC, (CK_BYTE_PTR)"booo", 4); + assert (rv == CKR_OK); + + length = sizeof (signature); + rv = (module->C_Sign) (0, (CK_BYTE_PTR)"bLAH", 4, signature, &length); + assert (rv == CKR_SESSION_HANDLE_INVALID); + + length = sizeof (signature); + rv = (module->C_Sign) (session, (CK_BYTE_PTR)"BLAh", 4, signature, &length); + assert (rv == CKR_OK); + + assert_num_eq (13, length); + assert (memcmp (signature, "prefix:value4", 13) == 0); + + rv = (module->C_SignInit) (session, &mech, MOCK_PRIVATE_KEY_PREFIX); + assert (rv == CKR_OK); + + rv = (module->C_Login) (session, CKU_CONTEXT_SPECIFIC, (CK_BYTE_PTR)"booo", 4); + assert (rv == CKR_OK); + + rv = (module->C_SignUpdate) (0, (CK_BYTE_PTR)"blah", 4); + assert (rv == CKR_SESSION_HANDLE_INVALID); + + rv = (module->C_SignUpdate) (session, (CK_BYTE_PTR)"sLuRM", 5); + assert (rv == CKR_OK); + + rv = (module->C_SignUpdate) (session, (CK_BYTE_PTR)"Other", 5); + assert (rv == CKR_OK); + + length = sizeof (signature); + rv = (module->C_SignFinal) (0, signature, &length); + assert (rv == CKR_SESSION_HANDLE_INVALID); + + length = sizeof (signature); + rv = (module->C_SignFinal) (session, signature, &length); + assert (rv == CKR_OK); + + assert_num_eq (14, length); + assert (memcmp (signature, "prefix:value10", 2) == 0); + + teardown_mock_module (module); +} + +static void +test_sign_recover (void) +{ + CK_FUNCTION_LIST_PTR module; + CK_SESSION_HANDLE session = 0; + CK_MECHANISM mech = { CKM_MOCK_PREFIX, "prefix:", 7 }; + CK_BYTE signature[128]; + CK_ULONG length; + CK_RV rv; + + module = setup_mock_module (&session); + + rv = (module->C_Login) (session, CKU_USER, (CK_BYTE_PTR)"booo", 4); + assert (rv == CKR_OK); + + rv = (module->C_SignRecoverInit) (0, &mech, MOCK_PRIVATE_KEY_PREFIX); + assert (rv == CKR_SESSION_HANDLE_INVALID); + + rv = (module->C_SignRecoverInit) (session, &mech, MOCK_PRIVATE_KEY_PREFIX); + assert (rv == CKR_OK); + + rv = (module->C_Login) (session, CKU_CONTEXT_SPECIFIC, (CK_BYTE_PTR)"booo", 4); + assert (rv == CKR_OK); + + length = sizeof (signature); + rv = (module->C_SignRecover) (0, (CK_BYTE_PTR)"bLAH", 4, signature, &length); + assert (rv == CKR_SESSION_HANDLE_INVALID); + + length = sizeof (signature); + rv = (module->C_SignRecover) (session, (CK_BYTE_PTR)"BLAh", 4, signature, &length); + assert (rv == CKR_OK); + + assert_num_eq (16, length); + assert (memcmp (signature, "prefix:valueBLAh", 16) == 0); + + teardown_mock_module (module); +} + +static void +test_verify (void) +{ + CK_FUNCTION_LIST_PTR module; + CK_SESSION_HANDLE session = 0; + CK_MECHANISM mech = { CKM_MOCK_PREFIX, "prefix:", 7 }; + CK_BYTE signature[128]; + CK_ULONG length; + CK_RV rv; + + module = setup_mock_module (&session); + + rv = (module->C_VerifyInit) (0, &mech, MOCK_PUBLIC_KEY_PREFIX); + assert (rv == CKR_SESSION_HANDLE_INVALID); + + rv = (module->C_VerifyInit) (session, &mech, MOCK_PUBLIC_KEY_PREFIX); + assert (rv == CKR_OK); + + length = 13; + memcpy (signature, "prefix:value4", length); + rv = (module->C_Verify) (0, (CK_BYTE_PTR)"bLAH", 4, signature, 5); + assert (rv == CKR_SESSION_HANDLE_INVALID); + + rv = (module->C_Verify) (session, (CK_BYTE_PTR)"BLAh", 4, signature, length); + assert (rv == CKR_OK); + + rv = (module->C_VerifyInit) (session, &mech, MOCK_PUBLIC_KEY_PREFIX); + assert (rv == CKR_OK); + + rv = (module->C_VerifyUpdate) (0, (CK_BYTE_PTR)"blah", 4); + assert (rv == CKR_SESSION_HANDLE_INVALID); + + rv = (module->C_VerifyUpdate) (session, (CK_BYTE_PTR)"sLuRM", 5); + assert (rv == CKR_OK); + + rv = (module->C_VerifyUpdate) (session, (CK_BYTE_PTR)"Other", 5); + assert (rv == CKR_OK); + + length = 14; + memcpy (signature, "prefix:value10", length); + + rv = (module->C_VerifyFinal) (session, signature, 5); + assert (rv == CKR_SIGNATURE_LEN_RANGE); + + rv = (module->C_VerifyFinal) (session, signature, length); + assert (rv == CKR_OK); + + teardown_mock_module (module); +} + +static void +test_verify_recover (void) +{ + CK_FUNCTION_LIST_PTR module; + CK_SESSION_HANDLE session = 0; + CK_MECHANISM mech = { CKM_MOCK_PREFIX, "prefix:", 7 }; + CK_BYTE data[128]; + CK_ULONG length; + CK_RV rv; + + module = setup_mock_module (&session); + + rv = (module->C_VerifyRecoverInit) (0, &mech, MOCK_PUBLIC_KEY_PREFIX); + assert (rv == CKR_SESSION_HANDLE_INVALID); + + rv = (module->C_VerifyRecoverInit) (session, &mech, MOCK_PUBLIC_KEY_PREFIX); + assert (rv == CKR_OK); + + length = sizeof (data); + rv = (module->C_VerifyRecover) (0, (CK_BYTE_PTR)"prefix:valueBLah", 16, data, &length); + assert (rv == CKR_SESSION_HANDLE_INVALID); + + length = sizeof (data); + rv = (module->C_VerifyRecover) (session, (CK_BYTE_PTR)"prefix:valueBLah", 16, data, &length); + assert (rv == CKR_OK); + + assert_num_eq (4, length); + assert (memcmp (data, "BLah", 4) == 0); + + teardown_mock_module (module); +} + +static void +test_digest_encrypt (void) +{ + CK_FUNCTION_LIST_PTR module; + CK_SESSION_HANDLE session = 0; + CK_MECHANISM mech = { CKM_MOCK_CAPITALIZE, NULL, 0 }; + CK_MECHANISM dmech = { CKM_MOCK_COUNT, NULL, 0 }; + CK_BYTE data[128]; + CK_ULONG length; + CK_RV rv; + + module = setup_mock_module (&session); + + rv = (module->C_EncryptInit) (session, &mech, MOCK_PUBLIC_KEY_CAPITALIZE); + assert (rv == CKR_OK); + + rv = (module->C_DigestInit) (session, &dmech); + assert (rv == CKR_OK); + + length = sizeof (data); + rv = (module->C_DigestEncryptUpdate) (0, (CK_BYTE_PTR)"blah", 4, data, &length); + assert (rv == CKR_SESSION_HANDLE_INVALID); + + length = sizeof (data); + rv = (module->C_DigestEncryptUpdate) (session, (CK_BYTE_PTR)"blah", 4, data, &length); + assert (rv == CKR_OK); + + assert_num_eq (4, length); + assert (memcmp (data, "BLAH", 4) == 0); + + length = sizeof (data); + rv = (module->C_EncryptFinal) (session, data, &length); + assert (rv == CKR_OK); + + length = sizeof (data); + rv = (module->C_DigestFinal) (session, data, &length); + assert (rv == CKR_OK); + + assert_num_eq (1, length); + assert (memcmp (data, "4", 1) == 0); + + teardown_mock_module (module); +} + +static void +test_decrypt_digest (void) +{ + CK_FUNCTION_LIST_PTR module; + CK_SESSION_HANDLE session = 0; + CK_MECHANISM mech = { CKM_MOCK_CAPITALIZE, NULL, 0 }; + CK_MECHANISM dmech = { CKM_MOCK_COUNT, NULL, 0 }; + CK_BYTE data[128]; + CK_ULONG length; + CK_RV rv; + + module = setup_mock_module (&session); + + rv = (module->C_Login) (session, CKU_USER, (CK_BYTE_PTR)"booo", 4); + assert (rv == CKR_OK); + + rv = (module->C_DecryptInit) (session, &mech, MOCK_PRIVATE_KEY_CAPITALIZE); + assert (rv == CKR_OK); + + rv = (module->C_DigestInit) (session, &dmech); + assert (rv == CKR_OK); + + length = sizeof (data); + rv = (module->C_DecryptDigestUpdate) (0, (CK_BYTE_PTR)"BLAH", 4, data, &length); + assert (rv == CKR_SESSION_HANDLE_INVALID); + + length = sizeof (data); + rv = (module->C_DecryptDigestUpdate) (session, (CK_BYTE_PTR)"BLAH", 4, data, &length); + assert (rv == CKR_OK); + + assert_num_eq (4, length); + assert (memcmp (data, "blah", 4) == 0); + + length = sizeof (data); + rv = (module->C_DecryptFinal) (session, data, &length); + assert (rv == CKR_OK); + + length = sizeof (data); + rv = (module->C_DigestFinal) (session, data, &length); + assert (rv == CKR_OK); + + assert_num_eq (1, length); + assert (memcmp (data, "4", 1) == 0); + + teardown_mock_module (module); +} + +static void +test_sign_encrypt (void) +{ + CK_FUNCTION_LIST_PTR module; + CK_SESSION_HANDLE session = 0; + CK_MECHANISM mech = { CKM_MOCK_CAPITALIZE, NULL, 0 }; + CK_MECHANISM smech = { CKM_MOCK_PREFIX, "p:", 2 }; + CK_BYTE data[128]; + CK_ULONG length; + CK_RV rv; + + module = setup_mock_module (&session); + + rv = (module->C_Login) (session, CKU_USER, (CK_BYTE_PTR)"booo", 4); + assert (rv == CKR_OK); + + rv = (module->C_EncryptInit) (session, &mech, MOCK_PUBLIC_KEY_CAPITALIZE); + assert (rv == CKR_OK); + + rv = (module->C_SignInit) (session, &smech, MOCK_PRIVATE_KEY_PREFIX); + assert (rv == CKR_OK); + + rv = (module->C_Login) (session, CKU_CONTEXT_SPECIFIC, (CK_BYTE_PTR)"booo", 4); + assert (rv == CKR_OK); + + length = sizeof (data); + rv = (module->C_SignEncryptUpdate) (0, (CK_BYTE_PTR)"blah", 4, data, &length); + assert (rv == CKR_SESSION_HANDLE_INVALID); + + length = sizeof (data); + rv = (module->C_SignEncryptUpdate) (session, (CK_BYTE_PTR)"blah", 4, data, &length); + assert (rv == CKR_OK); + + assert_num_eq (4, length); + assert (memcmp (data, "BLAH", 4) == 0); + + length = sizeof (data); + rv = (module->C_EncryptFinal) (session, data, &length); + assert (rv == CKR_OK); + + length = sizeof (data); + rv = (module->C_SignFinal) (session, data, &length); + assert (rv == CKR_OK); + + assert_num_eq (8, length); + assert (memcmp (data, "p:value4", 1) == 0); + + teardown_mock_module (module); +} + +static void +test_decrypt_verify (void) +{ + CK_FUNCTION_LIST_PTR module; + CK_SESSION_HANDLE session = 0; + CK_MECHANISM mech = { CKM_MOCK_CAPITALIZE, NULL, 0 }; + CK_MECHANISM vmech = { CKM_MOCK_PREFIX, "p:", 2 }; + CK_BYTE data[128]; + CK_ULONG length; + CK_RV rv; + + module = setup_mock_module (&session); + + rv = (module->C_Login) (session, CKU_USER, (CK_BYTE_PTR)"booo", 4); + assert (rv == CKR_OK); + + rv = (module->C_DecryptInit) (session, &mech, MOCK_PRIVATE_KEY_CAPITALIZE); + assert (rv == CKR_OK); + + rv = (module->C_VerifyInit) (session, &vmech, MOCK_PUBLIC_KEY_PREFIX); + assert (rv == CKR_OK); + + length = sizeof (data); + rv = (module->C_DecryptVerifyUpdate) (0, (CK_BYTE_PTR)"BLAH", 4, data, &length); + assert (rv == CKR_SESSION_HANDLE_INVALID); + + length = sizeof (data); + rv = (module->C_DecryptVerifyUpdate) (session, (CK_BYTE_PTR)"BLAH", 4, data, &length); + assert (rv == CKR_OK); + + assert_num_eq (4, length); + assert (memcmp (data, "blah", 4) == 0); + + length = sizeof (data); + rv = (module->C_DecryptFinal) (session, data, &length); + assert (rv == CKR_OK); + + rv = (module->C_VerifyFinal) (session, (CK_BYTE_PTR)"p:value4", 8); + assert (rv == CKR_OK); + + teardown_mock_module (module); +} + +static void +test_generate_key (void) +{ + CK_FUNCTION_LIST_PTR module; + CK_SESSION_HANDLE session = 0; + CK_OBJECT_HANDLE object; + CK_MECHANISM mech = { CKM_MOCK_GENERATE, NULL, 0 }; + CK_ATTRIBUTE attrs[8]; + char label[32]; + char value[64]; + CK_ULONG bits; + CK_RV rv; + + module = setup_mock_module (&session); + + strcpy (label, "Blahooo"); + bits = 1555; + + attrs[0].type = CKA_LABEL; + attrs[0].pValue = label; + attrs[0].ulValueLen = strlen (label); + attrs[1].type = CKA_BITS_PER_PIXEL; + attrs[1].pValue = &bits; + attrs[1].ulValueLen = sizeof (bits); + + rv = (module->C_GenerateKey) (session, &mech, attrs, 2, &object); + assert (rv == CKR_MECHANISM_PARAM_INVALID); + + mech.pParameter = "generate"; + mech.ulParameterLen = 9; + + rv = (module->C_GenerateKey) (session, &mech, attrs, 2, &object); + assert (rv == CKR_OK); + + attrs[0].ulValueLen = sizeof (label); + memset (label, 0, sizeof (label)); + bits = 0; + attrs[2].type = CKA_VALUE; + attrs[2].pValue = value; + attrs[2].ulValueLen = sizeof (value); + + rv = (module->C_GetAttributeValue) (session, object, attrs, 3); + assert (rv == CKR_OK); + + assert_num_eq (bits, 1555); + assert_num_eq (7, attrs[0].ulValueLen); + assert (memcmp (label, "Blahooo", attrs[0].ulValueLen) == 0); + assert_num_eq (9, attrs[2].ulValueLen); + assert (memcmp (value, "generated", attrs[2].ulValueLen) == 0); + + teardown_mock_module (module); +} + +static void +test_generate_key_pair (void) +{ + CK_FUNCTION_LIST_PTR module; + CK_SESSION_HANDLE session = 0; + CK_OBJECT_HANDLE pub_object; + CK_OBJECT_HANDLE priv_object; + CK_MECHANISM mech = { CKM_MOCK_GENERATE, "generated", 9 }; + CK_ATTRIBUTE pub_attrs[8]; + CK_ATTRIBUTE priv_attrs[8]; + char pub_label[32]; + char pub_value[64]; + char priv_label[32]; + char priv_value[64]; + CK_ULONG pub_bits; + CK_ULONG priv_bits; + CK_RV rv; + + module = setup_mock_module (&session); + + strcpy (pub_label, "Blahooo"); + pub_bits = 1555; + pub_attrs[0].type = CKA_LABEL; + pub_attrs[0].pValue = pub_label; + pub_attrs[0].ulValueLen = strlen (pub_label); + pub_attrs[1].type = CKA_BITS_PER_PIXEL; + pub_attrs[1].pValue = &pub_bits; + pub_attrs[1].ulValueLen = sizeof (pub_bits); + + strcpy (priv_label, "Private"); + priv_bits = 1666; + priv_attrs[0].type = CKA_LABEL; + priv_attrs[0].pValue = priv_label; + priv_attrs[0].ulValueLen = strlen (priv_label); + priv_attrs[1].type = CKA_BITS_PER_PIXEL; + priv_attrs[1].pValue = &priv_bits; + priv_attrs[1].ulValueLen = sizeof (priv_bits); + + rv = (module->C_GenerateKeyPair) (0, &mech, pub_attrs, 2, priv_attrs, 2, + &pub_object, &priv_object); + assert (rv == CKR_SESSION_HANDLE_INVALID); + + mech.pParameter = "generate"; + mech.ulParameterLen = 9; + + rv = (module->C_GenerateKeyPair) (session, &mech, pub_attrs, 2, priv_attrs, 2, + &pub_object, &priv_object); + assert (rv == CKR_OK); + + pub_bits = 0; + pub_attrs[0].ulValueLen = sizeof (pub_label); + memset (pub_label, 0, sizeof (pub_label)); + pub_attrs[2].type = CKA_VALUE; + pub_attrs[2].pValue = pub_value; + pub_attrs[2].ulValueLen = sizeof (pub_value); + + rv = (module->C_GetAttributeValue) (session, pub_object, pub_attrs, 3); + assert (rv == CKR_OK); + + assert_num_eq (1555, pub_bits); + assert_num_eq (7, pub_attrs[0].ulValueLen); + assert (memcmp (pub_label, "Blahooo", pub_attrs[0].ulValueLen) == 0); + assert_num_eq (9, pub_attrs[2].ulValueLen); + assert (memcmp (pub_value, "generated", pub_attrs[2].ulValueLen) == 0); + + priv_bits = 0; + priv_attrs[0].ulValueLen = sizeof (priv_label); + memset (priv_label, 0, sizeof (priv_label)); + priv_attrs[2].type = CKA_VALUE; + priv_attrs[2].pValue = priv_value; + priv_attrs[2].ulValueLen = sizeof (priv_value); + + rv = (module->C_GetAttributeValue) (session, priv_object, priv_attrs, 3); + assert (rv == CKR_OK); + + assert_num_eq (1666, priv_bits); + assert_num_eq (7, priv_attrs[0].ulValueLen); + assert (memcmp (priv_label, "Private", priv_attrs[0].ulValueLen) == 0); + assert_num_eq (9, priv_attrs[2].ulValueLen); + assert (memcmp (priv_value, "generated", priv_attrs[2].ulValueLen) == 0); + + teardown_mock_module (module); +} + +static void +test_wrap_key (void) +{ + CK_FUNCTION_LIST_PTR module; + CK_SESSION_HANDLE session = 0; + CK_MECHANISM mech = { CKM_MOCK_WRAP, NULL, 0 }; + CK_BYTE data[128]; + CK_ULONG length; + CK_RV rv; + + module = setup_mock_module (&session); + + length = sizeof (data); + rv = (module->C_WrapKey) (session, &mech, MOCK_PUBLIC_KEY_PREFIX, MOCK_PUBLIC_KEY_PREFIX, data, &length); + assert (rv == CKR_MECHANISM_PARAM_INVALID); + + mech.pParameter = "wrap"; + mech.ulParameterLen = 4; + + rv = (module->C_WrapKey) (session, &mech, MOCK_PUBLIC_KEY_PREFIX, MOCK_PUBLIC_KEY_PREFIX, data, &length); + assert (rv == CKR_OK); + + assert_num_eq (5, length); + assert (memcmp (data, "value", 5) == 0); + + teardown_mock_module (module); +} + +static void +test_unwrap_key (void) +{ + CK_FUNCTION_LIST_PTR module; + CK_SESSION_HANDLE session = 0; + CK_OBJECT_HANDLE object; + CK_MECHANISM mech = { CKM_MOCK_WRAP, NULL, 0 }; + CK_ATTRIBUTE attrs[8]; + char label[32]; + char value[64]; + CK_ULONG bits; + CK_RV rv; + + module = setup_mock_module (&session); + + strcpy (label, "Blahooo"); + bits = 1555; + + attrs[0].type = CKA_LABEL; + attrs[0].pValue = label; + attrs[0].ulValueLen = strlen (label); + attrs[1].type = CKA_BITS_PER_PIXEL; + attrs[1].pValue = &bits; + attrs[1].ulValueLen = sizeof (bits); + + rv = (module->C_UnwrapKey) (session, &mech, MOCK_PUBLIC_KEY_PREFIX, + (CK_BYTE_PTR)"wheee", 5, attrs, 2, &object); + assert (rv == CKR_MECHANISM_PARAM_INVALID); + + mech.pParameter = "wrap"; + mech.ulParameterLen = 4; + + rv = (module->C_UnwrapKey) (session, &mech, MOCK_PUBLIC_KEY_PREFIX, + (CK_BYTE_PTR)"wheee", 5, attrs, 2, &object); + assert (rv == CKR_OK); + + attrs[0].ulValueLen = sizeof (label); + memset (label, 0, sizeof (label)); + bits = 0; + attrs[2].type = CKA_VALUE; + attrs[2].pValue = value; + attrs[2].ulValueLen = sizeof (value); + + rv = (module->C_GetAttributeValue) (session, object, attrs, 3); + assert (rv == CKR_OK); + + assert_num_eq (bits, 1555); + assert_num_eq (7, attrs[0].ulValueLen); + assert (memcmp (label, "Blahooo", attrs[0].ulValueLen) == 0); + assert_num_eq (5, attrs[2].ulValueLen); + assert (memcmp (value, "wheee", attrs[2].ulValueLen) == 0); + + teardown_mock_module (module); +} + +static void +test_derive_key (void) +{ + CK_FUNCTION_LIST_PTR module; + CK_SESSION_HANDLE session = 0; + CK_OBJECT_HANDLE object; + CK_MECHANISM mech = { CKM_MOCK_DERIVE, NULL, 0 }; + CK_ATTRIBUTE attrs[8]; + char label[32]; + char value[64]; + CK_ULONG bits; + CK_RV rv; + + module = setup_mock_module (&session); + + strcpy (label, "Blahooo"); + bits = 1555; + + attrs[0].type = CKA_LABEL; + attrs[0].pValue = label; + attrs[0].ulValueLen = strlen (label); + attrs[1].type = CKA_BITS_PER_PIXEL; + attrs[1].pValue = &bits; + attrs[1].ulValueLen = sizeof (bits); + + rv = (module->C_DeriveKey) (session, &mech, MOCK_PUBLIC_KEY_PREFIX, + attrs, 2, &object); + assert (rv == CKR_MECHANISM_PARAM_INVALID); + + mech.pParameter = "derive"; + mech.ulParameterLen = 6; + + rv = (module->C_DeriveKey) (session, &mech, MOCK_PUBLIC_KEY_PREFIX, + attrs, 2, &object); + assert (rv == CKR_OK); + + attrs[0].ulValueLen = sizeof (label); + memset (label, 0, sizeof (label)); + bits = 0; + attrs[2].type = CKA_VALUE; + attrs[2].pValue = value; + attrs[2].ulValueLen = sizeof (value); + + rv = (module->C_GetAttributeValue) (session, object, attrs, 3); + assert (rv == CKR_OK); + + assert_num_eq (bits, 1555); + assert_num_eq (7, attrs[0].ulValueLen); + assert (memcmp (label, "Blahooo", attrs[0].ulValueLen) == 0); + assert_num_eq (7, attrs[2].ulValueLen); + assert (memcmp (value, "derived", attrs[2].ulValueLen) == 0); + + teardown_mock_module (module); +} + +static void +test_random (void) +{ + CK_FUNCTION_LIST_PTR module; + CK_SESSION_HANDLE session = 0; + CK_BYTE data[10]; + CK_RV rv; + + module = setup_mock_module (&session); + + rv = (module->C_SeedRandom) (0, (CK_BYTE_PTR)"seed", 4); + assert (rv == CKR_SESSION_HANDLE_INVALID); + + rv = (module->C_SeedRandom) (session, (CK_BYTE_PTR)"seed", 4); + assert (rv == CKR_OK); + + rv = (module->C_GenerateRandom) (0, data, sizeof (data)); + assert (rv == CKR_SESSION_HANDLE_INVALID); + + rv = (module->C_GenerateRandom) (session, data, sizeof (data)); + assert (rv == CKR_OK); + + assert (memcmp (data, "seedseedse", sizeof (data)) == 0); + + teardown_mock_module (module); +} + +static void +test_mock_add_tests (const char *prefix) +{ + p11_test (test_get_info, "%s/test_get_info", prefix); + p11_test (test_get_slot_list, "%s/test_get_slot_list", prefix); + p11_test (test_get_slot_info, "%s/test_get_slot_info", prefix); + p11_test (test_get_token_info, "%s/test_get_token_info", prefix); + p11_test (test_get_mechanism_list, "%s/test_get_mechanism_list", prefix); + p11_test (test_get_mechanism_info, "%s/test_get_mechanism_info", prefix); + p11_test (test_init_token, "%s/test_init_token", prefix); + p11_test (test_wait_for_slot_event, "%s/test_wait_for_slot_event", prefix); + p11_test (test_open_close_session, "%s/test_open_close_session", prefix); + p11_test (test_close_all_sessions, "%s/test_close_all_sessions", prefix); + p11_test (test_get_function_status, "%s/test_get_function_status", prefix); + p11_test (test_cancel_function, "%s/test_cancel_function", prefix); + p11_test (test_get_session_info, "%s/test_get_session_info", prefix); + p11_test (test_init_pin, "%s/test_init_pin", prefix); + p11_test (test_set_pin, "%s/test_set_pin", prefix); + p11_test (test_operation_state, "%s/test_operation_state", prefix); + p11_test (test_login_logout, "%s/test_login_logout", prefix); + p11_test (test_get_attribute_value, "%s/test_get_attribute_value", prefix); + p11_test (test_set_attribute_value, "%s/test_set_attribute_value", prefix); + p11_test (test_create_object, "%s/test_create_object", prefix); + p11_test (test_copy_object, "%s/test_copy_object", prefix); + p11_test (test_destroy_object, "%s/test_destroy_object", prefix); + p11_test (test_get_object_size, "%s/test_get_object_size", prefix); + p11_test (test_find_objects, "%s/test_find_objects", prefix); + p11_test (test_encrypt, "%s/test_encrypt", prefix); + p11_test (test_decrypt, "%s/test_decrypt", prefix); + p11_test (test_digest, "%s/test_digest", prefix); + p11_test (test_sign, "%s/test_sign", prefix); + p11_test (test_sign_recover, "%s/test_sign_recover", prefix); + p11_test (test_verify, "%s/test_verify", prefix); + p11_test (test_verify_recover, "%s/test_verify_recover", prefix); + p11_test (test_digest_encrypt, "%s/test_digest_encrypt", prefix); + p11_test (test_decrypt_digest, "%s/test_decrypt_digest", prefix); + p11_test (test_sign_encrypt, "%s/test_sign_encrypt", prefix); + p11_test (test_decrypt_verify, "%s/test_decrypt_verify", prefix); + p11_test (test_generate_key, "%s/test_generate_key", prefix); + p11_test (test_generate_key_pair, "%s/test_generate_key_pair", prefix); + p11_test (test_wrap_key, "%s/test_wrap_key", prefix); + p11_test (test_unwrap_key, "%s/test_unwrap_key", prefix); + p11_test (test_derive_key, "%s/test_derive_key", prefix); + p11_test (test_random, "%s/test_random", prefix); +} diff --git a/p11-kit/tests/test-modules.c b/p11-kit/tests/test-modules.c index 3a6e968..d50b2d5 100644 --- a/p11-kit/tests/test-modules.c +++ b/p11-kit/tests/test-modules.c @@ -33,7 +33,7 @@ */ #include "config.h" -#include "CuTest.h" +#include "test.h" #include <errno.h> #include <stdlib.h> @@ -47,32 +47,24 @@ #include "dict.h" static CK_FUNCTION_LIST_PTR_PTR -initialize_and_get_modules (CuTest *tc) +initialize_and_get_modules (void) { CK_FUNCTION_LIST_PTR_PTR modules; - CK_RV rv; - rv = p11_kit_initialize_registered (); - CuAssertIntEquals (tc, CKR_OK, rv); - modules = p11_kit_registered_modules (); - CuAssertTrue (tc, modules != NULL && modules[0] != NULL); + modules = p11_kit_modules_load_and_initialize (0); + assert (modules != NULL && modules[0] != NULL); return modules; } static void -finalize_and_free_modules (CuTest *tc, - CK_FUNCTION_LIST_PTR_PTR modules) +finalize_and_free_modules (CK_FUNCTION_LIST_PTR_PTR modules) { - CK_RV rv; - - free (modules); - rv = p11_kit_finalize_registered (); - CuAssertIntEquals (tc, CKR_OK, rv); + p11_kit_modules_finalize_and_release (modules); } static void -test_no_duplicates (CuTest *tc) +test_no_duplicates (void) { CK_FUNCTION_LIST_PTR_PTR modules; p11_dict *paths; @@ -80,35 +72,34 @@ test_no_duplicates (CuTest *tc) char *path; int i; - modules = initialize_and_get_modules (tc); + modules = initialize_and_get_modules (); paths = p11_dict_new (p11_dict_str_hash, p11_dict_str_equal, NULL, NULL); funcs = p11_dict_new (p11_dict_direct_hash, p11_dict_direct_equal, NULL, NULL); /* The loaded modules should not contain duplicates */ for (i = 0; modules[i] != NULL; i++) { - path = p11_kit_registered_option (modules[i], "module"); + path = p11_kit_config_option (modules[i], "module"); if (p11_dict_get (funcs, modules[i])) - CuAssert (tc, "found duplicate function list pointer", 0); + assert_fail ("found duplicate function list pointer", NULL); if (p11_dict_get (paths, path)) - CuAssert (tc, "found duplicate path name", 0); + assert_fail ("found duplicate path name", NULL); if (!p11_dict_set (funcs, modules[i], "")) - CuAssert (tc, "shouldn't be reached", 0); + assert_not_reached (); if (!p11_dict_set (paths, path, "")) - CuAssert (tc, "shouldn't be reached", 0); + assert_not_reached (); free (path); } p11_dict_free (paths); p11_dict_free (funcs); - finalize_and_free_modules (tc, modules); + finalize_and_free_modules (modules); } static CK_FUNCTION_LIST_PTR -lookup_module_with_name (CuTest *tc, - CK_FUNCTION_LIST_PTR_PTR modules, +lookup_module_with_name (CK_FUNCTION_LIST_PTR_PTR modules, const char *name) { CK_FUNCTION_LIST_PTR match = NULL; @@ -117,8 +108,8 @@ lookup_module_with_name (CuTest *tc, int i; for (i = 0; match == NULL && modules[i] != NULL; i++) { - module_name = p11_kit_registered_module_to_name (modules[i]); - CuAssertPtrNotNull (tc, module_name); + module_name = p11_kit_module_get_name (modules[i]); + assert_ptr_not_null (module_name); if (strcmp (module_name, name) == 0) match = modules[i]; free (module_name); @@ -128,15 +119,15 @@ lookup_module_with_name (CuTest *tc, * As a side effect, we should check that the results of this function * matches the above search. */ - module = p11_kit_registered_name_to_module (name); - CuAssert(tc, "different result from p11_kit_registered_name_to_module()", - module == match); + module = p11_kit_module_for_name (modules, name); + if (module != match) + assert_fail ("different result from p11_kit_module_for_name ()", NULL); return match; } static void -test_disable (CuTest *tc) +test_disable (void) { CK_FUNCTION_LIST_PTR_PTR modules; @@ -145,9 +136,9 @@ test_disable (CuTest *tc) * that it has disabled. */ - modules = initialize_and_get_modules (tc); - CuAssertTrue (tc, lookup_module_with_name (tc, modules, "four") != NULL); - finalize_and_free_modules (tc, modules); + modules = initialize_and_get_modules (); + assert (lookup_module_with_name (modules, "four") != NULL); + finalize_and_free_modules (modules); /* * The module two shouldn't have been loaded, because in its config @@ -158,18 +149,17 @@ test_disable (CuTest *tc) p11_kit_set_progname ("test-disable"); - modules = initialize_and_get_modules (tc); - CuAssertTrue (tc, lookup_module_with_name (tc, modules, "four") == NULL); - finalize_and_free_modules (tc, modules); + modules = initialize_and_get_modules (); + assert (lookup_module_with_name (modules, "four") == NULL); + finalize_and_free_modules (modules); p11_kit_set_progname (NULL); } static void -test_disable_later (CuTest *tc) +test_disable_later (void) { CK_FUNCTION_LIST_PTR_PTR modules; - CK_RV rv; /* * The module two shouldn't be matched, because in its config @@ -178,22 +168,19 @@ test_disable_later (CuTest *tc) * disable-in: test-disable */ - rv = p11_kit_initialize_registered (); - CuAssertIntEquals (tc, CKR_OK, rv); - p11_kit_set_progname ("test-disable"); - modules = p11_kit_registered_modules (); - CuAssertTrue (tc, modules != NULL && modules[0] != NULL); + modules = p11_kit_modules_load_and_initialize (0); + assert (modules != NULL && modules[0] != NULL); - CuAssertTrue (tc, lookup_module_with_name (tc, modules, "two") == NULL); - finalize_and_free_modules (tc, modules); + assert (lookup_module_with_name (modules, "two") == NULL); + finalize_and_free_modules (modules); p11_kit_set_progname (NULL); } static void -test_enable (CuTest *tc) +test_enable (void) { CK_FUNCTION_LIST_PTR_PTR modules; @@ -202,9 +189,9 @@ test_enable (CuTest *tc) * program. */ - modules = initialize_and_get_modules (tc); - CuAssertTrue (tc, lookup_module_with_name (tc, modules, "three") == NULL); - finalize_and_free_modules (tc, modules); + modules = initialize_and_get_modules (); + assert (lookup_module_with_name (modules, "three") == NULL); + finalize_and_free_modules (modules); /* * The module three should be loaded here , because in its config @@ -215,15 +202,15 @@ test_enable (CuTest *tc) p11_kit_set_progname ("test-enable"); - modules = initialize_and_get_modules (tc); - CuAssertTrue (tc, lookup_module_with_name (tc, modules, "three") != NULL); - finalize_and_free_modules (tc, modules); + modules = initialize_and_get_modules (); + assert (lookup_module_with_name (modules, "three") != NULL); + finalize_and_free_modules (modules); p11_kit_set_progname (NULL); } static void -test_priority (CuTest *tc) +test_priority (void) { CK_FUNCTION_LIST_PTR_PTR modules; char *name; @@ -242,12 +229,12 @@ test_priority (CuTest *tc) /* This enables module three */ p11_kit_set_progname ("test-enable"); - modules = initialize_and_get_modules (tc); + modules = initialize_and_get_modules (); /* The loaded modules should not contain duplicates */ for (i = 0; modules[i] != NULL; i++) { - name = p11_kit_registered_module_to_name (modules[i]); - CuAssertPtrNotNull (tc, name); + name = p11_kit_module_get_name (modules[i]); + assert_ptr_not_null (name); /* Either one of these can be loaded, as this is a duplicate module */ if (strcmp (name, "two-duplicate") == 0) { @@ -255,38 +242,124 @@ test_priority (CuTest *tc) name = strdup ("two.badname"); } - CuAssertStrEquals (tc, expected[i], name); + assert_str_eq (expected[i], name); free (name); } - CuAssertIntEquals (tc, 4, i); - finalize_and_free_modules (tc, modules); + assert_num_eq (4, i); + finalize_and_free_modules (modules); } -int -main (void) +static void +test_module_name (void) { - CuString *output = CuStringNew (); - CuSuite* suite = CuSuiteNew (); - int ret; + CK_FUNCTION_LIST_PTR_PTR modules; + CK_FUNCTION_LIST_PTR module; + char *name; + + /* + * The module three should not be present, as we don't match the current + * program. + */ + + modules = initialize_and_get_modules (); + + module = p11_kit_module_for_name (modules, "one"); + assert_ptr_not_null (module); + name = p11_kit_module_get_name (module); + assert_str_eq ("one", name); + free (name); + + module = p11_kit_module_for_name (modules, "invalid"); + assert_ptr_eq (NULL, module); + + module = p11_kit_module_for_name (NULL, "one"); + assert_ptr_eq (NULL, module); + + finalize_and_free_modules (modules); +} + +static void +test_module_flags (void) +{ + CK_FUNCTION_LIST **modules; + CK_FUNCTION_LIST **unmanaged; + int flags; + + /* + * The module three should not be present, as we don't match the current + * program. + */ + + modules = initialize_and_get_modules (); - putenv ("P11_KIT_STRICT=1"); + flags = p11_kit_module_get_flags (modules[0]); + assert_num_eq (0, flags); + + unmanaged = p11_kit_modules_load (NULL, P11_KIT_MODULE_UNMANAGED); + assert (unmanaged != NULL && unmanaged[0] != NULL); + + flags = p11_kit_module_get_flags (unmanaged[0]); + assert_num_eq (P11_KIT_MODULE_UNMANAGED, flags); + + finalize_and_free_modules (modules); + p11_kit_modules_release (unmanaged); +} + +static void +test_config_option (void) +{ + CK_FUNCTION_LIST_PTR_PTR modules; + CK_FUNCTION_LIST_PTR module; + char *value; + + /* + * The module three should not be present, as we don't match the current + * program. + */ + + modules = initialize_and_get_modules (); + + value = p11_kit_config_option (NULL, "new"); + assert_str_eq ("world", value); + free (value); + + module = p11_kit_module_for_name (modules, "one"); + assert_ptr_not_null (module); + + value = p11_kit_config_option (module, "setting"); + assert_str_eq ("user1", value); + free (value); + + value = p11_kit_config_option (NULL, "invalid"); + assert_ptr_eq (NULL, value); + + value = p11_kit_config_option (module, "invalid"); + assert_ptr_eq (NULL, value); + + /* Invalid but non-NULL module pointer */ + value = p11_kit_config_option (module + 1, "setting"); + assert_ptr_eq (NULL, value); + + finalize_and_free_modules (modules); +} + +int +main (int argc, + char *argv[]) +{ p11_library_init (); - SUITE_ADD_TEST (suite, test_no_duplicates); - SUITE_ADD_TEST (suite, test_disable); - SUITE_ADD_TEST (suite, test_disable_later); - SUITE_ADD_TEST (suite, test_enable); - SUITE_ADD_TEST (suite, test_priority); + p11_test (test_no_duplicates, "/modules/test_no_duplicates"); + p11_test (test_disable, "/modules/test_disable"); + p11_test (test_disable_later, "/modules/test_disable_later"); + p11_test (test_enable, "/modules/test_enable"); + p11_test (test_priority, "/modules/test_priority"); + p11_test (test_module_name, "/modules/test_module_name"); + p11_test (test_module_flags, "/modules/test_module_flags"); + p11_test (test_config_option, "/modules/test_config_option"); p11_kit_be_quiet (); - CuSuiteRun (suite); - CuSuiteSummary (suite, output); - CuSuiteDetails (suite, output); - printf ("%s\n", output->buffer); - ret = suite->failCount; - CuSuiteDelete (suite); - CuStringDelete (output); - return ret; + return p11_test_run (argc, argv); } diff --git a/p11-kit/tests/pin-test.c b/p11-kit/tests/test-pin.c index dd020bc..ebe3efc 100644 --- a/p11-kit/tests/pin-test.c +++ b/p11-kit/tests/test-pin.c @@ -33,7 +33,7 @@ */ #include "config.h" -#include "CuTest.h" +#include "test.h" #include "library.h" @@ -71,7 +71,7 @@ destroy_data (void *callback_data) } static void -test_pin_register_unregister (CuTest *tc) +test_pin_register_unregister (void) { int data = 33; @@ -81,11 +81,11 @@ test_pin_register_unregister (CuTest *tc) p11_kit_pin_unregister_callback ("/the/pin_source", callback_one, &data); - CuAssertIntEquals (tc, 34, data); + assert_num_eq (34, data); } static void -test_pin_read (CuTest *tc) +test_pin_read (void) { P11KitUri *uri; P11KitPin *pin; @@ -101,10 +101,10 @@ test_pin_read (CuTest *tc) P11_KIT_PIN_FLAGS_USER_LOGIN); p11_kit_uri_free (uri); - CuAssertPtrNotNull (tc, pin); + assert_ptr_not_null (pin); ptr = p11_kit_pin_get_value (pin, &length); - CuAssertIntEquals (tc, 3, length); - CuAssertTrue (tc, memcmp (ptr, "one", 3) == 0); + assert_num_eq (3, length); + assert (memcmp (ptr, "one", 3) == 0); p11_kit_pin_unregister_callback ("/the/pin_source", callback_one, &data); @@ -113,7 +113,7 @@ test_pin_read (CuTest *tc) } static void -test_pin_read_no_match (CuTest *tc) +test_pin_read_no_match (void) { P11KitUri *uri; P11KitPin *pin; @@ -123,11 +123,11 @@ test_pin_read_no_match (CuTest *tc) P11_KIT_PIN_FLAGS_USER_LOGIN); p11_kit_uri_free (uri); - CuAssertPtrEquals (tc, NULL, pin); + assert_ptr_eq (NULL, pin); } static void -test_pin_register_duplicate (CuTest *tc) +test_pin_register_duplicate (void) { P11KitUri *uri; P11KitPin *pin; @@ -147,10 +147,10 @@ test_pin_register_duplicate (CuTest *tc) pin = p11_kit_pin_request ("/the/pin_source", uri, "The token", P11_KIT_PIN_FLAGS_USER_LOGIN); - CuAssertPtrNotNull (tc, pin); + assert_ptr_not_null (pin); ptr = p11_kit_pin_get_value (pin, &length); - CuAssertIntEquals (tc, 6, length); - CuAssertTrue (tc, memcmp (ptr, "secret", length) == 0); + assert_num_eq (6, length); + assert (memcmp (ptr, "secret", length) == 0); p11_kit_pin_unref (pin); p11_kit_pin_unregister_callback ("/the/pin_source", callback_other, @@ -159,10 +159,10 @@ test_pin_register_duplicate (CuTest *tc) pin = p11_kit_pin_request ("/the/pin_source", uri, "The token", P11_KIT_PIN_FLAGS_USER_LOGIN); - CuAssertPtrNotNull (tc, pin); + assert_ptr_not_null (pin); ptr = p11_kit_pin_get_value (pin, &length); - CuAssertIntEquals (tc, 3, length); - CuAssertTrue (tc, memcmp (ptr, "one", length) == 0); + assert_num_eq (3, length); + assert (memcmp (ptr, "one", length) == 0); p11_kit_pin_unref (pin); p11_kit_pin_unregister_callback ("/the/pin_source", callback_one, @@ -171,13 +171,13 @@ test_pin_register_duplicate (CuTest *tc) pin = p11_kit_pin_request ("/the/pin_source", uri, "The token", P11_KIT_PIN_FLAGS_USER_LOGIN); - CuAssertPtrEquals (tc, NULL, pin); + assert_ptr_eq (NULL, pin); p11_kit_uri_free (uri); } static void -test_pin_register_fallback (CuTest *tc) +test_pin_register_fallback (void) { char *value = "secret"; P11KitUri *uri; @@ -194,10 +194,10 @@ test_pin_register_fallback (CuTest *tc) pin = p11_kit_pin_request ("/the/pin_source", uri, "The token", P11_KIT_PIN_FLAGS_USER_LOGIN); - CuAssertPtrNotNull (tc, pin); + assert_ptr_not_null (pin); ptr = p11_kit_pin_get_value (pin, &length); - CuAssertIntEquals (tc, 3, length); - CuAssertTrue (tc, memcmp (ptr, "one", length) == 0); + assert_num_eq (3, length); + assert (memcmp (ptr, "one", length) == 0); p11_kit_pin_unref (pin); p11_kit_pin_register_callback ("/the/pin_source", callback_other, @@ -206,10 +206,10 @@ test_pin_register_fallback (CuTest *tc) pin = p11_kit_pin_request ("/the/pin_source", uri, "The token", P11_KIT_PIN_FLAGS_USER_LOGIN); - CuAssertPtrNotNull (tc, pin); + assert_ptr_not_null (pin); ptr = p11_kit_pin_get_value (pin, &length); - CuAssertIntEquals (tc, 6, length); - CuAssertTrue (tc, memcmp (ptr, "secret", length) == 0); + assert_num_eq (6, length); + assert (memcmp (ptr, "secret", length) == 0); p11_kit_pin_unref (pin); p11_kit_pin_unregister_callback ("/the/pin_source", callback_other, @@ -222,7 +222,7 @@ test_pin_register_fallback (CuTest *tc) } static void -test_pin_file (CuTest *tc) +test_pin_file (void) { P11KitUri *uri; P11KitPin *pin; @@ -237,16 +237,16 @@ test_pin_file (CuTest *tc) pin = p11_kit_pin_request (SRCDIR "/files/test-pinfile", uri, "The token", P11_KIT_PIN_FLAGS_USER_LOGIN); - CuAssertPtrNotNull (tc, pin); + assert_ptr_not_null (pin); ptr = p11_kit_pin_get_value (pin, &length); - CuAssertIntEquals (tc, 12, length); - CuAssertTrue (tc, memcmp (ptr, "yogabbagabba", length) == 0); + assert_num_eq (12, length); + assert (memcmp (ptr, "yogabbagabba", length) == 0); p11_kit_pin_unref (pin); pin = p11_kit_pin_request (SRCDIR "/files/nonexistant", uri, "The token", P11_KIT_PIN_FLAGS_USER_LOGIN); - CuAssertPtrEquals (tc, NULL, pin); + assert_ptr_eq (NULL, pin); p11_kit_pin_unregister_callback (P11_KIT_PIN_FALLBACK, p11_kit_pin_file_callback, NULL); @@ -255,7 +255,7 @@ test_pin_file (CuTest *tc) } static void -test_pin_file_large (CuTest *tc) +test_pin_file_large (void) { P11KitUri *uri; P11KitPin *pin; @@ -270,8 +270,8 @@ test_pin_file_large (CuTest *tc) P11_KIT_PIN_FLAGS_USER_LOGIN); error = errno; - CuAssertPtrEquals (tc, NULL, pin); - CuAssertIntEquals (tc, EFBIG, error); + assert_ptr_eq (NULL, pin); + assert_num_eq (EFBIG, error); p11_kit_pin_unregister_callback (P11_KIT_PIN_FALLBACK, p11_kit_pin_file_callback, NULL); @@ -280,7 +280,7 @@ test_pin_file_large (CuTest *tc) } static void -test_pin_ref_unref (CuTest *tc) +test_pin_ref_unref (void) { P11KitPin *pin; P11KitPin *check; @@ -288,38 +288,26 @@ test_pin_ref_unref (CuTest *tc) pin = p11_kit_pin_new_for_string ("crack of lies"); check = p11_kit_pin_ref (pin); - CuAssertPtrEquals (tc, pin, check); + assert_ptr_eq (pin, check); p11_kit_pin_unref (pin); p11_kit_pin_unref (check); } int -main (void) +main (int argc, + char *argv[]) { - CuString *output = CuStringNew (); - CuSuite* suite = CuSuiteNew (); - int ret; - - putenv ("P11_KIT_STRICT=1"); p11_library_init (); - SUITE_ADD_TEST (suite, test_pin_register_unregister); - SUITE_ADD_TEST (suite, test_pin_read); - SUITE_ADD_TEST (suite, test_pin_read_no_match); - SUITE_ADD_TEST (suite, test_pin_register_duplicate); - SUITE_ADD_TEST (suite, test_pin_register_fallback); - SUITE_ADD_TEST (suite, test_pin_file); - SUITE_ADD_TEST (suite, test_pin_file_large); - SUITE_ADD_TEST (suite, test_pin_ref_unref); - - CuSuiteRun (suite); - CuSuiteSummary (suite, output); - CuSuiteDetails (suite, output); - printf ("%s\n", output->buffer); - ret = suite->failCount; - CuSuiteDelete (suite); - CuStringDelete (output); - - return ret; + p11_test (test_pin_register_unregister, "/pin/test_pin_register_unregister"); + p11_test (test_pin_read, "/pin/test_pin_read"); + p11_test (test_pin_read_no_match, "/pin/test_pin_read_no_match"); + p11_test (test_pin_register_duplicate, "/pin/test_pin_register_duplicate"); + p11_test (test_pin_register_fallback, "/pin/test_pin_register_fallback"); + p11_test (test_pin_file, "/pin/test_pin_file"); + p11_test (test_pin_file_large, "/pin/test_pin_file_large"); + p11_test (test_pin_ref_unref, "/pin/test_pin_ref_unref"); + + return p11_test_run (argc, argv); } diff --git a/p11-kit/tests/progname-test.c b/p11-kit/tests/test-progname.c index 18a8c55..76b136d 100644 --- a/p11-kit/tests/progname-test.c +++ b/p11-kit/tests/test-progname.c @@ -33,7 +33,7 @@ */ #include "config.h" -#include "CuTest.h" +#include "test.h" #include "library.h" @@ -47,52 +47,40 @@ #include "p11-kit/private.h" static void -test_progname_default (CuTest *tc) +test_progname_default (void) { const char *progname; progname = _p11_get_progname_unlocked (); - CuAssertStrEquals (tc, "progname-test", progname); + assert_str_eq ("test-progname", progname); } static void -test_progname_set (CuTest *tc) +test_progname_set (void) { const char *progname; p11_kit_set_progname ("love-generation"); progname = _p11_get_progname_unlocked (); - CuAssertStrEquals (tc, "love-generation", progname); + assert_str_eq ("love-generation", progname); _p11_set_progname_unlocked (NULL); progname = _p11_get_progname_unlocked (); - CuAssertStrEquals (tc, "progname-test", progname); + assert_str_eq ("test-progname", progname); } /* Defined in util.c */ extern char p11_my_progname[]; int -main (void) +main (int argc, + char *argv[]) { - CuString *output = CuStringNew (); - CuSuite* suite = CuSuiteNew (); - int ret; - - putenv ("P11_KIT_STRICT=1"); p11_library_init (); - SUITE_ADD_TEST (suite, test_progname_default); - SUITE_ADD_TEST (suite, test_progname_set); - - CuSuiteRun (suite); - CuSuiteSummary (suite, output); - CuSuiteDetails (suite, output); - printf ("%s\n", output->buffer); - ret = suite->failCount; - CuSuiteDelete (suite); - CuStringDelete (output); - return ret; + p11_test (test_progname_default, "/progname/test_progname_default"); + p11_test (test_progname_set, "/progname/test_progname_set"); + return p11_test_run (argc, argv); } diff --git a/p11-kit/tests/test-proxy.c b/p11-kit/tests/test-proxy.c new file mode 100644 index 0000000..bf5007d --- /dev/null +++ b/p11-kit/tests/test-proxy.c @@ -0,0 +1,195 @@ +/* + * Copyright (c) 2013 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 <stefw@redhat.com> + */ + +#define CRYPTOKI_EXPORTS + +#include "config.h" +#include "test.h" + +#include "library.h" +#include "mock.h" +#include "p11-kit.h" +#include "pkcs11.h" +#include "proxy.h" + +#include <sys/types.h> + +#include <assert.h> +#include <errno.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <time.h> +#include <unistd.h> + +/* This is the proxy module entry point in proxy.c, and linked to this test */ +CK_RV C_GetFunctionList (CK_FUNCTION_LIST_PTR_PTR list); + +static CK_SLOT_ID mock_slot_one_id; +static CK_SLOT_ID mock_slot_two_id; +static CK_ULONG mock_slots_present; +static CK_ULONG mock_slots_all; + +static void +test_initialize_finalize (void) +{ + CK_FUNCTION_LIST_PTR proxy; + CK_RV rv; + + 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_Finalize (NULL); + assert (rv == CKR_OK); + + p11_proxy_module_cleanup (); +} + +static void +test_initialize_multiple (void) +{ + CK_FUNCTION_LIST_PTR proxy; + CK_RV rv; + + 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_Initialize (NULL); + assert (rv == CKR_OK); + + rv = proxy->C_Finalize (NULL); + assert (rv == CKR_OK); + + rv = proxy->C_Finalize (NULL); + assert (rv == CKR_OK); + + rv = proxy->C_Finalize (NULL); + assert (rv == CKR_CRYPTOKI_NOT_INITIALIZED); + + p11_proxy_module_cleanup (); +} + +static CK_FUNCTION_LIST_PTR +setup_mock_module (CK_SESSION_HANDLE *session) +{ + CK_FUNCTION_LIST_PTR proxy; + CK_SLOT_ID slots[32]; + CK_RV rv; + + rv = C_GetFunctionList (&proxy); + assert (rv == CKR_OK); + + assert (p11_proxy_module_check (proxy)); + + rv = proxy->C_Initialize (NULL); + assert (rv == CKR_OK); + + mock_slots_all = 32; + rv = proxy->C_GetSlotList (CK_FALSE, slots, &mock_slots_all); + assert (rv == CKR_OK); + assert (mock_slots_all >= 2); + + /* Assume this is the slot we want to deal with */ + mock_slot_one_id = slots[0]; + mock_slot_two_id = slots[1]; + + rv = proxy->C_GetSlotList (CK_TRUE, NULL, &mock_slots_present); + assert (rv == CKR_OK); + assert (mock_slots_present > 1); + + if (session) { + rv = (proxy->C_OpenSession) (mock_slot_one_id, + CKF_RW_SESSION | CKF_SERIAL_SESSION, + NULL, NULL, session); + assert (rv == CKR_OK); + } + + return proxy; +} + +static void +teardown_mock_module (CK_FUNCTION_LIST_PTR module) +{ + CK_RV rv; + + rv = module->C_Finalize (NULL); + assert (rv == CKR_OK); +} + +/* + * We redefine the mock module slot id so that the tests in test-mock.c + * use the proxy mapped slot id rather than the hard coded one + */ +#define MOCK_SLOT_ONE_ID mock_slot_one_id +#define MOCK_SLOT_TWO_ID mock_slot_two_id +#define MOCK_SLOTS_PRESENT mock_slots_present +#define MOCK_SLOTS_ALL mock_slots_all +#define MOCK_INFO mock_info +#define MOCK_SKIP_WAIT_TEST + +static const CK_INFO mock_info = { + { CRYPTOKI_VERSION_MAJOR, CRYPTOKI_VERSION_MINOR }, + "PKCS#11 Kit ", + 0, + "PKCS#11 Kit Proxy Module ", + { 1, 1 } +}; + +/* Bring in all the mock module tests */ +#include "test-mock.c" + +int +main (int argc, + char *argv[]) +{ + p11_library_init (); + p11_kit_be_quiet (); + + p11_test (test_initialize_finalize, "/proxy/initialize-finalize"); + p11_test (test_initialize_multiple, "/proxy/initialize-multiple"); + + test_mock_add_tests ("/proxy"); + + return p11_test_run (argc, argv); +} diff --git a/p11-kit/tests/uri-test.c b/p11-kit/tests/test-uri.c index 2bc121c..f514f7a 100644 --- a/p11-kit/tests/uri-test.c +++ b/p11-kit/tests/test-uri.c @@ -33,7 +33,7 @@ */ #include "config.h" -#include "CuTest.h" +#include "test.h" #include "debug.h" #include "message.h" @@ -75,138 +75,138 @@ are_attributes_empty (P11KitUri *uri) } static void -test_uri_parse (CuTest *tc) +test_uri_parse (void) { P11KitUri *uri; int ret; uri = p11_kit_uri_new (); - CuAssertPtrNotNull (tc, uri); + assert_ptr_not_null (uri); ret = p11_kit_uri_parse ("pkcs11:", P11_KIT_URI_FOR_MODULE, uri); - CuAssertIntEquals (tc, P11_KIT_URI_OK, ret); + assert_num_eq (P11_KIT_URI_OK, ret); - CuAssertTrue (tc, is_module_empty (uri)); - CuAssertTrue (tc, is_token_empty (uri)); - CuAssertTrue (tc, are_attributes_empty (uri)); + assert (is_module_empty (uri)); + assert (is_token_empty (uri)); + assert (are_attributes_empty (uri)); p11_kit_uri_free (uri); } static void -test_uri_parse_bad_scheme (CuTest *tc) +test_uri_parse_bad_scheme (void) { P11KitUri *uri; int ret; uri = p11_kit_uri_new (); - CuAssertPtrNotNull (tc, uri); + assert_ptr_not_null (uri); ret = p11_kit_uri_parse ("http:\\example.com\test", P11_KIT_URI_FOR_ANY, uri); - CuAssertIntEquals (tc, P11_KIT_URI_BAD_SCHEME, ret); + assert_num_eq (P11_KIT_URI_BAD_SCHEME, ret); p11_kit_uri_free (uri); } static void -test_uri_parse_with_label (CuTest *tc) +test_uri_parse_with_label (void) { CK_ATTRIBUTE_PTR attr; P11KitUri *uri; int ret; uri = p11_kit_uri_new (); - CuAssertPtrNotNull (tc, uri); + assert_ptr_not_null (uri); ret = p11_kit_uri_parse ("pkcs11:object=Test%20Label", P11_KIT_URI_FOR_ANY, uri); - CuAssertIntEquals (tc, P11_KIT_URI_OK, ret); + assert_num_eq (P11_KIT_URI_OK, ret); - CuAssertTrue (tc, is_module_empty (uri)); - CuAssertTrue (tc, is_token_empty (uri)); + assert (is_module_empty (uri)); + assert (is_token_empty (uri)); attr = p11_kit_uri_get_attribute (uri, CKA_LABEL); - CuAssertPtrNotNull (tc, attr); - CuAssertTrue (tc, attr->ulValueLen == strlen ("Test Label")); - CuAssertTrue (tc, memcmp (attr->pValue, "Test Label", attr->ulValueLen) == 0); + assert_ptr_not_null (attr); + assert (attr->ulValueLen == strlen ("Test Label")); + assert (memcmp (attr->pValue, "Test Label", attr->ulValueLen) == 0); p11_kit_uri_free (uri); } static void -test_uri_parse_with_label_and_klass (CuTest *tc) +test_uri_parse_with_label_and_klass (void) { CK_ATTRIBUTE_PTR attr; P11KitUri *uri; int ret; uri = p11_kit_uri_new (); - CuAssertPtrNotNull (tc, uri); + assert_ptr_not_null (uri); ret = p11_kit_uri_parse ("pkcs11:object=Test%20Label;object-type=cert", P11_KIT_URI_FOR_ANY, uri); - CuAssertIntEquals (tc, P11_KIT_URI_OK, ret); + assert_num_eq (P11_KIT_URI_OK, ret); attr = p11_kit_uri_get_attribute (uri, CKA_LABEL); - CuAssertPtrNotNull (tc, attr); - CuAssertTrue (tc, attr->ulValueLen == strlen ("Test Label")); - CuAssertTrue (tc, memcmp (attr->pValue, "Test Label", attr->ulValueLen) == 0); + assert_ptr_not_null (attr); + assert (attr->ulValueLen == strlen ("Test Label")); + assert (memcmp (attr->pValue, "Test Label", attr->ulValueLen) == 0); attr = p11_kit_uri_get_attribute (uri, CKA_CLASS); - CuAssertPtrNotNull (tc, attr); - CuAssertTrue (tc, attr->ulValueLen == sizeof (CK_OBJECT_CLASS)); - CuAssertTrue (tc, *((CK_OBJECT_CLASS_PTR)attr->pValue) == CKO_CERTIFICATE); + assert_ptr_not_null (attr); + assert (attr->ulValueLen == sizeof (CK_OBJECT_CLASS)); + assert (*((CK_OBJECT_CLASS_PTR)attr->pValue) == CKO_CERTIFICATE); p11_kit_uri_free (uri); } static void -test_uri_parse_with_id (CuTest *tc) +test_uri_parse_with_id (void) { CK_ATTRIBUTE_PTR attr; P11KitUri *uri; int ret; uri = p11_kit_uri_new (); - CuAssertPtrNotNull (tc, uri); + assert_ptr_not_null (uri); ret = p11_kit_uri_parse ("pkcs11:id=%54%45%53%54%00", P11_KIT_URI_FOR_OBJECT, uri); - CuAssertIntEquals (tc, P11_KIT_URI_OK, ret); + assert_num_eq (P11_KIT_URI_OK, ret); /* Note that there's a NULL in the attribute (end) */ attr = p11_kit_uri_get_attribute (uri, CKA_ID); - CuAssertPtrNotNull (tc, attr); - CuAssertTrue (tc, attr->ulValueLen == 5); - CuAssertTrue (tc, memcmp (attr->pValue, "TEST", 5) == 0); + assert_ptr_not_null (attr); + assert (attr->ulValueLen == 5); + assert (memcmp (attr->pValue, "TEST", 5) == 0); p11_kit_uri_free (uri); } static void -test_uri_parse_with_bad_string_encoding (CuTest *tc) +test_uri_parse_with_bad_string_encoding (void) { P11KitUri *uri; int ret; uri = p11_kit_uri_new (); - CuAssertPtrNotNull (tc, uri); + assert_ptr_not_null (uri); ret = p11_kit_uri_parse ("pkcs11:object=Test%", P11_KIT_URI_FOR_OBJECT, uri); - CuAssertIntEquals (tc, P11_KIT_URI_BAD_ENCODING, ret); + assert_num_eq (P11_KIT_URI_BAD_ENCODING, ret); p11_kit_uri_free (uri); } static void -test_uri_parse_with_bad_hex_encoding (CuTest *tc) +test_uri_parse_with_bad_hex_encoding (void) { P11KitUri *uri; int ret; uri = p11_kit_uri_new (); - CuAssertPtrNotNull (tc, uri); + assert_ptr_not_null (uri); ret = p11_kit_uri_parse ("pkcs11:object=T%xxest", P11_KIT_URI_FOR_OBJECT, uri); - CuAssertIntEquals (tc, P11_KIT_URI_BAD_ENCODING, ret); + assert_num_eq (P11_KIT_URI_BAD_ENCODING, ret); p11_kit_uri_free (uri); } @@ -226,131 +226,131 @@ is_space_string (CK_UTF8CHAR_PTR string, CK_ULONG size, const char *check) } static void -test_uri_parse_with_token (CuTest *tc) +test_uri_parse_with_token (void) { P11KitUri *uri = NULL; CK_TOKEN_INFO_PTR token; int ret; uri = p11_kit_uri_new (); - CuAssertPtrNotNull (tc, uri); + assert_ptr_not_null (uri); ret = p11_kit_uri_parse ("pkcs11:token=Token%20Label;serial=3333;model=Deluxe;manufacturer=Me", P11_KIT_URI_FOR_TOKEN, uri); - CuAssertIntEquals (tc, P11_KIT_URI_OK, ret); + assert_num_eq (P11_KIT_URI_OK, ret); token = p11_kit_uri_get_token_info (uri); - CuAssertTrue (tc, is_space_string (token->label, sizeof (token->label), "Token Label")); - CuAssertTrue (tc, is_space_string (token->serialNumber, sizeof (token->serialNumber), "3333")); - CuAssertTrue (tc, is_space_string (token->model, sizeof (token->model), "Deluxe")); - CuAssertTrue (tc, is_space_string (token->manufacturerID, sizeof (token->manufacturerID), "Me")); + assert (is_space_string (token->label, sizeof (token->label), "Token Label")); + assert (is_space_string (token->serialNumber, sizeof (token->serialNumber), "3333")); + assert (is_space_string (token->model, sizeof (token->model), "Deluxe")); + assert (is_space_string (token->manufacturerID, sizeof (token->manufacturerID), "Me")); p11_kit_uri_free (uri); } static void -test_uri_parse_with_token_bad_encoding (CuTest *tc) +test_uri_parse_with_token_bad_encoding (void) { P11KitUri *uri; int ret; uri = p11_kit_uri_new (); - CuAssertPtrNotNull (tc, uri); + assert_ptr_not_null (uri); ret = p11_kit_uri_parse ("pkcs11:token=Token%", P11_KIT_URI_FOR_TOKEN, uri); - CuAssertIntEquals (tc, P11_KIT_URI_BAD_ENCODING, ret); + assert_num_eq (P11_KIT_URI_BAD_ENCODING, ret); p11_kit_uri_free (uri); } static void -test_uri_parse_with_bad_syntax (CuTest *tc) +test_uri_parse_with_bad_syntax (void) { P11KitUri *uri; int ret; uri = p11_kit_uri_new (); - CuAssertPtrNotNull (tc, uri); + assert_ptr_not_null (uri); ret = p11_kit_uri_parse ("pkcs11:token", P11_KIT_URI_FOR_ANY, uri); - CuAssertIntEquals (tc, P11_KIT_URI_BAD_SYNTAX, ret); + assert_num_eq (P11_KIT_URI_BAD_SYNTAX, ret); p11_kit_uri_free (uri); } static void -test_uri_parse_with_spaces (CuTest *tc) +test_uri_parse_with_spaces (void) { P11KitUri *uri = NULL; CK_INFO_PTR info; int ret; uri = p11_kit_uri_new (); - CuAssertPtrNotNull (tc, uri); + assert_ptr_not_null (uri); ret = p11_kit_uri_parse ("pkc\ns11: lib rary-desc\rrip \n tion =The%20Library;\n\n\nlibrary-manufacturer=\rMe", P11_KIT_URI_FOR_MODULE, uri); - CuAssertIntEquals (tc, P11_KIT_URI_OK, ret); + assert_num_eq (P11_KIT_URI_OK, ret); info = p11_kit_uri_get_module_info (uri); - CuAssertTrue (tc, is_space_string (info->manufacturerID, sizeof (info->manufacturerID), "Me")); - CuAssertTrue (tc, is_space_string (info->libraryDescription, sizeof (info->libraryDescription), "The Library")); + assert (is_space_string (info->manufacturerID, sizeof (info->manufacturerID), "Me")); + assert (is_space_string (info->libraryDescription, sizeof (info->libraryDescription), "The Library")); p11_kit_uri_free (uri); } static void -test_uri_parse_with_library (CuTest *tc) +test_uri_parse_with_library (void) { P11KitUri *uri = NULL; CK_INFO_PTR info; int ret; uri = p11_kit_uri_new (); - CuAssertPtrNotNull (tc, uri); + assert_ptr_not_null (uri); ret = p11_kit_uri_parse ("pkcs11:library-description=The%20Library;library-manufacturer=Me", P11_KIT_URI_FOR_MODULE, uri); - CuAssertIntEquals (tc, P11_KIT_URI_OK, ret); + assert_num_eq (P11_KIT_URI_OK, ret); info = p11_kit_uri_get_module_info (uri); - CuAssertTrue (tc, is_space_string (info->manufacturerID, sizeof (info->manufacturerID), "Me")); - CuAssertTrue (tc, is_space_string (info->libraryDescription, sizeof (info->libraryDescription), "The Library")); + assert (is_space_string (info->manufacturerID, sizeof (info->manufacturerID), "Me")); + assert (is_space_string (info->libraryDescription, sizeof (info->libraryDescription), "The Library")); p11_kit_uri_free (uri); } static void -test_uri_parse_with_library_bad_encoding (CuTest *tc) +test_uri_parse_with_library_bad_encoding (void) { P11KitUri *uri; int ret; uri = p11_kit_uri_new (); - CuAssertPtrNotNull (tc, uri); + assert_ptr_not_null (uri); ret = p11_kit_uri_parse ("pkcs11:library-description=Library%", P11_KIT_URI_FOR_MODULE, uri); - CuAssertIntEquals (tc, P11_KIT_URI_BAD_ENCODING, ret); + assert_num_eq (P11_KIT_URI_BAD_ENCODING, ret); p11_kit_uri_free (uri); } static void -test_uri_build_empty (CuTest *tc) +test_uri_build_empty (void) { P11KitUri *uri; char *string; int ret; uri = p11_kit_uri_new (); - CuAssertPtrNotNull (tc, uri); + assert_ptr_not_null (uri); ret = p11_kit_uri_format (uri, P11_KIT_URI_FOR_ANY, &string); - CuAssertIntEquals (tc, P11_KIT_URI_OK, ret); - CuAssertStrEquals (tc, "pkcs11:", string); + assert_num_eq (P11_KIT_URI_OK, ret); + assert_str_eq ("pkcs11:", string); free (string); p11_kit_uri_free (uri); @@ -366,7 +366,7 @@ set_space_string (CK_BYTE_PTR buffer, CK_ULONG length, const char *string) } static void -test_uri_build_with_token_info (CuTest *tc) +test_uri_build_with_token_info (void) { char *string = NULL; P11KitUri *uri; @@ -375,7 +375,7 @@ test_uri_build_with_token_info (CuTest *tc) int ret; uri = p11_kit_uri_new (); - CuAssertPtrNotNull (tc, uri); + assert_ptr_not_null (uri); token = p11_kit_uri_get_token_info (uri); set_space_string (token->label, sizeof (token->label), "The Label"); @@ -384,30 +384,30 @@ test_uri_build_with_token_info (CuTest *tc) set_space_string (token->model, sizeof (token->model), "Deluxe"); ret = p11_kit_uri_format (uri, P11_KIT_URI_FOR_ANY, &string); - CuAssertIntEquals (tc, P11_KIT_URI_OK, ret); - CuAssertPtrNotNull (tc, string); + assert_num_eq (P11_KIT_URI_OK, ret); + assert_ptr_not_null (string); check = p11_kit_uri_new (); - CuAssertPtrNotNull (tc, check); + assert_ptr_not_null (check); ret = p11_kit_uri_parse (string, P11_KIT_URI_FOR_TOKEN, check); - CuAssertIntEquals (tc, P11_KIT_URI_OK, ret); + assert_num_eq (P11_KIT_URI_OK, ret); p11_kit_uri_match_token_info (check, p11_kit_uri_get_token_info (uri)); p11_kit_uri_free (uri); p11_kit_uri_free (check); - CuAssertTrue (tc, strstr (string, "token=The%20Label") != NULL); - CuAssertTrue (tc, strstr (string, "serial=44444") != NULL); - CuAssertTrue (tc, strstr (string, "manufacturer=Me") != NULL); - CuAssertTrue (tc, strstr (string, "model=Deluxe") != NULL); + assert (strstr (string, "token=The%20Label") != NULL); + assert (strstr (string, "serial=44444") != NULL); + assert (strstr (string, "manufacturer=Me") != NULL); + assert (strstr (string, "model=Deluxe") != NULL); free (string); } static void -test_uri_build_with_token_null_info (CuTest *tc) +test_uri_build_with_token_null_info (void) { char *string = NULL; P11KitUri *uri; @@ -415,23 +415,23 @@ test_uri_build_with_token_null_info (CuTest *tc) int ret; uri = p11_kit_uri_new (); - CuAssertPtrNotNull (tc, uri); + assert_ptr_not_null (uri); token = p11_kit_uri_get_token_info (uri); set_space_string (token->label, sizeof (token->label), "The Label"); ret = p11_kit_uri_format (uri, P11_KIT_URI_FOR_ANY, &string); - CuAssertIntEquals (tc, P11_KIT_URI_OK, ret); + assert_num_eq (P11_KIT_URI_OK, ret); - CuAssertTrue (tc, strstr (string, "token=The%20Label") != NULL); - CuAssertTrue (tc, strstr (string, "serial=") == NULL); + assert (strstr (string, "token=The%20Label") != NULL); + assert (strstr (string, "serial=") == NULL); free (string); p11_kit_uri_free (uri); } static void -test_uri_build_with_token_empty_info (CuTest *tc) +test_uri_build_with_token_empty_info (void) { char *string = NULL; P11KitUri *uri; @@ -439,24 +439,24 @@ test_uri_build_with_token_empty_info (CuTest *tc) int ret; uri = p11_kit_uri_new (); - CuAssertPtrNotNull (tc, uri); + assert_ptr_not_null (uri); token = p11_kit_uri_get_token_info (uri); set_space_string (token->label, sizeof (token->label), ""); set_space_string (token->serialNumber, sizeof (token->serialNumber), ""); ret = p11_kit_uri_format (uri, P11_KIT_URI_FOR_ANY, &string); - CuAssertIntEquals (tc, P11_KIT_URI_OK, ret); + assert_num_eq (P11_KIT_URI_OK, ret); - CuAssertTrue (tc, strstr (string, "token=") != NULL); - CuAssertTrue (tc, strstr (string, "serial=") != NULL); + assert (strstr (string, "token=") != NULL); + assert (strstr (string, "serial=") != NULL); free (string); p11_kit_uri_free (uri); } static void -test_uri_build_with_attributes (CuTest *tc) +test_uri_build_with_attributes (void) { char *string = NULL; P11KitUri *uri; @@ -467,7 +467,7 @@ test_uri_build_with_attributes (CuTest *tc) int ret; uri = p11_kit_uri_new (); - CuAssertPtrNotNull (tc, uri); + assert_ptr_not_null (uri); at.type = CKA_LABEL; at.pValue = "The Label"; @@ -486,175 +486,175 @@ test_uri_build_with_attributes (CuTest *tc) ret = p11_kit_uri_set_attribute (uri, &at); ret = p11_kit_uri_format (uri, P11_KIT_URI_FOR_ANY, &string); - CuAssertIntEquals (tc, P11_KIT_URI_OK, ret); + assert_num_eq (P11_KIT_URI_OK, ret); check = p11_kit_uri_new (); - CuAssertPtrNotNull (tc, check); + assert_ptr_not_null (check); ret = p11_kit_uri_parse (string, P11_KIT_URI_FOR_ANY, check); - CuAssertIntEquals (tc, P11_KIT_URI_OK, ret); + assert_num_eq (P11_KIT_URI_OK, ret); attr = p11_kit_uri_get_attribute (check, CKA_LABEL); - CuAssertPtrNotNull (tc, attr); - CuAssertTrue (tc, attr->ulValueLen == 9); - CuAssertTrue (tc, memcmp (attr->pValue, "The Label", attr->ulValueLen) == 0); + assert_ptr_not_null (attr); + assert (attr->ulValueLen == 9); + assert (memcmp (attr->pValue, "The Label", attr->ulValueLen) == 0); attr = p11_kit_uri_get_attribute (check, CKA_CLASS); - CuAssertPtrNotNull (tc, attr); - CuAssertTrue (tc, attr->ulValueLen == sizeof (klass)); - CuAssertTrue (tc, *((CK_OBJECT_CLASS_PTR)attr->pValue) == klass); + assert_ptr_not_null (attr); + assert (attr->ulValueLen == sizeof (klass)); + assert (*((CK_OBJECT_CLASS_PTR)attr->pValue) == klass); attr = p11_kit_uri_get_attribute (check, CKA_ID); - CuAssertPtrNotNull (tc, attr); - CuAssertTrue (tc, attr->ulValueLen == 5); - CuAssertTrue (tc, memcmp (attr->pValue, "HELLO", attr->ulValueLen) == 0); + assert_ptr_not_null (attr); + assert (attr->ulValueLen == 5); + assert (memcmp (attr->pValue, "HELLO", attr->ulValueLen) == 0); p11_kit_uri_free (check); - CuAssertTrue (tc, strstr (string, "object=The%20Label") != NULL); - CuAssertTrue (tc, strstr (string, "object-type=data") != NULL); - CuAssertTrue (tc, strstr (string, "id=%48%45%4c%4c%4f") != NULL); + assert (strstr (string, "object=The%20Label") != NULL); + assert (strstr (string, "object-type=data") != NULL); + assert (strstr (string, "id=%48%45%4c%4c%4f") != NULL); free (string); p11_kit_uri_free (uri); } static void -test_uri_parse_private_key (CuTest *tc) +test_uri_parse_private_key (void) { P11KitUri *uri; CK_ATTRIBUTE_PTR attr; int ret; uri = p11_kit_uri_new (); - CuAssertPtrNotNull (tc, uri); + assert_ptr_not_null (uri); ret = p11_kit_uri_parse ("pkcs11:object-type=private", P11_KIT_URI_FOR_OBJECT, uri); - CuAssertIntEquals (tc, P11_KIT_URI_OK, ret); + assert_num_eq (P11_KIT_URI_OK, ret); attr = p11_kit_uri_get_attribute (uri, CKA_CLASS); - CuAssertPtrNotNull (tc, attr); - CuAssertTrue (tc, attr->ulValueLen == sizeof (CK_OBJECT_CLASS)); - CuAssertTrue (tc, *((CK_OBJECT_CLASS_PTR)attr->pValue) == CKO_PRIVATE_KEY); + assert_ptr_not_null (attr); + assert (attr->ulValueLen == sizeof (CK_OBJECT_CLASS)); + assert (*((CK_OBJECT_CLASS_PTR)attr->pValue) == CKO_PRIVATE_KEY); p11_kit_uri_free (uri); } static void -test_uri_parse_secret_key (CuTest *tc) +test_uri_parse_secret_key (void) { P11KitUri *uri; CK_ATTRIBUTE_PTR attr; int ret; uri = p11_kit_uri_new (); - CuAssertPtrNotNull (tc, uri); + assert_ptr_not_null (uri); ret = p11_kit_uri_parse ("pkcs11:object-type=secret-key", P11_KIT_URI_FOR_OBJECT, uri); - CuAssertIntEquals (tc, P11_KIT_URI_OK, ret); + assert_num_eq (P11_KIT_URI_OK, ret); attr = p11_kit_uri_get_attribute (uri, CKA_CLASS); - CuAssertPtrNotNull (tc, attr); - CuAssertTrue (tc, attr->ulValueLen == sizeof (CK_OBJECT_CLASS)); - CuAssertTrue (tc, *((CK_OBJECT_CLASS_PTR)attr->pValue) == CKO_SECRET_KEY); + assert_ptr_not_null (attr); + assert (attr->ulValueLen == sizeof (CK_OBJECT_CLASS)); + assert (*((CK_OBJECT_CLASS_PTR)attr->pValue) == CKO_SECRET_KEY); p11_kit_uri_free (uri); } static void -test_uri_parse_library_version (CuTest *tc) +test_uri_parse_library_version (void) { P11KitUri *uri; CK_INFO_PTR info; int ret; uri = p11_kit_uri_new (); - CuAssertPtrNotNull (tc, uri); + assert_ptr_not_null (uri); ret = p11_kit_uri_parse ("pkcs11:library-version=2.101", P11_KIT_URI_FOR_MODULE_WITH_VERSION, uri); - CuAssertIntEquals (tc, P11_KIT_URI_OK, ret); + assert_num_eq (P11_KIT_URI_OK, ret); info = p11_kit_uri_get_module_info (uri); - CuAssertIntEquals (tc, 2, info->libraryVersion.major); - CuAssertIntEquals (tc, 101, info->libraryVersion.minor); + assert_num_eq (2, info->libraryVersion.major); + assert_num_eq (101, info->libraryVersion.minor); ret = p11_kit_uri_parse ("pkcs11:library-version=23", P11_KIT_URI_FOR_MODULE_WITH_VERSION, uri); - CuAssertIntEquals (tc, P11_KIT_URI_OK, ret); + assert_num_eq (P11_KIT_URI_OK, ret); info = p11_kit_uri_get_module_info (uri); - CuAssertIntEquals (tc, 23, info->libraryVersion.major); - CuAssertIntEquals (tc, 0, info->libraryVersion.minor); + assert_num_eq (23, info->libraryVersion.major); + assert_num_eq (0, info->libraryVersion.minor); ret = p11_kit_uri_parse ("pkcs11:library-version=23.", P11_KIT_URI_FOR_MODULE_WITH_VERSION, uri); - CuAssertIntEquals (tc, P11_KIT_URI_BAD_VERSION, ret); + assert_num_eq (P11_KIT_URI_BAD_VERSION, ret); ret = p11_kit_uri_parse ("pkcs11:library-version=a.a", P11_KIT_URI_FOR_MODULE_WITH_VERSION, uri); - CuAssertIntEquals (tc, P11_KIT_URI_BAD_VERSION, ret); + assert_num_eq (P11_KIT_URI_BAD_VERSION, ret); ret = p11_kit_uri_parse ("pkcs11:library-version=.23", P11_KIT_URI_FOR_MODULE_WITH_VERSION, uri); - CuAssertIntEquals (tc, P11_KIT_URI_BAD_VERSION, ret); + assert_num_eq (P11_KIT_URI_BAD_VERSION, ret); ret = p11_kit_uri_parse ("pkcs11:library-version=1000", P11_KIT_URI_FOR_MODULE_WITH_VERSION, uri); - CuAssertIntEquals (tc, P11_KIT_URI_BAD_VERSION, ret); + assert_num_eq (P11_KIT_URI_BAD_VERSION, ret); ret = p11_kit_uri_parse ("pkcs11:library-version=2.1000", P11_KIT_URI_FOR_MODULE_WITH_VERSION, uri); - CuAssertIntEquals (tc, P11_KIT_URI_BAD_VERSION, ret); + assert_num_eq (P11_KIT_URI_BAD_VERSION, ret); p11_kit_uri_free (uri); } static void -test_uri_parse_parse_unknown_object_type (CuTest *tc) +test_uri_parse_parse_unknown_object_type (void) { P11KitUri *uri; CK_ATTRIBUTE_PTR attr; int ret; uri = p11_kit_uri_new (); - CuAssertPtrNotNull (tc, uri); + assert_ptr_not_null (uri); ret = p11_kit_uri_parse ("pkcs11:object-type=unknown", P11_KIT_URI_FOR_OBJECT, uri); - CuAssertIntEquals (tc, P11_KIT_URI_OK, ret); + assert_num_eq (P11_KIT_URI_OK, ret); attr = p11_kit_uri_get_attribute (uri, CKA_CLASS); - CuAssertPtrEquals (tc, NULL, attr); + assert_ptr_eq (NULL, attr); p11_kit_uri_free (uri); } static void -test_uri_parse_unrecognized (CuTest *tc) +test_uri_parse_unrecognized (void) { P11KitUri *uri; int ret; uri = p11_kit_uri_new (); - CuAssertPtrNotNull (tc, uri); + assert_ptr_not_null (uri); ret = p11_kit_uri_parse ("pkcs11:x-blah=some-value", P11_KIT_URI_FOR_ANY, uri); - CuAssertIntEquals (tc, P11_KIT_URI_OK, ret); + assert_num_eq (P11_KIT_URI_OK, ret); ret = p11_kit_uri_any_unrecognized (uri); - CuAssertIntEquals (tc, 1, ret); + assert_num_eq (1, ret); p11_kit_uri_free (uri); } static void -test_uri_parse_too_long_is_unrecognized (CuTest *tc) +test_uri_parse_too_long_is_unrecognized (void) { P11KitUri *uri; int ret; uri = p11_kit_uri_new (); - CuAssertPtrNotNull (tc, uri); + assert_ptr_not_null (uri); ret = p11_kit_uri_parse ("pkcs11:model=a-value-that-is-too-long-for-the-field-that-it-goes-with", P11_KIT_URI_FOR_ANY, uri); - CuAssertIntEquals (tc, P11_KIT_URI_OK, ret); + assert_num_eq (P11_KIT_URI_OK, ret); ret = p11_kit_uri_any_unrecognized (uri); - CuAssertIntEquals (tc, 1, ret); + assert_num_eq (1, ret); p11_kit_uri_free (uri); } @@ -662,7 +662,7 @@ test_uri_parse_too_long_is_unrecognized (CuTest *tc) static void -test_uri_build_object_type_cert (CuTest *tc) +test_uri_build_object_type_cert (void) { CK_ATTRIBUTE attr; CK_OBJECT_CLASS klass; @@ -671,7 +671,7 @@ test_uri_build_object_type_cert (CuTest *tc) int ret; uri = p11_kit_uri_new (); - CuAssertPtrNotNull (tc, uri); + assert_ptr_not_null (uri); klass = CKO_CERTIFICATE; attr.type = CKA_CLASS; @@ -680,15 +680,15 @@ test_uri_build_object_type_cert (CuTest *tc) p11_kit_uri_set_attribute (uri, &attr); ret = p11_kit_uri_format (uri, P11_KIT_URI_FOR_ANY, &string); - CuAssertIntEquals (tc, P11_KIT_URI_OK, ret); - CuAssertTrue (tc, strstr (string, "object-type=cert") != NULL); + assert_num_eq (P11_KIT_URI_OK, ret); + assert (strstr (string, "object-type=cert") != NULL); p11_kit_uri_free (uri); free (string); } static void -test_uri_build_object_type_private (CuTest *tc) +test_uri_build_object_type_private (void) { CK_ATTRIBUTE attr; CK_OBJECT_CLASS klass; @@ -697,7 +697,7 @@ test_uri_build_object_type_private (CuTest *tc) int ret; uri = p11_kit_uri_new (); - CuAssertPtrNotNull (tc, uri); + assert_ptr_not_null (uri); klass = CKO_PRIVATE_KEY; attr.type = CKA_CLASS; @@ -706,15 +706,15 @@ test_uri_build_object_type_private (CuTest *tc) p11_kit_uri_set_attribute (uri, &attr); ret = p11_kit_uri_format (uri, P11_KIT_URI_FOR_ANY, &string); - CuAssertIntEquals (tc, P11_KIT_URI_OK, ret); - CuAssertTrue (tc, strstr (string, "object-type=private") != NULL); + assert_num_eq (P11_KIT_URI_OK, ret); + assert (strstr (string, "object-type=private") != NULL); p11_kit_uri_free (uri); free (string); } static void -test_uri_build_object_type_public (CuTest *tc) +test_uri_build_object_type_public (void) { CK_ATTRIBUTE attr; CK_OBJECT_CLASS klass; @@ -723,7 +723,7 @@ test_uri_build_object_type_public (CuTest *tc) int ret; uri = p11_kit_uri_new (); - CuAssertPtrNotNull (tc, uri); + assert_ptr_not_null (uri); klass = CKO_PUBLIC_KEY; attr.type = CKA_CLASS; @@ -732,15 +732,15 @@ test_uri_build_object_type_public (CuTest *tc) p11_kit_uri_set_attribute (uri, &attr); ret = p11_kit_uri_format (uri, P11_KIT_URI_FOR_ANY, &string); - CuAssertIntEquals (tc, P11_KIT_URI_OK, ret); - CuAssertTrue (tc, strstr (string, "object-type=public") != NULL); + assert_num_eq (P11_KIT_URI_OK, ret); + assert (strstr (string, "object-type=public") != NULL); p11_kit_uri_free (uri); free (string); } static void -test_uri_build_object_type_secret (CuTest *tc) +test_uri_build_object_type_secret (void) { CK_ATTRIBUTE attr; CK_OBJECT_CLASS klass; @@ -749,7 +749,7 @@ test_uri_build_object_type_secret (CuTest *tc) int ret; uri = p11_kit_uri_new (); - CuAssertPtrNotNull (tc, uri); + assert_ptr_not_null (uri); klass = CKO_SECRET_KEY; attr.type = CKA_CLASS; @@ -758,15 +758,15 @@ test_uri_build_object_type_secret (CuTest *tc) p11_kit_uri_set_attribute (uri, &attr); ret = p11_kit_uri_format (uri, P11_KIT_URI_FOR_ANY, &string); - CuAssertIntEquals (tc, P11_KIT_URI_OK, ret); - CuAssertTrue (tc, strstr (string, "object-type=secret-key") != NULL); + assert_num_eq (P11_KIT_URI_OK, ret); + assert (strstr (string, "object-type=secret-key") != NULL); p11_kit_uri_free (uri); free (string); } static void -test_uri_build_with_library (CuTest *tc) +test_uri_build_with_library (void) { CK_INFO_PTR info; P11KitUri *uri; @@ -774,21 +774,21 @@ test_uri_build_with_library (CuTest *tc) int ret; uri = p11_kit_uri_new (); - CuAssertPtrNotNull (tc, uri); + assert_ptr_not_null (uri); info = p11_kit_uri_get_module_info (uri); set_space_string (info->libraryDescription, sizeof (info->libraryDescription), "The Description"); ret = p11_kit_uri_format (uri, P11_KIT_URI_FOR_ANY, &string); - CuAssertIntEquals (tc, P11_KIT_URI_OK, ret); - CuAssertTrue (tc, strstr (string, "library-description=The%20Description") != NULL); + assert_num_eq (P11_KIT_URI_OK, ret); + assert (strstr (string, "library-description=The%20Description") != NULL); p11_kit_uri_free (uri); free (string); } static void -test_uri_build_library_version (CuTest *tc) +test_uri_build_library_version (void) { CK_INFO_PTR info; P11KitUri *uri; @@ -796,121 +796,121 @@ test_uri_build_library_version (CuTest *tc) int ret; uri = p11_kit_uri_new (); - CuAssertPtrNotNull (tc, uri); + assert_ptr_not_null (uri); info = p11_kit_uri_get_module_info (uri); info->libraryVersion.major = 2; info->libraryVersion.minor = 10; ret = p11_kit_uri_format (uri, P11_KIT_URI_FOR_ANY, &string); - CuAssertIntEquals (tc, P11_KIT_URI_OK, ret); - CuAssertTrue (tc, strstr (string, "library-version=2.10") != NULL); + assert_num_eq (P11_KIT_URI_OK, ret); + assert (strstr (string, "library-version=2.10") != NULL); p11_kit_uri_free (uri); free (string); } static void -test_uri_get_set_unrecognized (CuTest *tc) +test_uri_get_set_unrecognized (void) { P11KitUri *uri; int ret; uri = p11_kit_uri_new (); - CuAssertPtrNotNull (tc, uri); + assert_ptr_not_null (uri); ret = p11_kit_uri_any_unrecognized (uri); - CuAssertIntEquals (tc, 0, ret); + assert_num_eq (0, ret); p11_kit_uri_set_unrecognized (uri, 1); ret = p11_kit_uri_any_unrecognized (uri); - CuAssertIntEquals (tc, 1, ret); + assert_num_eq (1, ret); p11_kit_uri_set_unrecognized (uri, 0); ret = p11_kit_uri_any_unrecognized (uri); - CuAssertIntEquals (tc, 0, ret); + assert_num_eq (0, ret); p11_kit_uri_free (uri); } static void -test_uri_match_token (CuTest *tc) +test_uri_match_token (void) { CK_TOKEN_INFO token; P11KitUri *uri; int ret; uri = p11_kit_uri_new (); - CuAssertPtrNotNull (tc, uri); + assert_ptr_not_null (uri); ret = p11_kit_uri_parse ("pkcs11:model=Giselle", P11_KIT_URI_FOR_ANY, uri); - CuAssertIntEquals (tc, P11_KIT_URI_OK, ret); + assert_num_eq (P11_KIT_URI_OK, ret); set_space_string (token.label, sizeof (token.label), "A label"); set_space_string (token.model, sizeof (token.model), "Giselle"); ret = p11_kit_uri_match_token_info (uri, &token); - CuAssertIntEquals (tc, 1, ret); + assert_num_eq (1, ret); set_space_string (token.label, sizeof (token.label), "Another label"); ret = p11_kit_uri_match_token_info (uri, &token); - CuAssertIntEquals (tc, 1, ret); + assert_num_eq (1, ret); set_space_string (token.model, sizeof (token.model), "Zoolander"); ret = p11_kit_uri_match_token_info (uri, &token); - CuAssertIntEquals (tc, 0, ret); + assert_num_eq (0, ret); p11_kit_uri_set_unrecognized (uri, 1); ret = p11_kit_uri_match_token_info (uri, &token); - CuAssertIntEquals (tc, 0, ret); + assert_num_eq (0, ret); p11_kit_uri_free (uri); } static void -test_uri_match_module (CuTest *tc) +test_uri_match_module (void) { CK_INFO info; P11KitUri *uri; int ret; uri = p11_kit_uri_new (); - CuAssertPtrNotNull (tc, uri); + assert_ptr_not_null (uri); ret = p11_kit_uri_parse ("pkcs11:library-description=Quiet", P11_KIT_URI_FOR_ANY, uri); - CuAssertIntEquals (tc, P11_KIT_URI_OK, ret); + assert_num_eq (P11_KIT_URI_OK, ret); set_space_string (info.libraryDescription, sizeof (info.libraryDescription), "Quiet"); set_space_string (info.manufacturerID, sizeof (info.manufacturerID), "Someone"); ret = p11_kit_uri_match_module_info (uri, &info); - CuAssertIntEquals (tc, 1, ret); + assert_num_eq (1, ret); set_space_string (info.manufacturerID, sizeof (info.manufacturerID), "Someone else"); ret = p11_kit_uri_match_module_info (uri, &info); - CuAssertIntEquals (tc, 1, ret); + assert_num_eq (1, ret); set_space_string (info.libraryDescription, sizeof (info.libraryDescription), "Leise"); ret = p11_kit_uri_match_module_info (uri, &info); - CuAssertIntEquals (tc, 0, ret); + assert_num_eq (0, ret); p11_kit_uri_set_unrecognized (uri, 1); ret = p11_kit_uri_match_module_info (uri, &info); - CuAssertIntEquals (tc, 0, ret); + assert_num_eq (0, ret); p11_kit_uri_free (uri); } static void -test_uri_match_version (CuTest *tc) +test_uri_match_version (void) { CK_INFO info; P11KitUri *uri; @@ -919,28 +919,28 @@ test_uri_match_version (CuTest *tc) memset (&info, 0, sizeof (info)); uri = p11_kit_uri_new (); - CuAssertPtrNotNull (tc, uri); + assert_ptr_not_null (uri); ret = p11_kit_uri_parse ("pkcs11:library-version=5.8", P11_KIT_URI_FOR_ANY, uri); - CuAssertIntEquals (tc, P11_KIT_URI_OK, ret); + assert_num_eq (P11_KIT_URI_OK, ret); info.libraryVersion.major = 5; info.libraryVersion.minor = 8; ret = p11_kit_uri_match_module_info (uri, &info); - CuAssertIntEquals (tc, 1, ret); + assert_num_eq (1, ret); info.libraryVersion.major = 2; info.libraryVersion.minor = 3; ret = p11_kit_uri_match_module_info (uri, &info); - CuAssertIntEquals (tc, 0, ret); + assert_num_eq (0, ret); p11_kit_uri_free (uri); } static void -test_uri_match_attributes (CuTest *tc) +test_uri_match_attributes (void) { CK_ATTRIBUTE attrs[4]; CK_OBJECT_CLASS klass; @@ -965,40 +965,40 @@ test_uri_match_attributes (CuTest *tc) attrs[3].ulValueLen = sizeof (klass); uri = p11_kit_uri_new (); - CuAssertPtrNotNull (tc, uri); + assert_ptr_not_null (uri); ret = p11_kit_uri_parse ("pkcs11:object=Fancy;id=Blah;object-type=data", P11_KIT_URI_FOR_ANY, uri); - CuAssertIntEquals (tc, P11_KIT_URI_OK, ret); + assert_num_eq (P11_KIT_URI_OK, ret); ret = p11_kit_uri_match_attributes (uri, attrs, 4); - CuAssertIntEquals (tc, 0, ret); + assert_num_eq (0, ret); attrs[1].pValue = "Fancy"; attrs[1].ulValueLen = 5; ret = p11_kit_uri_match_attributes (uri, attrs, 4); - CuAssertIntEquals (tc, 1, ret); + assert_num_eq (1, ret); p11_kit_uri_clear_attribute (uri, CKA_CLASS); ret = p11_kit_uri_match_attributes (uri, attrs, 4); - CuAssertIntEquals (tc, 1, ret); + assert_num_eq (1, ret); attrs[2].pValue = "pink"; ret = p11_kit_uri_match_attributes (uri, attrs, 4); - CuAssertIntEquals (tc, 1, ret); + assert_num_eq (1, ret); p11_kit_uri_set_unrecognized (uri, 1); ret = p11_kit_uri_match_attributes (uri, attrs, 4); - CuAssertIntEquals (tc, 0, ret); + assert_num_eq (0, ret); p11_kit_uri_free (uri); } static void -test_uri_get_set_attribute (CuTest *tc) +test_uri_get_set_attribute (void) { CK_ATTRIBUTE attr; CK_ATTRIBUTE_PTR ptr; @@ -1006,51 +1006,51 @@ test_uri_get_set_attribute (CuTest *tc) int ret; uri = p11_kit_uri_new (); - CuAssertPtrNotNull (tc, uri); + assert_ptr_not_null (uri); ptr = p11_kit_uri_get_attribute (uri, CKA_LABEL); - CuAssertPtrEquals (tc, NULL, ptr); + assert_ptr_eq (NULL, ptr); ret = p11_kit_uri_clear_attribute (uri, CKA_LABEL); - CuAssertIntEquals (tc, P11_KIT_URI_OK, ret); + assert_num_eq (P11_KIT_URI_OK, ret); ret = p11_kit_uri_clear_attribute (uri, CKA_COLOR); - CuAssertIntEquals (tc, P11_KIT_URI_NOT_FOUND, ret); + assert_num_eq (P11_KIT_URI_NOT_FOUND, ret); attr.type = CKA_LABEL; attr.pValue = "Test"; attr.ulValueLen = 4; ret = p11_kit_uri_set_attribute (uri, &attr); - CuAssertIntEquals (tc, P11_KIT_URI_OK, ret); + assert_num_eq (P11_KIT_URI_OK, ret); /* We can set other attributes */ attr.type = CKA_COLOR; ret = p11_kit_uri_set_attribute (uri, &attr); - CuAssertIntEquals (tc, P11_KIT_URI_OK, ret); + assert_num_eq (P11_KIT_URI_OK, ret); /* And get them too */ ptr = p11_kit_uri_get_attribute (uri, CKA_COLOR); - CuAssertPtrNotNull (tc, ptr); + assert_ptr_not_null (ptr); ptr = p11_kit_uri_get_attribute (uri, CKA_LABEL); - CuAssertPtrNotNull (tc, ptr); + assert_ptr_not_null (ptr); - CuAssertTrue (tc, ptr->type == CKA_LABEL); - CuAssertTrue (tc, ptr->ulValueLen == 4); - CuAssertTrue (tc, memcmp (ptr->pValue, "Test", 4) == 0); + assert (ptr->type == CKA_LABEL); + assert (ptr->ulValueLen == 4); + assert (memcmp (ptr->pValue, "Test", 4) == 0); ret = p11_kit_uri_clear_attribute (uri, CKA_LABEL); - CuAssertIntEquals (tc, P11_KIT_URI_OK, ret); + assert_num_eq (P11_KIT_URI_OK, ret); ptr = p11_kit_uri_get_attribute (uri, CKA_LABEL); - CuAssertPtrEquals (tc, NULL, ptr); + assert_ptr_eq (NULL, ptr); p11_kit_uri_free (uri); } static void -test_uri_get_set_attributes (CuTest *tc) +test_uri_get_set_attributes (void) { CK_ATTRIBUTE_PTR attrs; CK_OBJECT_CLASS klass; @@ -1060,39 +1060,39 @@ test_uri_get_set_attributes (CuTest *tc) int ret; uri = p11_kit_uri_new (); - CuAssertPtrNotNull (tc, uri); + assert_ptr_not_null (uri); attrs = p11_kit_uri_get_attributes (uri, &n_attrs); - CuAssertPtrNotNull (tc, attrs); - CuAssertIntEquals (tc, 0, n_attrs); + assert_ptr_not_null (attrs); + assert_num_eq (0, n_attrs); attr.type = CKA_LABEL; attr.pValue = "Test"; attr.ulValueLen = 4; ret = p11_kit_uri_set_attribute (uri, &attr); - CuAssertIntEquals (tc, P11_KIT_URI_OK, ret); + assert_num_eq (P11_KIT_URI_OK, ret); attrs = p11_kit_uri_get_attributes (uri, &n_attrs); - CuAssertPtrNotNull (tc, attrs); - CuAssertIntEquals (tc, 1, n_attrs); - CuAssertTrue (tc, attrs[0].type == CKA_LABEL); - CuAssertTrue (tc, attrs[0].ulValueLen == 4); - CuAssertTrue (tc, memcmp (attrs[0].pValue, "Test", 4) == 0); + assert_ptr_not_null (attrs); + assert_num_eq (1, n_attrs); + assert (attrs[0].type == CKA_LABEL); + assert (attrs[0].ulValueLen == 4); + assert (memcmp (attrs[0].pValue, "Test", 4) == 0); attr.type = CKA_LABEL; attr.pValue = "Kablooey"; attr.ulValueLen = 8; ret = p11_kit_uri_set_attribute (uri, &attr); - CuAssertIntEquals (tc, P11_KIT_URI_OK, ret); + assert_num_eq (P11_KIT_URI_OK, ret); attrs = p11_kit_uri_get_attributes (uri, &n_attrs); - CuAssertPtrNotNull (tc, attrs); - CuAssertIntEquals (tc, 1, n_attrs); - CuAssertTrue (tc, attrs[0].type == CKA_LABEL); - CuAssertTrue (tc, attrs[0].ulValueLen == 8); - CuAssertTrue (tc, memcmp (attrs[0].pValue, "Kablooey", 8) == 0); + assert_ptr_not_null (attrs); + assert_num_eq (1, n_attrs); + assert (attrs[0].type == CKA_LABEL); + assert (attrs[0].ulValueLen == 8); + assert (memcmp (attrs[0].pValue, "Kablooey", 8) == 0); klass = CKO_DATA; attr.type = CKA_CLASS; @@ -1100,52 +1100,52 @@ test_uri_get_set_attributes (CuTest *tc) attr.ulValueLen = sizeof (klass); ret = p11_kit_uri_set_attribute (uri, &attr); - CuAssertIntEquals (tc, P11_KIT_URI_OK, ret); + assert_num_eq (P11_KIT_URI_OK, ret); attrs = p11_kit_uri_get_attributes (uri, &n_attrs); - CuAssertPtrNotNull (tc, attrs); - CuAssertIntEquals (tc, 2, n_attrs); - CuAssertTrue (tc, attrs[0].type == CKA_LABEL); - CuAssertTrue (tc, attrs[0].ulValueLen == 8); - CuAssertTrue (tc, memcmp (attrs[0].pValue, "Kablooey", 8) == 0); - CuAssertTrue (tc, attrs[1].type == CKA_CLASS); - CuAssertTrue (tc, attrs[1].ulValueLen == sizeof (klass)); - CuAssertTrue (tc, memcmp (attrs[1].pValue, &klass, sizeof (klass)) == 0); + assert_ptr_not_null (attrs); + assert_num_eq (2, n_attrs); + assert (attrs[0].type == CKA_LABEL); + assert (attrs[0].ulValueLen == 8); + assert (memcmp (attrs[0].pValue, "Kablooey", 8) == 0); + assert (attrs[1].type == CKA_CLASS); + assert (attrs[1].ulValueLen == sizeof (klass)); + assert (memcmp (attrs[1].pValue, &klass, sizeof (klass)) == 0); ret = p11_kit_uri_clear_attribute (uri, CKA_LABEL); - CuAssertIntEquals (tc, P11_KIT_URI_OK, ret); + assert_num_eq (P11_KIT_URI_OK, ret); attrs = p11_kit_uri_get_attributes (uri, &n_attrs); - CuAssertPtrNotNull (tc, attrs); - CuAssertIntEquals (tc, 1, n_attrs); - CuAssertTrue (tc, attrs[0].type == CKA_CLASS); - CuAssertTrue (tc, attrs[0].ulValueLen == sizeof (klass)); - CuAssertTrue (tc, memcmp (attrs[0].pValue, &klass, sizeof (klass)) == 0); + assert_ptr_not_null (attrs); + assert_num_eq (1, n_attrs); + assert (attrs[0].type == CKA_CLASS); + assert (attrs[0].ulValueLen == sizeof (klass)); + assert (memcmp (attrs[0].pValue, &klass, sizeof (klass)) == 0); attr.type = CKA_LABEL; attr.pValue = "Three"; attr.ulValueLen = 5; ret = p11_kit_uri_set_attributes (uri, &attr, 1); - CuAssertIntEquals (tc, P11_KIT_URI_OK, ret); + assert_num_eq (P11_KIT_URI_OK, ret); attrs = p11_kit_uri_get_attributes (uri, &n_attrs); - CuAssertPtrNotNull (tc, attrs); - CuAssertIntEquals (tc, 1, n_attrs); - CuAssertTrue (tc, attrs[0].type == CKA_LABEL); - CuAssertTrue (tc, attrs[0].ulValueLen == 5); - CuAssertTrue (tc, memcmp (attrs[0].pValue, "Three", 5) == 0); + assert_ptr_not_null (attrs); + assert_num_eq (1, n_attrs); + assert (attrs[0].type == CKA_LABEL); + assert (attrs[0].ulValueLen == 5); + assert (memcmp (attrs[0].pValue, "Three", 5) == 0); p11_kit_uri_clear_attributes (uri); attrs = p11_kit_uri_get_attributes (uri, &n_attrs); - CuAssertPtrNotNull (tc, attrs); - CuAssertIntEquals (tc, 0, n_attrs); + assert_ptr_not_null (attrs); + assert_num_eq (0, n_attrs); p11_kit_uri_free (uri); } static void -test_uri_pin_source (CuTest *tc) +test_uri_pin_source (void) { P11KitUri *uri; const char *pin_source; @@ -1153,106 +1153,93 @@ test_uri_pin_source (CuTest *tc) int ret; uri = p11_kit_uri_new (); - CuAssertPtrNotNull (tc, uri); + assert_ptr_not_null (uri); p11_kit_uri_set_pin_source (uri, "|my-pin-source"); pin_source = p11_kit_uri_get_pin_source (uri); - CuAssertStrEquals (tc, "|my-pin-source", pin_source); + assert_str_eq ("|my-pin-source", pin_source); pin_source = p11_kit_uri_get_pinfile (uri); - CuAssertStrEquals (tc, "|my-pin-source", pin_source); + assert_str_eq ("|my-pin-source", pin_source); p11_kit_uri_set_pinfile (uri, "|my-pin-file"); pin_source = p11_kit_uri_get_pin_source (uri); - CuAssertStrEquals (tc, "|my-pin-file", pin_source); + assert_str_eq ("|my-pin-file", pin_source); ret = p11_kit_uri_format (uri, P11_KIT_URI_FOR_ANY, &string); - CuAssertIntEquals (tc, P11_KIT_URI_OK, ret); - CuAssertTrue (tc, strstr (string, "pin-source=%7cmy-pin-file") != NULL); + assert_num_eq (P11_KIT_URI_OK, ret); + assert (strstr (string, "pin-source=%7cmy-pin-file") != NULL); free (string); ret = p11_kit_uri_parse ("pkcs11:pin-source=blah%2Fblah", P11_KIT_URI_FOR_ANY, uri); - CuAssertIntEquals (tc, P11_KIT_URI_OK, ret); + assert_num_eq (P11_KIT_URI_OK, ret); pin_source = p11_kit_uri_get_pin_source (uri); - CuAssertStrEquals (tc, "blah/blah", pin_source); + assert_str_eq ("blah/blah", pin_source); p11_kit_uri_free (uri); } static void -test_uri_free_null (CuTest *tc) +test_uri_free_null (void) { p11_kit_uri_free (NULL); } static void -test_uri_message (CuTest *tc) +test_uri_message (void) { - CuAssertTrue (tc, p11_kit_uri_message (P11_KIT_URI_OK) == NULL); - CuAssertPtrNotNull (tc, p11_kit_uri_message (P11_KIT_URI_UNEXPECTED)); - CuAssertPtrNotNull (tc, p11_kit_uri_message (-555555)); + assert (p11_kit_uri_message (P11_KIT_URI_OK) == NULL); + assert_ptr_not_null (p11_kit_uri_message (P11_KIT_URI_UNEXPECTED)); + assert_ptr_not_null (p11_kit_uri_message (-555555)); } int -main (void) +main (int argc, + char *argv[]) { - CuString *output = CuStringNew (); - CuSuite* suite = CuSuiteNew (); - int ret; - - putenv ("P11_KIT_STRICT=1"); - p11_debug_init (); - - SUITE_ADD_TEST (suite, test_uri_parse); - SUITE_ADD_TEST (suite, test_uri_parse_bad_scheme); - SUITE_ADD_TEST (suite, test_uri_parse_with_label); - SUITE_ADD_TEST (suite, test_uri_parse_with_label_and_klass); - SUITE_ADD_TEST (suite, test_uri_parse_with_id); - SUITE_ADD_TEST (suite, test_uri_parse_with_bad_string_encoding); - SUITE_ADD_TEST (suite, test_uri_parse_with_bad_hex_encoding); - SUITE_ADD_TEST (suite, test_uri_parse_with_token); - SUITE_ADD_TEST (suite, test_uri_parse_with_token_bad_encoding); - SUITE_ADD_TEST (suite, test_uri_parse_with_bad_syntax); - SUITE_ADD_TEST (suite, test_uri_parse_with_spaces); - SUITE_ADD_TEST (suite, test_uri_parse_with_library); - SUITE_ADD_TEST (suite, test_uri_parse_with_library_bad_encoding); - SUITE_ADD_TEST (suite, test_uri_build_empty); - SUITE_ADD_TEST (suite, test_uri_build_with_token_info); - SUITE_ADD_TEST (suite, test_uri_build_with_token_null_info); - SUITE_ADD_TEST (suite, test_uri_build_with_token_empty_info); - SUITE_ADD_TEST (suite, test_uri_build_with_attributes); - SUITE_ADD_TEST (suite, test_uri_parse_private_key); - SUITE_ADD_TEST (suite, test_uri_parse_secret_key); - SUITE_ADD_TEST (suite, test_uri_parse_library_version); - SUITE_ADD_TEST (suite, test_uri_parse_parse_unknown_object_type); - SUITE_ADD_TEST (suite, test_uri_parse_unrecognized); - SUITE_ADD_TEST (suite, test_uri_parse_too_long_is_unrecognized); - SUITE_ADD_TEST (suite, test_uri_build_object_type_cert); - SUITE_ADD_TEST (suite, test_uri_build_object_type_private); - SUITE_ADD_TEST (suite, test_uri_build_object_type_public); - SUITE_ADD_TEST (suite, test_uri_build_object_type_secret); - SUITE_ADD_TEST (suite, test_uri_build_with_library); - SUITE_ADD_TEST (suite, test_uri_build_library_version); - SUITE_ADD_TEST (suite, test_uri_get_set_unrecognized); - SUITE_ADD_TEST (suite, test_uri_match_token); - SUITE_ADD_TEST (suite, test_uri_match_module); - SUITE_ADD_TEST (suite, test_uri_match_version); - SUITE_ADD_TEST (suite, test_uri_match_attributes); - SUITE_ADD_TEST (suite, test_uri_get_set_attribute); - SUITE_ADD_TEST (suite, test_uri_get_set_attributes); - SUITE_ADD_TEST (suite, test_uri_pin_source); - SUITE_ADD_TEST (suite, test_uri_free_null); - SUITE_ADD_TEST (suite, test_uri_message); - - CuSuiteRun (suite); - CuSuiteSummary (suite, output); - CuSuiteDetails (suite, output); - printf ("%s\n", output->buffer); - ret = suite->failCount; - CuSuiteDelete (suite); - CuStringDelete (output); - return ret; + p11_test (test_uri_parse, "/uri/test_uri_parse"); + p11_test (test_uri_parse_bad_scheme, "/uri/test_uri_parse_bad_scheme"); + p11_test (test_uri_parse_with_label, "/uri/test_uri_parse_with_label"); + p11_test (test_uri_parse_with_label_and_klass, "/uri/test_uri_parse_with_label_and_klass"); + p11_test (test_uri_parse_with_id, "/uri/test_uri_parse_with_id"); + p11_test (test_uri_parse_with_bad_string_encoding, "/uri/test_uri_parse_with_bad_string_encoding"); + p11_test (test_uri_parse_with_bad_hex_encoding, "/uri/test_uri_parse_with_bad_hex_encoding"); + p11_test (test_uri_parse_with_token, "/uri/test_uri_parse_with_token"); + p11_test (test_uri_parse_with_token_bad_encoding, "/uri/test_uri_parse_with_token_bad_encoding"); + p11_test (test_uri_parse_with_bad_syntax, "/uri/test_uri_parse_with_bad_syntax"); + p11_test (test_uri_parse_with_spaces, "/uri/test_uri_parse_with_spaces"); + p11_test (test_uri_parse_with_library, "/uri/test_uri_parse_with_library"); + p11_test (test_uri_parse_with_library_bad_encoding, "/uri/test_uri_parse_with_library_bad_encoding"); + p11_test (test_uri_build_empty, "/uri/test_uri_build_empty"); + p11_test (test_uri_build_with_token_info, "/uri/test_uri_build_with_token_info"); + p11_test (test_uri_build_with_token_null_info, "/uri/test_uri_build_with_token_null_info"); + p11_test (test_uri_build_with_token_empty_info, "/uri/test_uri_build_with_token_empty_info"); + p11_test (test_uri_build_with_attributes, "/uri/test_uri_build_with_attributes"); + p11_test (test_uri_parse_private_key, "/uri/test_uri_parse_private_key"); + p11_test (test_uri_parse_secret_key, "/uri/test_uri_parse_secret_key"); + p11_test (test_uri_parse_library_version, "/uri/test_uri_parse_library_version"); + p11_test (test_uri_parse_parse_unknown_object_type, "/uri/test_uri_parse_parse_unknown_object_type"); + p11_test (test_uri_parse_unrecognized, "/uri/test_uri_parse_unrecognized"); + p11_test (test_uri_parse_too_long_is_unrecognized, "/uri/test_uri_parse_too_long_is_unrecognized"); + p11_test (test_uri_build_object_type_cert, "/uri/test_uri_build_object_type_cert"); + p11_test (test_uri_build_object_type_private, "/uri/test_uri_build_object_type_private"); + p11_test (test_uri_build_object_type_public, "/uri/test_uri_build_object_type_public"); + p11_test (test_uri_build_object_type_secret, "/uri/test_uri_build_object_type_secret"); + p11_test (test_uri_build_with_library, "/uri/test_uri_build_with_library"); + p11_test (test_uri_build_library_version, "/uri/test_uri_build_library_version"); + p11_test (test_uri_get_set_unrecognized, "/uri/test_uri_get_set_unrecognized"); + p11_test (test_uri_match_token, "/uri/test_uri_match_token"); + p11_test (test_uri_match_module, "/uri/test_uri_match_module"); + p11_test (test_uri_match_version, "/uri/test_uri_match_version"); + p11_test (test_uri_match_attributes, "/uri/test_uri_match_attributes"); + p11_test (test_uri_get_set_attribute, "/uri/test_uri_get_set_attribute"); + p11_test (test_uri_get_set_attributes, "/uri/test_uri_get_set_attributes"); + p11_test (test_uri_pin_source, "/uri/test_uri_pin_source"); + p11_test (test_uri_free_null, "/uri/test_uri_free_null"); + p11_test (test_uri_message, "/uri/test_uri_message"); + + return p11_test_run (argc, argv); } diff --git a/p11-kit/tests/test-virtual.c b/p11-kit/tests/test-virtual.c new file mode 100644 index 0000000..73777d3 --- /dev/null +++ b/p11-kit/tests/test-virtual.c @@ -0,0 +1,171 @@ +/* + * Copyright (c) 2012 Stefan Walter + * Copyright (c) 2012 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> + */ + +#include "config.h" + +#include "library.h" +#include "p11-kit.h" +#include "private.h" +#include "virtual.h" + +#include "test.h" + +#include "mock.h" + +#include <sys/types.h> +#include <assert.h> +#include <string.h> +#include <stdio.h> +#include <stdlib.h> + +/* + * test-managed.c is a pretty good test of the closure code, so we + * just test a few things here. + */ + +typedef struct { + p11_virtual virt; + void *check; +} Override; + +static CK_RV +override_initialize (CK_X_FUNCTION_LIST *self, + CK_VOID_PTR args) +{ + Override *over = (Override *)self; + + assert_str_eq ("initialize-arg", args); + assert_str_eq ("overide-arg", over->check); + + /* An arbitrary error code to check */ + return CKR_NEED_TO_CREATE_THREADS; +} + +static bool test_destroyed = false; + +static void +test_destroyer (void *data) +{ + assert (data == &mock_x_module_no_slots); + assert (test_destroyed == false); + test_destroyed = true; +} + +static void +test_initialize (void) +{ + CK_FUNCTION_LIST_PTR module; + Override over = { }; + CK_RV rv; + + p11_virtual_init (&over.virt, &p11_virtual_stack, &mock_x_module_no_slots, test_destroyer); + over.virt.funcs.C_Initialize = override_initialize; + over.check = "overide-arg"; + test_destroyed = false; + + module = p11_virtual_wrap (&over.virt, (p11_destroyer)p11_virtual_uninit); + assert_ptr_not_null (module); + + rv = (module->C_Initialize) ("initialize-arg"); + assert_num_eq (CKR_NEED_TO_CREATE_THREADS, rv); + + p11_virtual_unwrap (module); + assert_num_eq (true, test_destroyed); +} + +static void +test_fall_through (void) +{ + CK_FUNCTION_LIST_PTR module; + Override over = { }; + p11_virtual base; + CK_RV rv; + + p11_virtual_init (&base, &p11_virtual_base, &mock_module_no_slots, NULL); + p11_virtual_init (&over.virt, &p11_virtual_stack, &base, NULL); + over.virt.funcs.C_Initialize = override_initialize; + over.check = "overide-arg"; + + module = p11_virtual_wrap (&over.virt, NULL); + assert_ptr_not_null (module); + + rv = (module->C_Initialize) ("initialize-arg"); + assert_num_eq (CKR_NEED_TO_CREATE_THREADS, rv); + + /* All other functiosn should have just fallen through */ + assert_ptr_eq (mock_module_no_slots.C_Finalize, module->C_Finalize); + + p11_virtual_unwrap (module); +} + +static void +test_get_function_list (void) +{ + CK_FUNCTION_LIST_PTR module; + CK_FUNCTION_LIST_PTR list; + p11_virtual virt; + CK_RV rv; + + p11_virtual_init (&virt, &p11_virtual_base, &mock_x_module_no_slots, NULL); + module = p11_virtual_wrap (&virt, NULL); + assert_ptr_not_null (module); + + rv = (module->C_GetFunctionList) (&list); + assert_num_eq (CKR_OK, rv); + assert_ptr_eq (module, list); + + rv = (module->C_GetFunctionList) (&list); + assert_num_eq (CKR_OK, rv); + + rv = (module->C_GetFunctionList) (NULL); + assert_num_eq (CKR_ARGUMENTS_BAD, rv); + + p11_virtual_unwrap (module); +} + +int +main (int argc, + char *argv[]) +{ + 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"); + + return p11_test_run (argc, argv); +} diff --git a/p11-kit/uri.c b/p11-kit/uri.c index a811b92..df069f4 100644 --- a/p11-kit/uri.c +++ b/p11-kit/uri.c @@ -625,6 +625,18 @@ p11_kit_uri_new (void) return uri; } +static void +format_name_equals (p11_buffer *buffer, + bool *is_first, + const char *name) +{ + if (!*is_first) + p11_buffer_add (buffer, ";", 1); + p11_buffer_add (buffer, name, -1); + p11_buffer_add (buffer, "=", 1); + *is_first = false; +} + static bool format_raw_string (p11_buffer *buffer, bool *is_first, @@ -635,12 +647,8 @@ format_raw_string (p11_buffer *buffer, if (!value) return true; - if (!*is_first) - p11_buffer_add (buffer, ";", 1); - p11_buffer_add (buffer, name, -1); - p11_buffer_add (buffer, "=", 1); + format_name_equals (buffer, is_first, name); p11_buffer_add (buffer, value, -1); - *is_first = false; return p11_buffer_ok (buffer); } @@ -653,16 +661,14 @@ format_encode_string (p11_buffer *buffer, size_t n_value, bool force) { - char *encoded; - bool ret; + /* Not set */ + if (!value) + return true; - encoded = p11_url_encode (value, value + n_value, - force ? "" : P11_URL_VERBATIM, NULL); - return_val_if_fail (encoded != NULL, false); + format_name_equals (buffer, is_first, name); + p11_url_encode (value, value + n_value, force ? "" : P11_URL_VERBATIM, buffer); - ret = format_raw_string (buffer, is_first, name, encoded); - free (encoded); - return ret; + return p11_buffer_ok (buffer); } diff --git a/p11-kit/util.c b/p11-kit/util.c index c4e5636..14c24f6 100644 --- a/p11-kit/util.c +++ b/p11-kit/util.c @@ -44,6 +44,7 @@ #include "message.h" #include "p11-kit.h" #include "private.h" +#include "proxy.h" #include <assert.h> #include <stdarg.h> @@ -258,6 +259,7 @@ __attribute__((destructor)) void _p11_kit_fini (void) { + p11_proxy_module_cleanup (); p11_library_uninit (); } @@ -280,6 +282,7 @@ DllMain (HINSTANCE instance, p11_library_thread_cleanup (); break; case DLL_PROCESS_DETACH: + p11_proxy_module_cleanup (); p11_library_uninit (); break; default: diff --git a/p11-kit/virtual.c b/p11-kit/virtual.c new file mode 100644 index 0000000..104ece0 --- /dev/null +++ b/p11-kit/virtual.c @@ -0,0 +1,2964 @@ +/* + * Copyright (C) 2008 Stefan Walter + * Copyright (C) 2012 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 <stefw@gnome.org> + */ + +#include "config.h" + +#include "compat.h" +#define P11_DEBUG_FLAG P11_DEBUG_LIB +#include "debug.h" +#include "library.h" +#include "virtual.h" + +#include <assert.h> +#include <stdarg.h> +#include <stdlib.h> +#include <string.h> + +#ifdef WITH_FFI + +/* + * We use libffi to build closures. Note that even with libffi certain + * platforms do not support using ffi_closure. In this case FFI_CLOSURES will + * not be defined. This is checked in configure.ac + */ + +#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 */ +#define MAX_FUNCTIONS 66 +#define MAX_ARGS 10 + +typedef struct { + /* This is first so we can cast between CK_FUNCTION_LIST* and Context* */ + CK_FUNCTION_LIST bound; + + /* The PKCS#11 functions to call into */ + p11_virtual *virt; + p11_destroyer destroyer; + + /* 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; +} Wrapper; + +static CK_RV +short_C_GetFunctionStatus (CK_SESSION_HANDLE handle) +{ + return CKR_FUNCTION_NOT_PARALLEL; +} + +static CK_RV +short_C_CancelFunction (CK_SESSION_HANDLE handle) +{ + return CKR_FUNCTION_NOT_PARALLEL; +} + +static void +binding_C_GetFunctionList (ffi_cif *cif, + CK_RV *ret, + void* args[], + Wrapper *wrapper) +{ + CK_FUNCTION_LIST_PTR_PTR list = *(CK_FUNCTION_LIST_PTR_PTR *)args[0]; + + if (list == NULL) { + *ret = CKR_ARGUMENTS_BAD; + } else { + *list = &wrapper->bound; + *ret = CKR_OK; + } +} + +static void +binding_C_Initialize (ffi_cif *cif, + CK_RV *ret, + void* args[], + CK_X_FUNCTION_LIST *funcs) +{ + *ret = funcs->C_Initialize (funcs, + *(CK_VOID_PTR *)args[0]); +} + +static void +binding_C_Finalize (ffi_cif *cif, + CK_RV *ret, + void* args[], + CK_X_FUNCTION_LIST *funcs) +{ + *ret = funcs->C_Finalize (funcs, + *(CK_VOID_PTR *)args[0]); +} + +static void +binding_C_GetInfo (ffi_cif *cif, + CK_RV *ret, + void* args[], + CK_X_FUNCTION_LIST *funcs) +{ + *ret = funcs->C_GetInfo (funcs, + *(CK_INFO_PTR *)args[0]); +} + +static void +binding_C_GetSlotList (ffi_cif *cif, + CK_RV *ret, + void* args[], + CK_X_FUNCTION_LIST *funcs) +{ + *ret = funcs->C_GetSlotList (funcs, + *(CK_BBOOL *)args[0], + *(CK_SLOT_ID_PTR *)args[1], + *(CK_ULONG_PTR *)args[2]); +} + +static void +binding_C_GetSlotInfo (ffi_cif *cif, + CK_RV *ret, + void* args[], + CK_X_FUNCTION_LIST *funcs) +{ + *ret = funcs->C_GetSlotInfo (funcs, + *(CK_SLOT_ID *)args[0], + *(CK_SLOT_INFO_PTR *)args[1]); +} + +static void +binding_C_GetTokenInfo (ffi_cif *cif, + CK_RV *ret, + void* args[], + CK_X_FUNCTION_LIST *funcs) +{ + *ret = funcs->C_GetTokenInfo (funcs, + *(CK_SLOT_ID *)args[0], + *(CK_TOKEN_INFO_PTR *)args[1]); +} + +static void +binding_C_WaitForSlotEvent (ffi_cif *cif, + CK_RV *ret, + void* args[], + CK_X_FUNCTION_LIST *funcs) +{ + *ret = funcs->C_WaitForSlotEvent (funcs, + *(CK_FLAGS *)args[0], + *(CK_SLOT_ID_PTR *)args[1], + *(CK_VOID_PTR *)args[2]); +} + +static void +binding_C_GetMechanismList (ffi_cif *cif, + CK_RV *ret, + void* args[], + CK_X_FUNCTION_LIST *funcs) +{ + *ret = funcs->C_GetMechanismList (funcs, + *(CK_SLOT_ID *)args[0], + *(CK_MECHANISM_TYPE_PTR *)args[1], + *(CK_ULONG_PTR *)args[2]); +} + +static void +binding_C_GetMechanismInfo (ffi_cif *cif, + CK_RV *ret, + void* args[], + CK_X_FUNCTION_LIST *funcs) +{ + *ret = funcs->C_GetMechanismInfo (funcs, + *(CK_SLOT_ID *)args[0], + *(CK_MECHANISM_TYPE *)args[1], + *(CK_MECHANISM_INFO_PTR *)args[2]); +} + +static void +binding_C_InitToken (ffi_cif *cif, + CK_RV *ret, + void* args[], + CK_X_FUNCTION_LIST *funcs) +{ + *ret = funcs->C_InitToken (funcs, + *(CK_SLOT_ID *)args[0], + *(CK_BYTE_PTR *)args[1], + *(CK_ULONG *)args[2], + *(CK_BYTE_PTR *)args[3]); +} + +static void +binding_C_InitPIN (ffi_cif *cif, + CK_RV *ret, + void* args[], + CK_X_FUNCTION_LIST *funcs) +{ + *ret = funcs->C_InitPIN (funcs, + *(CK_SESSION_HANDLE *)args[0], + *(CK_BYTE_PTR *)args[1], + *(CK_ULONG *)args[2]); +} + +static void +binding_C_SetPIN (ffi_cif *cif, + CK_RV *ret, + void* args[], + CK_X_FUNCTION_LIST *funcs) +{ + *ret = funcs->C_SetPIN (funcs, + *(CK_SESSION_HANDLE *)args[0], + *(CK_BYTE_PTR *)args[1], + *(CK_ULONG *)args[2], + *(CK_BYTE_PTR *)args[3], + *(CK_ULONG *)args[4]); +} + +static void +binding_C_OpenSession (ffi_cif *cif, + CK_RV *ret, + void* args[], + CK_X_FUNCTION_LIST *funcs) +{ + *ret = funcs->C_OpenSession (funcs, + *(CK_SLOT_ID *)args[0], + *(CK_FLAGS *)args[1], + *(CK_VOID_PTR *)args[2], + *(CK_NOTIFY *)args[3], + *(CK_SESSION_HANDLE_PTR *)args[4]); +} + +static void +binding_C_CloseSession (ffi_cif *cif, + CK_RV *ret, + void* args[], + CK_X_FUNCTION_LIST *funcs) +{ + *ret = funcs->C_CloseSession (funcs, + *(CK_SESSION_HANDLE *)args[0]); +} + +static void +binding_C_CloseAllSessions (ffi_cif *cif, + CK_RV *ret, + void* args[], + CK_X_FUNCTION_LIST *funcs) +{ + *ret = funcs->C_CloseAllSessions (funcs, + *(CK_SLOT_ID *)args[0]); +} + +static void +binding_C_GetSessionInfo (ffi_cif *cif, + CK_RV *ret, + void* args[], + CK_X_FUNCTION_LIST *funcs) +{ + *ret = funcs->C_GetSessionInfo (funcs, + *(CK_SESSION_HANDLE *)args[0], + *(CK_SESSION_INFO_PTR *)args[1]); +} + +static void +binding_C_GetOperationState (ffi_cif *cif, + CK_RV *ret, + void* args[], + CK_X_FUNCTION_LIST *funcs) +{ + *ret = funcs->C_GetOperationState (funcs, + *(CK_SESSION_HANDLE *)args[0], + *(CK_BYTE_PTR *)args[1], + *(CK_ULONG_PTR *)args[2]); +} + +static void +binding_C_SetOperationState (ffi_cif *cif, + CK_RV *ret, + void* args[], + CK_X_FUNCTION_LIST *funcs) +{ + *ret = funcs->C_SetOperationState (funcs, + *(CK_SESSION_HANDLE *)args[0], + *(CK_BYTE_PTR *)args[1], + *(CK_ULONG *)args[2], + *(CK_OBJECT_HANDLE *)args[3], + *(CK_OBJECT_HANDLE *)args[4]); +} + +static void +binding_C_Login (ffi_cif *cif, + CK_RV *ret, + void* args[], + CK_X_FUNCTION_LIST *funcs) +{ + *ret = funcs->C_Login (funcs, + *(CK_SESSION_HANDLE *)args[0], + *(CK_USER_TYPE *)args[1], + *(CK_BYTE_PTR *)args[2], + *(CK_ULONG *)args[3]); +} + +static void +binding_C_Logout (ffi_cif *cif, + CK_RV *ret, + void* args[], + CK_X_FUNCTION_LIST *funcs) +{ + *ret = funcs->C_Logout (funcs, + *(CK_SESSION_HANDLE *)args[0]); +} + +static void +binding_C_CreateObject (ffi_cif *cif, + CK_RV *ret, + void* args[], + CK_X_FUNCTION_LIST *funcs) +{ + *ret = funcs->C_CreateObject (funcs, + *(CK_SESSION_HANDLE *)args[0], + *(CK_ATTRIBUTE_PTR *)args[1], + *(CK_ULONG *)args[2], + *(CK_OBJECT_HANDLE_PTR *)args[3]); +} + +static void +binding_C_CopyObject (ffi_cif *cif, + CK_RV *ret, + void* args[], + CK_X_FUNCTION_LIST *funcs) +{ + *ret = funcs->C_CopyObject (funcs, + *(CK_SESSION_HANDLE *)args[0], + *(CK_OBJECT_HANDLE *)args[1], + *(CK_ATTRIBUTE_PTR *)args[2], + *(CK_ULONG *)args[3], + *(CK_OBJECT_HANDLE_PTR *)args[4]); +} + +static void +binding_C_DestroyObject (ffi_cif *cif, + CK_RV *ret, + void* args[], + CK_X_FUNCTION_LIST *funcs) +{ + *ret = funcs->C_DestroyObject (funcs, + *(CK_SESSION_HANDLE *)args[0], + *(CK_OBJECT_HANDLE *)args[1]); +} + +static void +binding_C_GetObjectSize (ffi_cif *cif, + CK_RV *ret, + void* args[], + CK_X_FUNCTION_LIST *funcs) +{ + *ret = funcs->C_GetObjectSize (funcs, + *(CK_SESSION_HANDLE *)args[0], + *(CK_OBJECT_HANDLE *)args[1], + *(CK_ULONG_PTR *)args[2]); +} + +static void +binding_C_GetAttributeValue (ffi_cif *cif, + CK_RV *ret, + void* args[], + CK_X_FUNCTION_LIST *funcs) +{ + *ret = funcs->C_GetAttributeValue (funcs, + *(CK_SESSION_HANDLE *)args[0], + *(CK_OBJECT_HANDLE *)args[1], + *(CK_ATTRIBUTE_PTR *)args[2], + *(CK_ULONG *)args[3]); +} + +static void +binding_C_SetAttributeValue (ffi_cif *cif, + CK_RV *ret, + void* args[], + CK_X_FUNCTION_LIST *funcs) +{ + *ret = funcs->C_SetAttributeValue (funcs, + *(CK_SESSION_HANDLE *)args[0], + *(CK_OBJECT_HANDLE *)args[1], + *(CK_ATTRIBUTE_PTR *)args[2], + *(CK_ULONG *)args[3]); +} + +static void +binding_C_FindObjectsInit (ffi_cif *cif, + CK_RV *ret, + void* args[], + CK_X_FUNCTION_LIST *funcs) +{ + *ret = funcs->C_FindObjectsInit (funcs, + *(CK_SESSION_HANDLE *)args[0], + *(CK_ATTRIBUTE_PTR *)args[1], + *(CK_ULONG *)args[2]); +} + +static void +binding_C_FindObjects (ffi_cif *cif, + CK_RV *ret, + void* args[], + CK_X_FUNCTION_LIST *funcs) +{ + *ret = funcs->C_FindObjects (funcs, + *(CK_SESSION_HANDLE *)args[0], + *(CK_OBJECT_HANDLE_PTR *)args[1], + *(CK_ULONG *)args[2], + *(CK_ULONG_PTR *)args[3]); +} + +static void +binding_C_FindObjectsFinal (ffi_cif *cif, + CK_RV *ret, + void* args[], + CK_X_FUNCTION_LIST *funcs) +{ + *ret = funcs->C_FindObjectsFinal (funcs, + *(CK_SESSION_HANDLE *)args[0]); +} + +static void +binding_C_EncryptInit (ffi_cif *cif, + CK_RV *ret, + void* args[], + CK_X_FUNCTION_LIST *funcs) +{ + *ret = funcs->C_EncryptInit (funcs, + *(CK_SESSION_HANDLE *)args[0], + *(CK_MECHANISM_PTR *)args[1], + *(CK_OBJECT_HANDLE *)args[2]); +} + +static void +binding_C_Encrypt (ffi_cif *cif, + CK_RV *ret, + void* args[], + CK_X_FUNCTION_LIST *funcs) +{ + *ret = funcs->C_Encrypt (funcs, + *(CK_SESSION_HANDLE *)args[0], + *(CK_BYTE_PTR *)args[1], + *(CK_ULONG *)args[2], + *(CK_BYTE_PTR *)args[3], + *(CK_ULONG_PTR *)args[4]); +} + +static void +binding_C_EncryptUpdate (ffi_cif *cif, + CK_RV *ret, + void* args[], + CK_X_FUNCTION_LIST *funcs) +{ + *ret = funcs->C_EncryptUpdate (funcs, + *(CK_SESSION_HANDLE *)args[0], + *(CK_BYTE_PTR *)args[1], + *(CK_ULONG *)args[2], + *(CK_BYTE_PTR *)args[3], + *(CK_ULONG_PTR *)args[4]); +} + +static void +binding_C_EncryptFinal (ffi_cif *cif, + CK_RV *ret, + void* args[], + CK_X_FUNCTION_LIST *funcs) +{ + *ret = funcs->C_EncryptFinal (funcs, + *(CK_SESSION_HANDLE *)args[0], + *(CK_BYTE_PTR *)args[1], + *(CK_ULONG_PTR *)args[2]); +} + +static void +binding_C_DecryptInit (ffi_cif *cif, + CK_RV *ret, + void* args[], + CK_X_FUNCTION_LIST *funcs) +{ + *ret = funcs->C_DecryptInit (funcs, + *(CK_SESSION_HANDLE *)args[0], + *(CK_MECHANISM_PTR *)args[1], + *(CK_OBJECT_HANDLE *)args[2]); +} + +static void +binding_C_Decrypt (ffi_cif *cif, + CK_RV *ret, + void* args[], + CK_X_FUNCTION_LIST *funcs) +{ + *ret = funcs->C_Decrypt (funcs, + *(CK_SESSION_HANDLE *)args[0], + *(CK_BYTE_PTR *)args[1], + *(CK_ULONG *)args[2], + *(CK_BYTE_PTR *)args[3], + *(CK_ULONG_PTR *)args[4]); +} + +static void +binding_C_DecryptUpdate (ffi_cif *cif, + CK_RV *ret, + void* args[], + CK_X_FUNCTION_LIST *funcs) +{ + *ret = funcs->C_DecryptUpdate (funcs, + *(CK_SESSION_HANDLE *)args[0], + *(CK_BYTE_PTR *)args[1], + *(CK_ULONG *)args[2], + *(CK_BYTE_PTR *)args[3], + *(CK_ULONG_PTR *)args[4]); +} + +static void +binding_C_DecryptFinal (ffi_cif *cif, + CK_RV *ret, + void* args[], + CK_X_FUNCTION_LIST *funcs) +{ + *ret = funcs->C_DecryptFinal (funcs, + *(CK_SESSION_HANDLE *)args[0], + *(CK_BYTE_PTR *)args[1], + *(CK_ULONG_PTR *)args[2]); +} + +static void +binding_C_DigestInit (ffi_cif *cif, + CK_RV *ret, + void* args[], + CK_X_FUNCTION_LIST *funcs) +{ + *ret = funcs->C_DigestInit (funcs, + *(CK_SESSION_HANDLE *)args[0], + *(CK_MECHANISM_PTR *)args[1]); +} + +static void +binding_C_Digest (ffi_cif *cif, + CK_RV *ret, + void* args[], + CK_X_FUNCTION_LIST *funcs) +{ + *ret = funcs->C_Digest (funcs, + *(CK_SESSION_HANDLE *)args[0], + *(CK_BYTE_PTR *)args[1], + *(CK_ULONG *)args[2], + *(CK_BYTE_PTR *)args[3], + *(CK_ULONG_PTR *)args[4]); +} + +static void +binding_C_DigestUpdate (ffi_cif *cif, + CK_RV *ret, + void* args[], + CK_X_FUNCTION_LIST *funcs) +{ + *ret = funcs->C_DigestUpdate (funcs, + *(CK_SESSION_HANDLE *)args[0], + *(CK_BYTE_PTR *)args[1], + *(CK_ULONG *)args[2]); +} + +static void +binding_C_DigestKey (ffi_cif *cif, + CK_RV *ret, + void* args[], + CK_X_FUNCTION_LIST *funcs) +{ + *ret = funcs->C_DigestKey (funcs, + *(CK_SESSION_HANDLE *)args[0], + *(CK_OBJECT_HANDLE *)args[1]); +} + +static void +binding_C_DigestFinal (ffi_cif *cif, + CK_RV *ret, + void* args[], + CK_X_FUNCTION_LIST *funcs) +{ + *ret = funcs->C_DigestFinal (funcs, + *(CK_SESSION_HANDLE *)args[0], + *(CK_BYTE_PTR *)args[1], + *(CK_ULONG_PTR *)args[2]); +} + +static void +binding_C_SignInit (ffi_cif *cif, + CK_RV *ret, + void* args[], + CK_X_FUNCTION_LIST *funcs) +{ + *ret = funcs->C_SignInit (funcs, + *(CK_SESSION_HANDLE *)args[0], + *(CK_MECHANISM_PTR *)args[1], + *(CK_OBJECT_HANDLE *)args[2]); +} + +static void +binding_C_Sign (ffi_cif *cif, + CK_RV *ret, + void* args[], + CK_X_FUNCTION_LIST *funcs) +{ + *ret = funcs->C_Sign (funcs, + *(CK_SESSION_HANDLE *)args[0], + *(CK_BYTE_PTR *)args[1], + *(CK_ULONG *)args[2], + *(CK_BYTE_PTR *)args[3], + *(CK_ULONG_PTR *)args[4]); +} + +static void +binding_C_SignUpdate (ffi_cif *cif, + CK_RV *ret, + void* args[], + CK_X_FUNCTION_LIST *funcs) +{ + *ret = funcs->C_SignUpdate (funcs, + *(CK_SESSION_HANDLE *)args[0], + *(CK_BYTE_PTR *)args[1], + *(CK_ULONG *)args[2]); +} + +static void +binding_C_SignFinal (ffi_cif *cif, + CK_RV *ret, + void* args[], + CK_X_FUNCTION_LIST *funcs) +{ + *ret = funcs->C_SignFinal (funcs, + *(CK_SESSION_HANDLE *)args[0], + *(CK_BYTE_PTR *)args[1], + *(CK_ULONG_PTR *)args[2]); +} + +static void +binding_C_SignRecoverInit (ffi_cif *cif, + CK_RV *ret, + void* args[], + CK_X_FUNCTION_LIST *funcs) +{ + *ret = funcs->C_SignRecoverInit (funcs, + *(CK_SESSION_HANDLE *)args[0], + *(CK_MECHANISM_PTR *)args[1], + *(CK_OBJECT_HANDLE *)args[2]); +} + +static void +binding_C_SignRecover (ffi_cif *cif, + CK_RV *ret, + void* args[], + CK_X_FUNCTION_LIST *funcs) +{ + *ret = funcs->C_SignRecover (funcs, + *(CK_SESSION_HANDLE *)args[0], + *(CK_BYTE_PTR *)args[1], + *(CK_ULONG *)args[2], + *(CK_BYTE_PTR *)args[3], + *(CK_ULONG_PTR *)args[4]); +} + +static void +binding_C_VerifyInit (ffi_cif *cif, + CK_RV *ret, + void* args[], + CK_X_FUNCTION_LIST *funcs) +{ + *ret = funcs->C_VerifyInit (funcs, + *(CK_SESSION_HANDLE *)args[0], + *(CK_MECHANISM_PTR *)args[1], + *(CK_OBJECT_HANDLE *)args[2]); +} + +static void +binding_C_Verify (ffi_cif *cif, + CK_RV *ret, + void* args[], + CK_X_FUNCTION_LIST *funcs) +{ + *ret = funcs->C_Verify (funcs, + *(CK_SESSION_HANDLE *)args[0], + *(CK_BYTE_PTR *)args[1], + *(CK_ULONG *)args[2], + *(CK_BYTE_PTR *)args[3], + *(CK_ULONG *)args[4]); +} + +static void +binding_C_VerifyUpdate (ffi_cif *cif, + CK_RV *ret, + void* args[], + CK_X_FUNCTION_LIST *funcs) +{ + *ret = funcs->C_VerifyUpdate (funcs, + *(CK_SESSION_HANDLE *)args[0], + *(CK_BYTE_PTR *)args[1], + *(CK_ULONG *)args[2]); +} + +static void +binding_C_VerifyFinal (ffi_cif *cif, + CK_RV *ret, + void* args[], + CK_X_FUNCTION_LIST *funcs) +{ + *ret = funcs->C_VerifyFinal (funcs, + *(CK_SESSION_HANDLE *)args[0], + *(CK_BYTE_PTR *)args[1], + *(CK_ULONG *)args[2]); +} + +static void +binding_C_VerifyRecoverInit (ffi_cif *cif, + CK_RV *ret, + void* args[], + CK_X_FUNCTION_LIST *funcs) +{ + *ret = funcs->C_VerifyRecoverInit (funcs, + *(CK_SESSION_HANDLE *)args[0], + *(CK_MECHANISM_PTR *)args[1], + *(CK_OBJECT_HANDLE *)args[2]); +} + +static void +binding_C_VerifyRecover (ffi_cif *cif, + CK_RV *ret, + void* args[], + CK_X_FUNCTION_LIST *funcs) +{ + *ret = funcs->C_VerifyRecover (funcs, + *(CK_SESSION_HANDLE *)args[0], + *(CK_BYTE_PTR *)args[1], + *(CK_ULONG *)args[2], + *(CK_BYTE_PTR *)args[3], + *(CK_ULONG_PTR *)args[4]); +} + +static void +binding_C_DigestEncryptUpdate (ffi_cif *cif, + CK_RV *ret, + void* args[], + CK_X_FUNCTION_LIST *funcs) +{ + *ret = funcs->C_DigestEncryptUpdate (funcs, + *(CK_SESSION_HANDLE *)args[0], + *(CK_BYTE_PTR *)args[1], + *(CK_ULONG *)args[2], + *(CK_BYTE_PTR *)args[3], + *(CK_ULONG_PTR *)args[4]); +} + +static void +binding_C_DecryptDigestUpdate (ffi_cif *cif, + CK_RV *ret, + void* args[], + CK_X_FUNCTION_LIST *funcs) +{ + *ret = funcs->C_DecryptDigestUpdate (funcs, + *(CK_SESSION_HANDLE *)args[0], + *(CK_BYTE_PTR *)args[1], + *(CK_ULONG *)args[2], + *(CK_BYTE_PTR *)args[3], + *(CK_ULONG_PTR *)args[4]); +} + +static void +binding_C_SignEncryptUpdate (ffi_cif *cif, + CK_RV *ret, + void* args[], + CK_X_FUNCTION_LIST *funcs) +{ + *ret = funcs->C_SignEncryptUpdate (funcs, + *(CK_SESSION_HANDLE *)args[0], + *(CK_BYTE_PTR *)args[1], + *(CK_ULONG *)args[2], + *(CK_BYTE_PTR *)args[3], + *(CK_ULONG_PTR *)args[4]); +} + +static void +binding_C_DecryptVerifyUpdate (ffi_cif *cif, + CK_RV *ret, + void* args[], + CK_X_FUNCTION_LIST *funcs) +{ + *ret = funcs->C_DecryptVerifyUpdate (funcs, + *(CK_SESSION_HANDLE *)args[0], + *(CK_BYTE_PTR *)args[1], + *(CK_ULONG *)args[2], + *(CK_BYTE_PTR *)args[3], + *(CK_ULONG_PTR *)args[4]); +} + +static void +binding_C_GenerateKey (ffi_cif *cif, + CK_RV *ret, + void* args[], + CK_X_FUNCTION_LIST *funcs) +{ + *ret = funcs->C_GenerateKey (funcs, + *(CK_SESSION_HANDLE *)args[0], + *(CK_MECHANISM_PTR *)args[1], + *(CK_ATTRIBUTE_PTR *)args[2], + *(CK_ULONG *)args[3], + *(CK_OBJECT_HANDLE_PTR *)args[4]); +} + +static void +binding_C_GenerateKeyPair (ffi_cif *cif, + CK_RV *ret, + void* args[], + CK_X_FUNCTION_LIST *funcs) +{ + *ret = funcs->C_GenerateKeyPair (funcs, + *(CK_SESSION_HANDLE *)args[0], + *(CK_MECHANISM_PTR *)args[1], + *(CK_ATTRIBUTE_PTR *)args[2], + *(CK_ULONG *)args[3], + *(CK_ATTRIBUTE_PTR *)args[4], + *(CK_ULONG *)args[5], + *(CK_OBJECT_HANDLE_PTR *)args[6], + *(CK_OBJECT_HANDLE_PTR *)args[7]); +} + +static void +binding_C_WrapKey (ffi_cif *cif, + CK_RV *ret, + void* args[], + CK_X_FUNCTION_LIST *funcs) +{ + *ret = funcs->C_WrapKey (funcs, + *(CK_SESSION_HANDLE *)args[0], + *(CK_MECHANISM_PTR *)args[1], + *(CK_OBJECT_HANDLE *)args[2], + *(CK_OBJECT_HANDLE *)args[3], + *(CK_BYTE_PTR *)args[4], + *(CK_ULONG_PTR *)args[5]); +} + +static void +binding_C_UnwrapKey (ffi_cif *cif, + CK_RV *ret, + void* args[], + CK_X_FUNCTION_LIST *funcs) +{ + *ret = funcs->C_UnwrapKey (funcs, + *(CK_SESSION_HANDLE *)args[0], + *(CK_MECHANISM_PTR *)args[1], + *(CK_OBJECT_HANDLE *)args[2], + *(CK_BYTE_PTR *)args[3], + *(CK_ULONG *)args[4], + *(CK_ATTRIBUTE_PTR *)args[5], + *(CK_ULONG *)args[6], + *(CK_OBJECT_HANDLE_PTR *)args[7]); +} + +static void +binding_C_DeriveKey (ffi_cif *cif, + CK_RV *ret, + void* args[], + CK_X_FUNCTION_LIST *funcs) +{ + *ret = funcs->C_DeriveKey (funcs, + *(CK_SESSION_HANDLE *)args[0], + *(CK_MECHANISM_PTR *)args[1], + *(CK_OBJECT_HANDLE *)args[2], + *(CK_ATTRIBUTE_PTR *)args[3], + *(CK_ULONG *)args[4], + *(CK_OBJECT_HANDLE_PTR *)args[5]); +} + +static void +binding_C_SeedRandom (ffi_cif *cif, + CK_RV *ret, + void* args[], + CK_X_FUNCTION_LIST *funcs) +{ + *ret = funcs->C_SeedRandom (funcs, + *(CK_SESSION_HANDLE *)args[0], + *(CK_BYTE_PTR *)args[1], + *(CK_ULONG *)args[2]); +} + +static void +binding_C_GenerateRandom (ffi_cif *cif, + CK_RV *ret, + void* args[], + CK_X_FUNCTION_LIST *funcs) +{ + *ret = funcs->C_GenerateRandom (funcs, + *(CK_SESSION_HANDLE *)args[0], + *(CK_BYTE_PTR *)args[1], + *(CK_ULONG *)args[2]); +} + +#endif /* WITH_FFI */ + +static CK_RV +stack_C_Initialize (CK_X_FUNCTION_LIST *self, + CK_VOID_PTR init_args) +{ + p11_virtual *virt = (p11_virtual *)self; + CK_X_FUNCTION_LIST *funcs = virt->lower_module; + return funcs->C_Initialize (funcs, init_args); +} + +static CK_RV +stack_C_Finalize (CK_X_FUNCTION_LIST *self, + CK_VOID_PTR reserved) +{ + p11_virtual *virt = (p11_virtual *)self; + CK_X_FUNCTION_LIST *funcs = virt->lower_module; + return funcs->C_Finalize (funcs, reserved); +} + +static CK_RV +stack_C_GetInfo (CK_X_FUNCTION_LIST *self, + CK_INFO_PTR info) +{ + p11_virtual *virt = (p11_virtual *)self; + CK_X_FUNCTION_LIST *funcs = virt->lower_module; + return funcs->C_GetInfo (funcs, info); +} + +static CK_RV +stack_C_GetSlotList (CK_X_FUNCTION_LIST *self, + CK_BBOOL token_present, + CK_SLOT_ID_PTR slot_list, + CK_ULONG_PTR count) +{ + p11_virtual *virt = (p11_virtual *)self; + CK_X_FUNCTION_LIST *funcs = virt->lower_module; + return funcs->C_GetSlotList (funcs, token_present, slot_list, count); +} + +static CK_RV +stack_C_GetSlotInfo (CK_X_FUNCTION_LIST *self, + CK_SLOT_ID slot_id, + CK_SLOT_INFO_PTR info) +{ + p11_virtual *virt = (p11_virtual *)self; + CK_X_FUNCTION_LIST *funcs = virt->lower_module; + return funcs->C_GetSlotInfo (funcs, slot_id, info); +} + +static CK_RV +stack_C_GetTokenInfo (CK_X_FUNCTION_LIST *self, + CK_SLOT_ID slot_id, + CK_TOKEN_INFO_PTR info) +{ + p11_virtual *virt = (p11_virtual *)self; + CK_X_FUNCTION_LIST *funcs = virt->lower_module; + return funcs->C_GetTokenInfo (funcs, slot_id, info); +} + +static CK_RV +stack_C_GetMechanismList (CK_X_FUNCTION_LIST *self, + CK_SLOT_ID slot_id, + CK_MECHANISM_TYPE_PTR mechanism_list, + CK_ULONG_PTR count) +{ + p11_virtual *virt = (p11_virtual *)self; + CK_X_FUNCTION_LIST *funcs = virt->lower_module; + return funcs->C_GetMechanismList (funcs, slot_id, mechanism_list, count); +} + +static CK_RV +stack_C_GetMechanismInfo (CK_X_FUNCTION_LIST *self, + CK_SLOT_ID slot_id, + CK_MECHANISM_TYPE type, + CK_MECHANISM_INFO_PTR info) +{ + p11_virtual *virt = (p11_virtual *)self; + CK_X_FUNCTION_LIST *funcs = virt->lower_module; + return funcs->C_GetMechanismInfo (funcs, slot_id, type, info); +} + +static CK_RV +stack_C_InitToken (CK_X_FUNCTION_LIST *self, + CK_SLOT_ID slot_id, + CK_UTF8CHAR_PTR pin, + CK_ULONG pin_len, + CK_UTF8CHAR_PTR label) +{ + p11_virtual *virt = (p11_virtual *)self; + CK_X_FUNCTION_LIST *funcs = virt->lower_module; + return funcs->C_InitToken (funcs, slot_id, pin, pin_len, label); +} + +static CK_RV +stack_C_OpenSession (CK_X_FUNCTION_LIST *self, + CK_SLOT_ID slot_id, + CK_FLAGS flags, + CK_VOID_PTR application, + CK_NOTIFY notify, + CK_SESSION_HANDLE_PTR session) +{ + p11_virtual *virt = (p11_virtual *)self; + CK_X_FUNCTION_LIST *funcs = virt->lower_module; + return funcs->C_OpenSession (funcs, slot_id, flags, application, notify, session); +} + +static CK_RV +stack_C_CloseSession (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE session) +{ + p11_virtual *virt = (p11_virtual *)self; + CK_X_FUNCTION_LIST *funcs = virt->lower_module; + return funcs->C_CloseSession (funcs, session); +} + +static CK_RV +stack_C_CloseAllSessions (CK_X_FUNCTION_LIST *self, + CK_SLOT_ID slot_id) +{ + p11_virtual *virt = (p11_virtual *)self; + CK_X_FUNCTION_LIST *funcs = virt->lower_module; + return funcs->C_CloseAllSessions (funcs, slot_id); +} + +static CK_RV +stack_C_GetSessionInfo (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE session, + CK_SESSION_INFO_PTR info) +{ + p11_virtual *virt = (p11_virtual *)self; + CK_X_FUNCTION_LIST *funcs = virt->lower_module; + return funcs->C_GetSessionInfo (funcs, session, info); +} + +static CK_RV +stack_C_InitPIN (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE session, + CK_UTF8CHAR_PTR pin, + CK_ULONG pin_len) +{ + p11_virtual *virt = (p11_virtual *)self; + CK_X_FUNCTION_LIST *funcs = virt->lower_module; + return funcs->C_InitPIN (funcs, session, pin, pin_len); +} + +static CK_RV +stack_C_SetPIN (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE session, + CK_UTF8CHAR_PTR old_pin, + CK_ULONG old_len, + CK_UTF8CHAR_PTR new_pin, + CK_ULONG new_len) +{ + p11_virtual *virt = (p11_virtual *)self; + CK_X_FUNCTION_LIST *funcs = virt->lower_module; + return funcs->C_SetPIN (funcs, session, old_pin, old_len, new_pin, new_len); +} + +static CK_RV +stack_C_GetOperationState (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE session, + CK_BYTE_PTR operation_state, + CK_ULONG_PTR operation_state_len) +{ + p11_virtual *virt = (p11_virtual *)self; + CK_X_FUNCTION_LIST *funcs = virt->lower_module; + return funcs->C_GetOperationState (funcs, session, operation_state, operation_state_len); +} + +static CK_RV +stack_C_SetOperationState (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE session, + CK_BYTE_PTR operation_state, + CK_ULONG operation_state_len, + CK_OBJECT_HANDLE encryption_key, + CK_OBJECT_HANDLE authentication_key) +{ + p11_virtual *virt = (p11_virtual *)self; + CK_X_FUNCTION_LIST *funcs = virt->lower_module; + return funcs->C_SetOperationState (funcs, session, operation_state, operation_state_len, + encryption_key, authentication_key); +} + +static CK_RV +stack_C_Login (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE session, + CK_USER_TYPE user_type, + CK_UTF8CHAR_PTR pin, + CK_ULONG pin_len) +{ + p11_virtual *virt = (p11_virtual *)self; + CK_X_FUNCTION_LIST *funcs = virt->lower_module; + return funcs->C_Login (funcs, session, user_type, pin, pin_len); +} + +static CK_RV +stack_C_Logout (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE session) +{ + p11_virtual *virt = (p11_virtual *)self; + CK_X_FUNCTION_LIST *funcs = virt->lower_module; + return funcs->C_Logout (funcs, session); +} + +static CK_RV +stack_C_CreateObject (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE session, + CK_ATTRIBUTE_PTR template, + CK_ULONG count, + CK_OBJECT_HANDLE_PTR object) +{ + p11_virtual *virt = (p11_virtual *)self; + CK_X_FUNCTION_LIST *funcs = virt->lower_module; + return funcs->C_CreateObject (funcs, session, template, count, object); +} + +static CK_RV +stack_C_CopyObject (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE session, + CK_OBJECT_HANDLE object, + CK_ATTRIBUTE_PTR template, + CK_ULONG count, + CK_OBJECT_HANDLE_PTR new_object) +{ + p11_virtual *virt = (p11_virtual *)self; + CK_X_FUNCTION_LIST *funcs = virt->lower_module; + return funcs->C_CopyObject (funcs, session, object, template, count, new_object); +} + + +static CK_RV +stack_C_DestroyObject (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE session, + CK_OBJECT_HANDLE object) +{ + p11_virtual *virt = (p11_virtual *)self; + CK_X_FUNCTION_LIST *funcs = virt->lower_module; + return funcs->C_DestroyObject (funcs, session, object); +} + +static CK_RV +stack_C_GetObjectSize (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE session, + CK_OBJECT_HANDLE object, + CK_ULONG_PTR size) +{ + p11_virtual *virt = (p11_virtual *)self; + CK_X_FUNCTION_LIST *funcs = virt->lower_module; + return funcs->C_GetObjectSize (funcs, session, object, size); +} + +static CK_RV +stack_C_GetAttributeValue (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE session, + CK_OBJECT_HANDLE object, + CK_ATTRIBUTE_PTR template, + CK_ULONG count) +{ + p11_virtual *virt = (p11_virtual *)self; + CK_X_FUNCTION_LIST *funcs = virt->lower_module; + return funcs->C_GetAttributeValue (funcs, session, object, template, count); +} + +static CK_RV +stack_C_SetAttributeValue (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE session, + CK_OBJECT_HANDLE object, + CK_ATTRIBUTE_PTR template, + CK_ULONG count) +{ + p11_virtual *virt = (p11_virtual *)self; + CK_X_FUNCTION_LIST *funcs = virt->lower_module; + return funcs->C_SetAttributeValue (funcs, session, object, template, count); +} + +static CK_RV +stack_C_FindObjectsInit (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE session, + CK_ATTRIBUTE_PTR template, + CK_ULONG count) +{ + p11_virtual *virt = (p11_virtual *)self; + CK_X_FUNCTION_LIST *funcs = virt->lower_module; + return funcs->C_FindObjectsInit (funcs, session, template, count); +} + +static CK_RV +stack_C_FindObjects (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE session, + CK_OBJECT_HANDLE_PTR object, + CK_ULONG max_object_count, + CK_ULONG_PTR object_count) +{ + p11_virtual *virt = (p11_virtual *)self; + CK_X_FUNCTION_LIST *funcs = virt->lower_module; + return funcs->C_FindObjects (funcs, session, object, max_object_count, object_count); +} + +static CK_RV +stack_C_FindObjectsFinal (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE session) +{ + p11_virtual *virt = (p11_virtual *)self; + CK_X_FUNCTION_LIST *funcs = virt->lower_module; + return funcs->C_FindObjectsFinal (funcs, session); +} + +static CK_RV +stack_C_EncryptInit (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE session, + CK_MECHANISM_PTR mechanism, + CK_OBJECT_HANDLE key) +{ + p11_virtual *virt = (p11_virtual *)self; + CK_X_FUNCTION_LIST *funcs = virt->lower_module; + return funcs->C_EncryptInit (funcs, session, mechanism, key); +} + +static CK_RV +stack_C_Encrypt (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE session, + CK_BYTE_PTR input, + CK_ULONG input_len, + CK_BYTE_PTR encrypted_data, + CK_ULONG_PTR encrypted_data_len) +{ + p11_virtual *virt = (p11_virtual *)self; + CK_X_FUNCTION_LIST *funcs = virt->lower_module; + return funcs->C_Encrypt (funcs, session, input, input_len, + encrypted_data, encrypted_data_len); +} + +static CK_RV +stack_C_EncryptUpdate (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE session, + CK_BYTE_PTR part, + CK_ULONG part_len, + CK_BYTE_PTR encrypted_part, + CK_ULONG_PTR encrypted_part_len) +{ + p11_virtual *virt = (p11_virtual *)self; + CK_X_FUNCTION_LIST *funcs = virt->lower_module; + return funcs->C_EncryptUpdate (funcs, session, part, part_len, + encrypted_part, encrypted_part_len); +} + +static CK_RV +stack_C_EncryptFinal (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE session, + CK_BYTE_PTR last_encrypted_part, + CK_ULONG_PTR last_encrypted_part_len) +{ + p11_virtual *virt = (p11_virtual *)self; + CK_X_FUNCTION_LIST *funcs = virt->lower_module; + return funcs->C_EncryptFinal (funcs, session, last_encrypted_part, + last_encrypted_part_len); +} + +static CK_RV +stack_C_DecryptInit (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE session, + CK_MECHANISM_PTR mechanism, + CK_OBJECT_HANDLE key) +{ + p11_virtual *virt = (p11_virtual *)self; + CK_X_FUNCTION_LIST *funcs = virt->lower_module; + return funcs->C_DecryptInit (funcs, session, mechanism, key); +} + +static CK_RV +stack_C_Decrypt (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE session, + CK_BYTE_PTR encrypted_data, + CK_ULONG encrypted_data_len, + CK_BYTE_PTR output, + CK_ULONG_PTR output_len) +{ + p11_virtual *virt = (p11_virtual *)self; + CK_X_FUNCTION_LIST *funcs = virt->lower_module; + return funcs->C_Decrypt (funcs, session, encrypted_data, encrypted_data_len, + output, output_len); +} + +static CK_RV +stack_C_DecryptUpdate (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE session, + CK_BYTE_PTR encrypted_part, + CK_ULONG encrypted_part_len, + CK_BYTE_PTR part, + CK_ULONG_PTR part_len) +{ + p11_virtual *virt = (p11_virtual *)self; + CK_X_FUNCTION_LIST *funcs = virt->lower_module; + return funcs->C_DecryptUpdate (funcs, session, encrypted_part, encrypted_part_len, + part, part_len); +} + +static CK_RV +stack_C_DecryptFinal (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE session, + CK_BYTE_PTR last_part, + CK_ULONG_PTR last_part_len) +{ + p11_virtual *virt = (p11_virtual *)self; + CK_X_FUNCTION_LIST *funcs = virt->lower_module; + return funcs->C_DecryptFinal (funcs, session, last_part, last_part_len); +} + +static CK_RV +stack_C_DigestInit (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE session, + CK_MECHANISM_PTR mechanism) +{ + p11_virtual *virt = (p11_virtual *)self; + CK_X_FUNCTION_LIST *funcs = virt->lower_module; + return funcs->C_DigestInit (funcs, session, mechanism); +} + +static CK_RV +stack_C_Digest (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE session, + CK_BYTE_PTR input, + CK_ULONG input_len, + CK_BYTE_PTR digest, + CK_ULONG_PTR digest_len) +{ + p11_virtual *virt = (p11_virtual *)self; + CK_X_FUNCTION_LIST *funcs = virt->lower_module; + return funcs->C_Digest (funcs, session, input, input_len, digest, digest_len); +} + +static CK_RV +stack_C_DigestUpdate (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE session, + CK_BYTE_PTR part, + CK_ULONG part_len) +{ + p11_virtual *virt = (p11_virtual *)self; + CK_X_FUNCTION_LIST *funcs = virt->lower_module; + return funcs->C_DigestUpdate (funcs, session, part, part_len); +} + +static CK_RV +stack_C_DigestKey (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE session, + CK_OBJECT_HANDLE key) +{ + p11_virtual *virt = (p11_virtual *)self; + CK_X_FUNCTION_LIST *funcs = virt->lower_module; + return funcs->C_DigestKey (funcs, session, key); +} + +static CK_RV +stack_C_DigestFinal (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE session, + CK_BYTE_PTR digest, + CK_ULONG_PTR digest_len) +{ + p11_virtual *virt = (p11_virtual *)self; + CK_X_FUNCTION_LIST *funcs = virt->lower_module; + return funcs->C_DigestFinal (funcs, session, digest, digest_len); +} + +static CK_RV +stack_C_SignInit (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE session, + CK_MECHANISM_PTR mechanism, + CK_OBJECT_HANDLE key) +{ + p11_virtual *virt = (p11_virtual *)self; + CK_X_FUNCTION_LIST *funcs = virt->lower_module; + return funcs->C_SignInit (funcs, session, mechanism, key); +} + +static CK_RV +stack_C_Sign (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE session, + CK_BYTE_PTR input, + CK_ULONG input_len, + CK_BYTE_PTR signature, + CK_ULONG_PTR signature_len) +{ + p11_virtual *virt = (p11_virtual *)self; + CK_X_FUNCTION_LIST *funcs = virt->lower_module; + return funcs->C_Sign (funcs, session, input, input_len, + signature, signature_len); +} + +static CK_RV +stack_C_SignUpdate (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE session, + CK_BYTE_PTR part, + CK_ULONG part_len) +{ + p11_virtual *virt = (p11_virtual *)self; + CK_X_FUNCTION_LIST *funcs = virt->lower_module; + return funcs->C_SignUpdate (funcs, session, part, part_len); +} + +static CK_RV +stack_C_SignFinal (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE session, + CK_BYTE_PTR signature, + CK_ULONG_PTR signature_len) +{ + p11_virtual *virt = (p11_virtual *)self; + CK_X_FUNCTION_LIST *funcs = virt->lower_module; + return funcs->C_SignFinal (funcs, session, signature, signature_len); +} + +static CK_RV +stack_C_SignRecoverInit (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE session, + CK_MECHANISM_PTR mechanism, + CK_OBJECT_HANDLE key) +{ + p11_virtual *virt = (p11_virtual *)self; + CK_X_FUNCTION_LIST *funcs = virt->lower_module; + return funcs->C_SignRecoverInit (funcs, session, mechanism, key); +} + +static CK_RV +stack_C_SignRecover (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE session, + CK_BYTE_PTR input, + CK_ULONG input_len, + CK_BYTE_PTR signature, + CK_ULONG_PTR signature_len) +{ + p11_virtual *virt = (p11_virtual *)self; + CK_X_FUNCTION_LIST *funcs = virt->lower_module; + return funcs->C_SignRecover (funcs, session, input, input_len, + signature, signature_len); +} + +static CK_RV +stack_C_VerifyInit (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE session, + CK_MECHANISM_PTR mechanism, + CK_OBJECT_HANDLE key) +{ + p11_virtual *virt = (p11_virtual *)self; + CK_X_FUNCTION_LIST *funcs = virt->lower_module; + return funcs->C_VerifyInit (funcs, session, mechanism, key); +} + +static CK_RV +stack_C_Verify (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE session, + CK_BYTE_PTR input, + CK_ULONG input_len, + CK_BYTE_PTR signature, + CK_ULONG signature_len) +{ + p11_virtual *virt = (p11_virtual *)self; + CK_X_FUNCTION_LIST *funcs = virt->lower_module; + return funcs->C_Verify (funcs, session, input, input_len, + signature, signature_len); +} + +static CK_RV +stack_C_VerifyUpdate (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE session, + CK_BYTE_PTR part, + CK_ULONG part_len) +{ + p11_virtual *virt = (p11_virtual *)self; + CK_X_FUNCTION_LIST *funcs = virt->lower_module; + return funcs->C_VerifyUpdate (funcs, session, part, part_len); +} + +static CK_RV +stack_C_VerifyFinal (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE session, + CK_BYTE_PTR signature, + CK_ULONG signature_len) +{ + p11_virtual *virt = (p11_virtual *)self; + CK_X_FUNCTION_LIST *funcs = virt->lower_module; + return funcs->C_VerifyFinal (funcs, session, signature, signature_len); +} + +static CK_RV +stack_C_VerifyRecoverInit (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE session, + CK_MECHANISM_PTR mechanism, + CK_OBJECT_HANDLE key) +{ + p11_virtual *virt = (p11_virtual *)self; + CK_X_FUNCTION_LIST *funcs = virt->lower_module; + return funcs->C_VerifyRecoverInit (funcs, session, mechanism, key); +} + +static CK_RV +stack_C_VerifyRecover (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE session, + CK_BYTE_PTR signature, + CK_ULONG signature_len, + CK_BYTE_PTR input, + CK_ULONG_PTR input_len) +{ + p11_virtual *virt = (p11_virtual *)self; + CK_X_FUNCTION_LIST *funcs = virt->lower_module; + return funcs->C_VerifyRecover (funcs, session, signature, signature_len, + input, input_len); +} + +static CK_RV +stack_C_DigestEncryptUpdate (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE session, + CK_BYTE_PTR part, + CK_ULONG part_len, + CK_BYTE_PTR encrypted_part, + CK_ULONG_PTR encrypted_part_len) +{ + p11_virtual *virt = (p11_virtual *)self; + CK_X_FUNCTION_LIST *funcs = virt->lower_module; + return funcs->C_DigestEncryptUpdate (funcs, session, part, part_len, + encrypted_part, encrypted_part_len); +} + +static CK_RV +stack_C_DecryptDigestUpdate (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE session, + CK_BYTE_PTR encrypted_part, + CK_ULONG encrypted_part_len, + CK_BYTE_PTR part, + CK_ULONG_PTR part_len) +{ + p11_virtual *virt = (p11_virtual *)self; + CK_X_FUNCTION_LIST *funcs = virt->lower_module; + return funcs->C_DecryptDigestUpdate (funcs, session, encrypted_part, encrypted_part_len, + part, part_len); +} + +static CK_RV +stack_C_SignEncryptUpdate (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE session, + CK_BYTE_PTR part, + CK_ULONG part_len, + CK_BYTE_PTR encrypted_part, + CK_ULONG_PTR encrypted_part_len) +{ + p11_virtual *virt = (p11_virtual *)self; + CK_X_FUNCTION_LIST *funcs = virt->lower_module; + return funcs->C_SignEncryptUpdate (funcs, session, part, part_len, + encrypted_part, encrypted_part_len); +} + +static CK_RV +stack_C_DecryptVerifyUpdate (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE session, + CK_BYTE_PTR encrypted_part, + CK_ULONG encrypted_part_len, + CK_BYTE_PTR part, + CK_ULONG_PTR part_len) +{ + p11_virtual *virt = (p11_virtual *)self; + CK_X_FUNCTION_LIST *funcs = virt->lower_module; + return funcs->C_DecryptVerifyUpdate (funcs, session, encrypted_part, encrypted_part_len, + part, part_len); +} + +static CK_RV +stack_C_GenerateKey (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE session, + CK_MECHANISM_PTR mechanism, + CK_ATTRIBUTE_PTR template, + CK_ULONG count, + CK_OBJECT_HANDLE_PTR key) +{ + p11_virtual *virt = (p11_virtual *)self; + CK_X_FUNCTION_LIST *funcs = virt->lower_module; + return funcs->C_GenerateKey (funcs, session, mechanism, template, count, key); +} + +static CK_RV +stack_C_GenerateKeyPair (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE session, + CK_MECHANISM_PTR mechanism, + CK_ATTRIBUTE_PTR public_key_template, + CK_ULONG public_key_count, + CK_ATTRIBUTE_PTR private_key_template, + CK_ULONG private_key_count, + CK_OBJECT_HANDLE_PTR public_key, + CK_OBJECT_HANDLE_PTR private_key) +{ + p11_virtual *virt = (p11_virtual *)self; + CK_X_FUNCTION_LIST *funcs = virt->lower_module; + return funcs->C_GenerateKeyPair (funcs, session, mechanism, public_key_template, + public_key_count, private_key_template, + private_key_count, public_key, private_key); +} + +static CK_RV +stack_C_WrapKey (CK_X_FUNCTION_LIST *self, + 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) +{ + p11_virtual *virt = (p11_virtual *)self; + CK_X_FUNCTION_LIST *funcs = virt->lower_module; + return funcs->C_WrapKey (funcs, session, mechanism, wrapping_key, key, + wrapped_key, wrapped_key_len); +} + +static CK_RV +stack_C_UnwrapKey (CK_X_FUNCTION_LIST *self, + 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 template, + CK_ULONG count, + CK_OBJECT_HANDLE_PTR key) +{ + p11_virtual *virt = (p11_virtual *)self; + CK_X_FUNCTION_LIST *funcs = virt->lower_module; + return funcs->C_UnwrapKey (funcs, session, mechanism, unwrapping_key, wrapped_key, + wrapped_key_len, template, count, key); +} + +static CK_RV +stack_C_DeriveKey (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE session, + CK_MECHANISM_PTR mechanism, + CK_OBJECT_HANDLE base_key, + CK_ATTRIBUTE_PTR template, + CK_ULONG count, + CK_OBJECT_HANDLE_PTR key) +{ + p11_virtual *virt = (p11_virtual *)self; + CK_X_FUNCTION_LIST *funcs = virt->lower_module; + return funcs->C_DeriveKey (funcs, session, mechanism, base_key, template, count, key); +} + +static CK_RV +stack_C_SeedRandom (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE session, + CK_BYTE_PTR seed, + CK_ULONG seed_len) +{ + p11_virtual *virt = (p11_virtual *)self; + CK_X_FUNCTION_LIST *funcs = virt->lower_module; + return funcs->C_SeedRandom (funcs, session, seed, seed_len); +} + +static CK_RV +stack_C_GenerateRandom (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE session, + CK_BYTE_PTR random_data, + CK_ULONG random_len) +{ + p11_virtual *virt = (p11_virtual *)self; + CK_X_FUNCTION_LIST *funcs = virt->lower_module; + return funcs->C_GenerateRandom (funcs, session, random_data, random_len); +} + +static CK_RV +stack_C_WaitForSlotEvent (CK_X_FUNCTION_LIST *self, + CK_FLAGS flags, + CK_SLOT_ID_PTR slot_id, + CK_VOID_PTR reserved) +{ + p11_virtual *virt = (p11_virtual *)self; + CK_X_FUNCTION_LIST *funcs = virt->lower_module; + return funcs->C_WaitForSlotEvent (funcs, flags, slot_id, reserved); +} + +static CK_RV +base_C_Initialize (CK_X_FUNCTION_LIST *self, + CK_VOID_PTR init_args) +{ + p11_virtual *virt = (p11_virtual *)self; + CK_FUNCTION_LIST *funcs = virt->lower_module; + return funcs->C_Initialize (init_args); +} + +static CK_RV +base_C_Finalize (CK_X_FUNCTION_LIST *self, + CK_VOID_PTR reserved) +{ + p11_virtual *virt = (p11_virtual *)self; + CK_FUNCTION_LIST *funcs = virt->lower_module; + return funcs->C_Finalize (reserved); +} + +static CK_RV +base_C_GetInfo (CK_X_FUNCTION_LIST *self, + CK_INFO_PTR info) +{ + p11_virtual *virt = (p11_virtual *)self; + CK_FUNCTION_LIST *funcs = virt->lower_module; + return funcs->C_GetInfo (info); +} + +static CK_RV +base_C_GetSlotList (CK_X_FUNCTION_LIST *self, + CK_BBOOL token_present, + CK_SLOT_ID_PTR slot_list, + CK_ULONG_PTR count) +{ + p11_virtual *virt = (p11_virtual *)self; + CK_FUNCTION_LIST *funcs = virt->lower_module; + return funcs->C_GetSlotList (token_present, slot_list, count); +} + +static CK_RV +base_C_GetSlotInfo (CK_X_FUNCTION_LIST *self, + CK_SLOT_ID slot_id, + CK_SLOT_INFO_PTR info) +{ + p11_virtual *virt = (p11_virtual *)self; + CK_FUNCTION_LIST *funcs = virt->lower_module; + return funcs->C_GetSlotInfo (slot_id, info); +} + +static CK_RV +base_C_GetTokenInfo (CK_X_FUNCTION_LIST *self, + CK_SLOT_ID slot_id, + CK_TOKEN_INFO_PTR info) +{ + p11_virtual *virt = (p11_virtual *)self; + CK_FUNCTION_LIST *funcs = virt->lower_module; + return funcs->C_GetTokenInfo (slot_id, info); +} + +static CK_RV +base_C_GetMechanismList (CK_X_FUNCTION_LIST *self, + CK_SLOT_ID slot_id, + CK_MECHANISM_TYPE_PTR mechanism_list, + CK_ULONG_PTR count) +{ + p11_virtual *virt = (p11_virtual *)self; + CK_FUNCTION_LIST *funcs = virt->lower_module; + return funcs->C_GetMechanismList (slot_id, mechanism_list, count); +} + +static CK_RV +base_C_GetMechanismInfo (CK_X_FUNCTION_LIST *self, + CK_SLOT_ID slot_id, + CK_MECHANISM_TYPE type, + CK_MECHANISM_INFO_PTR info) +{ + p11_virtual *virt = (p11_virtual *)self; + CK_FUNCTION_LIST *funcs = virt->lower_module; + return funcs->C_GetMechanismInfo (slot_id, type, info); +} + +static CK_RV +base_C_InitToken (CK_X_FUNCTION_LIST *self, + CK_SLOT_ID slot_id, + CK_UTF8CHAR_PTR pin, + CK_ULONG pin_len, + CK_UTF8CHAR_PTR label) +{ + p11_virtual *virt = (p11_virtual *)self; + CK_FUNCTION_LIST *funcs = virt->lower_module; + return funcs->C_InitToken (slot_id, pin, pin_len, label); +} + +static CK_RV +base_C_OpenSession (CK_X_FUNCTION_LIST *self, + CK_SLOT_ID slot_id, + CK_FLAGS flags, + CK_VOID_PTR application, + CK_NOTIFY notify, + CK_SESSION_HANDLE_PTR session) +{ + p11_virtual *virt = (p11_virtual *)self; + CK_FUNCTION_LIST *funcs = virt->lower_module; + return funcs->C_OpenSession (slot_id, flags, application, notify, session); +} + +static CK_RV +base_C_CloseSession (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE session) +{ + p11_virtual *virt = (p11_virtual *)self; + CK_FUNCTION_LIST *funcs = virt->lower_module; + return funcs->C_CloseSession (session); +} + +static CK_RV +base_C_CloseAllSessions (CK_X_FUNCTION_LIST *self, + CK_SLOT_ID slot_id) +{ + p11_virtual *virt = (p11_virtual *)self; + CK_FUNCTION_LIST *funcs = virt->lower_module; + return funcs->C_CloseAllSessions (slot_id); +} + +static CK_RV +base_C_GetSessionInfo (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE session, + CK_SESSION_INFO_PTR info) +{ + p11_virtual *virt = (p11_virtual *)self; + CK_FUNCTION_LIST *funcs = virt->lower_module; + return funcs->C_GetSessionInfo (session, info); +} + +static CK_RV +base_C_InitPIN (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE session, + CK_UTF8CHAR_PTR pin, + CK_ULONG pin_len) +{ + p11_virtual *virt = (p11_virtual *)self; + CK_FUNCTION_LIST *funcs = virt->lower_module; + return funcs->C_InitPIN (session, pin, pin_len); +} + +static CK_RV +base_C_SetPIN (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE session, + CK_UTF8CHAR_PTR old_pin, + CK_ULONG old_len, + CK_UTF8CHAR_PTR new_pin, + CK_ULONG new_len) +{ + p11_virtual *virt = (p11_virtual *)self; + CK_FUNCTION_LIST *funcs = virt->lower_module; + return funcs->C_SetPIN (session, old_pin, old_len, new_pin, new_len); +} + +static CK_RV +base_C_GetOperationState (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE session, + CK_BYTE_PTR operation_state, + CK_ULONG_PTR operation_state_len) +{ + p11_virtual *virt = (p11_virtual *)self; + CK_FUNCTION_LIST *funcs = virt->lower_module; + return funcs->C_GetOperationState (session, operation_state, operation_state_len); +} + +static CK_RV +base_C_SetOperationState (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE session, + CK_BYTE_PTR operation_state, + CK_ULONG operation_state_len, + CK_OBJECT_HANDLE encryption_key, + CK_OBJECT_HANDLE authentication_key) +{ + p11_virtual *virt = (p11_virtual *)self; + CK_FUNCTION_LIST *funcs = virt->lower_module; + return funcs->C_SetOperationState (session, operation_state, operation_state_len, + encryption_key, authentication_key); +} + +static CK_RV +base_C_Login (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE session, + CK_USER_TYPE user_type, + CK_UTF8CHAR_PTR pin, + CK_ULONG pin_len) +{ + p11_virtual *virt = (p11_virtual *)self; + CK_FUNCTION_LIST *funcs = virt->lower_module; + return funcs->C_Login (session, user_type, pin, pin_len); +} + +static CK_RV +base_C_Logout (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE session) +{ + p11_virtual *virt = (p11_virtual *)self; + CK_FUNCTION_LIST *funcs = virt->lower_module; + return funcs->C_Logout (session); +} + +static CK_RV +base_C_CreateObject (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE session, + CK_ATTRIBUTE_PTR template, + CK_ULONG count, + CK_OBJECT_HANDLE_PTR object) +{ + p11_virtual *virt = (p11_virtual *)self; + CK_FUNCTION_LIST *funcs = virt->lower_module; + return funcs->C_CreateObject (session, template, count, object); +} + +static CK_RV +base_C_CopyObject (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE session, + CK_OBJECT_HANDLE object, + CK_ATTRIBUTE_PTR template, + CK_ULONG count, + CK_OBJECT_HANDLE_PTR new_object) +{ + p11_virtual *virt = (p11_virtual *)self; + CK_FUNCTION_LIST *funcs = virt->lower_module; + return funcs->C_CopyObject (session, object, template, count, new_object); +} + + +static CK_RV +base_C_DestroyObject (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE session, + CK_OBJECT_HANDLE object) +{ + p11_virtual *virt = (p11_virtual *)self; + CK_FUNCTION_LIST *funcs = virt->lower_module; + return funcs->C_DestroyObject (session, object); +} + +static CK_RV +base_C_GetObjectSize (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE session, + CK_OBJECT_HANDLE object, + CK_ULONG_PTR size) +{ + p11_virtual *virt = (p11_virtual *)self; + CK_FUNCTION_LIST *funcs = virt->lower_module; + return funcs->C_GetObjectSize (session, object, size); +} + +static CK_RV +base_C_GetAttributeValue (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE session, + CK_OBJECT_HANDLE object, + CK_ATTRIBUTE_PTR template, + CK_ULONG count) +{ + p11_virtual *virt = (p11_virtual *)self; + CK_FUNCTION_LIST *funcs = virt->lower_module; + return funcs->C_GetAttributeValue (session, object, template, count); +} + +static CK_RV +base_C_SetAttributeValue (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE session, + CK_OBJECT_HANDLE object, + CK_ATTRIBUTE_PTR template, + CK_ULONG count) +{ + p11_virtual *virt = (p11_virtual *)self; + CK_FUNCTION_LIST *funcs = virt->lower_module; + return funcs->C_SetAttributeValue (session, object, template, count); +} + +static CK_RV +base_C_FindObjectsInit (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE session, + CK_ATTRIBUTE_PTR template, + CK_ULONG count) +{ + p11_virtual *virt = (p11_virtual *)self; + CK_FUNCTION_LIST *funcs = virt->lower_module; + return funcs->C_FindObjectsInit (session, template, count); +} + +static CK_RV +base_C_FindObjects (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE session, + CK_OBJECT_HANDLE_PTR object, + CK_ULONG max_object_count, + CK_ULONG_PTR object_count) +{ + p11_virtual *virt = (p11_virtual *)self; + CK_FUNCTION_LIST *funcs = virt->lower_module; + return funcs->C_FindObjects (session, object, max_object_count, object_count); +} + +static CK_RV +base_C_FindObjectsFinal (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE session) +{ + p11_virtual *virt = (p11_virtual *)self; + CK_FUNCTION_LIST *funcs = virt->lower_module; + return funcs->C_FindObjectsFinal (session); +} + +static CK_RV +base_C_EncryptInit (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE session, + CK_MECHANISM_PTR mechanism, + CK_OBJECT_HANDLE key) +{ + p11_virtual *virt = (p11_virtual *)self; + CK_FUNCTION_LIST *funcs = virt->lower_module; + return funcs->C_EncryptInit (session, mechanism, key); +} + +static CK_RV +base_C_Encrypt (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE session, + CK_BYTE_PTR input, + CK_ULONG input_len, + CK_BYTE_PTR encrypted_data, + CK_ULONG_PTR encrypted_data_len) +{ + p11_virtual *virt = (p11_virtual *)self; + CK_FUNCTION_LIST *funcs = virt->lower_module; + return funcs->C_Encrypt (session, input, input_len, + encrypted_data, encrypted_data_len); +} + +static CK_RV +base_C_EncryptUpdate (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE session, + CK_BYTE_PTR part, + CK_ULONG part_len, + CK_BYTE_PTR encrypted_part, + CK_ULONG_PTR encrypted_part_len) +{ + p11_virtual *virt = (p11_virtual *)self; + CK_FUNCTION_LIST *funcs = virt->lower_module; + return funcs->C_EncryptUpdate (session, part, part_len, + encrypted_part, encrypted_part_len); +} + +static CK_RV +base_C_EncryptFinal (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE session, + CK_BYTE_PTR last_encrypted_part, + CK_ULONG_PTR last_encrypted_part_len) +{ + p11_virtual *virt = (p11_virtual *)self; + CK_FUNCTION_LIST *funcs = virt->lower_module; + return funcs->C_EncryptFinal (session, last_encrypted_part, + last_encrypted_part_len); +} + +static CK_RV +base_C_DecryptInit (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE session, + CK_MECHANISM_PTR mechanism, + CK_OBJECT_HANDLE key) +{ + p11_virtual *virt = (p11_virtual *)self; + CK_FUNCTION_LIST *funcs = virt->lower_module; + return funcs->C_DecryptInit (session, mechanism, key); +} + +static CK_RV +base_C_Decrypt (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE session, + CK_BYTE_PTR encrypted_data, + CK_ULONG encrypted_data_len, + CK_BYTE_PTR output, + CK_ULONG_PTR output_len) +{ + p11_virtual *virt = (p11_virtual *)self; + CK_FUNCTION_LIST *funcs = virt->lower_module; + return funcs->C_Decrypt (session, encrypted_data, encrypted_data_len, + output, output_len); +} + +static CK_RV +base_C_DecryptUpdate (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE session, + CK_BYTE_PTR encrypted_part, + CK_ULONG encrypted_part_len, + CK_BYTE_PTR part, + CK_ULONG_PTR part_len) +{ + p11_virtual *virt = (p11_virtual *)self; + CK_FUNCTION_LIST *funcs = virt->lower_module; + return funcs->C_DecryptUpdate (session, encrypted_part, encrypted_part_len, + part, part_len); +} + +static CK_RV +base_C_DecryptFinal (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE session, + CK_BYTE_PTR last_part, + CK_ULONG_PTR last_part_len) +{ + p11_virtual *virt = (p11_virtual *)self; + CK_FUNCTION_LIST *funcs = virt->lower_module; + return funcs->C_DecryptFinal (session, last_part, last_part_len); +} + +static CK_RV +base_C_DigestInit (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE session, + CK_MECHANISM_PTR mechanism) +{ + p11_virtual *virt = (p11_virtual *)self; + CK_FUNCTION_LIST *funcs = virt->lower_module; + return funcs->C_DigestInit (session, mechanism); +} + +static CK_RV +base_C_Digest (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE session, + CK_BYTE_PTR input, + CK_ULONG input_len, + CK_BYTE_PTR digest, + CK_ULONG_PTR digest_len) +{ + p11_virtual *virt = (p11_virtual *)self; + CK_FUNCTION_LIST *funcs = virt->lower_module; + return funcs->C_Digest (session, input, input_len, digest, digest_len); +} + +static CK_RV +base_C_DigestUpdate (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE session, + CK_BYTE_PTR part, + CK_ULONG part_len) +{ + p11_virtual *virt = (p11_virtual *)self; + CK_FUNCTION_LIST *funcs = virt->lower_module; + return funcs->C_DigestUpdate (session, part, part_len); +} + +static CK_RV +base_C_DigestKey (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE session, + CK_OBJECT_HANDLE key) +{ + p11_virtual *virt = (p11_virtual *)self; + CK_FUNCTION_LIST *funcs = virt->lower_module; + return funcs->C_DigestKey (session, key); +} + +static CK_RV +base_C_DigestFinal (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE session, + CK_BYTE_PTR digest, + CK_ULONG_PTR digest_len) +{ + p11_virtual *virt = (p11_virtual *)self; + CK_FUNCTION_LIST *funcs = virt->lower_module; + return funcs->C_DigestFinal (session, digest, digest_len); +} + +static CK_RV +base_C_SignInit (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE session, + CK_MECHANISM_PTR mechanism, + CK_OBJECT_HANDLE key) +{ + p11_virtual *virt = (p11_virtual *)self; + CK_FUNCTION_LIST *funcs = virt->lower_module; + return funcs->C_SignInit (session, mechanism, key); +} + +static CK_RV +base_C_Sign (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE session, + CK_BYTE_PTR input, + CK_ULONG input_len, + CK_BYTE_PTR signature, + CK_ULONG_PTR signature_len) +{ + p11_virtual *virt = (p11_virtual *)self; + CK_FUNCTION_LIST *funcs = virt->lower_module; + return funcs->C_Sign (session, input, input_len, + signature, signature_len); +} + +static CK_RV +base_C_SignUpdate (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE session, + CK_BYTE_PTR part, + CK_ULONG part_len) +{ + p11_virtual *virt = (p11_virtual *)self; + CK_FUNCTION_LIST *funcs = virt->lower_module; + return funcs->C_SignUpdate (session, part, part_len); +} + +static CK_RV +base_C_SignFinal (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE session, + CK_BYTE_PTR signature, + CK_ULONG_PTR signature_len) +{ + p11_virtual *virt = (p11_virtual *)self; + CK_FUNCTION_LIST *funcs = virt->lower_module; + return funcs->C_SignFinal (session, signature, signature_len); +} + +static CK_RV +base_C_SignRecoverInit (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE session, + CK_MECHANISM_PTR mechanism, + CK_OBJECT_HANDLE key) +{ + p11_virtual *virt = (p11_virtual *)self; + CK_FUNCTION_LIST *funcs = virt->lower_module; + return funcs->C_SignRecoverInit (session, mechanism, key); +} + +static CK_RV +base_C_SignRecover (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE session, + CK_BYTE_PTR input, + CK_ULONG input_len, + CK_BYTE_PTR signature, + CK_ULONG_PTR signature_len) +{ + p11_virtual *virt = (p11_virtual *)self; + CK_FUNCTION_LIST *funcs = virt->lower_module; + return funcs->C_SignRecover (session, input, input_len, + signature, signature_len); +} + +static CK_RV +base_C_VerifyInit (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE session, + CK_MECHANISM_PTR mechanism, + CK_OBJECT_HANDLE key) +{ + p11_virtual *virt = (p11_virtual *)self; + CK_FUNCTION_LIST *funcs = virt->lower_module; + return funcs->C_VerifyInit (session, mechanism, key); +} + +static CK_RV +base_C_Verify (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE session, + CK_BYTE_PTR input, + CK_ULONG input_len, + CK_BYTE_PTR signature, + CK_ULONG signature_len) +{ + p11_virtual *virt = (p11_virtual *)self; + CK_FUNCTION_LIST *funcs = virt->lower_module; + return funcs->C_Verify (session, input, input_len, + signature, signature_len); +} + +static CK_RV +base_C_VerifyUpdate (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE session, + CK_BYTE_PTR part, + CK_ULONG part_len) +{ + p11_virtual *virt = (p11_virtual *)self; + CK_FUNCTION_LIST *funcs = virt->lower_module; + return funcs->C_VerifyUpdate (session, part, part_len); +} + +static CK_RV +base_C_VerifyFinal (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE session, + CK_BYTE_PTR signature, + CK_ULONG signature_len) +{ + p11_virtual *virt = (p11_virtual *)self; + CK_FUNCTION_LIST *funcs = virt->lower_module; + return funcs->C_VerifyFinal (session, signature, signature_len); +} + +static CK_RV +base_C_VerifyRecoverInit (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE session, + CK_MECHANISM_PTR mechanism, + CK_OBJECT_HANDLE key) +{ + p11_virtual *virt = (p11_virtual *)self; + CK_FUNCTION_LIST *funcs = virt->lower_module; + return funcs->C_VerifyRecoverInit (session, mechanism, key); +} + +static CK_RV +base_C_VerifyRecover (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE session, + CK_BYTE_PTR signature, + CK_ULONG signature_len, + CK_BYTE_PTR input, + CK_ULONG_PTR input_len) +{ + p11_virtual *virt = (p11_virtual *)self; + CK_FUNCTION_LIST *funcs = virt->lower_module; + return funcs->C_VerifyRecover (session, signature, signature_len, + input, input_len); +} + +static CK_RV +base_C_DigestEncryptUpdate (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE session, + CK_BYTE_PTR part, + CK_ULONG part_len, + CK_BYTE_PTR encrypted_part, + CK_ULONG_PTR encrypted_part_len) +{ + p11_virtual *virt = (p11_virtual *)self; + CK_FUNCTION_LIST *funcs = virt->lower_module; + return funcs->C_DigestEncryptUpdate (session, part, part_len, + encrypted_part, encrypted_part_len); +} + +static CK_RV +base_C_DecryptDigestUpdate (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE session, + CK_BYTE_PTR encrypted_part, + CK_ULONG encrypted_part_len, + CK_BYTE_PTR part, + CK_ULONG_PTR part_len) +{ + p11_virtual *virt = (p11_virtual *)self; + CK_FUNCTION_LIST *funcs = virt->lower_module; + return funcs->C_DecryptDigestUpdate (session, encrypted_part, encrypted_part_len, + part, part_len); +} + +static CK_RV +base_C_SignEncryptUpdate (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE session, + CK_BYTE_PTR part, + CK_ULONG part_len, + CK_BYTE_PTR encrypted_part, + CK_ULONG_PTR encrypted_part_len) +{ + p11_virtual *virt = (p11_virtual *)self; + CK_FUNCTION_LIST *funcs = virt->lower_module; + return funcs->C_SignEncryptUpdate (session, part, part_len, + encrypted_part, encrypted_part_len); +} + +static CK_RV +base_C_DecryptVerifyUpdate (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE session, + CK_BYTE_PTR encrypted_part, + CK_ULONG encrypted_part_len, + CK_BYTE_PTR part, + CK_ULONG_PTR part_len) +{ + p11_virtual *virt = (p11_virtual *)self; + CK_FUNCTION_LIST *funcs = virt->lower_module; + return funcs->C_DecryptVerifyUpdate (session, encrypted_part, encrypted_part_len, + part, part_len); +} + +static CK_RV +base_C_GenerateKey (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE session, + CK_MECHANISM_PTR mechanism, + CK_ATTRIBUTE_PTR template, + CK_ULONG count, + CK_OBJECT_HANDLE_PTR key) +{ + p11_virtual *virt = (p11_virtual *)self; + CK_FUNCTION_LIST *funcs = virt->lower_module; + return funcs->C_GenerateKey (session, mechanism, template, count, key); +} + +static CK_RV +base_C_GenerateKeyPair (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE session, + CK_MECHANISM_PTR mechanism, + CK_ATTRIBUTE_PTR public_key_template, + CK_ULONG public_key_count, + CK_ATTRIBUTE_PTR private_key_template, + CK_ULONG private_key_count, + CK_OBJECT_HANDLE_PTR public_key, + CK_OBJECT_HANDLE_PTR private_key) +{ + p11_virtual *virt = (p11_virtual *)self; + CK_FUNCTION_LIST *funcs = virt->lower_module; + return funcs->C_GenerateKeyPair (session, mechanism, public_key_template, + public_key_count, private_key_template, + private_key_count, public_key, private_key); +} + +static CK_RV +base_C_WrapKey (CK_X_FUNCTION_LIST *self, + 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) +{ + p11_virtual *virt = (p11_virtual *)self; + CK_FUNCTION_LIST *funcs = virt->lower_module; + return funcs->C_WrapKey (session, mechanism, wrapping_key, key, + wrapped_key, wrapped_key_len); +} + +static CK_RV +base_C_UnwrapKey (CK_X_FUNCTION_LIST *self, + 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 template, + CK_ULONG count, + CK_OBJECT_HANDLE_PTR key) +{ + p11_virtual *virt = (p11_virtual *)self; + CK_FUNCTION_LIST *funcs = virt->lower_module; + return funcs->C_UnwrapKey (session, mechanism, unwrapping_key, wrapped_key, + wrapped_key_len, template, count, key); +} + +static CK_RV +base_C_DeriveKey (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE session, + CK_MECHANISM_PTR mechanism, + CK_OBJECT_HANDLE base_key, + CK_ATTRIBUTE_PTR template, + CK_ULONG count, + CK_OBJECT_HANDLE_PTR key) +{ + p11_virtual *virt = (p11_virtual *)self; + CK_FUNCTION_LIST *funcs = virt->lower_module; + return funcs->C_DeriveKey (session, mechanism, base_key, template, count, key); +} + +static CK_RV +base_C_SeedRandom (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE session, + CK_BYTE_PTR seed, + CK_ULONG seed_len) +{ + p11_virtual *virt = (p11_virtual *)self; + CK_FUNCTION_LIST *funcs = virt->lower_module; + return funcs->C_SeedRandom (session, seed, seed_len); +} + +static CK_RV +base_C_GenerateRandom (CK_X_FUNCTION_LIST *self, + CK_SESSION_HANDLE session, + CK_BYTE_PTR random_data, + CK_ULONG random_len) +{ + p11_virtual *virt = (p11_virtual *)self; + CK_FUNCTION_LIST *funcs = virt->lower_module; + return funcs->C_GenerateRandom (session, random_data, random_len); +} + +static CK_RV +base_C_WaitForSlotEvent (CK_X_FUNCTION_LIST *self, + CK_FLAGS flags, + CK_SLOT_ID_PTR slot_id, + CK_VOID_PTR reserved) +{ + p11_virtual *virt = (p11_virtual *)self; + CK_FUNCTION_LIST *funcs = virt->lower_module; + return funcs->C_WaitForSlotEvent (flags, slot_id, reserved); +} + +void +p11_virtual_init (p11_virtual *virt, + CK_X_FUNCTION_LIST *funcs, + void *lower_module, + p11_destroyer lower_destroy) +{ + memcpy (virt, funcs, sizeof (CK_X_FUNCTION_LIST)); + virt->lower_module = lower_module; + virt->lower_destroy = lower_destroy; +} + +void +p11_virtual_uninit (p11_virtual *virt) +{ + if (virt->lower_destroy) + (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) \ + ((size_t) ((unsigned char *) &((struct_type *) 0)->member)) +#define STRUCT_MEMBER_P(struct_p, struct_offset) \ + ((void *) ((unsigned char *) (struct_p) + (long) (struct_offset))) +#define STRUCT_MEMBER(member_type, struct_p, struct_offset) \ + (*(member_type*) STRUCT_MEMBER_P ((struct_p), (struct_offset))) + +#define FUNCTION(name) \ + #name, binding_C_##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, } +}; + +static bool +lookup_fall_through (p11_virtual *virt, + const FunctionInfo *info, + void **bound_func) +{ + void *func; + + /* + * So the basic concept here is if we have only fall-through functions + * all the way down the stack, then we can just get the actual module + * function, so that calls go right through. + */ + + func = STRUCT_MEMBER (void *, virt, info->virtual_offset); + + /* + * This is a fall-through function and the stack goes down further, so + * ask the next level down for the + */ + if (func == info->stack_fallback) { + return lookup_fall_through (virt->lower_module, info, bound_func); + + /* + * This is a fall-through function at the bottom level of the stack + * so return the function from the module. + */ + } else if (func == info->base_fallback) { + *bound_func = STRUCT_MEMBER (void *, virt->lower_module, info->module_offset); + return true; + } + + return false; +} + +static bool +bind_ffi_closure (Wrapper *wrapper, + void *binding_data, + void *binding_func, + ffi_type **args, + void **bound_func) +{ + ffi_closure *clo; + ffi_cif *cif; + int nargs = 0; + int i = 0; + int ret; + + assert (wrapper->ffi_used < MAX_FUNCTIONS); + cif = wrapper->ffi_cifs + wrapper->ffi_used; + + /* The number of arguments */ + for (i = 0, nargs = 0; args[i] != NULL; i++) + nargs++; + + assert (nargs <= MAX_ARGS); + + /* + * The failures here are unexpected conditions. There's a chance they + * might occur on other esoteric platforms, so we take a little + * extra care to print relevant debugging info, and return a status, + * so that we can get back useful debug info on platforms that we + * don't have access to. + */ + + ret = ffi_prep_cif (cif, FFI_DEFAULT_ABI, nargs, &ffi_type_ulong, args); + if (ret != FFI_OK) { + p11_debug_precond ("ffi_prep_cif failed: %d\n", ret); + return false; + } + + clo = ffi_closure_alloc (sizeof (ffi_closure), bound_func); + if (clo == NULL) { + p11_debug_precond ("ffi_closure_alloc failed\n"); + return false; + } + + ret = ffi_prep_closure_loc (clo, cif, binding_func, binding_data, *bound_func); + if (ret != FFI_OK) { + p11_debug_precond ("ffi_prep_closure_loc failed: %d\n", ret); + return false; + } + + wrapper->ffi_closures[wrapper->ffi_used] = clo; + wrapper->ffi_used++; + return true; +} + +static bool +init_wrapper_funcs (Wrapper *wrapper) +{ + static const ffi_type *get_function_list_args[] = { &ffi_type_pointer, NULL }; + const FunctionInfo *info; + CK_X_FUNCTION_LIST *over; + void **bound; + int i; + + /* Pointer to where our calls go */ + over = &wrapper->virt->funcs; + + for (i = 0; function_info[i].name != NULL; i++) { + info = function_info + i; + + /* Address to where we're placing the bound function */ + bound = &STRUCT_MEMBER (void *, &wrapper->bound, 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)) { + if (!bind_ffi_closure (wrapper, over, + info->binding_function, + (ffi_type **)info->types, bound)) + return_val_if_reached (false); + } + } + + /* Always bind the C_GetFunctionList function itself */ + if (!bind_ffi_closure (wrapper, wrapper, + binding_C_GetFunctionList, + (ffi_type **)get_function_list_args, + (void **)&wrapper->bound.C_GetFunctionList)) + return_val_if_reached (false); + + /* + * 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 void +uninit_wrapper_funcs (Wrapper *wrapper) +{ + int i; + + for (i = 0; i < wrapper->ffi_used; i++) + ffi_closure_free (wrapper->ffi_closures[i]); +} + +CK_FUNCTION_LIST * +p11_virtual_wrap (p11_virtual *virt, + 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; + + if (!init_wrapper_funcs (wrapper)) + return_val_if_reached (NULL); + + assert ((void *)wrapper == (void *)&wrapper->bound); + assert (p11_virtual_is_wrapper (&wrapper->bound)); + assert (wrapper->bound.C_GetFunctionList != NULL); + return &wrapper->bound; +} + +bool +p11_virtual_can_wrap (void) +{ + return TRUE; +} + +bool +p11_virtual_is_wrapper (CK_FUNCTION_LIST_PTR module) +{ + /* + * We use these functions 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. + */ + return (module->C_GetFunctionStatus == short_C_GetFunctionStatus && + module->C_CancelFunction == short_C_CancelFunction); +} + +void +p11_virtual_unwrap (CK_FUNCTION_LIST_PTR module) +{ + Wrapper *wrapper; + + return_if_fail (p11_virtual_is_wrapper (module)); + + /* The bound CK_FUNCTION_LIST_PTR sits at the front of Context */ + wrapper = (Wrapper *)module; + + /* + * Make sure that the CK_FUNCTION_LIST_PTR is invalid, and that + * p11_virtual_is_wrapper() recognizes this. This is in case the + * destroyer callback tries to do something fancy. + */ + memset (&wrapper->bound, 0xFEEEFEEE, sizeof (wrapper->bound)); + + if (wrapper->destroyer) + (wrapper->destroyer) (wrapper->virt); + + uninit_wrapper_funcs (wrapper); + 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, + stack_C_Finalize, + stack_C_GetInfo, + stack_C_GetSlotList, + stack_C_GetSlotInfo, + stack_C_GetTokenInfo, + stack_C_GetMechanismList, + stack_C_GetMechanismInfo, + stack_C_InitToken, + stack_C_InitPIN, + stack_C_SetPIN, + stack_C_OpenSession, + stack_C_CloseSession, + stack_C_CloseAllSessions, + stack_C_GetSessionInfo, + stack_C_GetOperationState, + stack_C_SetOperationState, + stack_C_Login, + stack_C_Logout, + stack_C_CreateObject, + stack_C_CopyObject, + stack_C_DestroyObject, + stack_C_GetObjectSize, + stack_C_GetAttributeValue, + stack_C_SetAttributeValue, + stack_C_FindObjectsInit, + stack_C_FindObjects, + stack_C_FindObjectsFinal, + stack_C_EncryptInit, + stack_C_Encrypt, + stack_C_EncryptUpdate, + stack_C_EncryptFinal, + stack_C_DecryptInit, + stack_C_Decrypt, + stack_C_DecryptUpdate, + stack_C_DecryptFinal, + stack_C_DigestInit, + stack_C_Digest, + stack_C_DigestUpdate, + stack_C_DigestKey, + stack_C_DigestFinal, + stack_C_SignInit, + stack_C_Sign, + stack_C_SignUpdate, + stack_C_SignFinal, + stack_C_SignRecoverInit, + stack_C_SignRecover, + stack_C_VerifyInit, + stack_C_Verify, + stack_C_VerifyUpdate, + stack_C_VerifyFinal, + stack_C_VerifyRecoverInit, + stack_C_VerifyRecover, + stack_C_DigestEncryptUpdate, + stack_C_DecryptDigestUpdate, + stack_C_SignEncryptUpdate, + stack_C_DecryptVerifyUpdate, + stack_C_GenerateKey, + stack_C_GenerateKeyPair, + stack_C_WrapKey, + stack_C_UnwrapKey, + stack_C_DeriveKey, + stack_C_SeedRandom, + stack_C_GenerateRandom, + stack_C_WaitForSlotEvent +}; + +CK_X_FUNCTION_LIST p11_virtual_base = { + { CRYPTOKI_VERSION_MAJOR, CRYPTOKI_VERSION_MINOR }, /* version */ + base_C_Initialize, + base_C_Finalize, + base_C_GetInfo, + base_C_GetSlotList, + base_C_GetSlotInfo, + base_C_GetTokenInfo, + base_C_GetMechanismList, + base_C_GetMechanismInfo, + base_C_InitToken, + base_C_InitPIN, + base_C_SetPIN, + base_C_OpenSession, + base_C_CloseSession, + base_C_CloseAllSessions, + base_C_GetSessionInfo, + base_C_GetOperationState, + base_C_SetOperationState, + base_C_Login, + base_C_Logout, + base_C_CreateObject, + base_C_CopyObject, + base_C_DestroyObject, + base_C_GetObjectSize, + base_C_GetAttributeValue, + base_C_SetAttributeValue, + base_C_FindObjectsInit, + base_C_FindObjects, + base_C_FindObjectsFinal, + base_C_EncryptInit, + base_C_Encrypt, + base_C_EncryptUpdate, + base_C_EncryptFinal, + base_C_DecryptInit, + base_C_Decrypt, + base_C_DecryptUpdate, + base_C_DecryptFinal, + base_C_DigestInit, + base_C_Digest, + base_C_DigestUpdate, + base_C_DigestKey, + base_C_DigestFinal, + base_C_SignInit, + base_C_Sign, + base_C_SignUpdate, + base_C_SignFinal, + base_C_SignRecoverInit, + base_C_SignRecover, + base_C_VerifyInit, + base_C_Verify, + base_C_VerifyUpdate, + base_C_VerifyFinal, + base_C_VerifyRecoverInit, + base_C_VerifyRecover, + base_C_DigestEncryptUpdate, + base_C_DecryptDigestUpdate, + base_C_SignEncryptUpdate, + base_C_DecryptVerifyUpdate, + base_C_GenerateKey, + base_C_GenerateKeyPair, + base_C_WrapKey, + base_C_UnwrapKey, + base_C_DeriveKey, + base_C_SeedRandom, + base_C_GenerateRandom, + base_C_WaitForSlotEvent +}; diff --git a/p11-kit/virtual.h b/p11-kit/virtual.h new file mode 100644 index 0000000..f1fb676 --- /dev/null +++ b/p11-kit/virtual.h @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2013 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 <stefw@redhat.com> + */ + +#ifndef __P11_VIRTUAL_H__ +#define __P11_VIRTUAL_H__ + +#include "pkcs11.h" +#include "pkcs11x.h" +#include "array.h" + +typedef struct { + CK_X_FUNCTION_LIST funcs; + void *lower_module; + p11_destroyer lower_destroy; +} p11_virtual; + +CK_X_FUNCTION_LIST p11_virtual_base; + +CK_X_FUNCTION_LIST p11_virtual_stack; + +void p11_virtual_init (p11_virtual *virt, + CK_X_FUNCTION_LIST *funcs, + void *lower_module, + p11_destroyer lower_destroy); + +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); + +bool p11_virtual_is_wrapper (CK_FUNCTION_LIST *module); + +void p11_virtual_unwrap (CK_FUNCTION_LIST *module); + +#endif /* __P11_VIRTUAL_H__ */ |