diff options
Diffstat (limited to 'p11-kit')
49 files changed, 4586 insertions, 1852 deletions
diff --git a/p11-kit/Makefile.am b/p11-kit/Makefile.am index 2985d85..11d5fae 100644 --- a/p11-kit/Makefile.am +++ b/p11-kit/Makefile.am @@ -1,8 +1,12 @@ NULL = +SUBDIRS = . tests + +COMMON = $(top_srcdir)/common + INCLUDES = \ -I$(top_srcdir) \ - -I$(top_srcdir)/common \ + -I$(COMMON) \ -DP11_KIT_FUTURE_UNSTABLE_API \ $(NULL) @@ -15,19 +19,24 @@ inc_HEADERS = \ pkcs11.h MODULE_SRCS = \ - util.c util.h \ + util.c \ conf.c conf.h \ - debug.c debug.h \ - hashmap.c hashmap.h \ modules.c \ pin.c \ proxy.c \ private.h \ - ptr-array.c ptr-array.h \ messages.c \ uri.c \ - $(top_srcdir)/common/compat.c \ - $(top_srcdir)/common/compat.h \ + $(COMMON)/array.c \ + $(COMMON)/array.h \ + $(COMMON)/compat.c \ + $(COMMON)/compat.h \ + $(COMMON)/debug.c \ + $(COMMON)/debug.h \ + $(COMMON)/dict.c \ + $(COMMON)/dict.h \ + $(COMMON)/library.c \ + $(COMMON)/library.h \ $(inc_HEADERS) lib_LTLIBRARIES = \ @@ -62,31 +71,34 @@ libp11_kit_testable_la_SOURCES = $(MODULE_SRCS) if OS_WIN32 libp11_kit_testable_la_CFLAGS = \ - -DP11_SYSTEM_CONFIG_FILE=\""$(abs_top_srcdir)/tests/files/system-pkcs11.conf"\" \ - -DP11_SYSTEM_CONFIG_MODULES=\""$(abs_top_srcdir)/tests/files/system-modules/win32"\" \ - -DP11_USER_CONFIG_FILE=\""$(abs_top_srcdir)/tests/files/user-pkcs11.conf"\" \ - -DP11_USER_CONFIG_MODULES=\""$(abs_top_srcdir)/tests/files/user-modules/win32"\" \ - -DP11_MODULE_PATH=\""$(abs_top_builddir)/tests/.libs"\" \ + -DP11_SYSTEM_CONFIG_FILE=\""$(abs_top_srcdir)/p11-kit/tests/files/system-pkcs11.conf"\" \ + -DP11_SYSTEM_CONFIG_MODULES=\""$(abs_top_srcdir)/p11-kit/tests/files/system-modules/win32"\" \ + -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"\" \ $(NULL) else libp11_kit_testable_la_CFLAGS = \ - -DP11_SYSTEM_CONFIG_FILE=\""$(abs_top_srcdir)/tests/files/system-pkcs11.conf"\" \ - -DP11_SYSTEM_CONFIG_MODULES=\""$(abs_top_srcdir)/tests/files/system-modules"\" \ - -DP11_USER_CONFIG_FILE=\""$(abs_top_srcdir)/tests/files/user-pkcs11.conf"\" \ - -DP11_USER_CONFIG_MODULES=\""$(abs_top_srcdir)/tests/files/user-modules"\" \ - -DP11_MODULE_PATH=\""$(abs_top_builddir)/tests/.libs"\" \ + -DP11_SYSTEM_CONFIG_FILE=\""$(abs_top_srcdir)/p11-kit/tests/files/system-pkcs11.conf"\" \ + -DP11_SYSTEM_CONFIG_MODULES=\""$(abs_top_srcdir)/p11-kit/tests/files/system-modules"\" \ + -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"\" \ $(NULL) endif libp11_kit_compat_la_SOURCES = \ - debug.c debug.h \ messages.c \ - util.c util.h \ - $(top_srcdir)/common/compat.c \ - $(top_srcdir)/common/compat.h + $(COMMON)/compat.c \ + $(COMMON)/compat.h \ + $(COMMON)/debug.c \ + $(COMMON)/debug.h \ + $(COMMON)/library.c \ + $(COMMON)/library.h \ + $(NULL) pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = p11-kit-1.pc diff --git a/p11-kit/conf.c b/p11-kit/conf.c index 8dda39f..1d92942 100644 --- a/p11-kit/conf.c +++ b/p11-kit/conf.c @@ -38,10 +38,10 @@ #include "config.h" #include "conf.h" -#define DEBUG_FLAG DEBUG_CONF +#define P11_DEBUG_FLAG P11_DEBUG_CONF #include "debug.h" +#include "library.h" #include "private.h" -#include "util.h" #include <sys/param.h> #include <sys/stat.h> @@ -167,20 +167,20 @@ read_config_file (const char* filename, int flags) error = errno; if ((flags & CONF_IGNORE_MISSING) && (error == ENOENT || error == ENOTDIR)) { - _p11_debug ("config file does not exist"); + p11_debug ("config file does not exist"); config = strdup ("\n"); return_val_if_fail (config != NULL, NULL); return config; } else if ((flags & CONF_IGNORE_ACCESS_DENIED) && (error == EPERM || error == EACCES)) { - _p11_debug ("config file is inaccessible"); + p11_debug ("config file is inaccessible"); config = strdup ("\n"); return_val_if_fail (config != NULL, NULL); return config; } - _p11_message ("couldn't open config file: %s: %s", filename, - strerror (error)); + p11_message ("couldn't open config file: %s: %s", filename, + strerror (error)); errno = error; return NULL; } @@ -190,14 +190,14 @@ read_config_file (const char* filename, int flags) (len = ftell (f)) == -1 || fseek (f, 0, SEEK_SET) == -1) { error = errno; - _p11_message ("couldn't seek config file: %s", filename); + p11_message ("couldn't seek config file: %s", filename); errno = error; return NULL; } config = malloc (len + 2); if (config == NULL) { - _p11_message ("config file is too large to read into memory: %lu", len); + p11_message ("config file is too large to read into memory: %lu", len); errno = ENOMEM; return NULL; } @@ -205,7 +205,7 @@ read_config_file (const char* filename, int flags) /* And read in one block */ if (fread (config, 1, len, f) != len) { error = errno; - _p11_message ("couldn't read config file: %s", filename); + p11_message ("couldn't read config file: %s", filename); errno = error; return NULL; } @@ -223,34 +223,35 @@ read_config_file (const char* filename, int flags) } int -_p11_conf_merge_defaults (hashmap *map, hashmap *defaults) +_p11_conf_merge_defaults (p11_dict *map, + p11_dict *defaults) { - hashiter iter; + p11_dictiter iter; void *key; void *value; - _p11_hash_iterate (defaults, &iter); - while (_p11_hash_next (&iter, &key, &value)) { + p11_dict_iterate (defaults, &iter); + while (p11_dict_next (&iter, &key, &value)) { /* Only override if not set */ - if (_p11_hash_get (map, key)) + if (p11_dict_get (map, key)) continue; key = strdup (key); return_val_if_fail (key != NULL, -1); value = strdup (value); return_val_if_fail (key != NULL, -1); - if (!_p11_hash_set (map, key, value)) + if (!p11_dict_set (map, key, value)) return_val_if_reached (-1); } return 0; } -hashmap * +p11_dict * _p11_conf_parse_file (const char* filename, int flags) { char *name; char *value; - hashmap *map = NULL; + p11_dict *map = NULL; char *data; char *next; char *end; @@ -258,14 +259,14 @@ _p11_conf_parse_file (const char* filename, int flags) assert (filename); - _p11_debug ("reading config file: %s", filename); + p11_debug ("reading config file: %s", filename); /* Adds an extra newline to end of file */ data = read_config_file (filename, flags); if (!data) return NULL; - map = _p11_hash_create (_p11_hash_string_hash, _p11_hash_string_equal, free, free); + map = p11_dict_new (p11_dict_str_hash, p11_dict_str_equal, free, free); return_val_if_fail (map != NULL, NULL); next = data; @@ -283,7 +284,7 @@ _p11_conf_parse_file (const char* filename, int flags) /* Look for the break between name: value on the same line */ value = name + strcspn (name, ":"); if (!*value) { - _p11_message ("%s: invalid config line: %s", filename, name); + p11_message ("%s: invalid config line: %s", filename, name); error = EINVAL; break; } @@ -301,16 +302,16 @@ _p11_conf_parse_file (const char* filename, int flags) value = strdup (value); return_val_if_fail (value != NULL, NULL); - _p11_debug ("config value: %s: %s", name, value); + p11_debug ("config value: %s: %s", name, value); - if (!_p11_hash_set (map, name, value)) + if (!p11_dict_set (map, name, value)) return_val_if_reached (NULL); } free (data); if (error != 0) { - _p11_hash_free (map); + p11_dict_free (map); map = NULL; errno = error; } @@ -339,8 +340,8 @@ expand_user_path (const char *path) pwd = getpwuid (getuid ()); if (!pwd) { error = errno; - _p11_message ("couldn't lookup home directory for user %d: %s", - getuid (), strerror (errno)); + p11_message ("couldn't lookup home directory for user %d: %s", + getuid (), strerror (errno)); errno = error; return NULL; } @@ -362,12 +363,13 @@ expand_user_path (const char *path) } static int -user_config_mode (hashmap *config, int defmode) +user_config_mode (p11_dict *config, + int defmode) { const char *mode; /* Whether we should use or override from user directory */ - mode = _p11_hash_get (config, "user-config"); + mode = p11_dict_get (config, "user-config"); if (mode == NULL) { return defmode; } else if (strequal (mode, "none")) { @@ -379,18 +381,18 @@ user_config_mode (hashmap *config, int defmode) } else if (strequal (mode, "override")) { return CONF_USER_ONLY; } else { - _p11_message ("invalid mode for 'user-config': %s", mode); + p11_message ("invalid mode for 'user-config': %s", mode); return CONF_USER_INVALID; } } -hashmap * +p11_dict * _p11_conf_load_globals (const char *system_conf, const char *user_conf, int *user_mode) { - hashmap *config = NULL; - hashmap *uconfig = NULL; - hashmap *result = NULL; + p11_dict *config = NULL; + p11_dict *uconfig = NULL; + p11_dict *result = NULL; char *path = NULL; int error = 0; int flags; @@ -447,7 +449,7 @@ _p11_conf_load_globals (const char *system_conf, const char *user_conf, /* If user config valid at all, then replace system with what we have */ if (mode != CONF_USER_NONE) { - _p11_hash_free (config); + p11_dict_free (config); config = uconfig; uconfig = NULL; } @@ -461,8 +463,8 @@ _p11_conf_load_globals (const char *system_conf, const char *user_conf, finished: free (path); - _p11_hash_free (config); - _p11_hash_free (uconfig); + p11_dict_free (config); + p11_dict_free (uconfig); errno = error; return result; } @@ -510,11 +512,11 @@ calc_name_from_filename (const char *fname) static int load_config_from_file (const char *configfile, const char *name, - hashmap *configs, + p11_dict *configs, int flags) { - hashmap *config; - hashmap *prev; + p11_dict *config; + p11_dict *prev; char *key; int error = 0; @@ -522,7 +524,7 @@ load_config_from_file (const char *configfile, key = calc_name_from_filename (name); if (key == NULL) { - _p11_message ("invalid config filename, will be ignored in the future: %s", configfile); + p11_message ("invalid config filename, will be ignored in the future: %s", configfile); key = strdup (name); return_val_if_fail (key != NULL, -1); } @@ -533,9 +535,9 @@ load_config_from_file (const char *configfile, return -1; } - prev = _p11_hash_get (configs, key); + prev = p11_dict_get (configs, key); if (prev == NULL) { - if (!_p11_hash_set (configs, key, config)) + if (!p11_dict_set (configs, key, config)) return_val_if_reached (-1); config = NULL; } else { @@ -545,7 +547,7 @@ load_config_from_file (const char *configfile, } /* If still set */ - _p11_hash_free (config); + p11_dict_free (config); if (error) { errno = error; @@ -557,7 +559,7 @@ load_config_from_file (const char *configfile, static int load_configs_from_directory (const char *directory, - hashmap *configs, + p11_dict *configs, int flags) { struct dirent *dp; @@ -568,7 +570,7 @@ load_configs_from_directory (const char *directory, char *path; int count = 0; - _p11_debug ("loading module configs in: %s", directory); + p11_debug ("loading module configs in: %s", directory); /* First we load all the modules */ dir = opendir (directory); @@ -576,15 +578,15 @@ load_configs_from_directory (const char *directory, error = errno; if ((flags & CONF_IGNORE_MISSING) && (errno == ENOENT || errno == ENOTDIR)) { - _p11_debug ("module configs do not exist"); + p11_debug ("module configs do not exist"); return 0; } else if ((flags & CONF_IGNORE_ACCESS_DENIED) && (errno == EPERM || errno == EACCES)) { - _p11_debug ("couldn't list inacessible module configs"); + p11_debug ("couldn't list inacessible module configs"); return 0; } - _p11_message ("couldn't list directory: %s: %s", directory, - strerror (error)); + p11_message ("couldn't list directory: %s: %s", directory, + strerror (error)); errno = error; return -1; } @@ -603,7 +605,7 @@ load_configs_from_directory (const char *directory, { if (stat (path, &st) < 0) { error = errno; - _p11_message ("couldn't stat path: %s", path); + p11_message ("couldn't stat path: %s", path); free (path); break; } @@ -630,17 +632,17 @@ load_configs_from_directory (const char *directory, return count; } -hashmap * +p11_dict * _p11_conf_load_modules (int mode, const char *system_dir, const char *user_dir) { - hashmap *configs; + p11_dict *configs; char *path; int error = 0; int flags; /* A hash table of name -> config */ - configs = _p11_hash_create (_p11_hash_string_hash, _p11_hash_string_equal, - free, (hash_destroy_func)_p11_hash_free); + configs = p11_dict_new (p11_dict_str_hash, p11_dict_str_equal, + free, (p11_destroyer)p11_dict_free); /* Load each user config first, if user config is allowed */ if (mode != CONF_USER_NONE) { @@ -652,7 +654,7 @@ _p11_conf_load_modules (int mode, const char *system_dir, const char *user_dir) error = errno; free (path); if (error != 0) { - _p11_hash_free (configs); + p11_dict_free (configs); errno = error; return NULL; } @@ -667,7 +669,7 @@ _p11_conf_load_modules (int mode, const char *system_dir, const char *user_dir) flags = CONF_IGNORE_MISSING; if (load_configs_from_directory (system_dir, configs, flags) < 0) { error = errno; - _p11_hash_free (configs); + p11_dict_free (configs); errno = error; return NULL; } @@ -688,8 +690,8 @@ _p11_conf_parse_boolean (const char *string, } else if (strcmp (string, "no") == 0) { return 0; } else { - _p11_message ("invalid setting '%s' defaulting to '%s'", - string, default_value ? "yes" : "no"); + p11_message ("invalid setting '%s' defaulting to '%s'", + string, default_value ? "yes" : "no"); return default_value; } } diff --git a/p11-kit/conf.h b/p11-kit/conf.h index 0627f14..b70666d 100644 --- a/p11-kit/conf.h +++ b/p11-kit/conf.h @@ -36,7 +36,7 @@ #ifndef __CONF_H__ #define __CONF_H__ -#include "hashmap.h" +#include "dict.h" enum { CONF_IGNORE_MISSING = 0x01, @@ -50,19 +50,21 @@ enum { CONF_USER_ONLY }; -int _p11_conf_merge_defaults (hashmap *config, - hashmap *defaults); +int _p11_conf_merge_defaults (p11_dict *config, + p11_dict *defaults); /* Returns a hash of char *key -> char *value */ -hashmap * _p11_conf_parse_file (const char *filename, +p11_dict * _p11_conf_parse_file (const char *filename, int flags); /* Returns a hash of char *key -> char *value */ -hashmap * _p11_conf_load_globals (const char *system_conf, const char *user_conf, +p11_dict * _p11_conf_load_globals (const char *system_conf, + const char *user_conf, int *user_mode); /* Returns a hash of char* name -> hash_t *config */ -hashmap * _p11_conf_load_modules (int user_mode, const char *system_dir, +p11_dict * _p11_conf_load_modules (int user_mode, + const char *system_dir, const char *user_dir); int _p11_conf_parse_boolean (const char *string, diff --git a/p11-kit/debug.c b/p11-kit/debug.c deleted file mode 100644 index a665d0f..0000000 --- a/p11-kit/debug.c +++ /dev/null @@ -1,151 +0,0 @@ -/* - * Copyright (c) 2011 Collabora Ltd. - * - * 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 "debug.h" - -#include <assert.h> -#include <stdio.h> -#include <stdarg.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> - -struct DebugKey { - const char *name; - int value; -}; - -static struct DebugKey debug_keys[] = { - { "lib", DEBUG_LIB }, - { "conf", DEBUG_CONF }, - { "uri", DEBUG_URI }, - { "proxy", DEBUG_PROXY }, - { 0, } -}; - -static int debug_inited = 0; -static int debug_strict = 0; - -/* global variable exported in debug.h */ -int _p11_debug_current_flags = ~0; - -static int -parse_environ_flags (void) -{ - const char *env; - int result = 0; - const char *p; - const char *q; - int i; - - env = getenv ("P11_KIT_STRICT"); - if (env && env[0] != '\0') - debug_strict = 1; - - env = getenv ("P11_KIT_DEBUG"); - if (!env) - return 0; - - if (strcmp (env, "all") == 0) { - for (i = 0; debug_keys[i].name; i++) - result |= debug_keys[i].value; - - } else if (strcmp (env, "help") == 0) { - fprintf (stderr, "Supported debug values:"); - for (i = 0; debug_keys[i].name; i++) - fprintf (stderr, " %s", debug_keys[i].name); - fprintf (stderr, "\n"); - - } else { - p = env; - while (*p) { - q = strpbrk (p, ":;, \t"); - if (!q) - q = p + strlen (p); - - for (i = 0; debug_keys[i].name; i++) { - if (q - p == strlen (debug_keys[i].name) && - strncmp (debug_keys[i].name, p, q - p) == 0) - result |= debug_keys[i].value; - } - - p = q; - if (*p) - p++; - } - } - - return result; -} - -void -_p11_debug_init (void) -{ - _p11_debug_current_flags = parse_environ_flags (); - debug_inited = 1; -} - -void -_p11_debug_message (int flag, - const char *format, ...) -{ - char buffer[512]; - va_list args; - - if (flag & _p11_debug_current_flags) { - va_start (args, format); - vsnprintf (buffer, sizeof (buffer), format, args); - buffer[sizeof (buffer) -1] = 0; - va_end (args); - fprintf (stderr, "(p11-kit:%d) %s\n", getpid(), buffer); - } -} - -void -_p11_debug_precond (const char *format, - ...) -{ - va_list va; - - va_start (va, format); - vfprintf (stderr, format, va); - va_end (va); - - if (debug_strict) - abort (); -} diff --git a/p11-kit/debug.h b/p11-kit/debug.h deleted file mode 100644 index c6e26f5..0000000 --- a/p11-kit/debug.h +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Copyright (c) 2011 Collabora Ltd. - * - * 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@collabora.co.uk> - */ - -#ifndef DEBUG_H -#define DEBUG_H - -#include "compat.h" - -/* Please keep this enum in sync with keys in debug.c */ -typedef enum { - DEBUG_LIB = 1 << 1, - DEBUG_CONF = 1 << 2, - DEBUG_URI = 1 << 3, - DEBUG_PROXY = 1 << 4, -} DebugFlags; - -extern int _p11_debug_current_flags; - -void _p11_debug_init (void); - -void _p11_debug_message (int flag, - const char *format, - ...) GNUC_PRINTF (2, 3); - -void _p11_debug_precond (const char *format, - ...) GNUC_PRINTF (1, 2); - -#define assert_not_reached() \ - (assert (0 && "this code should not be reached")) - -#define return_val_if_fail(x, v) \ - do { if (!(x)) { \ - _p11_debug_precond ("p11-kit: '%s' not true at %s\n", #x, __func__); \ - return v; \ - } } while (0) - -#define return_if_fail(x) \ - do { if (!(x)) { \ - _p11_debug_precond ("p11-kit: '%s' not true at %s\n", #x, __func__); \ - return; \ - } } while (0) - -#define return_if_reached() \ - do { \ - _p11_debug_precond ("p11-kit: shouldn't be reached at %s\n", __func__); \ - return; \ - } while (0) - -#define return_val_if_reached(v) \ - do { \ - _p11_debug_precond ("p11-kit: shouldn't be reached at %s\n", __func__); \ - return v; \ - } while (0) - -#endif /* DEBUG_H */ - -/* ----------------------------------------------------------------------------- - * Below this point is outside the DEBUG_H guard - so it can take effect - * more than once. So you can do: - * - * #define DEBUG_FLAG DEBUG_ONE_THING - * #include "debug.h" - * ... - * DEBUG ("if we're debugging one thing"); - * ... - * #undef DEBUG_FLAG - * #define DEBUG_FLAG DEBUG_OTHER_THING - * #include "debug.h" - * ... - * DEBUG ("if we're debugging the other thing"); - * ... - */ - -#ifdef DEBUG_FLAG -#ifdef WITH_DEBUG - -#undef _p11_debug -#define _p11_debug(format, ...) do { \ - if (DEBUG_FLAG & _p11_debug_current_flags) \ - _p11_debug_message (DEBUG_FLAG, "%s: " format, __PRETTY_FUNCTION__, ##__VA_ARGS__); \ - } while (0) - -#undef _p11_debugging -#define _p11_debugging \ - (DEBUG_FLAG & _p11_debug_current_flags) - -#else /* !defined (WITH_DEBUG) */ - -#undef _p11_debug -#define _p11_debug(format, ...) \ - do {} while (0) - -#undef _p11_debugging -#define _p11_debugging 0 - -#endif /* !defined (WITH_DEBUG) */ - -#endif /* defined (DEBUG_FLAG) */ diff --git a/p11-kit/hashmap.c b/p11-kit/hashmap.c deleted file mode 100644 index d420221..0000000 --- a/p11-kit/hashmap.c +++ /dev/null @@ -1,391 +0,0 @@ -/* - * Copyright (c) 2004 Stefan Walter - * Copyright (c) 2011 Collabora Ltd. - * - * 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. - */ - -#include "config.h" - -#include "hashmap.h" - -#include <sys/types.h> - -#include <assert.h> -#include <stdlib.h> -#include <string.h> - -struct _hashmap { - hash_hash_func hash_func; - hash_equal_func equal_func; - hash_destroy_func key_destroy_func; - hash_destroy_func value_destroy_func; - - struct _hashbucket **buckets; - unsigned int num_items; - unsigned int num_buckets; -}; - -typedef struct _hashbucket { - void *key; - unsigned int hashed; - void *value; - struct _hashbucket *next; -} hashbucket; - -static hashbucket * -next_entry (hashiter *iter) -{ - hashbucket *bucket = iter->next; - while (!bucket) { - if (iter->index >= iter->map->num_buckets) - return NULL; - bucket = iter->map->buckets[iter->index++]; - } - iter->next = bucket->next; - return bucket; -} - - -int -_p11_hash_next (hashiter *iter, - void **key, - void **value) -{ - hashbucket *bucket = next_entry (iter); - if (bucket == NULL) - return 0; - if (key) - *key = bucket->key; - if (value) - *value = bucket->value; - return 1; -} - -void -_p11_hash_iterate (hashmap *map, - hashiter *iter) -{ - iter->map = map; - iter->index = 0; - iter->next = NULL; -} - -static hashbucket ** -lookup_or_create_bucket (hashmap *map, - const void *key, - int create) -{ - hashbucket **bucketp; - unsigned int hash; - - /* Perform the hashing */ - hash = map->hash_func (key); - - /* scan linked list */ - for (bucketp = &map->buckets[hash % map->num_buckets]; - *bucketp != NULL; bucketp = &(*bucketp)->next) { - if((*bucketp)->hashed == hash && map->equal_func ((*bucketp)->key, key)) - break; - } - - if ((*bucketp) != NULL || !create) - return bucketp; - - /* add a new entry for non-NULL val */ - (*bucketp) = calloc (sizeof (hashbucket), 1); - - if (*bucketp != NULL) { - (*bucketp)->key = (void*)key; - (*bucketp)->hashed = hash; - map->num_items++; - } - - return bucketp; -} - -void * -_p11_hash_get (hashmap *map, - const void *key) -{ - hashbucket **bucketp; - - bucketp = lookup_or_create_bucket (map, key, 0); - if (bucketp && *bucketp) - return (void*)((*bucketp)->value); - else - return NULL; -} - -int -_p11_hash_set (hashmap *map, - void *key, - void *val) -{ - hashbucket **bucketp; - hashiter iter; - hashbucket *bucket; - hashbucket **new_buckets; - unsigned int num_buckets; - - bucketp = lookup_or_create_bucket (map, key, 1); - if(bucketp && *bucketp) { - - /* Destroy the previous key */ - if ((*bucketp)->key && (*bucketp)->key != key && map->key_destroy_func) - map->key_destroy_func ((*bucketp)->key); - - /* Destroy the previous value */ - if ((*bucketp)->value && (*bucketp)->value != val && map->value_destroy_func) - map->value_destroy_func ((*bucketp)->value); - - /* replace entry */ - (*bucketp)->key = key; - (*bucketp)->value = val; - - /* check that the collision rate isn't too high */ - if (map->num_items > map->num_buckets) { - num_buckets = map->num_buckets * 2 + 1; - new_buckets = (hashbucket **)calloc (sizeof (hashbucket *), num_buckets); - - /* Ignore failures, maybe we can expand later */ - if(new_buckets) { - _p11_hash_iterate (map, &iter); - while ((bucket = next_entry (&iter)) != NULL) { - unsigned int i = bucket->hashed % num_buckets; - bucket->next = new_buckets[i]; - new_buckets[i] = bucket; - } - - free (map->buckets); - map->buckets = new_buckets; - map->num_buckets = num_buckets; - } - } - - return 1; - } - - return 0; -} - -int -_p11_hash_steal (hashmap *map, - const void *key, - void **stolen_key, - void **stolen_value) -{ - hashbucket **bucketp; - - bucketp = lookup_or_create_bucket (map, key, 0); - if (bucketp && *bucketp) { - hashbucket *old = *bucketp; - *bucketp = (*bucketp)->next; - --map->num_items; - if (stolen_key) - *stolen_key = old->key; - if (stolen_value) - *stolen_value = old->value; - free (old); - return 1; - } - - return 0; - -} - -int -_p11_hash_remove (hashmap *map, - const void *key) -{ - void *old_key; - void *old_value; - - if (!_p11_hash_steal (map, key, &old_key, &old_value)) - return 0; - - if (map->key_destroy_func) - map->key_destroy_func (old_key); - if (map->value_destroy_func) - map->value_destroy_func (old_value); - return 1; -} - -void -_p11_hash_clear (hashmap *map) -{ - hashbucket *bucket, *next; - int i; - - /* Free all entries in the array */ - for (i = 0; i < map->num_buckets; ++i) { - bucket = map->buckets[i]; - while (bucket != NULL) { - next = bucket->next; - if (map->key_destroy_func) - map->key_destroy_func (bucket->key); - if (map->value_destroy_func) - map->value_destroy_func (bucket->value); - free (bucket); - bucket = next; - } - } - - memset (map->buckets, 0, map->num_buckets * sizeof (hashbucket *)); - map->num_items = 0; -} - -hashmap * -_p11_hash_create (hash_hash_func hash_func, - hash_equal_func equal_func, - hash_destroy_func key_destroy_func, - hash_destroy_func value_destroy_func) -{ - hashmap *map; - - assert (hash_func); - assert (equal_func); - - map = malloc (sizeof (hashmap)); - if (map) { - map->hash_func = hash_func; - map->equal_func = equal_func; - map->key_destroy_func = key_destroy_func; - map->value_destroy_func = value_destroy_func; - - map->num_buckets = 9; - map->buckets = (hashbucket **)calloc (sizeof (hashbucket *), map->num_buckets); - if (!map->buckets) { - free (map); - return NULL; - } - - map->num_items = 0; - } - - return map; -} - -void -_p11_hash_free (hashmap *map) -{ - hashbucket *bucket; - hashiter iter; - - if (!map) - return; - - _p11_hash_iterate (map, &iter); - while ((bucket = next_entry (&iter)) != NULL) { - if (map->key_destroy_func) - map->key_destroy_func (bucket->key); - if (map->value_destroy_func) - map->value_destroy_func (bucket->value); - free (bucket); - } - - if (map->buckets) - free (map->buckets); - - free (map); -} - -unsigned int -_p11_hash_size (hashmap *map) -{ - return map->num_items; -} - -unsigned int -_p11_hash_string_hash (const void *string) -{ - const char *p = string; - unsigned int hash = *p; - - if (hash) - for (p += 1; *p != '\0'; p++) - hash = (hash << 5) - hash + *p; - - return hash; -} - -int -_p11_hash_string_equal (const void *string_one, - const void *string_two) -{ - assert (string_one); - assert (string_two); - - return strcmp (string_one, string_two) == 0; -} - -unsigned int -_p11_hash_ulongptr_hash (const void *to_ulong) -{ - assert (to_ulong); - return (unsigned int)*((unsigned long*)to_ulong); -} - -int -_p11_hash_ulongptr_equal (const void *ulong_one, - const void *ulong_two) -{ - assert (ulong_one); - assert (ulong_two); - return *((unsigned long*)ulong_one) == *((unsigned long*)ulong_two); -} - -unsigned int -_p11_hash_intptr_hash (const void *to_int) -{ - assert (to_int); - return (unsigned int)*((int*)to_int); -} - -int -_p11_hash_intptr_equal (const void *int_one, - const void *int_two) -{ - assert (int_one); - assert (int_two); - return *((int*)int_one) == *((int*)int_two); -} - -unsigned int -_p11_hash_direct_hash (const void *ptr) -{ - return (unsigned int)(size_t)ptr; -} - -int -_p11_hash_direct_equal (const void *ptr_one, - const void *ptr_two) -{ - return ptr_one == ptr_two; -} diff --git a/p11-kit/hashmap.h b/p11-kit/hashmap.h deleted file mode 100644 index 3b35487..0000000 --- a/p11-kit/hashmap.h +++ /dev/null @@ -1,173 +0,0 @@ -/* - * Copyright (c) 2004 Stefan Walter - * Copyright (c) 2011 Collabora Ltd. - * - * 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 Waler <stefw@collabora.co.uk> - */ - -#ifndef HASHMAP_H_ -#define HASHMAP_H_ - -#include <sys/types.h> - -/* - * ARGUMENT DOCUMENTATION - * - * map: The hashmap - * key: Pointer to the key value - * val: Pointer to the value - * iter: A hashmap iterator - */ - - -/* ---------------------------------------------------------------------------------- - * TYPES - */ - -/* Abstract type for hash maps. */ -typedef struct _hashmap hashmap; - -/* Type for scanning hash tables. */ -typedef struct _hashiter { - hashmap *map; - struct _hashbucket *next; - unsigned int index; -} hashiter; - -typedef unsigned int (*hash_hash_func) (const void *data); - -typedef int (*hash_equal_func) (const void *one, - const void *two); - -typedef void (*hash_destroy_func) (void *data); - -/* ----------------------------------------------------------------------------- - * MAIN - */ - -/* - * _p11_hash_create : Create a hash table - * - returns an allocated hashtable - */ -hashmap* _p11_hash_create (hash_hash_func hash_func, - hash_equal_func equal_func, - hash_destroy_func key_destroy_func, - hash_destroy_func value_destroy_func); - -/* - * _p11_hash_free : Free a hash table - */ -void _p11_hash_free (hashmap *map); - -/* - * _p11_hash_size: Number of values in hash table - * - returns the number of entries in hash table - */ -unsigned int _p11_hash_size (hashmap *map); - -/* - * _p11_hash_get: Retrieves a value from the hash table - * - returns the value of the entry - */ -void* _p11_hash_get (hashmap *map, - const void *key); - -/* - * _p11_hash_set: Set a value in the hash table - * - returns 1 if the entry was added properly - */ -int _p11_hash_set (hashmap *map, - void *key, - void *value); - -/* - * _p11_hash_remove: Remove a value from the hash table - * - returns 1 if the entry was found - */ -int _p11_hash_remove (hashmap *map, - const void *key); - -/* - * _p11_hash_steal: Remove a value from the hash table without calling - * destroy funcs - * - returns 1 if the entry was found - */ -int _p11_hash_steal (hashmap *map, - const void *key, - void **stolen_key, - void **stolen_value); - -/* - * _p11_hash_iterate: Start enumerating through the hash table - * - returns a hash iterator - */ -void _p11_hash_iterate (hashmap *map, - hashiter *iter); - -/* - * _p11_hash_next: Enumerate through hash table - * - sets key and value to key and/or value - * - returns whether there was another entry - */ -int _p11_hash_next (hashiter *iter, - void **key, - void **value); - -/* - * _p11_hash_clear: Clear all values from has htable. - */ -void _p11_hash_clear (hashmap *map); - -/* ----------------------------------------------------------------------------- - * HASH FUNCTIONS - */ - -unsigned int _p11_hash_string_hash (const void *string); - -int _p11_hash_string_equal (const void *string_one, - const void *string_two); - -unsigned int _p11_hash_ulongptr_hash (const void *to_ulong); - -int _p11_hash_ulongptr_equal (const void *ulong_one, - const void *ulong_two); - -unsigned int _p11_hash_intptr_hash (const void *to_int); - -int _p11_hash_intptr_equal (const void *int_one, - const void *int_two); - -unsigned int _p11_hash_direct_hash (const void *ptr); - -int _p11_hash_direct_equal (const void *ptr_one, - const void *ptr_two); - -#endif /* __HASHMAP_H__ */ diff --git a/p11-kit/modules.c b/p11-kit/modules.c index c097c4b..e4b0f66 100644 --- a/p11-kit/modules.c +++ b/p11-kit/modules.c @@ -36,9 +36,10 @@ #include "config.h" #include "conf.h" -#define DEBUG_FLAG DEBUG_LIB +#define P11_DEBUG_FLAG P11_DEBUG_LIB #include "debug.h" -#include "hashmap.h" +#include "dict.h" +#include "library.h" #include "pkcs11.h" #include "p11-kit.h" #include "private.h" @@ -101,15 +102,15 @@ typedef struct _Module { /* Registered modules */ char *name; - hashmap *config; + p11_dict *config; /* Loaded modules */ dl_module_t dl_module; /* Initialization, mutex must be held */ - mutex_t initialize_mutex; + p11_mutex_t initialize_mutex; int initialize_called; - thread_id_t initialize_thread; + p11_thread_id_t initialize_thread; } Module; /* @@ -117,8 +118,8 @@ typedef struct _Module { * we can audit thread safety easier. */ static struct _Shared { - hashmap *modules; - hashmap *config; + p11_dict *modules; + p11_dict *config; } gl = { NULL, NULL }; /* ----------------------------------------------------------------------------- @@ -128,14 +129,14 @@ static struct _Shared { static CK_RV create_mutex (CK_VOID_PTR_PTR mut) { - mutex_t *pmutex; + p11_mutex_t *pmutex; return_val_if_fail (mut != NULL, CKR_ARGUMENTS_BAD); - pmutex = malloc (sizeof (mutex_t)); + pmutex = malloc (sizeof (p11_mutex_t)); return_val_if_fail (pmutex != NULL, CKR_HOST_MEMORY); - _p11_mutex_init (pmutex); + p11_mutex_init (pmutex); *mut = pmutex; return CKR_OK; } @@ -143,11 +144,11 @@ create_mutex (CK_VOID_PTR_PTR mut) static CK_RV destroy_mutex (CK_VOID_PTR mut) { - mutex_t *pmutex = mut; + p11_mutex_t *pmutex = mut; return_val_if_fail (mut != NULL, CKR_MUTEX_BAD); - _p11_mutex_uninit (pmutex); + p11_mutex_uninit (pmutex); free (pmutex); return CKR_OK; } @@ -155,22 +156,22 @@ destroy_mutex (CK_VOID_PTR mut) static CK_RV lock_mutex (CK_VOID_PTR mut) { - mutex_t *pmutex = mut; + p11_mutex_t *pmutex = mut; return_val_if_fail (mut != NULL, CKR_MUTEX_BAD); - _p11_mutex_lock (pmutex); + p11_mutex_lock (pmutex); return CKR_OK; } static CK_RV unlock_mutex (CK_VOID_PTR mut) { - mutex_t *pmutex = mut; + p11_mutex_t *pmutex = mut; return_val_if_fail (mut != NULL, CKR_MUTEX_BAD); - _p11_mutex_unlock (pmutex); + p11_mutex_unlock (pmutex); return CKR_OK; } @@ -189,10 +190,10 @@ free_module_unlocked (void *data) assert (mod->ref_count == 0); if (mod->dl_module) - _p11_module_close (mod->dl_module); + p11_module_close (mod->dl_module); - _p11_mutex_uninit (&mod->initialize_mutex); - _p11_hash_free (mod->config); + p11_mutex_uninit (&mod->initialize_mutex); + p11_dict_free (mod->config); free (mod->name); free (mod); } @@ -210,7 +211,7 @@ alloc_module_unlocked (void) mod->init_args.LockMutex = lock_mutex; mod->init_args.UnlockMutex = unlock_mutex; mod->init_args.flags = CKF_OS_LOCKING_OK; - _p11_mutex_init (&mod->initialize_mutex); + p11_mutex_init (&mod->initialize_mutex); return mod; } @@ -257,27 +258,27 @@ dlopen_and_get_function_list (Module *mod, const char *path) assert (mod); assert (path); - mod->dl_module = _p11_module_open (path); + mod->dl_module = p11_module_open (path); if (mod->dl_module == NULL) { - _p11_message ("couldn't load module: %s: %s", path, _p11_module_error ()); + p11_message ("couldn't load module: %s: %s", path, p11_module_error ()); return CKR_GENERAL_ERROR; } - gfl = _p11_module_symbol (mod->dl_module, "C_GetFunctionList"); + gfl = p11_module_symbol (mod->dl_module, "C_GetFunctionList"); if (!gfl) { - _p11_message ("couldn't find C_GetFunctionList entry point in module: %s: %s", - path, _p11_module_error ()); + p11_message ("couldn't find C_GetFunctionList entry point in module: %s: %s", + path, p11_module_error ()); return CKR_GENERAL_ERROR; } rv = gfl (&mod->funcs); if (rv != CKR_OK) { - _p11_message ("call to C_GetFunctiontList failed in module: %s: %s", - path, p11_kit_strerror (rv)); + p11_message ("call to C_GetFunctiontList failed in module: %s: %s", + path, p11_kit_strerror (rv)); return rv; } - _p11_debug ("opened module: %s", path); + p11_debug ("opened module: %s", path); return CKR_OK; } @@ -298,14 +299,14 @@ load_module_from_file_unlocked (const char *path, Module **result) } /* Do we have a previous one like this, if so ignore load */ - prev = _p11_hash_get (gl.modules, mod->funcs); + prev = p11_dict_get (gl.modules, mod->funcs); if (prev != NULL) { - _p11_debug ("duplicate module %s, using previous", path); + p11_debug ("duplicate module %s, using previous", path); free_module_unlocked (mod); mod = prev; - } else if (!_p11_hash_set (gl.modules, mod->funcs, mod)) { + } else if (!p11_dict_set (gl.modules, mod->funcs, mod)) { return_val_if_reached (CKR_HOST_MEMORY); } @@ -320,7 +321,7 @@ expand_module_path (const char *filename) char *path; if (is_relative_path (filename)) { - _p11_debug ("module path is relative, loading from: %s", P11_MODULE_PATH); + p11_debug ("module path is relative, loading from: %s", P11_MODULE_PATH); path = build_path (P11_MODULE_PATH, filename); } else { path = strdup (filename); @@ -355,15 +356,15 @@ is_string_in_list (const char *list, static int is_module_enabled_unlocked (const char *name, - hashmap *config) + p11_dict *config) { const char *progname; const char *enable_in; const char *disable_in; int enable = 0; - enable_in = _p11_hash_get (config, "enable-in"); - disable_in = _p11_hash_get (config, "disable-in"); + enable_in = p11_dict_get (config, "enable-in"); + disable_in = p11_dict_get (config, "disable-in"); /* Defaults to enabled if neither of these are set */ if (!enable_in && !disable_in) @@ -371,13 +372,13 @@ is_module_enabled_unlocked (const char *name, progname = _p11_get_progname_unlocked (); if (enable_in && disable_in) - _p11_message ("module '%s' has both enable-in and disable-in options", name); + p11_message ("module '%s' has both enable-in and disable-in options", name); if (enable_in) enable = (progname != NULL && is_string_in_list (enable_in, progname)); else if (disable_in) enable = (progname == NULL || !is_string_in_list (disable_in, progname)); - _p11_debug ("%s module '%s' running in '%s'", + p11_debug ("%s module '%s' running in '%s'", enable ? "enabled" : "disabled", name, progname ? progname : "(null)"); @@ -385,7 +386,8 @@ is_module_enabled_unlocked (const char *name, } static CK_RV -take_config_and_load_module_unlocked (char **name, hashmap **config) +take_config_and_load_module_unlocked (char **name, + p11_dict **config) { Module *mod, *prev; const char *module_filename; @@ -401,9 +403,9 @@ take_config_and_load_module_unlocked (char **name, hashmap **config) if (!is_module_enabled_unlocked (*name, *config)) return CKR_OK; - module_filename = _p11_hash_get (*config, "module"); + module_filename = p11_dict_get (*config, "module"); if (module_filename == NULL) { - _p11_debug ("no module path for module, skipping: %s", *name); + p11_debug ("no module path for module, skipping: %s", *name); return CKR_OK; } @@ -414,7 +416,7 @@ take_config_and_load_module_unlocked (char **name, hashmap **config) return_val_if_fail (key != NULL, CKR_HOST_MEMORY); /* The hash map will take ownership of the variable */ - if (!_p11_hash_set (*config, key, path)) + if (!p11_dict_set (*config, key, path)) return_val_if_reached (CKR_HOST_MEMORY); mod = alloc_module_unlocked (); @@ -437,9 +439,9 @@ take_config_and_load_module_unlocked (char **name, hashmap **config) * 'x-init-reserved' setting in the config. This only works with specific * PKCS#11 modules, and is non-standard use of that field. */ - mod->init_args.pReserved = _p11_hash_get (mod->config, "x-init-reserved"); + mod->init_args.pReserved = p11_dict_get (mod->config, "x-init-reserved"); - prev = _p11_hash_get (gl.modules, mod->funcs); + prev = p11_dict_get (gl.modules, mod->funcs); /* If same module was loaded previously, just take over config */ if (prev && !prev->name && !prev->config) { @@ -451,12 +453,12 @@ take_config_and_load_module_unlocked (char **name, hashmap **config) /* Ignore duplicate module */ } else if (prev) { - _p11_message ("duplicate configured module: %s: %s", mod->name, path); + 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_hash_set (gl.modules, mod->funcs, mod)) + if (!p11_dict_set (gl.modules, mod->funcs, mod)) return_val_if_reached (CKR_HOST_MEMORY); } @@ -466,11 +468,11 @@ take_config_and_load_module_unlocked (char **name, hashmap **config) static CK_RV load_registered_modules_unlocked (void) { - hashiter iter; - hashmap *configs; + p11_dictiter iter; + p11_dict *configs; void *key; char *name; - hashmap *config; + p11_dict *config; int mode; CK_RV rv; int critical; @@ -489,7 +491,7 @@ load_registered_modules_unlocked (void) P11_USER_CONFIG_MODULES); if (configs == NULL) { rv = CKR_GENERAL_ERROR; - _p11_hash_free (config); + p11_dict_free (config); return rv; } @@ -500,13 +502,13 @@ load_registered_modules_unlocked (void) * Now go through each config and turn it into a module. As we iterate * we steal the values of the config. */ - _p11_hash_iterate (configs, &iter); - while (_p11_hash_next (&iter, &key, NULL)) { - if (!_p11_hash_steal (configs, key, (void**)&name, (void**)&config)) + p11_dict_iterate (configs, &iter); + while (p11_dict_next (&iter, &key, NULL)) { + if (!p11_dict_steal (configs, key, (void**)&name, (void**)&config)) assert_not_reached (); /* Is this a critical module, should abort loading of others? */ - critical = _p11_conf_parse_boolean (_p11_hash_get (config, "critical"), 0); + critical = _p11_conf_parse_boolean (p11_dict_get (config, "critical"), 0); rv = take_config_and_load_module_unlocked (&name, &config); @@ -514,12 +516,12 @@ load_registered_modules_unlocked (void) * These variables will be cleared if ownership is transeferred * by the above function call. */ - _p11_hash_free (config); + p11_dict_free (config); if (critical && rv != CKR_OK) { - _p11_message ("aborting initialization because module '%s' was marked as critical", - name); - _p11_hash_free (configs); + p11_message ("aborting initialization because module '%s' was marked as critical", + name); + p11_dict_free (configs); free (name); return rv; } @@ -527,7 +529,7 @@ load_registered_modules_unlocked (void) free (name); } - _p11_hash_free (configs); + p11_dict_free (configs); return CKR_OK; } @@ -535,13 +537,13 @@ static CK_RV initialize_module_unlocked_reentrant (Module *mod) { CK_RV rv = CKR_OK; - thread_id_t self; + p11_thread_id_t self; assert (mod); - self = _p11_thread_id_self (); + self = p11_thread_id_self (); if (mod->initialize_thread == self) { - _p11_message ("p11-kit initialization called recursively"); + p11_message ("p11-kit initialization called recursively"); return CKR_FUNCTION_FAILED; } @@ -553,22 +555,22 @@ 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); + p11_unlock (); 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"); + p11_message ("refusing to load the p11-kit-proxy.so module as a registered module"); rv = CKR_FUNCTION_FAILED; } else { - _p11_debug ("C_Initialize: calling"); + p11_debug ("C_Initialize: calling"); rv = mod->funcs->C_Initialize (&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 */ @@ -580,8 +582,8 @@ initialize_module_unlocked_reentrant (Module *mod) rv = CKR_OK; } - _p11_mutex_unlock (&mod->initialize_mutex); - _p11_lock (); + p11_mutex_unlock (&mod->initialize_mutex); + p11_lock (); /* Don't claim reference if failed */ if (rv != CKR_OK) @@ -596,20 +598,20 @@ initialize_module_unlocked_reentrant (Module *mod) static void reinitialize_after_fork (void) { - hashiter iter; + p11_dictiter iter; Module *mod; - _p11_debug ("forked"); + p11_debug ("forked"); - _p11_lock (); + p11_lock (); if (gl.modules) { - _p11_hash_iterate (gl.modules, &iter); - while (_p11_hash_next (&iter, NULL, (void **)&mod)) + p11_dict_iterate (gl.modules, &iter); + while (p11_dict_next (&iter, NULL, (void **)&mod)) mod->initialize_called = 0; } - _p11_unlock (); + p11_unlock (); _p11_kit_proxy_after_fork (); } @@ -622,8 +624,8 @@ init_globals_unlocked (void) static int once = 0; if (!gl.modules) { - gl.modules = _p11_hash_create (_p11_hash_direct_hash, _p11_hash_direct_equal, - NULL, free_module_unlocked); + gl.modules = p11_dict_new (p11_dict_direct_hash, p11_dict_direct_equal, + NULL, free_module_unlocked); return_val_if_fail (gl.modules != NULL, CKR_HOST_MEMORY); } @@ -642,18 +644,18 @@ static void free_modules_when_no_refs_unlocked (void) { Module *mod; - hashiter iter; + p11_dictiter iter; /* Check if any modules have a ref count */ - _p11_hash_iterate (gl.modules, &iter); - while (_p11_hash_next (&iter, NULL, (void **)&mod)) { + p11_dict_iterate (gl.modules, &iter); + while (p11_dict_next (&iter, NULL, (void **)&mod)) { if (mod->ref_count) return; } - _p11_hash_free (gl.modules); + p11_dict_free (gl.modules); gl.modules = NULL; - _p11_hash_free (gl.config); + p11_dict_free (gl.config); gl.config = NULL; } @@ -679,8 +681,8 @@ finalize_module_unlocked_reentrant (Module *mod) */ ++mod->ref_count; - _p11_mutex_lock (&mod->initialize_mutex); - _p11_unlock (); + p11_mutex_lock (&mod->initialize_mutex); + p11_unlock (); if (mod->initialize_called) { @@ -690,8 +692,8 @@ finalize_module_unlocked_reentrant (Module *mod) mod->initialize_called = 0; } - _p11_mutex_unlock (&mod->initialize_mutex); - _p11_lock (); + p11_mutex_unlock (&mod->initialize_mutex); + p11_lock (); /* Match the increment above */ --mod->ref_count; @@ -704,12 +706,12 @@ static Module* find_module_for_name_unlocked (const char *name) { Module *mod; - hashiter iter; + p11_dictiter iter; assert (name); - _p11_hash_iterate (gl.modules, &iter); - while (_p11_hash_next (&iter, NULL, (void **)&mod)) + 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; @@ -719,7 +721,7 @@ CK_RV _p11_kit_initialize_registered_unlocked_reentrant (void) { Module *mod; - hashiter iter; + p11_dictiter iter; int critical; CK_RV rv; @@ -729,8 +731,8 @@ _p11_kit_initialize_registered_unlocked_reentrant (void) rv = load_registered_modules_unlocked (); if (rv == CKR_OK) { - _p11_hash_iterate (gl.modules, &iter); - while (_p11_hash_next (&iter, NULL, (void **)&mod)) { + p11_dict_iterate (gl.modules, &iter); + while (p11_dict_next (&iter, NULL, (void **)&mod)) { /* Skip all modules that aren't registered */ if (mod->name == NULL || !is_module_enabled_unlocked (mod->name, mod->config)) @@ -743,12 +745,12 @@ _p11_kit_initialize_registered_unlocked_reentrant (void) * then this, should abort loading of others. */ if (rv != CKR_OK) { - _p11_message ("failed to initialize module: %s: %s", - mod->name, p11_kit_strerror (rv)); + p11_message ("failed to initialize module: %s: %s", + mod->name, p11_kit_strerror (rv)); - critical = _p11_conf_parse_boolean (_p11_hash_get (mod->config, "critical"), 0); + critical = _p11_conf_parse_boolean (p11_dict_get (mod->config, "critical"), 0); if (!critical) { - _p11_debug ("ignoring failure, non-critical module: %s", mod->name); + p11_debug ("ignoring failure, non-critical module: %s", mod->name); rv = CKR_OK; } } @@ -780,27 +782,27 @@ p11_kit_initialize_registered (void) { CK_RV rv; - _p11_library_init_once (); + p11_library_init_once (); /* WARNING: This function must be reentrant */ - _p11_debug ("in"); + p11_debug ("in"); - _p11_lock (); + p11_lock (); - _p11_kit_clear_message (); + p11_message_clear (); /* WARNING: Reentrancy can occur here */ rv = _p11_kit_initialize_registered_unlocked_reentrant (); _p11_kit_default_message (rv); - _p11_unlock (); + p11_unlock (); /* Cleanup any partial initialization */ if (rv != CKR_OK) p11_kit_finalize_registered (); - _p11_debug ("out: %lu", rv); + p11_debug ("out: %lu", rv); return rv; } @@ -808,7 +810,7 @@ CK_RV _p11_kit_finalize_registered_unlocked_reentrant (void) { Module *mod; - hashiter iter; + p11_dictiter iter; Module **to_finalize; int i, count; @@ -817,20 +819,20 @@ _p11_kit_finalize_registered_unlocked_reentrant (void) /* WARNING: This function must be reentrant */ - to_finalize = calloc (_p11_hash_size (gl.modules), sizeof (Module *)); + to_finalize = calloc (p11_dict_size (gl.modules), sizeof (Module *)); if (!to_finalize) return CKR_HOST_MEMORY; count = 0; - _p11_hash_iterate (gl.modules, &iter); - while (_p11_hash_next (&iter, NULL, (void **)&mod)) { + p11_dict_iterate (gl.modules, &iter); + while (p11_dict_next (&iter, NULL, (void **)&mod)) { /* Skip all modules that aren't registered */ if (mod->name) to_finalize[count++] = mod; } - _p11_debug ("finalizing %d modules", count); + p11_debug ("finalizing %d modules", count); for (i = 0; i < count; ++i) { /* WARNING: Reentrant calls can occur here */ @@ -867,23 +869,23 @@ p11_kit_finalize_registered (void) { CK_RV rv; - _p11_library_init_once (); + p11_library_init_once (); /* WARNING: This function must be reentrant */ - _p11_debug ("in"); + p11_debug ("in"); - _p11_lock (); + p11_lock (); - _p11_kit_clear_message (); + p11_message_clear (); /* WARNING: Reentrant calls can occur here */ rv = _p11_kit_finalize_registered_unlocked_reentrant (); _p11_kit_default_message (rv); - _p11_unlock (); + p11_unlock (); - _p11_debug ("out: %lu", rv); + p11_debug ("out: %lu", rv); return rv; } @@ -892,15 +894,15 @@ _p11_kit_registered_modules_unlocked (void) { CK_FUNCTION_LIST_PTR_PTR result = NULL; Module *mod; - hashiter iter; + p11_dictiter iter; int i = 0; if (gl.modules) { - result = calloc (_p11_hash_size (gl.modules) + 1, sizeof (CK_FUNCTION_LIST_PTR)); + result = calloc (p11_dict_size (gl.modules) + 1, sizeof (CK_FUNCTION_LIST_PTR)); return_val_if_fail (result != NULL, NULL); - _p11_hash_iterate (gl.modules, &iter); - while (_p11_hash_next (&iter, NULL, (void **)&mod)) { + p11_dict_iterate (gl.modules, &iter); + while (p11_dict_next (&iter, NULL, (void **)&mod)) { /* * We don't include unreferenced modules. We don't include @@ -940,15 +942,15 @@ p11_kit_registered_modules (void) { CK_FUNCTION_LIST_PTR_PTR result; - _p11_library_init_once (); + p11_library_init_once (); - _p11_lock (); + p11_lock (); - _p11_kit_clear_message (); + p11_message_clear (); result = _p11_kit_registered_modules_unlocked (); - _p11_unlock (); + p11_unlock (); return result; } @@ -974,17 +976,17 @@ p11_kit_registered_module_to_name (CK_FUNCTION_LIST_PTR module) return_val_if_fail (module != NULL, NULL); - _p11_library_init_once (); + p11_library_init_once (); - _p11_lock (); + p11_lock (); - _p11_kit_clear_message (); + p11_message_clear (); - mod = module && gl.modules ? _p11_hash_get (gl.modules, module) : NULL; + mod = module && gl.modules ? p11_dict_get (gl.modules, module) : NULL; if (mod && mod->name) name = strdup (mod->name); - _p11_unlock (); + p11_unlock (); return name; } @@ -1007,9 +1009,9 @@ p11_kit_registered_name_to_module (const char *name) return_val_if_fail (name != NULL, NULL); - _p11_lock (); + p11_lock (); - _p11_kit_clear_message (); + p11_message_clear (); if (gl.modules) { mod = find_module_for_name_unlocked (name); @@ -1017,7 +1019,7 @@ p11_kit_registered_name_to_module (const char *name) module = mod->funcs; } - _p11_unlock (); + p11_unlock (); return module; } @@ -1040,32 +1042,32 @@ p11_kit_registered_option (CK_FUNCTION_LIST_PTR module, const char *field) { Module *mod = NULL; char *option = NULL; - hashmap *config = NULL; + p11_dict *config = NULL; return_val_if_fail (field != NULL, NULL); - _p11_library_init_once (); + p11_library_init_once (); - _p11_lock (); + p11_lock (); - _p11_kit_clear_message (); + p11_message_clear (); if (module == NULL) { config = gl.config; } else { - mod = gl.modules ? _p11_hash_get (gl.modules, module) : NULL; + mod = gl.modules ? p11_dict_get (gl.modules, module) : NULL; if (mod) config = mod->config; } if (config && field) { - option = _p11_hash_get (config, field); + option = p11_dict_get (config, field); if (option) option = strdup (option); } - _p11_unlock (); + p11_unlock (); return option; } @@ -1109,21 +1111,21 @@ p11_kit_initialize_module (CK_FUNCTION_LIST_PTR module) return_val_if_fail (module != NULL, CKR_ARGUMENTS_BAD); - _p11_library_init_once (); + p11_library_init_once (); /* WARNING: This function must be reentrant for the same arguments */ - _p11_debug ("in"); + p11_debug ("in"); - _p11_lock (); + p11_lock (); - _p11_kit_clear_message (); + p11_message_clear (); rv = init_globals_unlocked (); if (rv == CKR_OK) { - mod = _p11_hash_get (gl.modules, module); + mod = p11_dict_get (gl.modules, module); if (mod == NULL) { - _p11_debug ("allocating new module"); + p11_debug ("allocating new module"); allocated = mod = alloc_module_unlocked (); if (mod == NULL) rv = CKR_HOST_MEMORY; @@ -1133,7 +1135,7 @@ p11_kit_initialize_module (CK_FUNCTION_LIST_PTR module) /* If this was newly allocated, add it to the list */ if (rv == CKR_OK && allocated) { - if (_p11_hash_set (gl.modules, allocated->funcs, allocated)) + if (p11_dict_set (gl.modules, allocated->funcs, allocated)) allocated = NULL; else rv = CKR_HOST_MEMORY; @@ -1158,9 +1160,9 @@ p11_kit_initialize_module (CK_FUNCTION_LIST_PTR module) _p11_kit_default_message (rv); - _p11_unlock (); + p11_unlock (); - _p11_debug ("out: %lu", rv); + p11_debug ("out: %lu", rv); return rv; } @@ -1196,18 +1198,18 @@ p11_kit_finalize_module (CK_FUNCTION_LIST_PTR module) return_val_if_fail (module != NULL, CKR_ARGUMENTS_BAD); - _p11_library_init_once (); + p11_library_init_once (); /* WARNING: This function must be reentrant for the same arguments */ - _p11_debug ("in"); + p11_debug ("in"); - _p11_lock (); + p11_lock (); - _p11_kit_clear_message (); + p11_message_clear (); - mod = gl.modules ? _p11_hash_get (gl.modules, module) : NULL; + mod = gl.modules ? p11_dict_get (gl.modules, module) : NULL; if (mod == NULL) { - _p11_debug ("module not found"); + p11_debug ("module not found"); rv = CKR_ARGUMENTS_BAD; } else { /* WARNING: Rentrancy can occur here */ @@ -1216,9 +1218,9 @@ p11_kit_finalize_module (CK_FUNCTION_LIST_PTR module) _p11_kit_default_message (rv); - _p11_unlock (); + p11_unlock (); - _p11_debug ("out: %lu", rv); + p11_debug ("out: %lu", rv); return rv; } @@ -1265,14 +1267,14 @@ p11_kit_load_initialize_module (const char *module_path, return_val_if_fail (module_path != NULL, CKR_ARGUMENTS_BAD); return_val_if_fail (module != NULL, CKR_ARGUMENTS_BAD); - _p11_library_init_once (); + p11_library_init_once (); /* WARNING: This function must be reentrant for the same arguments */ - _p11_debug ("in: %s", module_path); + p11_debug ("in: %s", module_path); - _p11_lock (); + p11_lock (); - _p11_kit_clear_message (); + p11_message_clear (); rv = init_globals_unlocked (); if (rv == CKR_OK) { @@ -1298,8 +1300,8 @@ p11_kit_load_initialize_module (const char *module_path, _p11_kit_default_message (rv); - _p11_unlock (); + p11_unlock (); - _p11_debug ("out: %lu", rv); + p11_debug ("out: %lu", rv); return rv; } diff --git a/p11-kit/pin.c b/p11-kit/pin.c index 96511e6..a8be64b 100644 --- a/p11-kit/pin.c +++ b/p11-kit/pin.c @@ -34,15 +34,15 @@ #include "config.h" -#define DEBUG_FLAG DEBUG_PIN +#define P11_DEBUG_FLAG P11_DEBUG_PIN #include "debug.h" -#include "hashmap.h" +#include "dict.h" +#include "library.h" #include "pkcs11.h" #include "p11-kit.h" #include "pin.h" #include "private.h" -#include "ptr-array.h" -#include "util.h" +#include "array.h" #include <assert.h> #include <errno.h> @@ -145,7 +145,7 @@ typedef struct _PinCallback { * we can audit thread safety easier. */ static struct _Shared { - hashmap *pin_sources; + p11_dict *pin_sources; } gl = { NULL }; static void* @@ -174,29 +174,29 @@ static int register_callback_unlocked (const char *pin_source, PinCallback *cb) { - ptr_array_t *callbacks = NULL; + p11_array *callbacks = NULL; char *name; name = strdup (pin_source); return_val_if_fail (name != NULL, -1); if (gl.pin_sources == NULL) { - gl.pin_sources = _p11_hash_create (_p11_hash_string_hash, _p11_hash_string_equal, - free, (hash_destroy_func)_p11_ptr_array_free); + gl.pin_sources = p11_dict_new (p11_dict_str_hash, p11_dict_str_equal, + free, (p11_destroyer)p11_array_free); return_val_if_fail (gl.pin_sources != NULL, -1); } if (gl.pin_sources != NULL) - callbacks = _p11_hash_get (gl.pin_sources, name); + callbacks = p11_dict_get (gl.pin_sources, name); if (callbacks == NULL) { - callbacks = _p11_ptr_array_create (unref_pin_callback); + callbacks = p11_array_new (unref_pin_callback); return_val_if_fail (callbacks != NULL, -1); - if (!_p11_hash_set (gl.pin_sources, name, callbacks)) + if (!p11_dict_set (gl.pin_sources, name, callbacks)) return_val_if_reached (-1); } - if (_p11_ptr_array_add (callbacks, cb) < 0) + if (p11_array_push (callbacks, cb) < 0) return_val_if_reached (-1); return 0; @@ -240,11 +240,11 @@ p11_kit_pin_register_callback (const char *pin_source, cb->user_data = callback_data; cb->destroy = callback_destroy; - _p11_lock (); + p11_lock (); ret = register_callback_unlocked (pin_source, cb); - _p11_unlock (); + p11_unlock (); return ret; } @@ -266,37 +266,37 @@ p11_kit_pin_unregister_callback (const char *pin_source, void *callback_data) { PinCallback *cb; - ptr_array_t *callbacks; + p11_array *callbacks; unsigned int i; return_if_fail (pin_source != NULL); return_if_fail (callback != NULL); - _p11_lock (); + p11_lock (); if (gl.pin_sources) { - callbacks = _p11_hash_get (gl.pin_sources, pin_source); + callbacks = p11_dict_get (gl.pin_sources, pin_source); if (callbacks) { - for (i = 0; i < _p11_ptr_array_count (callbacks); i++) { - cb = _p11_ptr_array_at (callbacks, i); + for (i = 0; i < callbacks->num; i++) { + cb = callbacks->elem[i]; if (cb->func == callback && cb->user_data == callback_data) { - _p11_ptr_array_remove (callbacks, i); + p11_array_remove (callbacks, i); break; } } - if (_p11_ptr_array_count (callbacks) == 0) - _p11_hash_remove (gl.pin_sources, pin_source); + if (callbacks->num == 0) + p11_dict_remove (gl.pin_sources, pin_source); } /* When there are no more pin sources, get rid of the hash table */ - if (_p11_hash_size (gl.pin_sources) == 0) { - _p11_hash_free (gl.pin_sources); + if (p11_dict_size (gl.pin_sources) == 0) { + p11_dict_free (gl.pin_sources); gl.pin_sources = NULL; } } - _p11_unlock (); + p11_unlock (); } /** @@ -338,31 +338,31 @@ p11_kit_pin_request (const char *pin_source, { PinCallback **snapshot = NULL; unsigned int snapshot_count = 0; - ptr_array_t *callbacks; + p11_array *callbacks; P11KitPin *pin; unsigned int i; return_val_if_fail (pin_source != NULL, NULL); - _p11_lock (); + p11_lock (); /* Find and ref the pin source data */ if (gl.pin_sources) { - callbacks = _p11_hash_get (gl.pin_sources, pin_source); + callbacks = p11_dict_get (gl.pin_sources, pin_source); /* If we didn't find any snapshots try the global ones */ if (callbacks == NULL) - callbacks = _p11_hash_get (gl.pin_sources, P11_KIT_PIN_FALLBACK); + callbacks = p11_dict_get (gl.pin_sources, P11_KIT_PIN_FALLBACK); if (callbacks != NULL) { - snapshot = (PinCallback**)_p11_ptr_array_snapshot (callbacks); - snapshot_count = _p11_ptr_array_count (callbacks); - for (i = 0; i < snapshot_count; i++) + snapshot = memdup (callbacks->elem, sizeof (void *) * callbacks->num); + snapshot_count = callbacks->num; + for (i = 0; snapshot && i < snapshot_count; i++) ref_pin_callback (snapshot[i]); } } - _p11_unlock (); + p11_unlock (); if (snapshot == NULL) return NULL; @@ -372,11 +372,11 @@ p11_kit_pin_request (const char *pin_source, snapshot[i - 1]->user_data); } - _p11_lock (); + p11_lock (); for (i = 0; i < snapshot_count; i++) unref_pin_callback (snapshot[i]); free (snapshot); - _p11_unlock (); + p11_unlock (); return pin; } @@ -666,11 +666,11 @@ p11_kit_pin_get_length (P11KitPin *pin) P11KitPin * p11_kit_pin_ref (P11KitPin *pin) { - _p11_lock (); + p11_lock (); pin->ref_count++; - _p11_unlock (); + p11_unlock (); return pin; } @@ -687,12 +687,12 @@ p11_kit_pin_unref (P11KitPin *pin) { int last = 0; - _p11_lock (); + p11_lock (); last = (pin->ref_count == 1); pin->ref_count--; - _p11_unlock (); + p11_unlock (); if (last) { if (pin->destroy) diff --git a/p11-kit/private.h b/p11-kit/private.h index 61cd142..7348e43 100644 --- a/p11-kit/private.h +++ b/p11-kit/private.h @@ -37,48 +37,9 @@ #include "compat.h" #include "pkcs11.h" -#include "util.h" - -extern mutex_t _p11_mutex; - -#define P11_MAX_MESSAGE 512 - -typedef struct { - char message[P11_MAX_MESSAGE]; -#ifdef OS_WIN32 - void *last_error; -#endif -} p11_local; - -#define _p11_lock() _p11_mutex_lock (&_p11_mutex); - -#define _p11_unlock() _p11_mutex_unlock (&_p11_mutex); - -void _p11_message (const char* msg, - ...) GNUC_PRINTF (1, 2); - -p11_local * _p11_library_get_thread_local (void); - -#ifdef OS_WIN32 - -/* No implementation, because done by DllMain */ -#define _p11_library_init_once() - -#else /* !OS_WIN32 */ - -extern pthread_once_t _p11_once; - -#define _p11_library_init_once() \ - pthread_once (&_p11_once, _p11_library_init); - -#endif /* !OS_WIN32 */ extern CK_FUNCTION_LIST _p11_proxy_function_list; -void _p11_library_init (void); - -void _p11_library_uninit (void); - CK_FUNCTION_LIST_PTR_PTR _p11_kit_registered_modules_unlocked (void); CK_RV _p11_kit_initialize_registered_unlocked_reentrant (void); @@ -91,8 +52,6 @@ CK_RV _p11_load_config_files_unlocked (const char *sys const char *user_conf, int *user_mode); -void _p11_kit_clear_message (void); - void _p11_kit_default_message (CK_RV rv); const char * _p11_get_progname_unlocked (void); diff --git a/p11-kit/proxy.c b/p11-kit/proxy.c index c8ba593..35f0c82 100644 --- a/p11-kit/proxy.c +++ b/p11-kit/proxy.c @@ -35,14 +35,14 @@ #include "config.h" -#define DEBUG_FLAG DEBUG_PROXY +#define P11_DEBUG_FLAG P11_DEBUG_PROXY #include "debug.h" -#include "hashmap.h" +#include "dict.h" +#include "library.h" #define CRYPTOKI_EXPORTS #include "pkcs11.h" #include "p11-kit.h" #include "private.h" -#include "util.h" #include <sys/types.h> #include <assert.h> @@ -77,7 +77,7 @@ static struct _Shared { Mapping *mappings; unsigned int n_mappings; int mappings_refs; - hashmap *sessions; + p11_dict *sessions; CK_ULONG last_handle; } gl = { NULL, 0, 0, NULL, FIRST_HANDLE }; @@ -115,7 +115,7 @@ map_slot_to_real (CK_SLOT_ID_PTR slot, Mapping *mapping) assert (mapping); - _p11_lock (); + p11_lock (); if (!gl.mappings) rv = CKR_CRYPTOKI_NOT_INITIALIZED; @@ -124,7 +124,7 @@ map_slot_to_real (CK_SLOT_ID_PTR slot, Mapping *mapping) if (rv == CKR_OK) *slot = mapping->real_slot; - _p11_unlock (); + p11_unlock (); return rv; } @@ -138,13 +138,13 @@ map_session_to_real (CK_SESSION_HANDLE_PTR handle, Mapping *mapping, Session *se assert (handle); assert (mapping); - _p11_lock (); + p11_lock (); if (!gl.sessions) { rv = CKR_CRYPTOKI_NOT_INITIALIZED; } else { assert (gl.sessions); - sess = _p11_hash_get (gl.sessions, handle); + sess = p11_dict_get (gl.sessions, handle); if (sess != NULL) { *handle = sess->real_session; rv = map_slot_unlocked (sess->wrap_slot, mapping); @@ -155,7 +155,7 @@ map_session_to_real (CK_SESSION_HANDLE_PTR handle, Mapping *mapping, Session *se } } - _p11_unlock (); + p11_unlock (); return rv; } @@ -174,7 +174,7 @@ finalize_mappings_unlocked (void) gl.n_mappings = 0; /* no more sessions */ - _p11_hash_free (gl.sessions); + p11_dict_free (gl.sessions); gl.sessions = NULL; } @@ -187,13 +187,13 @@ _p11_kit_proxy_after_fork (void) * up any mappings and all */ - _p11_lock (); + p11_lock (); gl.mappings_refs = 1; finalize_mappings_unlocked (); assert (!gl.mappings); - _p11_unlock (); + p11_unlock (); } static CK_RV @@ -201,7 +201,7 @@ proxy_C_Finalize (CK_VOID_PTR reserved) { CK_RV rv; - _p11_debug ("in"); + p11_debug ("in"); /* WARNING: This function must be reentrant */ @@ -209,7 +209,7 @@ proxy_C_Finalize (CK_VOID_PTR reserved) rv = CKR_ARGUMENTS_BAD; } else { - _p11_lock (); + p11_lock (); /* WARNING: Reentrancy can occur here */ rv = _p11_kit_finalize_registered_unlocked_reentrant (); @@ -221,10 +221,10 @@ proxy_C_Finalize (CK_VOID_PTR reserved) if (gl.mappings_refs) finalize_mappings_unlocked (); - _p11_unlock (); + p11_unlock (); } - _p11_debug ("out: %lu", rv); + p11_debug ("out: %lu", rv); return rv; } @@ -248,7 +248,7 @@ initialize_mappings_unlocked_reentrant (void) assert (funcs); slots = NULL; - _p11_unlock (); + p11_unlock (); /* Ask module for its slots */ rv = (funcs->C_GetSlotList) (FALSE, NULL, &count); @@ -257,7 +257,7 @@ initialize_mappings_unlocked_reentrant (void) rv = (funcs->C_GetSlotList) (FALSE, slots, &count); } - _p11_lock (); + p11_lock (); if (rv != CKR_OK) { free (slots); @@ -291,7 +291,7 @@ initialize_mappings_unlocked_reentrant (void) assert (!gl.sessions); gl.mappings = mappings; gl.n_mappings = n_mappings; - gl.sessions = _p11_hash_create (_p11_hash_ulongptr_hash, _p11_hash_ulongptr_equal, NULL, free); + gl.sessions = p11_dict_new (p11_dict_ulongptr_hash, p11_dict_ulongptr_equal, NULL, free); ++gl.mappings_refs; /* Any cleanup necessary for failure will happen at caller */ @@ -303,13 +303,13 @@ proxy_C_Initialize (CK_VOID_PTR init_args) { CK_RV rv; - _p11_library_init_once (); + p11_library_init_once (); /* WARNING: This function must be reentrant */ - _p11_debug ("in"); + p11_debug ("in"); - _p11_lock (); + p11_lock (); /* WARNING: Reentrancy can occur here */ rv = _p11_kit_initialize_registered_unlocked_reentrant (); @@ -318,14 +318,14 @@ proxy_C_Initialize (CK_VOID_PTR init_args) if (rv == CKR_OK && gl.mappings_refs == 0) rv = initialize_mappings_unlocked_reentrant (); - _p11_unlock (); + p11_unlock (); - _p11_debug ("here"); + p11_debug ("here"); if (rv != CKR_OK) proxy_C_Finalize (NULL); - _p11_debug ("out: %lu", rv); + p11_debug ("out: %lu", rv); return rv; } @@ -334,16 +334,16 @@ proxy_C_GetInfo (CK_INFO_PTR info) { CK_RV rv = CKR_OK; - _p11_library_init_once (); + p11_library_init_once (); return_val_if_fail (info != NULL, CKR_ARGUMENTS_BAD); - _p11_lock (); + p11_lock (); if (!gl.mappings) rv = CKR_CRYPTOKI_NOT_INITIALIZED; - _p11_unlock (); + p11_unlock (); if (rv != CKR_OK) return rv; @@ -380,7 +380,7 @@ proxy_C_GetSlotList (CK_BBOOL token_present, CK_SLOT_ID_PTR slot_list, return_val_if_fail (count != NULL, CKR_ARGUMENTS_BAD); - _p11_lock (); + p11_lock (); if (!gl.mappings) { rv = CKR_CRYPTOKI_NOT_INITIALIZED; @@ -413,7 +413,7 @@ proxy_C_GetSlotList (CK_BBOOL token_present, CK_SLOT_ID_PTR slot_list, *count = index; } - _p11_unlock (); + p11_unlock (); return rv; } @@ -503,7 +503,7 @@ proxy_C_OpenSession (CK_SLOT_ID id, CK_FLAGS flags, CK_VOID_PTR user_data, rv = (map.funcs->C_OpenSession) (id, flags, user_data, callback, handle); if (rv == CKR_OK) { - _p11_lock (); + p11_lock (); if (!gl.sessions) { /* @@ -519,11 +519,11 @@ proxy_C_OpenSession (CK_SLOT_ID id, CK_FLAGS flags, CK_VOID_PTR user_data, sess->wrap_slot = map.wrap_slot; sess->real_session = *handle; sess->wrap_session = ++gl.last_handle; /* TODO: Handle wrapping, and then collisions */ - _p11_hash_set (gl.sessions, &sess->wrap_session, sess); + p11_dict_set (gl.sessions, &sess->wrap_session, sess); *handle = sess->wrap_session; } - _p11_unlock (); + p11_unlock (); } return rv; @@ -543,12 +543,12 @@ proxy_C_CloseSession (CK_SESSION_HANDLE handle) rv = (map.funcs->C_CloseSession) (handle); if (rv == CKR_OK) { - _p11_lock (); + p11_lock (); if (gl.sessions) - _p11_hash_remove (gl.sessions, &key); + p11_dict_remove (gl.sessions, &key); - _p11_unlock (); + p11_unlock (); } return rv; @@ -561,27 +561,27 @@ proxy_C_CloseAllSessions (CK_SLOT_ID id) CK_RV rv = CKR_OK; Session *sess; CK_ULONG i, count = 0; - hashiter iter; + p11_dictiter iter; - _p11_lock (); + p11_lock (); if (!gl.sessions) { rv = CKR_CRYPTOKI_NOT_INITIALIZED; } else { - to_close = calloc (sizeof (CK_SESSION_HANDLE), _p11_hash_size (gl.sessions)); + to_close = calloc (sizeof (CK_SESSION_HANDLE), p11_dict_size (gl.sessions)); if (!to_close) { rv = CKR_HOST_MEMORY; } else { - _p11_hash_iterate (gl.sessions, &iter); + p11_dict_iterate (gl.sessions, &iter); count = 0; - while (_p11_hash_next (&iter, NULL, (void**)&sess)) { + while (p11_dict_next (&iter, NULL, (void**)&sess)) { if (sess->wrap_slot == id && to_close) to_close[count++] = sess->wrap_session; } } } - _p11_unlock (); + p11_unlock (); if (rv != CKR_OK) return rv; @@ -1390,6 +1390,6 @@ __declspec(dllexport) CK_RV C_GetFunctionList (CK_FUNCTION_LIST_PTR_PTR list) { - _p11_library_init_once (); + p11_library_init_once (); return proxy_C_GetFunctionList (list); } diff --git a/p11-kit/ptr-array.c b/p11-kit/ptr-array.c deleted file mode 100644 index f393641..0000000 --- a/p11-kit/ptr-array.c +++ /dev/null @@ -1,154 +0,0 @@ -/* - * Copyright (c) 2011 Collabora Ltd. - * - * 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. - */ - -#include "config.h" - -#include "ptr-array.h" - -#include <stdlib.h> -#include <string.h> - -struct ptr_array { - void **memory; - unsigned int length; - unsigned int allocated; - ptr_array_destroy_func destroy; -}; - -static int -maybe_expand_array (ptr_array_t *array, - unsigned int length) -{ - unsigned int new_allocated; - void **new_memory; - - if (length <= array->allocated) - return 1; - - new_allocated = array->allocated + 16; - if (new_allocated < length) - new_allocated = length; - - new_memory = realloc (array->memory, new_allocated * sizeof (void*)); - if (new_memory == NULL) - return 0; - - array->memory = new_memory; - array->allocated = new_allocated; - return 1; -} - -ptr_array_t * -_p11_ptr_array_create (ptr_array_destroy_func destroy_func) -{ - ptr_array_t *array; - - array = calloc (1, sizeof (ptr_array_t)); - if (array == NULL) - return NULL; - - if (!maybe_expand_array (array, 2)) { - _p11_ptr_array_free (array); - return NULL; - } - - array->destroy = destroy_func; - return array; -} - -void -_p11_ptr_array_free (ptr_array_t *array) -{ - unsigned int i; - - if (array == NULL) - return; - - if (array->destroy) { - for (i = 0; i < array->length; i++) - (array->destroy) (array->memory[i]); - } - - free (array->memory); - free (array); -} - -unsigned int -_p11_ptr_array_count (ptr_array_t *array) -{ - return array->length; -} - -int -_p11_ptr_array_add (ptr_array_t *array, - void *value) -{ - if (!maybe_expand_array (array, array->length + 1)) - return 0; - - array->memory[array->length] = value; - array->length++; - return 1; -} - -void -_p11_ptr_array_remove (ptr_array_t *array, - unsigned int index) -{ - if (array->destroy) - (array->destroy) (array->memory[index]); - memmove (array->memory + index, array->memory + index + 1, - (array->length - (index + 1)) * sizeof (void*)); - array->length--; -} - -void * -_p11_ptr_array_at (ptr_array_t *array, - unsigned int index) -{ - return array->memory[index]; -} - -void ** -_p11_ptr_array_snapshot (ptr_array_t *array) -{ - void **snapshot; - size_t bytes; - - bytes = array->length * sizeof (void*); - snapshot = malloc (bytes); - if (!snapshot) - return NULL; - - memcpy (snapshot, array->memory, bytes); - return snapshot; -} diff --git a/p11-kit/tests/Makefile.am b/p11-kit/tests/Makefile.am new file mode 100644 index 0000000..bd08426 --- /dev/null +++ b/p11-kit/tests/Makefile.am @@ -0,0 +1,63 @@ + +include $(top_srcdir)/build/Makefile.tests + +INCLUDES = \ + -I$(top_srcdir) \ + -I$(srcdir)/.. \ + -I$(top_srcdir)/common \ + $(CUTEST_CFLAGS) + +LDADD = \ + $(top_builddir)/p11-kit/libp11-kit-testable.la \ + $(CUTEST_LIBS) \ + $(LTLIBINTL) + +CHECK_PROGS = \ + progname-test \ + conf-test \ + uri-test \ + pin-test \ + test-init \ + test-modules + +noinst_PROGRAMS = \ + print-messages \ + $(CHECK_PROGS) + +test_init_SOURCES = test-init.c \ + mock-module.c mock-module.h +test_init_CFLAGS = $(AM_CFLAGS) + +TESTS = $(CHECK_PROGS:=$(EXEEXT)) + +noinst_LTLIBRARIES = \ + mock-one.la \ + mock-two.la \ + mock-three.la \ + mock-four.la + +mock_one_la_SOURCES = \ + mock-module.c mock-module.h \ + mock-module-ep.c + +mock_one_la_LIBADD = \ + $(top_builddir)/p11-kit/libp11-kit-compat.la + +mock_one_la_LDFLAGS = \ + -module -avoid-version -rpath /nowhere \ + -no-undefined -export-symbols-regex 'C_GetFunctionList' + +mock_two_la_SOURCES = $(mock_one_la_SOURCES) +mock_two_la_LDFLAGS = $(mock_one_la_LDFLAGS) +mock_two_la_LIBADD = $(mock_one_la_LIBADD) + +mock_three_la_SOURCES = $(mock_one_la_SOURCES) +mock_three_la_LDFLAGS = $(mock_one_la_LDFLAGS) +mock_three_la_LIBADD = $(mock_one_la_LIBADD) + +mock_four_la_SOURCES = $(mock_one_la_SOURCES) +mock_four_la_LDFLAGS = $(mock_one_la_LDFLAGS) +mock_four_la_LIBADD = $(mock_one_la_LIBADD) + +EXTRA_DIST = \ + files diff --git a/p11-kit/tests/conf-test.c b/p11-kit/tests/conf-test.c new file mode 100644 index 0000000..4ea1313 --- /dev/null +++ b/p11-kit/tests/conf-test.c @@ -0,0 +1,415 @@ +/* + * Copyright (c) 2011, Collabora Ltd. + * + * 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@collabora.co.uk> + */ + +#include "config.h" +#include "CuTest.h" + +#include <errno.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +#include "conf.h" +#include "library.h" +#include "p11-kit.h" +#include "private.h" + +static void +test_parse_conf_1 (CuTest *tc) +{ + p11_dict *map; + const char *value; + + map = _p11_conf_parse_file (SRCDIR "/files/test-1.conf", 0); + CuAssertPtrNotNull (tc, map); + + value = p11_dict_get (map, "key1"); + CuAssertStrEquals (tc, "value1", value); + + value = p11_dict_get (map, "with-colon"); + CuAssertStrEquals (tc, "value-of-colon", value); + + value = p11_dict_get (map, "with-whitespace"); + CuAssertStrEquals (tc, "value-with-whitespace", value); + + value = p11_dict_get (map, "embedded-comment"); + CuAssertStrEquals (tc, "this is # not a comment", value); + + p11_dict_free (map); +} + +static void +test_parse_ignore_missing (CuTest *tc) +{ + p11_dict *map; + + map = _p11_conf_parse_file (SRCDIR "/files/non-existant.conf", CONF_IGNORE_MISSING); + CuAssertPtrNotNull (tc, map); + + CuAssertIntEquals (tc, 0, p11_dict_size (map)); + CuAssertPtrEquals (tc, NULL, (void*)p11_kit_message ()); + p11_dict_free (map); +} + +static void +test_parse_fail_missing (CuTest *tc) +{ + p11_dict *map; + + map = _p11_conf_parse_file (SRCDIR "/files/non-existant.conf", 0); + CuAssertPtrEquals (tc, map, NULL); + CuAssertPtrNotNull (tc, p11_kit_message ()); +} + +static void +test_merge_defaults (CuTest *tc) +{ + p11_dict *values; + p11_dict *defaults; + + values = p11_dict_new (p11_dict_str_hash, p11_dict_str_equal, free, free); + defaults = p11_dict_new (p11_dict_str_hash, p11_dict_str_equal, free, free); + + p11_dict_set (values, strdup ("one"), strdup ("real1")); + p11_dict_set (values, strdup ("two"), strdup ("real2")); + + p11_dict_set (defaults, strdup ("two"), strdup ("default2")); + p11_dict_set (defaults, strdup ("three"), strdup ("default3")); + + if (_p11_conf_merge_defaults (values, defaults) < 0) + CuFail (tc, "should not be 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"); + + p11_dict_free (values); +} + +static void +test_load_globals_merge (CuTest *tc) +{ + int user_mode = -1; + p11_dict *config; + + p11_message_clear (); + + 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_kit_message ()); + CuAssertIntEquals (tc, 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"); + + p11_dict_free (config); +} + +static void +test_load_globals_no_user (CuTest *tc) +{ + int user_mode = -1; + p11_dict *config; + + p11_message_clear (); + + 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_kit_message ()); + CuAssertIntEquals (tc, 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"); + + p11_dict_free (config); +} + +static void +test_load_globals_user_sets_only (CuTest *tc) +{ + int user_mode = -1; + p11_dict *config; + + p11_message_clear (); + + 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_kit_message ()); + CuAssertIntEquals (tc, 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"); + + p11_dict_free (config); +} + +static void +test_load_globals_system_sets_only (CuTest *tc) +{ + int user_mode = -1; + p11_dict *config; + + p11_message_clear (); + + 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_kit_message ()); + CuAssertIntEquals (tc, 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"); + + p11_dict_free (config); +} + +static void +test_load_globals_system_sets_invalid (CuTest *tc) +{ + int user_mode = -1; + p11_dict *config; + int error; + + p11_message_clear (); + + config = _p11_conf_load_globals (SRCDIR "/files/test-system-invalid.conf", + SRCDIR "/files/non-existant.conf", + &user_mode); + error = errno; + CuAssertPtrEquals (tc, NULL, config); + CuAssertIntEquals (tc, EINVAL, error); + CuAssertPtrNotNull (tc, p11_kit_message ()); + + p11_dict_free (config); +} + +static void +test_load_globals_user_sets_invalid (CuTest *tc) +{ + int user_mode = -1; + p11_dict *config; + int error; + + p11_message_clear (); + + config = _p11_conf_load_globals (SRCDIR "/files/test-system-merge.conf", + SRCDIR "/files/test-user-invalid.conf", + &user_mode); + error = errno; + CuAssertPtrEquals (tc, NULL, config); + CuAssertIntEquals (tc, EINVAL, error); + CuAssertPtrNotNull (tc, p11_kit_message ()); + + p11_dict_free (config); +} + +static int +assert_msg_contains (const char *msg, + const char *text) +{ + if (msg == NULL) + return 0; + return strstr (msg, text) ? 1 : 0; +} + +static void +test_load_modules_merge (CuTest *tc) +{ + p11_dict *configs; + p11_dict *config; + + p11_message_clear (); + + configs = _p11_conf_load_modules (CONF_USER_MERGE, + SRCDIR "/files/system-modules", + SRCDIR "/files/user-modules"); + CuAssertPtrNotNull (tc, configs); + CuAssertTrue (tc, assert_msg_contains (p11_kit_message (), "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"); + + 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"); + + 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"); + + p11_dict_free (configs); +} + +static void +test_load_modules_user_none (CuTest *tc) +{ + p11_dict *configs; + p11_dict *config; + + p11_message_clear (); + + configs = _p11_conf_load_modules (CONF_USER_NONE, + SRCDIR "/files/system-modules", + SRCDIR "/files/user-modules"); + CuAssertPtrNotNull (tc, configs); + CuAssertTrue (tc, assert_msg_contains (p11_kit_message (), "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"); + + 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"); + + config = p11_dict_get (configs, "three"); + CuAssertPtrEquals (tc, NULL, config); + + p11_dict_free (configs); +} + +static void +test_load_modules_user_only (CuTest *tc) +{ + p11_dict *configs; + p11_dict *config; + + p11_message_clear (); + + configs = _p11_conf_load_modules (CONF_USER_ONLY, + SRCDIR "/files/system-modules", + SRCDIR "/files/user-modules"); + CuAssertPtrNotNull (tc, configs); + CuAssertPtrEquals (tc, NULL, (void *)p11_kit_message ()); + + 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"); + + config = p11_dict_get (configs, "two.badname"); + CuAssertPtrEquals (tc, 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"); + + p11_dict_free (configs); +} + +static void +test_load_modules_no_user (CuTest *tc) +{ + p11_dict *configs; + p11_dict *config; + + p11_message_clear (); + + configs = _p11_conf_load_modules (CONF_USER_MERGE, + SRCDIR "/files/system-modules", + SRCDIR "/files/non-existant"); + CuAssertPtrNotNull (tc, configs); + CuAssertTrue (tc, assert_msg_contains (p11_kit_message (), "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"); + + 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"); + + config = p11_dict_get (configs, "three"); + CuAssertPtrEquals (tc, NULL, config); + + p11_dict_free (configs); +} + +int +main (void) +{ + CuString *output = CuStringNew (); + CuSuite* suite = CuSuiteNew (); + int ret; + + p11_library_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); + + 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; +} diff --git a/p11-kit/tests/files/system-modules/four.module b/p11-kit/tests/files/system-modules/four.module new file mode 100644 index 0000000..6eace3c --- /dev/null +++ b/p11-kit/tests/files/system-modules/four.module @@ -0,0 +1,3 @@ + +module: mock-four.so +disable-in: test-disable, test-other diff --git a/p11-kit/tests/files/system-modules/one.module b/p11-kit/tests/files/system-modules/one.module new file mode 100644 index 0000000..3620869 --- /dev/null +++ b/p11-kit/tests/files/system-modules/one.module @@ -0,0 +1,3 @@ + +module: mock-one.so +setting: system1
\ No newline at end of file diff --git a/p11-kit/tests/files/system-modules/two-duplicate.module b/p11-kit/tests/files/system-modules/two-duplicate.module new file mode 100644 index 0000000..907aa75 --- /dev/null +++ b/p11-kit/tests/files/system-modules/two-duplicate.module @@ -0,0 +1,3 @@ + +# This is a duplicate of the 'two' module +module: mock-two.so diff --git a/p11-kit/tests/files/system-modules/two.badname b/p11-kit/tests/files/system-modules/two.badname new file mode 100644 index 0000000..0d41cac --- /dev/null +++ b/p11-kit/tests/files/system-modules/two.badname @@ -0,0 +1,5 @@ +# This module doesn't have a .module extension, but p11-kit doesn't yet +# enforce the naming, just warns, so it should still be loaded + +module: mock-two.so +setting: system2 diff --git a/p11-kit/tests/files/system-modules/win32/four.module b/p11-kit/tests/files/system-modules/win32/four.module new file mode 100644 index 0000000..7fd1540 --- /dev/null +++ b/p11-kit/tests/files/system-modules/win32/four.module @@ -0,0 +1,3 @@ + +module: mock-four.dll +disable-in: test-disable, test-other diff --git a/p11-kit/tests/files/system-modules/win32/one.module b/p11-kit/tests/files/system-modules/win32/one.module new file mode 100644 index 0000000..5f80304 --- /dev/null +++ b/p11-kit/tests/files/system-modules/win32/one.module @@ -0,0 +1,3 @@ + +module: mock-one.dll +setting: system1
\ No newline at end of file diff --git a/p11-kit/tests/files/system-modules/win32/two-duplicate.module b/p11-kit/tests/files/system-modules/win32/two-duplicate.module new file mode 100644 index 0000000..e80c9e8 --- /dev/null +++ b/p11-kit/tests/files/system-modules/win32/two-duplicate.module @@ -0,0 +1,3 @@ + +# This is a duplicate of the 'two' module +module: mock-two.dll diff --git a/p11-kit/tests/files/system-modules/win32/two.badname b/p11-kit/tests/files/system-modules/win32/two.badname new file mode 100644 index 0000000..ae44b83 --- /dev/null +++ b/p11-kit/tests/files/system-modules/win32/two.badname @@ -0,0 +1,5 @@ +# This module doesn't have a .module extension, but p11-kit doesn't yet +# enforce the naming, just warns, so it should still be loaded + +module: mock-two.dll +setting: system2 diff --git a/p11-kit/tests/files/system-pkcs11.conf b/p11-kit/tests/files/system-pkcs11.conf new file mode 100644 index 0000000..20741e7 --- /dev/null +++ b/p11-kit/tests/files/system-pkcs11.conf @@ -0,0 +1,3 @@ + +# Merge in user config +user-config: merge
\ No newline at end of file diff --git a/p11-kit/tests/files/test-1.conf b/p11-kit/tests/files/test-1.conf new file mode 100644 index 0000000..d4ae0a1 --- /dev/null +++ b/p11-kit/tests/files/test-1.conf @@ -0,0 +1,6 @@ +key1:value1 +with-whitespace : value-with-whitespace +with-colon: value-of-colon + +# A comment +embedded-comment: this is # not a comment diff --git a/p11-kit/tests/files/test-pinfile b/p11-kit/tests/files/test-pinfile new file mode 100644 index 0000000..f646f3d --- /dev/null +++ b/p11-kit/tests/files/test-pinfile @@ -0,0 +1 @@ +yogabbagabba
\ No newline at end of file diff --git a/p11-kit/tests/files/test-pinfile-large b/p11-kit/tests/files/test-pinfile-large new file mode 100644 index 0000000..506668d --- /dev/null +++ b/p11-kit/tests/files/test-pinfile-large @@ -0,0 +1,53 @@ +yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba +yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba +yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba +yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba +yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba +yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba +yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba +yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba +yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba +yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba +yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba +yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba +yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba +yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba +yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba +yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba +yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba +yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba +yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba +yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba +yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba +yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba +yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba +yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba +yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba +yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba +yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba +yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba +yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba +yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba +yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba +yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba +yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba +yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba +yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba +yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba +yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba +yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba +yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba +yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba +yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba +yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba +yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba +yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba +yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba +yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba +yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba +yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba +yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba +yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba +yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba +yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba yogabbagabba +yogabbagabba yogabbagabba yogabbagabba yo
\ No newline at end of file diff --git a/p11-kit/tests/files/test-system-invalid.conf b/p11-kit/tests/files/test-system-invalid.conf new file mode 100644 index 0000000..344ee96 --- /dev/null +++ b/p11-kit/tests/files/test-system-invalid.conf @@ -0,0 +1,3 @@ + +# Invalid user-config setting +user-config: bad diff --git a/p11-kit/tests/files/test-system-merge.conf b/p11-kit/tests/files/test-system-merge.conf new file mode 100644 index 0000000..978427d --- /dev/null +++ b/p11-kit/tests/files/test-system-merge.conf @@ -0,0 +1,7 @@ + +# Merge in user config +user-config: merge + +key1: system1 +key2: system2 +key3: system3
\ No newline at end of file diff --git a/p11-kit/tests/files/test-system-none.conf b/p11-kit/tests/files/test-system-none.conf new file mode 100644 index 0000000..95351e6 --- /dev/null +++ b/p11-kit/tests/files/test-system-none.conf @@ -0,0 +1,8 @@ + +# Only user config +user-config: none + +# These values will not be overriden +key1: system1 +key2: system2 +key3: system3
\ No newline at end of file diff --git a/p11-kit/tests/files/test-system-only.conf b/p11-kit/tests/files/test-system-only.conf new file mode 100644 index 0000000..589f1c7 --- /dev/null +++ b/p11-kit/tests/files/test-system-only.conf @@ -0,0 +1,8 @@ + +# Only user config +user-config: only + +# This stuff will be ignored +key1: system1 +key2: system2 +key3: system3
\ No newline at end of file diff --git a/p11-kit/tests/files/test-user-invalid.conf b/p11-kit/tests/files/test-user-invalid.conf new file mode 100644 index 0000000..344ee96 --- /dev/null +++ b/p11-kit/tests/files/test-user-invalid.conf @@ -0,0 +1,3 @@ + +# Invalid user-config setting +user-config: bad diff --git a/p11-kit/tests/files/test-user-only.conf b/p11-kit/tests/files/test-user-only.conf new file mode 100644 index 0000000..3224c01 --- /dev/null +++ b/p11-kit/tests/files/test-user-only.conf @@ -0,0 +1,4 @@ + +user-config: only +key2: user2 +key3: user3
\ No newline at end of file diff --git a/p11-kit/tests/files/test-user.conf b/p11-kit/tests/files/test-user.conf new file mode 100644 index 0000000..369544a --- /dev/null +++ b/p11-kit/tests/files/test-user.conf @@ -0,0 +1,3 @@ + +key2: user2 +key3: user3
\ 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 new file mode 100644 index 0000000..c371e4a --- /dev/null +++ b/p11-kit/tests/files/user-modules/one.module @@ -0,0 +1,2 @@ + +setting: user1
\ No newline at end of file diff --git a/p11-kit/tests/files/user-modules/three.module b/p11-kit/tests/files/user-modules/three.module new file mode 100644 index 0000000..00caab5 --- /dev/null +++ b/p11-kit/tests/files/user-modules/three.module @@ -0,0 +1,5 @@ + +module: mock-three.so +setting: user3 + +enable-in: test-enable
\ No newline at end of file diff --git a/p11-kit/tests/files/user-modules/win32/one.module b/p11-kit/tests/files/user-modules/win32/one.module new file mode 100644 index 0000000..c371e4a --- /dev/null +++ b/p11-kit/tests/files/user-modules/win32/one.module @@ -0,0 +1,2 @@ + +setting: user1
\ No newline at end of file diff --git a/p11-kit/tests/files/user-modules/win32/three.module b/p11-kit/tests/files/user-modules/win32/three.module new file mode 100644 index 0000000..58f883d --- /dev/null +++ b/p11-kit/tests/files/user-modules/win32/three.module @@ -0,0 +1,5 @@ + +module: mock-three.dll +setting: user3 + +enable-in: test-enable
\ No newline at end of file diff --git a/p11-kit/ptr-array.h b/p11-kit/tests/mock-module-ep.c index ba7ec87..7440a74 100644 --- a/p11-kit/ptr-array.h +++ b/p11-kit/tests/mock-module-ep.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011 Collabora Ltd. + * Copyright (c) 2012 Stefan Walter * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -29,33 +29,24 @@ * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH * DAMAGE. * - * Author: Stef Waler <stefw@collabora.co.uk> + * Author: Stef Walter <stef@thewalter.net> */ -#ifndef __PTR_ARRAY_H__ -#define __PTR_ARRAY_H__ - -#include <sys/types.h> - -typedef struct ptr_array ptr_array_t; - -typedef void (*ptr_array_destroy_func) (void *data); - -ptr_array_t* _p11_ptr_array_create (ptr_array_destroy_func destroy_func); - -void _p11_ptr_array_free (ptr_array_t *array); - -unsigned int _p11_ptr_array_count (ptr_array_t *array); - -int _p11_ptr_array_add (ptr_array_t *array, - void *value); - -void _p11_ptr_array_remove (ptr_array_t *array, - unsigned int index); - -void* _p11_ptr_array_at (ptr_array_t *array, - unsigned int index); - -void** _p11_ptr_array_snapshot (ptr_array_t *array); - -#endif /* __PTR_ARRAY_H__ */ +#include "config.h" + +#define CRYPTOKI_EXPORTS 1 +#include "pkcs11.h" +#include "mock-module.h" + +#ifdef OS_WIN32 +__declspec(dllexport) +#endif +CK_RV +C_GetFunctionList (CK_FUNCTION_LIST_PTR_PTR list) +{ + mock_module_init (); + if (list == NULL) + return CKR_ARGUMENTS_BAD; + *list = &mock_module_no_slots; + return CKR_OK; +} diff --git a/p11-kit/tests/mock-module.c b/p11-kit/tests/mock-module.c new file mode 100644 index 0000000..1a74806 --- /dev/null +++ b/p11-kit/tests/mock-module.c @@ -0,0 +1,898 @@ +/* + * Copyright (c) 2011, Collabora Ltd. + * + * 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@collabora.co.uk> + */ + +#include "config.h" + +#include "library.h" +#define CRYPTOKI_EXPORTS +#include "pkcs11.h" + +#include "mock-module.h" + +#include <stdarg.h> +#include <stdio.h> +#include <string.h> +#include <unistd.h> + +/* ------------------------------------------------------------------- + * GLOBALS / DEFINES + */ + +/* Various mutexes */ +static p11_mutex_t init_mutex; + +/* Whether we've been initialized, and on what process id it happened */ +static int pkcs11_initialized = 0; +static pid_t pkcs11_initialized_pid = 0; + +/* ----------------------------------------------------------------------------- + * LOGGING and DEBUGGING + */ + +#define DEBUG_OUTPUT 0 + +#if DEBUG_OUTPUT +#define debug(x) mock_log x +#else +#define debug(x) +#endif + +#define warning(x) mock_log x + +#define return_val_if_fail(x, v) \ + if (!(x)) { mock_log ("'%s' not true at %s", #x, __func__); return v; } + +static void +mock_log (const char *format, ...) +{ + va_list va; + va_start (va, format); + fprintf (stderr, "mock-module: "); + vfprintf (stderr, format, va); + fprintf (stderr, "\n"); + va_end (va); +} + +/* ------------------------------------------------------------------- + * INITIALIZATION and 'GLOBAL' CALLS + */ + +CK_RV +mock_C_Initialize (CK_VOID_PTR init_args) +{ + CK_C_INITIALIZE_ARGS_PTR args = NULL; + CK_RV ret = CKR_OK; + pid_t pid; + + debug (("C_Initialize: enter")); + + p11_mutex_lock (&init_mutex); + + if (init_args != NULL) { + int supplied_ok; + + /* pReserved must be NULL */ + args = init_args; + + /* ALL supplied function pointers need to have the value either NULL or non-NULL. */ + supplied_ok = (args->CreateMutex == NULL && args->DestroyMutex == NULL && + args->LockMutex == NULL && args->UnlockMutex == NULL) || + (args->CreateMutex != NULL && args->DestroyMutex != NULL && + args->LockMutex != NULL && args->UnlockMutex != NULL); + if (!supplied_ok) { + warning (("invalid set of mutex calls supplied")); + ret = CKR_ARGUMENTS_BAD; + goto done; + } + + /* + * When the CKF_OS_LOCKING_OK flag isn't set return an error. + * We must be able to use our pthread functionality. + */ + if (!(args->flags & CKF_OS_LOCKING_OK)) { + warning (("can't do without os locking")); + ret = CKR_CANT_LOCK; + goto done; + } + } + + pid = getpid (); + if (pkcs11_initialized) { + + /* This process has called C_Initialize already */ + if (pid == pkcs11_initialized_pid) { + warning (("C_Initialize called twice for same process")); + ret = CKR_CRYPTOKI_ALREADY_INITIALIZED; + goto done; + } + } + +done: + /* Mark us as officially initialized */ + if (ret == CKR_OK) { + pkcs11_initialized = 1; + pkcs11_initialized_pid = pid; + } else if (ret != CKR_CRYPTOKI_ALREADY_INITIALIZED) { + pkcs11_initialized = 0; + pkcs11_initialized_pid = 0; + } + + p11_mutex_unlock (&init_mutex); + + debug (("C_Initialize: %d", ret)); + return ret; +} + +CK_RV +mock_C_Finalize (CK_VOID_PTR reserved) +{ + debug (("C_Finalize: enter")); + return_val_if_fail (pkcs11_initialized != 0, CKR_CRYPTOKI_NOT_INITIALIZED); + return_val_if_fail (reserved == NULL, CKR_ARGUMENTS_BAD); + + p11_mutex_lock (&init_mutex); + + /* This should stop all other calls in */ + pkcs11_initialized = 0; + pkcs11_initialized_pid = 0; + + p11_mutex_unlock (&init_mutex); + + debug (("C_Finalize: %d", CKR_OK)); + return CKR_OK; +} + +static const CK_INFO MOCK_INFO = { + { CRYPTOKI_VERSION_MAJOR, CRYPTOKI_VERSION_MINOR }, + "MOCK MANUFACTURER ", + 0, + "MOCK LIBRARY ", + { 45, 145 } +}; + + +CK_RV +mock_C_GetInfo (CK_INFO_PTR info) +{ + return_val_if_fail (info, CKR_ARGUMENTS_BAD); + + memcpy (info, &MOCK_INFO, sizeof (*info)); + return CKR_OK; +} + +CK_RV +mock_C_GetFunctionList (CK_FUNCTION_LIST_PTR_PTR list) +{ + /* This would be a strange call to receive */ + return C_GetFunctionList (list); +} + +CK_RV +mock_C_GetSlotList__no_tokens (CK_BBOOL token_present, + CK_SLOT_ID_PTR slot_list, + CK_ULONG_PTR count) +{ + return_val_if_fail (count, CKR_ARGUMENTS_BAD); + + /* No tokens */ + *count = 0; + return CKR_OK; +} + +CK_RV +mock_C_GetSlotInfo__invalid_slotid (CK_SLOT_ID id, + CK_SLOT_INFO_PTR info) +{ + return_val_if_fail (info, CKR_ARGUMENTS_BAD); + + return CKR_SLOT_ID_INVALID; +} + +CK_RV +mock_C_GetTokenInfo__invalid_slotid (CK_SLOT_ID id, + CK_TOKEN_INFO_PTR info) +{ + return_val_if_fail (info, CKR_ARGUMENTS_BAD); + + return CKR_SLOT_ID_INVALID; +} + +CK_RV +mock_C_GetMechanismList__invalid_slotid (CK_SLOT_ID id, + CK_MECHANISM_TYPE_PTR mechanism_list, + CK_ULONG_PTR count) +{ + return_val_if_fail (count, CKR_ARGUMENTS_BAD); + + return CKR_SLOT_ID_INVALID; +} + +CK_RV +mock_C_GetMechanismInfo__invalid_slotid (CK_SLOT_ID id, + CK_MECHANISM_TYPE type, + CK_MECHANISM_INFO_PTR info) +{ + return_val_if_fail (info, CKR_ARGUMENTS_BAD); + + return CKR_SLOT_ID_INVALID; +} + +CK_RV +mock_C_InitToken__invalid_slotid (CK_SLOT_ID id, + CK_UTF8CHAR_PTR pin, + CK_ULONG pin_len, + CK_UTF8CHAR_PTR label) +{ + return CKR_SLOT_ID_INVALID; +} + +CK_RV +mock_C_WaitForSlotEvent__no_event (CK_FLAGS flags, + CK_SLOT_ID_PTR slot, + CK_VOID_PTR reserved) +{ + return_val_if_fail (slot, CKR_ARGUMENTS_BAD); + + return CKR_NO_EVENT; +} + +CK_RV +mock_C_OpenSession__invalid_slotid (CK_SLOT_ID id, + CK_FLAGS flags, + CK_VOID_PTR user_data, + CK_NOTIFY callback, + CK_SESSION_HANDLE_PTR session) +{ + return_val_if_fail (session, CKR_ARGUMENTS_BAD); + + return CKR_SLOT_ID_INVALID; +} + +CK_RV +mock_C_CloseSession__invalid_handle (CK_SESSION_HANDLE session) +{ + return CKR_SESSION_HANDLE_INVALID; +} + +CK_RV +mock_C_CloseAllSessions__invalid_slotid (CK_SLOT_ID id) +{ + return CKR_SLOT_ID_INVALID; +} + +CK_RV +mock_C_GetFunctionStatus__not_parallel (CK_SESSION_HANDLE session) +{ + return CKR_FUNCTION_NOT_PARALLEL; +} + +CK_RV +mock_C_CancelFunction__not_parallel (CK_SESSION_HANDLE session) +{ + return CKR_FUNCTION_NOT_PARALLEL; +} + +CK_RV +mock_C_GetSessionInfo__invalid_handle (CK_SESSION_HANDLE session, + CK_SESSION_INFO_PTR info) +{ + return_val_if_fail (info, CKR_ARGUMENTS_BAD); + + return CKR_SESSION_HANDLE_INVALID; +} + +CK_RV +mock_C_InitPIN__invalid_handle (CK_SESSION_HANDLE session, + CK_UTF8CHAR_PTR pin, + CK_ULONG pin_len) +{ + return CKR_SESSION_HANDLE_INVALID; +} + +CK_RV +mock_C_SetPIN__invalid_handle (CK_SESSION_HANDLE session, + CK_UTF8CHAR_PTR old_pin, + CK_ULONG old_pin_len, + CK_UTF8CHAR_PTR new_pin, + CK_ULONG new_pin_len) +{ + return CKR_SESSION_HANDLE_INVALID; +} + +CK_RV +mock_C_GetOperationState__invalid_handle (CK_SESSION_HANDLE session, + CK_BYTE_PTR operation_state, + CK_ULONG_PTR operation_state_len) +{ + return_val_if_fail (operation_state_len, CKR_ARGUMENTS_BAD); + + return CKR_SESSION_HANDLE_INVALID; +} + +CK_RV +mock_C_SetOperationState__invalid_handle (CK_SESSION_HANDLE session, + CK_BYTE_PTR operation_state, + CK_ULONG operation_state_len, + CK_OBJECT_HANDLE encryption_key, + CK_OBJECT_HANDLE authentication_key) +{ + return CKR_SESSION_HANDLE_INVALID; +} + +CK_RV +mock_C_Login__invalid_handle (CK_SESSION_HANDLE session, + CK_USER_TYPE user_type, + CK_UTF8CHAR_PTR pin, + CK_ULONG pin_len) +{ + return CKR_SESSION_HANDLE_INVALID; + +} + +CK_RV +mock_C_Logout__invalid_handle (CK_SESSION_HANDLE session) +{ + return CKR_SESSION_HANDLE_INVALID; + +} + +CK_RV +mock_C_CreateObject__invalid_handle (CK_SESSION_HANDLE session, + CK_ATTRIBUTE_PTR template, + CK_ULONG count, + CK_OBJECT_HANDLE_PTR new_object) +{ + return_val_if_fail (new_object, CKR_ARGUMENTS_BAD); + + return CKR_SESSION_HANDLE_INVALID; +} + +CK_RV +mock_C_CopyObject__invalid_handle (CK_SESSION_HANDLE session, + CK_OBJECT_HANDLE object, + CK_ATTRIBUTE_PTR template, + CK_ULONG count, + CK_OBJECT_HANDLE_PTR new_object) +{ + return_val_if_fail (new_object, CKR_ARGUMENTS_BAD); + + return CKR_SESSION_HANDLE_INVALID; +} + + +CK_RV +mock_C_DestroyObject__invalid_handle (CK_SESSION_HANDLE session, + CK_OBJECT_HANDLE object) +{ + return CKR_SESSION_HANDLE_INVALID; +} + +CK_RV +mock_C_GetObjectSize__invalid_handle (CK_SESSION_HANDLE session, + CK_OBJECT_HANDLE object, + CK_ULONG_PTR size) +{ + return_val_if_fail (size, CKR_ARGUMENTS_BAD); + + return CKR_SESSION_HANDLE_INVALID; +} + +CK_RV +mock_C_GetAttributeValue__invalid_handle (CK_SESSION_HANDLE session, + CK_OBJECT_HANDLE object, + CK_ATTRIBUTE_PTR template, + CK_ULONG count) +{ + return CKR_SESSION_HANDLE_INVALID; +} + +CK_RV +mock_C_SetAttributeValue__invalid_handle (CK_SESSION_HANDLE session, + CK_OBJECT_HANDLE object, + CK_ATTRIBUTE_PTR template, + CK_ULONG count) +{ + return CKR_SESSION_HANDLE_INVALID; +} + +CK_RV +mock_C_FindObjectsInit__invalid_handle (CK_SESSION_HANDLE session, + CK_ATTRIBUTE_PTR template, + CK_ULONG count) +{ + return CKR_SESSION_HANDLE_INVALID; +} + +CK_RV +mock_C_FindObjects__invalid_handle (CK_SESSION_HANDLE session, + CK_OBJECT_HANDLE_PTR objects, + CK_ULONG max_count, + CK_ULONG_PTR count) +{ + return_val_if_fail (count, CKR_ARGUMENTS_BAD); + + return CKR_SESSION_HANDLE_INVALID; +} + +CK_RV +mock_C_FindObjectsFinal__invalid_handle (CK_SESSION_HANDLE session) +{ + return CKR_SESSION_HANDLE_INVALID; +} + +CK_RV +mock_C_EncryptInit__invalid_handle (CK_SESSION_HANDLE session, + CK_MECHANISM_PTR mechanism, + CK_OBJECT_HANDLE key) +{ + return CKR_SESSION_HANDLE_INVALID; +} + +CK_RV +mock_C_Encrypt__invalid_handle (CK_SESSION_HANDLE session, + CK_BYTE_PTR data, CK_ULONG data_len, + CK_BYTE_PTR encrypted_data, + CK_ULONG_PTR encrypted_data_len) +{ + return_val_if_fail (encrypted_data_len, CKR_ARGUMENTS_BAD); + + return CKR_SESSION_HANDLE_INVALID; +} + +CK_RV +mock_C_EncryptUpdate__invalid_handle (CK_SESSION_HANDLE session, + CK_BYTE_PTR part, + CK_ULONG part_len, + CK_BYTE_PTR encrypted_part, + CK_ULONG_PTR encrypted_part_len) +{ + return_val_if_fail (encrypted_part_len, CKR_ARGUMENTS_BAD); + + return CKR_SESSION_HANDLE_INVALID; +} + +CK_RV +mock_C_EncryptFinal__invalid_handle (CK_SESSION_HANDLE session, + CK_BYTE_PTR last_part, + CK_ULONG_PTR last_part_len) +{ + return_val_if_fail (last_part_len, CKR_ARGUMENTS_BAD); + + return CKR_SESSION_HANDLE_INVALID; +} + +CK_RV +mock_C_DecryptInit__invalid_handle (CK_SESSION_HANDLE session, + CK_MECHANISM_PTR mechanism, + CK_OBJECT_HANDLE key) +{ + return CKR_SESSION_HANDLE_INVALID; +} + +CK_RV +mock_C_Decrypt__invalid_handle (CK_SESSION_HANDLE session, + CK_BYTE_PTR enc_data, + CK_ULONG enc_data_len, + CK_BYTE_PTR data, + CK_ULONG_PTR data_len) +{ + return_val_if_fail (data_len, CKR_ARGUMENTS_BAD); + + return CKR_SESSION_HANDLE_INVALID; +} + +CK_RV +mock_C_DecryptUpdate__invalid_handle (CK_SESSION_HANDLE session, + CK_BYTE_PTR enc_part, + CK_ULONG enc_part_len, + CK_BYTE_PTR part, + CK_ULONG_PTR part_len) +{ + return_val_if_fail (part_len, CKR_ARGUMENTS_BAD); + + return CKR_SESSION_HANDLE_INVALID; +} + +CK_RV +mock_C_DecryptFinal__invalid_handle (CK_SESSION_HANDLE session, + CK_BYTE_PTR last_part, + CK_ULONG_PTR last_part_len) +{ + return_val_if_fail (last_part_len, CKR_ARGUMENTS_BAD); + + return CKR_SESSION_HANDLE_INVALID; +} + +CK_RV +mock_C_DigestInit__invalid_handle (CK_SESSION_HANDLE session, + CK_MECHANISM_PTR mechanism) +{ + return CKR_SESSION_HANDLE_INVALID; +} + +CK_RV +mock_C_Digest__invalid_handle (CK_SESSION_HANDLE session, + CK_BYTE_PTR data, + CK_ULONG data_len, + CK_BYTE_PTR digest, + CK_ULONG_PTR digest_len) +{ + return_val_if_fail (digest_len, CKR_ARGUMENTS_BAD); + + return CKR_SESSION_HANDLE_INVALID; +} + +CK_RV +mock_C_DigestUpdate__invalid_handle (CK_SESSION_HANDLE session, + CK_BYTE_PTR part, + CK_ULONG part_len) +{ + return CKR_SESSION_HANDLE_INVALID; +} + +CK_RV +mock_C_DigestKey__invalid_handle (CK_SESSION_HANDLE session, + CK_OBJECT_HANDLE key) +{ + return CKR_SESSION_HANDLE_INVALID; +} + +CK_RV +mock_C_DigestFinal__invalid_handle (CK_SESSION_HANDLE session, + CK_BYTE_PTR digest, + CK_ULONG_PTR digest_len) +{ + return_val_if_fail (digest_len, CKR_ARGUMENTS_BAD); + + return CKR_SESSION_HANDLE_INVALID; +} + +CK_RV +mock_C_SignInit__invalid_handle (CK_SESSION_HANDLE session, + CK_MECHANISM_PTR mechanism, + CK_OBJECT_HANDLE key) +{ + return CKR_SESSION_HANDLE_INVALID; +} + +CK_RV +mock_C_Sign__invalid_handle (CK_SESSION_HANDLE session, + CK_BYTE_PTR data, + CK_ULONG data_len, + CK_BYTE_PTR signature, + CK_ULONG_PTR signature_len) +{ + return_val_if_fail (signature_len, CKR_ARGUMENTS_BAD); + + return CKR_SESSION_HANDLE_INVALID; +} + +CK_RV +mock_C_SignUpdate__invalid_handle (CK_SESSION_HANDLE session, + CK_BYTE_PTR part, + CK_ULONG part_len) +{ + return_val_if_fail (part_len, CKR_ARGUMENTS_BAD); + + return CKR_SESSION_HANDLE_INVALID; +} + +CK_RV +mock_C_SignFinal__invalid_handle (CK_SESSION_HANDLE session, + CK_BYTE_PTR signature, + CK_ULONG_PTR signature_len) +{ + return_val_if_fail (signature_len, CKR_ARGUMENTS_BAD); + + return CKR_SESSION_HANDLE_INVALID; +} + +CK_RV +mock_C_SignRecoverInit__invalid_handle (CK_SESSION_HANDLE session, + CK_MECHANISM_PTR mechanism, + CK_OBJECT_HANDLE key) +{ + return CKR_SESSION_HANDLE_INVALID; +} + +CK_RV +mock_C_SignRecover__invalid_handle (CK_SESSION_HANDLE session, + CK_BYTE_PTR data, + CK_ULONG data_len, + CK_BYTE_PTR signature, + CK_ULONG_PTR signature_len) +{ + return_val_if_fail (signature_len, CKR_ARGUMENTS_BAD); + + return CKR_SESSION_HANDLE_INVALID; +} + +CK_RV +mock_C_VerifyInit__invalid_handle (CK_SESSION_HANDLE session, + CK_MECHANISM_PTR mechanism, + CK_OBJECT_HANDLE key) +{ + return CKR_SESSION_HANDLE_INVALID; +} + +CK_RV +mock_C_Verify__invalid_handle (CK_SESSION_HANDLE session, + CK_BYTE_PTR data, + CK_ULONG data_len, + CK_BYTE_PTR signature, + CK_ULONG signature_len) +{ + return CKR_SESSION_HANDLE_INVALID; +} + +CK_RV +mock_C_VerifyUpdate__invalid_handle (CK_SESSION_HANDLE session, + CK_BYTE_PTR part, + CK_ULONG part_len) +{ + return CKR_SESSION_HANDLE_INVALID; +} + +CK_RV +mock_C_VerifyFinal__invalid_handle (CK_SESSION_HANDLE session, + CK_BYTE_PTR signature, + CK_ULONG signature_len) +{ + return CKR_SESSION_HANDLE_INVALID; +} + +CK_RV +mock_C_VerifyRecoverInit__invalid_handle (CK_SESSION_HANDLE session, + CK_MECHANISM_PTR mechanism, + CK_OBJECT_HANDLE key) +{ + return CKR_SESSION_HANDLE_INVALID; +} + +CK_RV +mock_C_VerifyRecover__invalid_handle (CK_SESSION_HANDLE session, + CK_BYTE_PTR signature, + CK_ULONG signature_len, + CK_BYTE_PTR data, + CK_ULONG_PTR data_len) +{ + return_val_if_fail (data_len, CKR_ARGUMENTS_BAD); + + return CKR_SESSION_HANDLE_INVALID; +} + +CK_RV +mock_C_DigestEncryptUpdate__invalid_handle (CK_SESSION_HANDLE session, + CK_BYTE_PTR part, + CK_ULONG part_len, CK_BYTE_PTR enc_part, + CK_ULONG_PTR enc_part_len) +{ + return_val_if_fail (enc_part_len, CKR_ARGUMENTS_BAD); + + return CKR_SESSION_HANDLE_INVALID; +} + +CK_RV +mock_C_DecryptDigestUpdate__invalid_handle (CK_SESSION_HANDLE session, + CK_BYTE_PTR enc_part, + CK_ULONG enc_part_len, + CK_BYTE_PTR part, + CK_ULONG_PTR part_len) +{ + return_val_if_fail (part_len, CKR_ARGUMENTS_BAD); + + return CKR_SESSION_HANDLE_INVALID; +} + +CK_RV +mock_C_SignEncryptUpdate__invalid_handle (CK_SESSION_HANDLE session, + CK_BYTE_PTR part, + CK_ULONG part_len, + CK_BYTE_PTR enc_part, + CK_ULONG_PTR enc_part_len) +{ + return_val_if_fail (enc_part_len, CKR_ARGUMENTS_BAD); + + return CKR_SESSION_HANDLE_INVALID; +} + +CK_RV +mock_C_DecryptVerifyUpdate__invalid_handle (CK_SESSION_HANDLE session, + CK_BYTE_PTR enc_part, + CK_ULONG enc_part_len, + CK_BYTE_PTR part, + CK_ULONG_PTR part_len) +{ + return_val_if_fail (part_len, CKR_ARGUMENTS_BAD); + + return CKR_SESSION_HANDLE_INVALID; +} + +CK_RV +mock_C_GenerateKey__invalid_handle (CK_SESSION_HANDLE session, + CK_MECHANISM_PTR mechanism, + CK_ATTRIBUTE_PTR template, + CK_ULONG count, + CK_OBJECT_HANDLE_PTR key) +{ + return CKR_SESSION_HANDLE_INVALID; +} + +CK_RV +mock_C_GenerateKeyPair__invalid_handle (CK_SESSION_HANDLE session, + 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 CKR_SESSION_HANDLE_INVALID; +} + +CK_RV +mock_C_WrapKey__invalid_handle (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) +{ + return_val_if_fail (wrapped_key_len, CKR_ARGUMENTS_BAD); + + return CKR_SESSION_HANDLE_INVALID; +} + +CK_RV +mock_C_UnwrapKey__invalid_handle (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) +{ + return CKR_SESSION_HANDLE_INVALID; +} + +CK_RV +mock_C_DeriveKey__invalid_handle (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) +{ + return CKR_SESSION_HANDLE_INVALID; +} + +CK_RV +mock_C_SeedRandom__invalid_handle (CK_SESSION_HANDLE session, + CK_BYTE_PTR seed, + CK_ULONG seed_len) +{ + return CKR_SESSION_HANDLE_INVALID; +} + +CK_RV +mock_C_GenerateRandom__invalid_handle (CK_SESSION_HANDLE session, + CK_BYTE_PTR random_data, + CK_ULONG random_len) +{ + return CKR_SESSION_HANDLE_INVALID; +} + +CK_FUNCTION_LIST mock_module_no_slots = { + { CRYPTOKI_VERSION_MAJOR, CRYPTOKI_VERSION_MINOR }, /* version */ + mock_C_Initialize, + mock_C_Finalize, + mock_C_GetInfo, + mock_C_GetFunctionList, + mock_C_GetSlotList__no_tokens, + mock_C_GetSlotInfo__invalid_slotid, + mock_C_GetTokenInfo__invalid_slotid, + mock_C_GetMechanismList__invalid_slotid, + mock_C_GetMechanismInfo__invalid_slotid, + mock_C_InitToken__invalid_slotid, + mock_C_InitPIN__invalid_handle, + mock_C_SetPIN__invalid_handle, + mock_C_OpenSession__invalid_slotid, + mock_C_CloseSession__invalid_handle, + mock_C_CloseAllSessions__invalid_slotid, + mock_C_GetSessionInfo__invalid_handle, + mock_C_GetOperationState__invalid_handle, + mock_C_SetOperationState__invalid_handle, + mock_C_Login__invalid_handle, + mock_C_Logout__invalid_handle, + mock_C_CreateObject__invalid_handle, + mock_C_CopyObject__invalid_handle, + mock_C_DestroyObject__invalid_handle, + mock_C_GetObjectSize__invalid_handle, + mock_C_GetAttributeValue__invalid_handle, + mock_C_SetAttributeValue__invalid_handle, + mock_C_FindObjectsInit__invalid_handle, + mock_C_FindObjects__invalid_handle, + mock_C_FindObjectsFinal__invalid_handle, + mock_C_EncryptInit__invalid_handle, + mock_C_Encrypt__invalid_handle, + mock_C_EncryptUpdate__invalid_handle, + mock_C_EncryptFinal__invalid_handle, + mock_C_DecryptInit__invalid_handle, + mock_C_Decrypt__invalid_handle, + mock_C_DecryptUpdate__invalid_handle, + mock_C_DecryptFinal__invalid_handle, + mock_C_DigestInit__invalid_handle, + mock_C_Digest__invalid_handle, + mock_C_DigestUpdate__invalid_handle, + mock_C_DigestKey__invalid_handle, + mock_C_DigestFinal__invalid_handle, + mock_C_SignInit__invalid_handle, + mock_C_Sign__invalid_handle, + mock_C_SignUpdate__invalid_handle, + mock_C_SignFinal__invalid_handle, + mock_C_SignRecoverInit__invalid_handle, + mock_C_SignRecover__invalid_handle, + mock_C_VerifyInit__invalid_handle, + mock_C_Verify__invalid_handle, + mock_C_VerifyUpdate__invalid_handle, + mock_C_VerifyFinal__invalid_handle, + mock_C_VerifyRecoverInit__invalid_handle, + mock_C_VerifyRecover__invalid_handle, + mock_C_DigestEncryptUpdate__invalid_handle, + mock_C_DecryptDigestUpdate__invalid_handle, + mock_C_SignEncryptUpdate__invalid_handle, + mock_C_DecryptVerifyUpdate__invalid_handle, + mock_C_GenerateKey__invalid_handle, + mock_C_GenerateKeyPair__invalid_handle, + mock_C_WrapKey__invalid_handle, + mock_C_UnwrapKey__invalid_handle, + mock_C_DeriveKey__invalid_handle, + mock_C_SeedRandom__invalid_handle, + mock_C_GenerateRandom__invalid_handle, + mock_C_GetFunctionStatus__not_parallel, + mock_C_CancelFunction__not_parallel, + mock_C_WaitForSlotEvent__no_event, +}; + +void +mock_module_init (void) +{ + static int initialized = 0; + if (!initialized) { + p11_mutex_init (&init_mutex); + initialized = 1; + } +} diff --git a/p11-kit/tests/mock-module.h b/p11-kit/tests/mock-module.h new file mode 100644 index 0000000..9557f70 --- /dev/null +++ b/p11-kit/tests/mock-module.h @@ -0,0 +1,337 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* mock-module.c - a mock PKCS#11 module + + Copyright (C) 2011 Collabora Ltd. + + The Gnome Keyring Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The Gnome Keyring Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the Gnome Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + Author: Stef Walter <stefw@collabora.co.uk> +*/ + +#ifndef __MOCK_MODULE_H__ +#define __MOCK_MODULE_H__ + +#include "pkcs11.h" + +extern CK_FUNCTION_LIST mock_module_no_slots; + +void mock_module_init (void); + +CK_RV mock_C_Initialize (CK_VOID_PTR init_args); + +CK_RV mock_C_Finalize (CK_VOID_PTR reserved); + +CK_RV mock_C_GetInfo (CK_INFO_PTR info); + +CK_RV mock_C_GetFunctionList (CK_FUNCTION_LIST_PTR_PTR list); + +CK_RV mock_C_GetSlotList__no_tokens (CK_BBOOL token_present, + CK_SLOT_ID_PTR slot_list, + CK_ULONG_PTR count); + +CK_RV mock_C_GetSlotInfo__invalid_slotid (CK_SLOT_ID id, + CK_SLOT_INFO_PTR info); + +CK_RV mock_C_GetTokenInfo__invalid_slotid (CK_SLOT_ID id, + CK_TOKEN_INFO_PTR info); + +CK_RV mock_C_GetMechanismList__invalid_slotid (CK_SLOT_ID id, + CK_MECHANISM_TYPE_PTR mechanism_list, + CK_ULONG_PTR count); + +CK_RV mock_C_GetMechanismInfo__invalid_slotid (CK_SLOT_ID id, + CK_MECHANISM_TYPE type, + CK_MECHANISM_INFO_PTR info); + +CK_RV mock_C_InitToken__invalid_slotid (CK_SLOT_ID id, + CK_UTF8CHAR_PTR pin, + CK_ULONG pin_len, + CK_UTF8CHAR_PTR label); + +CK_RV mock_C_WaitForSlotEvent__no_event (CK_FLAGS flags, + CK_SLOT_ID_PTR slot, + CK_VOID_PTR reserved); + +CK_RV mock_C_OpenSession__invalid_slotid (CK_SLOT_ID id, + CK_FLAGS flags, + CK_VOID_PTR user_data, + CK_NOTIFY callback, + CK_SESSION_HANDLE_PTR session); + +CK_RV mock_C_CloseSession__invalid_handle (CK_SESSION_HANDLE session); + +CK_RV mock_C_CloseAllSessions__invalid_slotid (CK_SLOT_ID id); + +CK_RV mock_C_GetFunctionStatus__not_parallel (CK_SESSION_HANDLE session); + +CK_RV mock_C_CancelFunction__not_parallel (CK_SESSION_HANDLE session); + +CK_RV mock_C_GetSessionInfo__invalid_handle (CK_SESSION_HANDLE session, + CK_SESSION_INFO_PTR info); + +CK_RV mock_C_InitPIN__invalid_handle (CK_SESSION_HANDLE session, + CK_UTF8CHAR_PTR pin, + CK_ULONG pin_len); + +CK_RV mock_C_SetPIN__invalid_handle (CK_SESSION_HANDLE session, + CK_UTF8CHAR_PTR old_pin, + CK_ULONG old_pin_len, + CK_UTF8CHAR_PTR new_pin, + CK_ULONG new_pin_len); + +CK_RV mock_C_GetOperationState__invalid_handle (CK_SESSION_HANDLE session, + CK_BYTE_PTR operation_state, + CK_ULONG_PTR operation_state_len); + +CK_RV mock_C_SetOperationState__invalid_handle (CK_SESSION_HANDLE session, + CK_BYTE_PTR operation_state, + CK_ULONG operation_state_len, + CK_OBJECT_HANDLE encryption_key, + CK_OBJECT_HANDLE authentication_key); + +CK_RV mock_C_Login__invalid_handle (CK_SESSION_HANDLE session, + CK_USER_TYPE user_type, + CK_UTF8CHAR_PTR pin, + CK_ULONG pin_len); + +CK_RV mock_C_Logout__invalid_handle (CK_SESSION_HANDLE session); + +CK_RV mock_C_CreateObject__invalid_handle (CK_SESSION_HANDLE session, + CK_ATTRIBUTE_PTR template, + CK_ULONG count, + CK_OBJECT_HANDLE_PTR new_object); + +CK_RV mock_C_CopyObject__invalid_handle (CK_SESSION_HANDLE session, + CK_OBJECT_HANDLE object, + CK_ATTRIBUTE_PTR template, + CK_ULONG count, + CK_OBJECT_HANDLE_PTR new_object); + +CK_RV mock_C_DestroyObject__invalid_handle (CK_SESSION_HANDLE session, + CK_OBJECT_HANDLE object); + +CK_RV mock_C_GetObjectSize__invalid_handle (CK_SESSION_HANDLE session, + CK_OBJECT_HANDLE object, + CK_ULONG_PTR size); + +CK_RV mock_C_GetAttributeValue__invalid_handle (CK_SESSION_HANDLE session, + CK_OBJECT_HANDLE object, + CK_ATTRIBUTE_PTR template, + CK_ULONG count); + +CK_RV mock_C_SetAttributeValue__invalid_handle (CK_SESSION_HANDLE session, + CK_OBJECT_HANDLE object, + CK_ATTRIBUTE_PTR template, + CK_ULONG count); + +CK_RV mock_C_FindObjectsInit__invalid_handle (CK_SESSION_HANDLE session, + CK_ATTRIBUTE_PTR template, + CK_ULONG count); + +CK_RV mock_C_FindObjects__invalid_handle (CK_SESSION_HANDLE session, + CK_OBJECT_HANDLE_PTR objects, + CK_ULONG max_count, + CK_ULONG_PTR count); + +CK_RV mock_C_FindObjectsFinal__invalid_handle (CK_SESSION_HANDLE session); + +CK_RV mock_C_EncryptInit__invalid_handle (CK_SESSION_HANDLE session, + CK_MECHANISM_PTR mechanism, + CK_OBJECT_HANDLE key); + +CK_RV mock_C_Encrypt__invalid_handle (CK_SESSION_HANDLE session, + CK_BYTE_PTR data, + CK_ULONG data_len, + CK_BYTE_PTR encrypted_data, + CK_ULONG_PTR encrypted_data_len); + +CK_RV mock_C_EncryptUpdate__invalid_handle (CK_SESSION_HANDLE session, + CK_BYTE_PTR part, + CK_ULONG part_len, + CK_BYTE_PTR encrypted_part, + CK_ULONG_PTR encrypted_part_len); + +CK_RV mock_C_EncryptFinal__invalid_handle (CK_SESSION_HANDLE session, + CK_BYTE_PTR last_part, + CK_ULONG_PTR last_part_len); + +CK_RV mock_C_DecryptInit__invalid_handle (CK_SESSION_HANDLE session, + CK_MECHANISM_PTR mechanism, + CK_OBJECT_HANDLE key); + +CK_RV mock_C_Decrypt__invalid_handle (CK_SESSION_HANDLE session, + CK_BYTE_PTR enc_data, + CK_ULONG enc_data_len, + CK_BYTE_PTR data, + CK_ULONG_PTR data_len); + +CK_RV mock_C_DecryptUpdate__invalid_handle (CK_SESSION_HANDLE session, + CK_BYTE_PTR enc_part, + CK_ULONG enc_part_len, + CK_BYTE_PTR part, + CK_ULONG_PTR part_len); + +CK_RV mock_C_DecryptFinal__invalid_handle (CK_SESSION_HANDLE session, + CK_BYTE_PTR last_part, + CK_ULONG_PTR last_part_len); + +CK_RV mock_C_DigestInit__invalid_handle (CK_SESSION_HANDLE session, + CK_MECHANISM_PTR mechanism); + +CK_RV mock_C_Digest__invalid_handle (CK_SESSION_HANDLE session, + CK_BYTE_PTR data, + CK_ULONG data_len, + CK_BYTE_PTR digest, + CK_ULONG_PTR digest_len); + +CK_RV mock_C_DigestUpdate__invalid_handle (CK_SESSION_HANDLE session, + CK_BYTE_PTR part, + CK_ULONG part_len); + +CK_RV mock_C_DigestKey__invalid_handle (CK_SESSION_HANDLE session, + CK_OBJECT_HANDLE key); + +CK_RV mock_C_DigestFinal__invalid_handle (CK_SESSION_HANDLE session, + CK_BYTE_PTR digest, + CK_ULONG_PTR digest_len); + +CK_RV mock_C_SignInit__invalid_handle (CK_SESSION_HANDLE session, + CK_MECHANISM_PTR mechanism, + CK_OBJECT_HANDLE key); + +CK_RV mock_C_Sign__invalid_handle (CK_SESSION_HANDLE session, + CK_BYTE_PTR data, + CK_ULONG data_len, + CK_BYTE_PTR signature, + CK_ULONG_PTR signature_len); + +CK_RV mock_C_SignUpdate__invalid_handle (CK_SESSION_HANDLE session, + CK_BYTE_PTR part, + CK_ULONG part_len); + +CK_RV mock_C_SignFinal__invalid_handle (CK_SESSION_HANDLE session, + CK_BYTE_PTR signature, + CK_ULONG_PTR signature_len); + +CK_RV mock_C_SignRecoverInit__invalid_handle (CK_SESSION_HANDLE session, + CK_MECHANISM_PTR mechanism, + CK_OBJECT_HANDLE key); + +CK_RV mock_C_SignRecover__invalid_handle (CK_SESSION_HANDLE session, + CK_BYTE_PTR data, + CK_ULONG data_len, + CK_BYTE_PTR signature, + CK_ULONG_PTR signature_len); + +CK_RV mock_C_VerifyInit__invalid_handle (CK_SESSION_HANDLE session, + CK_MECHANISM_PTR mechanism, + CK_OBJECT_HANDLE key); + +CK_RV mock_C_Verify__invalid_handle (CK_SESSION_HANDLE session, + CK_BYTE_PTR data, + CK_ULONG data_len, + CK_BYTE_PTR signature, + CK_ULONG signature_len); + +CK_RV mock_C_VerifyUpdate__invalid_handle (CK_SESSION_HANDLE session, + CK_BYTE_PTR part, + CK_ULONG part_len); + +CK_RV mock_C_VerifyFinal__invalid_handle (CK_SESSION_HANDLE session, + CK_BYTE_PTR signature, + CK_ULONG signature_len); + +CK_RV mock_C_VerifyRecoverInit__invalid_handle (CK_SESSION_HANDLE session, + CK_MECHANISM_PTR mechanism, + CK_OBJECT_HANDLE key); + +CK_RV mock_C_VerifyRecover__invalid_handle (CK_SESSION_HANDLE session, + CK_BYTE_PTR signature, + CK_ULONG signature_len, + CK_BYTE_PTR data, + CK_ULONG_PTR data_len); + +CK_RV mock_C_DigestEncryptUpdate__invalid_handle (CK_SESSION_HANDLE session, + CK_BYTE_PTR part, + CK_ULONG part_len, + CK_BYTE_PTR enc_part, + CK_ULONG_PTR enc_part_len); + +CK_RV mock_C_DecryptDigestUpdate__invalid_handle (CK_SESSION_HANDLE session, + CK_BYTE_PTR enc_part, + CK_ULONG enc_part_len, + CK_BYTE_PTR part, + CK_ULONG_PTR part_len); + +CK_RV mock_C_SignEncryptUpdate__invalid_handle (CK_SESSION_HANDLE session, + CK_BYTE_PTR part, + CK_ULONG part_len, + CK_BYTE_PTR enc_part, + CK_ULONG_PTR enc_part_len); + +CK_RV mock_C_DecryptVerifyUpdate__invalid_handle (CK_SESSION_HANDLE session, + CK_BYTE_PTR enc_part, + CK_ULONG enc_part_len, + CK_BYTE_PTR part, + CK_ULONG_PTR part_len); + +CK_RV mock_C_GenerateKey__invalid_handle (CK_SESSION_HANDLE session, + CK_MECHANISM_PTR mechanism, + CK_ATTRIBUTE_PTR template, + CK_ULONG count, + CK_OBJECT_HANDLE_PTR key); + +CK_RV mock_C_GenerateKeyPair__invalid_handle (CK_SESSION_HANDLE session, + 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); + +CK_RV mock_C_WrapKey__invalid_handle (CK_SESSION_HANDLE session, + CK_MECHANISM_PTR mechanism, + CK_OBJECT_HANDLE wrapping_key, + CK_OBJECT_HANDLE key, + CK_BYTE_PTR wrapped_key, + CK_ULONG_PTR wrapped_key_len); + +CK_RV mock_C_UnwrapKey__invalid_handle (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); + +CK_RV mock_C_DeriveKey__invalid_handle (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); + +CK_RV mock_C_SeedRandom__invalid_handle (CK_SESSION_HANDLE session, + CK_BYTE_PTR seed, + CK_ULONG seed_len); + +CK_RV mock_C_GenerateRandom__invalid_handle (CK_SESSION_HANDLE session, + CK_BYTE_PTR random_data, + CK_ULONG random_len); + +#endif /* __MOCK_MODULE_H__ */ diff --git a/p11-kit/tests/pin-test.c b/p11-kit/tests/pin-test.c new file mode 100644 index 0000000..5427f8b --- /dev/null +++ b/p11-kit/tests/pin-test.c @@ -0,0 +1,325 @@ +/* + * Copyright (c) 2011, Collabora Ltd. + * + * 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@collabora.co.uk> + */ + +#include "config.h" +#include "CuTest.h" + +#include "library.h" + +#include <assert.h> +#include <errno.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +#include "p11-kit/pin.h" +#include "p11-kit/private.h" + +static P11KitPin * +callback_one (const char *pin_source, P11KitUri *pin_uri, const char *pin_description, + P11KitPinFlags pin_flags, void *callback_data) +{ + int *data = callback_data; + assert (*data == 33); + return p11_kit_pin_new_for_buffer ((unsigned char*)strdup ("one"), 3, free); +} + +static P11KitPin* +callback_other (const char *pin_source, P11KitUri *pin_uri, const char *pin_description, + P11KitPinFlags pin_flags, void *callback_data) +{ + char *data = callback_data; + return p11_kit_pin_new_for_string (data); +} + +static void +destroy_data (void *callback_data) +{ + int *data = callback_data; + (*data)++; +} + +static void +test_pin_register_unregister (CuTest *tc) +{ + int data = 33; + + p11_kit_pin_register_callback ("/the/pin_source", callback_one, + &data, destroy_data); + + p11_kit_pin_unregister_callback ("/the/pin_source", callback_one, + &data); + + CuAssertIntEquals (tc, 34, data); +} + +static void +test_pin_read (CuTest *tc) +{ + P11KitUri *uri; + P11KitPin *pin; + int data = 33; + size_t length; + const unsigned char *ptr; + + p11_kit_pin_register_callback ("/the/pin_source", callback_one, + &data, destroy_data); + + uri = p11_kit_uri_new (); + pin = p11_kit_pin_request ("/the/pin_source", uri, "The token", + P11_KIT_PIN_FLAGS_USER_LOGIN); + p11_kit_uri_free (uri); + + CuAssertPtrNotNull (tc, pin); + ptr = p11_kit_pin_get_value (pin, &length); + CuAssertIntEquals (tc, 3, length); + CuAssertTrue (tc, memcmp (ptr, "one", 3) == 0); + + p11_kit_pin_unregister_callback ("/the/pin_source", callback_one, + &data); + + p11_kit_pin_ref (pin); + p11_kit_pin_unref (pin); +} + +static void +test_pin_read_no_match (CuTest *tc) +{ + P11KitUri *uri; + P11KitPin *pin; + + uri = p11_kit_uri_new (); + pin = p11_kit_pin_request ("/the/pin_source", uri, "The token", + P11_KIT_PIN_FLAGS_USER_LOGIN); + p11_kit_uri_free (uri); + + CuAssertPtrEquals (tc, NULL, pin); +} + +static void +test_pin_register_duplicate (CuTest *tc) +{ + P11KitUri *uri; + P11KitPin *pin; + char *value = "secret"; + int data = 33; + size_t length; + const unsigned char *ptr; + + uri = p11_kit_uri_new (); + + p11_kit_pin_register_callback ("/the/pin_source", callback_one, + &data, destroy_data); + + p11_kit_pin_register_callback ("/the/pin_source", callback_other, + value, NULL); + + pin = p11_kit_pin_request ("/the/pin_source", uri, "The token", + P11_KIT_PIN_FLAGS_USER_LOGIN); + + CuAssertPtrNotNull (tc, pin); + ptr = p11_kit_pin_get_value (pin, &length); + CuAssertIntEquals (tc, 6, length); + CuAssertTrue (tc, memcmp (ptr, "secret", length) == 0); + p11_kit_pin_unref (pin); + + p11_kit_pin_unregister_callback ("/the/pin_source", callback_other, + value); + + pin = p11_kit_pin_request ("/the/pin_source", uri, "The token", + P11_KIT_PIN_FLAGS_USER_LOGIN); + + CuAssertPtrNotNull (tc, pin); + ptr = p11_kit_pin_get_value (pin, &length); + CuAssertIntEquals (tc, 3, length); + CuAssertTrue (tc, memcmp (ptr, "one", length) == 0); + p11_kit_pin_unref (pin); + + p11_kit_pin_unregister_callback ("/the/pin_source", callback_one, + &data); + + pin = p11_kit_pin_request ("/the/pin_source", uri, "The token", + P11_KIT_PIN_FLAGS_USER_LOGIN); + + CuAssertPtrEquals (tc, NULL, pin); + + p11_kit_uri_free (uri); +} + +static void +test_pin_register_fallback (CuTest *tc) +{ + char *value = "secret"; + P11KitUri *uri; + P11KitPin *pin; + int data = 33; + size_t length; + const unsigned char *ptr; + + uri = p11_kit_uri_new (); + + p11_kit_pin_register_callback (P11_KIT_PIN_FALLBACK, callback_one, + &data, destroy_data); + + pin = p11_kit_pin_request ("/the/pin_source", uri, "The token", + P11_KIT_PIN_FLAGS_USER_LOGIN); + + CuAssertPtrNotNull (tc, pin); + ptr = p11_kit_pin_get_value (pin, &length); + CuAssertIntEquals (tc, 3, length); + CuAssertTrue (tc, memcmp (ptr, "one", length) == 0); + p11_kit_pin_unref (pin); + + p11_kit_pin_register_callback ("/the/pin_source", callback_other, + value, NULL); + + pin = p11_kit_pin_request ("/the/pin_source", uri, "The token", + P11_KIT_PIN_FLAGS_USER_LOGIN); + + CuAssertPtrNotNull (tc, pin); + ptr = p11_kit_pin_get_value (pin, &length); + CuAssertIntEquals (tc, 6, length); + CuAssertTrue (tc, memcmp (ptr, "secret", length) == 0); + p11_kit_pin_unref (pin); + + p11_kit_pin_unregister_callback ("/the/pin_source", callback_other, + value); + + p11_kit_pin_unregister_callback (P11_KIT_PIN_FALLBACK, callback_one, + &data); + + p11_kit_uri_free (uri); +} + +static void +test_pin_file (CuTest *tc) +{ + P11KitUri *uri; + P11KitPin *pin; + size_t length; + const unsigned char *ptr; + + uri = p11_kit_uri_new (); + + p11_kit_pin_register_callback (P11_KIT_PIN_FALLBACK, p11_kit_pin_file_callback, + NULL, NULL); + + pin = p11_kit_pin_request (SRCDIR "/files/test-pinfile", uri, "The token", + P11_KIT_PIN_FLAGS_USER_LOGIN); + + CuAssertPtrNotNull (tc, pin); + ptr = p11_kit_pin_get_value (pin, &length); + CuAssertIntEquals (tc, 12, length); + CuAssertTrue (tc, 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); + + p11_kit_pin_unregister_callback (P11_KIT_PIN_FALLBACK, p11_kit_pin_file_callback, + NULL); + + p11_kit_uri_free (uri); +} + +static void +test_pin_file_large (CuTest *tc) +{ + P11KitUri *uri; + P11KitPin *pin; + int error; + + uri = p11_kit_uri_new (); + + p11_kit_pin_register_callback (P11_KIT_PIN_FALLBACK, p11_kit_pin_file_callback, + NULL, NULL); + + pin = p11_kit_pin_request (SRCDIR "/files/test-pinfile-large", uri, "The token", + P11_KIT_PIN_FLAGS_USER_LOGIN); + + error = errno; + CuAssertPtrEquals (tc, NULL, pin); + CuAssertIntEquals (tc, EFBIG, error); + + p11_kit_pin_unregister_callback (P11_KIT_PIN_FALLBACK, p11_kit_pin_file_callback, + NULL); + + p11_kit_uri_free (uri); +} + +static void +test_pin_ref_unref (CuTest *tc) +{ + P11KitPin *pin; + P11KitPin *check; + + pin = p11_kit_pin_new_for_string ("crack of lies"); + + check = p11_kit_pin_ref (pin); + CuAssertPtrEquals (tc, pin, check); + + p11_kit_pin_unref (pin); + p11_kit_pin_unref (check); +} + +int +main (void) +{ + CuString *output = CuStringNew (); + CuSuite* suite = CuSuiteNew (); + int ret; + + 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; +} diff --git a/p11-kit/tests/print-messages.c b/p11-kit/tests/print-messages.c new file mode 100644 index 0000000..5870ad1 --- /dev/null +++ b/p11-kit/tests/print-messages.c @@ -0,0 +1,137 @@ +/* + * Copyright (c) 2011, Collabora Ltd. + * + * 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@collabora.co.uk> + */ + +#include "config.h" + +#include <assert.h> +#include <string.h> +#include <stdio.h> +#include <stdlib.h> + +#include "p11-kit.h" + +int +main (int argc, char *argv[]) +{ + if (argc != 1) { + fprintf (stderr, "usage: print-messages\n"); + exit (2); + } + + #define X(x) printf ("%s: %s\n", #x, p11_kit_strerror (x)) + X(CKR_CANCEL); + X(CKR_FUNCTION_CANCELED); + X(CKR_HOST_MEMORY); + X(CKR_SLOT_ID_INVALID); + X(CKR_GENERAL_ERROR); + X(CKR_FUNCTION_FAILED); + X(CKR_ARGUMENTS_BAD); + X(CKR_NEED_TO_CREATE_THREADS); + X(CKR_CANT_LOCK); + X(CKR_ATTRIBUTE_READ_ONLY); + X(CKR_ATTRIBUTE_SENSITIVE); + X(CKR_ATTRIBUTE_TYPE_INVALID); + X(CKR_ATTRIBUTE_VALUE_INVALID); + X(CKR_DATA_INVALID); + X(CKR_DATA_LEN_RANGE); + X(CKR_DEVICE_ERROR); + X(CKR_DEVICE_MEMORY); + X(CKR_DEVICE_REMOVED); + X(CKR_ENCRYPTED_DATA_INVALID); + X(CKR_ENCRYPTED_DATA_LEN_RANGE); + X(CKR_FUNCTION_NOT_SUPPORTED); + X(CKR_KEY_HANDLE_INVALID); + X(CKR_KEY_SIZE_RANGE); + X(CKR_KEY_TYPE_INCONSISTENT); + X(CKR_KEY_NOT_NEEDED); + X(CKR_KEY_CHANGED); + X(CKR_KEY_NEEDED); + X(CKR_KEY_INDIGESTIBLE); + X(CKR_KEY_FUNCTION_NOT_PERMITTED); + X(CKR_KEY_NOT_WRAPPABLE); + X(CKR_KEY_UNEXTRACTABLE); + X(CKR_MECHANISM_INVALID); + X(CKR_MECHANISM_PARAM_INVALID); + X(CKR_OBJECT_HANDLE_INVALID); + X(CKR_OPERATION_ACTIVE); + X(CKR_OPERATION_NOT_INITIALIZED); + X(CKR_PIN_INCORRECT); + X(CKR_PIN_INVALID); + X(CKR_PIN_LEN_RANGE); + X(CKR_PIN_EXPIRED); + X(CKR_PIN_LOCKED); + X(CKR_SESSION_CLOSED); + X(CKR_SESSION_COUNT); + X(CKR_SESSION_HANDLE_INVALID); + X(CKR_SESSION_READ_ONLY); + X(CKR_SESSION_EXISTS); + X(CKR_SESSION_READ_ONLY_EXISTS); + X(CKR_SESSION_READ_WRITE_SO_EXISTS); + X(CKR_SIGNATURE_INVALID); + X(CKR_SIGNATURE_LEN_RANGE); + X(CKR_TEMPLATE_INCOMPLETE); + X(CKR_TEMPLATE_INCONSISTENT); + X(CKR_TOKEN_NOT_PRESENT); + X(CKR_TOKEN_NOT_RECOGNIZED); + X(CKR_TOKEN_WRITE_PROTECTED); + X(CKR_UNWRAPPING_KEY_HANDLE_INVALID); + X(CKR_UNWRAPPING_KEY_SIZE_RANGE); + X(CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT); + X(CKR_USER_ALREADY_LOGGED_IN); + X(CKR_USER_NOT_LOGGED_IN); + X(CKR_USER_PIN_NOT_INITIALIZED); + X(CKR_USER_TYPE_INVALID); + X(CKR_USER_ANOTHER_ALREADY_LOGGED_IN); + X(CKR_USER_TOO_MANY_TYPES); + X(CKR_WRAPPED_KEY_INVALID); + X(CKR_WRAPPED_KEY_LEN_RANGE); + X(CKR_WRAPPING_KEY_HANDLE_INVALID); + X(CKR_WRAPPING_KEY_SIZE_RANGE); + X(CKR_WRAPPING_KEY_TYPE_INCONSISTENT); + X(CKR_RANDOM_SEED_NOT_SUPPORTED); + X(CKR_RANDOM_NO_RNG); + X(CKR_DOMAIN_PARAMS_INVALID); + X(CKR_BUFFER_TOO_SMALL); + X(CKR_SAVED_STATE_INVALID); + X(CKR_INFORMATION_SENSITIVE); + X(CKR_STATE_UNSAVEABLE); + X(CKR_CRYPTOKI_NOT_INITIALIZED); + X(CKR_CRYPTOKI_ALREADY_INITIALIZED); + X(CKR_MUTEX_BAD); + X(CKR_MUTEX_NOT_LOCKED); + X(CKR_FUNCTION_REJECTED); + #undef X + + return 0; +} diff --git a/p11-kit/tests/progname-test.c b/p11-kit/tests/progname-test.c new file mode 100644 index 0000000..bd37400 --- /dev/null +++ b/p11-kit/tests/progname-test.c @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2012 Stefan Walter + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * * Redistributions in binary form must reproduce the + * above copyright notice, this list of conditions and + * the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * * The names of contributors to this software may not be + * used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * Author: Stef Walter <stef@thewalter.net> + */ + +#include "config.h" +#include "CuTest.h" + +#include "library.h" + +#include <assert.h> +#include <string.h> +#include <stdio.h> +#include <stdlib.h> + +#include "p11-kit/uri.h" +#include "p11-kit/p11-kit.h" +#include "p11-kit/private.h" + +static void +test_progname_default (CuTest *tc) +{ + const char *progname; + + progname = _p11_get_progname_unlocked (); + CuAssertStrEquals (tc, "progname-test", progname); +} + +static void +test_progname_set (CuTest *tc) +{ + const char *progname; + + p11_kit_set_progname ("love-generation"); + + progname = _p11_get_progname_unlocked (); + CuAssertStrEquals (tc, "love-generation", progname); + + _p11_set_progname_unlocked (NULL); + + progname = _p11_get_progname_unlocked (); + CuAssertStrEquals (tc, "progname-test", progname); +} + +/* Defined in util.c */ +extern char p11_my_progname[]; + +int +main (void) +{ + CuString *output = CuStringNew (); + CuSuite* suite = CuSuiteNew (); + int ret; + + 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; +} diff --git a/p11-kit/tests/test-init.c b/p11-kit/tests/test-init.c new file mode 100644 index 0000000..5861bbf --- /dev/null +++ b/p11-kit/tests/test-init.c @@ -0,0 +1,320 @@ +/* + * Copyright (c) 2011, Collabora Ltd. + * + * 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@collabora.co.uk> + */ + +#include "config.h" +#include "CuTest.h" + +#include <sys/types.h> + +#include "library.h" + +#include <assert.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <time.h> +#include <unistd.h> + +#include "p11-kit/p11-kit.h" + +#include "mock-module.h" + +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 (CuTest *tc) +{ + 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__with_fork; + + rv = p11_kit_initialize_module (&module); + CuAssertTrue (tc, rv == CKR_OK); + + rv = p11_kit_finalize_module (&module); + CuAssertTrue (tc, rv == CKR_OK); +} + +#endif /* OS_UNIX */ + +static CK_RV +mock_C_Initialize__with_recursive (CK_VOID_PTR init_args) +{ + CK_RV rv; + + rv = mock_C_Initialize (init_args); + assert (rv == CKR_OK); + + /* Recursively initialize, this is broken */ + return p11_kit_initialize_module (&module); +} + +static void +test_recursive_initialization (CuTest *tc) +{ + 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__with_recursive; + + rv = p11_kit_initialize_module (&module); + CuAssertTrue (tc, rv == CKR_FUNCTION_FAILED); +} + +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) +{ + /* 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) +{ + CuTest *tc = data; + CK_RV rv; + + rv = p11_kit_initialize_module (&module); + CuAssertTrue (tc, rv == CKR_OK); + + return tc; +} + +static void * +finalization_thread (void *data) +{ + CuTest *tc = data; + CK_RV rv; + + rv = p11_kit_finalize_module (&module); + CuAssertTrue (tc, rv == CKR_OK); + + return tc; +} + +static void +test_threaded_initialization (CuTest *tc) +{ + static const int num_threads = 2; + p11_thread_t threads[num_threads]; + int ret; + int i; + + /* 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, tc); + CuAssertIntEquals (tc, 0, ret); + CuAssertTrue (tc, threads[i] != 0); + } + + for (i = 0; i < num_threads; i++) { + ret = p11_thread_join (threads[i]); + CuAssertIntEquals (tc, 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); + } + + for (i = 0; i < num_threads; i++) { + ret = p11_thread_join (threads[i]); + CuAssertIntEquals (tc, 0, ret); + threads[i] = 0; + } + + /* C_Initialize should have been called exactly once */ + CuAssertIntEquals (tc, 1, initialization_count); + CuAssertIntEquals (tc, 1, finalization_count); +} + +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; + + 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 (CuTest *tc) +{ + 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); + + rv = p11_kit_finalize_module (&module); + CuAssertTrue (tc, rv == CKR_OK); +} + +static void +test_load_and_initialize (CuTest *tc) +{ + 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); + + rv = (module->C_GetInfo) (&info); + CuAssertTrue (tc, rv == CKR_OK); + + ret = memcmp (info.manufacturerID, "MOCK MANUFACTURER ", 32); + CuAssertTrue (tc, ret == 0); + + rv = p11_kit_finalize_module (module); + CuAssertTrue (tc, ret == CKR_OK); +} + +int +main (void) +{ + CuString *output = CuStringNew (); + CuSuite* suite = CuSuiteNew (); + int ret; + + p11_mutex_init (&race_mutex); + mock_module_init (); + p11_library_init (); + +#ifdef OS_UNIX + SUITE_ADD_TEST (suite, 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); + + return ret; +} diff --git a/p11-kit/tests/test-modules.c b/p11-kit/tests/test-modules.c new file mode 100644 index 0000000..159e04e --- /dev/null +++ b/p11-kit/tests/test-modules.c @@ -0,0 +1,246 @@ +/* + * 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 "CuTest.h" + +#include <errno.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +#include "library.h" +#include "p11-kit.h" +#include "private.h" +#include "dict.h" + +static CK_FUNCTION_LIST_PTR_PTR +initialize_and_get_modules (CuTest *tc) +{ + 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); + + return modules; +} + +static void +finalize_and_free_modules (CuTest *tc, + CK_FUNCTION_LIST_PTR_PTR modules) +{ + CK_RV rv; + + free (modules); + rv = p11_kit_finalize_registered (); + CuAssertIntEquals (tc, CKR_OK, rv); +} + +static void +test_no_duplicates (CuTest *tc) +{ + CK_FUNCTION_LIST_PTR_PTR modules; + p11_dict *paths; + p11_dict *funcs; + char *path; + int i; + + modules = initialize_and_get_modules (tc); + 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])) + CuAssert (tc, "found duplicate function list pointer", 0); + if (p11_dict_get (paths, path)) + CuAssert (tc, "found duplicate path name", 0); + + if (!p11_dict_set (funcs, modules[i], "")) + CuAssert (tc, "shouldn't be reached", 0); + if (!p11_dict_set (paths, path, "")) + CuAssert (tc, "shouldn't be reached", 0); + } + + p11_dict_free (paths); + p11_dict_free (funcs); + finalize_and_free_modules (tc, modules); +} + +static CK_FUNCTION_LIST_PTR +lookup_module_with_name (CuTest *tc, + 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]); + CuAssertPtrNotNull (tc, 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); + CuAssert(tc, "different result from p11_kit_registered_name_to_module()", + module == match); + + return match; +} + +static void +test_disable (CuTest *tc) +{ + 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 (tc); + CuAssertTrue (tc, lookup_module_with_name (tc, modules, "four") != NULL); + finalize_and_free_modules (tc, 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 (tc); + CuAssertTrue (tc, lookup_module_with_name (tc, modules, "four") == NULL); + finalize_and_free_modules (tc, modules); + + p11_kit_set_progname (NULL); +} + +static void +test_disable_later (CuTest *tc) +{ + 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 (); + CuAssertIntEquals (tc, CKR_OK, rv); + + p11_kit_set_progname ("test-disable"); + + modules = p11_kit_registered_modules (); + CuAssertTrue (tc, modules != NULL && modules[0] != NULL); + + CuAssertTrue (tc, lookup_module_with_name (tc, modules, "two") == NULL); + finalize_and_free_modules (tc, modules); + + p11_kit_set_progname (NULL); +} + +static void +test_enable (CuTest *tc) +{ + 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 (tc); + CuAssertTrue (tc, lookup_module_with_name (tc, modules, "three") == NULL); + finalize_and_free_modules (tc, 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 (tc); + CuAssertTrue (tc, lookup_module_with_name (tc, modules, "three") != NULL); + finalize_and_free_modules (tc, modules); + + p11_kit_set_progname (NULL); +} + +int +main (void) +{ + CuString *output = CuStringNew (); + CuSuite* suite = CuSuiteNew (); + int ret; + + 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); + + 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; +} diff --git a/p11-kit/tests/uri-test.c b/p11-kit/tests/uri-test.c new file mode 100644 index 0000000..0e3e722 --- /dev/null +++ b/p11-kit/tests/uri-test.c @@ -0,0 +1,1223 @@ +/* + * Copyright (c) 2011, Collabora Ltd. + * + * 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@collabora.co.uk> + */ + +#include "config.h" +#include "CuTest.h" + +#include "library.h" + +#include <assert.h> +#include <string.h> +#include <stdio.h> +#include <stdlib.h> + +#include "p11-kit/uri.h" +#include "p11-kit/private.h" + +static int +is_module_empty (P11KitUri *uri) +{ + CK_INFO_PTR info = p11_kit_uri_get_module_info (uri); + return (info->libraryDescription[0] == 0 && + info->manufacturerID[0] == 0 && + info->libraryVersion.major == (CK_BYTE)-1 && + info->libraryVersion.minor == (CK_BYTE)-1); +} + +static int +is_token_empty (P11KitUri *uri) +{ + CK_TOKEN_INFO_PTR token = p11_kit_uri_get_token_info (uri); + return (token->serialNumber[0] == 0 && + token->manufacturerID[0] == 0 && + token->label[0] == 0 && + token->model[0] == 0); +} + +static int +are_attributes_empty (P11KitUri *uri) +{ + return (p11_kit_uri_get_attribute (uri, CKA_LABEL) == NULL && + p11_kit_uri_get_attribute (uri, CKA_ID) == NULL && + p11_kit_uri_get_attribute (uri, CKA_CLASS) == NULL); +} + +static void +test_uri_parse (CuTest *tc) +{ + P11KitUri *uri; + int ret; + + uri = p11_kit_uri_new (); + CuAssertPtrNotNull (tc, uri); + + ret = p11_kit_uri_parse ("pkcs11:", P11_KIT_URI_FOR_MODULE, uri); + CuAssertIntEquals (tc, P11_KIT_URI_OK, ret); + + CuAssertTrue (tc, is_module_empty (uri)); + CuAssertTrue (tc, is_token_empty (uri)); + CuAssertTrue (tc, are_attributes_empty (uri)); + + p11_kit_uri_free (uri); +} + +static void +test_uri_parse_bad_scheme (CuTest *tc) +{ + P11KitUri *uri; + int ret; + + uri = p11_kit_uri_new (); + CuAssertPtrNotNull (tc, uri); + + ret = p11_kit_uri_parse ("http:\\example.com\test", P11_KIT_URI_FOR_ANY, uri); + CuAssertIntEquals (tc, P11_KIT_URI_BAD_SCHEME, ret); + + p11_kit_uri_free (uri); +} + +static void +test_uri_parse_with_label (CuTest *tc) +{ + CK_ATTRIBUTE_PTR attr; + P11KitUri *uri; + int ret; + + uri = p11_kit_uri_new (); + CuAssertPtrNotNull (tc, uri); + + ret = p11_kit_uri_parse ("pkcs11:object=Test%20Label", P11_KIT_URI_FOR_ANY, uri); + CuAssertIntEquals (tc, P11_KIT_URI_OK, ret); + + CuAssertTrue (tc, is_module_empty (uri)); + CuAssertTrue (tc, 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); + + p11_kit_uri_free (uri); +} + +static void +test_uri_parse_with_label_and_klass (CuTest *tc) +{ + CK_ATTRIBUTE_PTR attr; + P11KitUri *uri; + int ret; + + uri = p11_kit_uri_new (); + CuAssertPtrNotNull (tc, 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); + + 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); + + 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); + + p11_kit_uri_free (uri); +} + +static void +test_uri_parse_with_id (CuTest *tc) +{ + CK_ATTRIBUTE_PTR attr; + P11KitUri *uri; + int ret; + + uri = p11_kit_uri_new (); + CuAssertPtrNotNull (tc, 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); + + /* 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); + + + p11_kit_uri_free (uri); +} + +static void +test_uri_parse_with_bad_string_encoding (CuTest *tc) +{ + P11KitUri *uri; + int ret; + + uri = p11_kit_uri_new (); + CuAssertPtrNotNull (tc, uri); + + ret = p11_kit_uri_parse ("pkcs11:object=Test%", P11_KIT_URI_FOR_OBJECT, uri); + CuAssertIntEquals (tc, P11_KIT_URI_BAD_ENCODING, ret); + + p11_kit_uri_free (uri); +} + +static void +test_uri_parse_with_bad_hex_encoding (CuTest *tc) +{ + P11KitUri *uri; + int ret; + + uri = p11_kit_uri_new (); + CuAssertPtrNotNull (tc, uri); + + ret = p11_kit_uri_parse ("pkcs11:object=T%xxest", P11_KIT_URI_FOR_OBJECT, uri); + CuAssertIntEquals (tc, P11_KIT_URI_BAD_ENCODING, ret); + + p11_kit_uri_free (uri); +} + +static int +is_space_string (CK_UTF8CHAR_PTR string, CK_ULONG size, const char *check) +{ + size_t i, len = strlen (check); + if (len > size) + return 0; + if (memcmp (string, check, len) != 0) + return 0; + for (i = len; i < size; ++i) + if (string[i] != ' ') + return 0; + return 1; +} + +static void +test_uri_parse_with_token (CuTest *tc) +{ + P11KitUri *uri = NULL; + CK_TOKEN_INFO_PTR token; + int ret; + + uri = p11_kit_uri_new (); + CuAssertPtrNotNull (tc, 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); + + 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")); + + p11_kit_uri_free (uri); +} + +static void +test_uri_parse_with_token_bad_encoding (CuTest *tc) +{ + P11KitUri *uri; + int ret; + + uri = p11_kit_uri_new (); + CuAssertPtrNotNull (tc, uri); + + ret = p11_kit_uri_parse ("pkcs11:token=Token%", P11_KIT_URI_FOR_TOKEN, uri); + CuAssertIntEquals (tc, P11_KIT_URI_BAD_ENCODING, ret); + + p11_kit_uri_free (uri); +} + +static void +test_uri_parse_with_bad_syntax (CuTest *tc) +{ + P11KitUri *uri; + int ret; + + uri = p11_kit_uri_new (); + CuAssertPtrNotNull (tc, uri); + + ret = p11_kit_uri_parse ("pkcs11:token", P11_KIT_URI_FOR_ANY, uri); + CuAssertIntEquals (tc, P11_KIT_URI_BAD_SYNTAX, ret); + + p11_kit_uri_free (uri); +} + +static void +test_uri_parse_with_spaces (CuTest *tc) +{ + P11KitUri *uri = NULL; + CK_INFO_PTR info; + int ret; + + uri = p11_kit_uri_new (); + CuAssertPtrNotNull (tc, 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); + + 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")); + + p11_kit_uri_free (uri); +} + + +static void +test_uri_parse_with_library (CuTest *tc) +{ + P11KitUri *uri = NULL; + CK_INFO_PTR info; + int ret; + + uri = p11_kit_uri_new (); + CuAssertPtrNotNull (tc, 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); + + 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")); + + p11_kit_uri_free (uri); +} + +static void +test_uri_parse_with_library_bad_encoding (CuTest *tc) +{ + P11KitUri *uri; + int ret; + + uri = p11_kit_uri_new (); + CuAssertPtrNotNull (tc, uri); + + ret = p11_kit_uri_parse ("pkcs11:library-description=Library%", P11_KIT_URI_FOR_MODULE, uri); + CuAssertIntEquals (tc, P11_KIT_URI_BAD_ENCODING, ret); + + p11_kit_uri_free (uri); +} + +static void +test_uri_build_empty (CuTest *tc) +{ + P11KitUri *uri; + char *string; + int ret; + + uri = p11_kit_uri_new (); + CuAssertPtrNotNull (tc, uri); + + ret = p11_kit_uri_format (uri, P11_KIT_URI_FOR_ANY, &string); + CuAssertIntEquals (tc, P11_KIT_URI_OK, ret); + CuAssertStrEquals (tc, "pkcs11:", string); + free (string); + + p11_kit_uri_free (uri); +} + +static void +set_space_string (CK_BYTE_PTR buffer, CK_ULONG length, const char *string) +{ + size_t len = strlen (string); + assert (len <= length); + memset (buffer, ' ', length); + memcpy (buffer, string, len); +} + +static void +test_uri_build_with_token_info (CuTest *tc) +{ + char *string = NULL; + P11KitUri *uri; + P11KitUri *check; + CK_TOKEN_INFO_PTR token; + int ret; + + uri = p11_kit_uri_new (); + CuAssertPtrNotNull (tc, uri); + + token = p11_kit_uri_get_token_info (uri); + set_space_string (token->label, sizeof (token->label), "The Label"); + set_space_string (token->serialNumber, sizeof (token->serialNumber), "44444"); + set_space_string (token->manufacturerID, sizeof (token->manufacturerID), "Me"); + 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); + + check = p11_kit_uri_new (); + CuAssertPtrNotNull (tc, check); + + ret = p11_kit_uri_parse (string, P11_KIT_URI_FOR_TOKEN, check); + CuAssertIntEquals (tc, 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); + + free (string); +} + +static void +test_uri_build_with_token_null_info (CuTest *tc) +{ + char *string = NULL; + P11KitUri *uri; + CK_TOKEN_INFO_PTR token; + int ret; + + uri = p11_kit_uri_new (); + CuAssertPtrNotNull (tc, 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); + + CuAssertTrue (tc, strstr (string, "token=The%20Label") != NULL); + CuAssertTrue (tc, strstr (string, "serial=") == NULL); + + free (string); + p11_kit_uri_free (uri); +} + +static void +test_uri_build_with_token_empty_info (CuTest *tc) +{ + char *string = NULL; + P11KitUri *uri; + CK_TOKEN_INFO_PTR token; + int ret; + + uri = p11_kit_uri_new (); + CuAssertPtrNotNull (tc, 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); + + CuAssertTrue (tc, strstr (string, "token=") != NULL); + CuAssertTrue (tc, strstr (string, "serial=") != NULL); + + free (string); + p11_kit_uri_free (uri); +} + +static void +test_uri_build_with_attributes (CuTest *tc) +{ + char *string = NULL; + P11KitUri *uri; + P11KitUri *check; + CK_OBJECT_CLASS klass; + CK_ATTRIBUTE_PTR attr; + CK_ATTRIBUTE at; + int ret; + + uri = p11_kit_uri_new (); + CuAssertPtrNotNull (tc, uri); + + at.type = CKA_LABEL; + at.pValue = "The Label"; + at.ulValueLen = 9; + ret = p11_kit_uri_set_attribute (uri, &at); + + at.type = CKA_ID; + at.pValue = "HELLO"; + at.ulValueLen = 5; + ret = p11_kit_uri_set_attribute (uri, &at); + + klass = CKO_DATA; + at.type = CKA_CLASS; + at.pValue = &klass; + at.ulValueLen = sizeof (klass); + 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); + + check = p11_kit_uri_new (); + CuAssertPtrNotNull (tc, check); + + ret = p11_kit_uri_parse (string, P11_KIT_URI_FOR_ANY, check); + CuAssertIntEquals (tc, 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); + + 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); + + 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); + + 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); + + free (string); + p11_kit_uri_free (uri); +} + +static void +test_uri_parse_private_key (CuTest *tc) +{ + P11KitUri *uri; + CK_ATTRIBUTE_PTR attr; + int ret; + + uri = p11_kit_uri_new (); + CuAssertPtrNotNull (tc, uri); + + ret = p11_kit_uri_parse ("pkcs11:object-type=private", P11_KIT_URI_FOR_OBJECT, uri); + CuAssertIntEquals (tc, 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); + + p11_kit_uri_free (uri); +} + +static void +test_uri_parse_secret_key (CuTest *tc) +{ + P11KitUri *uri; + CK_ATTRIBUTE_PTR attr; + int ret; + + uri = p11_kit_uri_new (); + CuAssertPtrNotNull (tc, uri); + + ret = p11_kit_uri_parse ("pkcs11:object-type=secret-key", P11_KIT_URI_FOR_OBJECT, uri); + CuAssertIntEquals (tc, 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); + + p11_kit_uri_free (uri); +} + +static void +test_uri_parse_library_version (CuTest *tc) +{ + P11KitUri *uri; + CK_INFO_PTR info; + int ret; + + uri = p11_kit_uri_new (); + CuAssertPtrNotNull (tc, 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); + + info = p11_kit_uri_get_module_info (uri); + CuAssertIntEquals (tc, 2, info->libraryVersion.major); + CuAssertIntEquals (tc, 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); + + info = p11_kit_uri_get_module_info (uri); + CuAssertIntEquals (tc, 23, info->libraryVersion.major); + CuAssertIntEquals (tc, 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); + + 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); + + 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); + + 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); + + 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); + + p11_kit_uri_free (uri); +} + +static void +test_uri_parse_parse_unknown_object_type (CuTest *tc) +{ + P11KitUri *uri; + CK_ATTRIBUTE_PTR attr; + int ret; + + uri = p11_kit_uri_new (); + CuAssertPtrNotNull (tc, uri); + + ret = p11_kit_uri_parse ("pkcs11:object-type=unknown", P11_KIT_URI_FOR_OBJECT, uri); + CuAssertIntEquals (tc, P11_KIT_URI_OK, ret); + + attr = p11_kit_uri_get_attribute (uri, CKA_CLASS); + CuAssertPtrEquals (tc, NULL, attr); + + p11_kit_uri_free (uri); +} + +static void +test_uri_parse_unrecognized (CuTest *tc) +{ + P11KitUri *uri; + int ret; + + uri = p11_kit_uri_new (); + CuAssertPtrNotNull (tc, uri); + + ret = p11_kit_uri_parse ("pkcs11:x-blah=some-value", P11_KIT_URI_FOR_ANY, uri); + CuAssertIntEquals (tc, P11_KIT_URI_OK, ret); + + ret = p11_kit_uri_any_unrecognized (uri); + CuAssertIntEquals (tc, 1, ret); + + p11_kit_uri_free (uri); +} + +static void +test_uri_parse_too_long_is_unrecognized (CuTest *tc) +{ + P11KitUri *uri; + int ret; + + uri = p11_kit_uri_new (); + CuAssertPtrNotNull (tc, 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); + + ret = p11_kit_uri_any_unrecognized (uri); + CuAssertIntEquals (tc, 1, ret); + + p11_kit_uri_free (uri); +} + + + +static void +test_uri_build_object_type_cert (CuTest *tc) +{ + CK_ATTRIBUTE attr; + CK_OBJECT_CLASS klass; + P11KitUri *uri; + char *string; + int ret; + + uri = p11_kit_uri_new (); + CuAssertPtrNotNull (tc, uri); + + klass = CKO_CERTIFICATE; + attr.type = CKA_CLASS; + attr.pValue = &klass; + attr.ulValueLen = sizeof (klass); + 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); + + p11_kit_uri_free (uri); + free (string); +} + +static void +test_uri_build_object_type_private (CuTest *tc) +{ + CK_ATTRIBUTE attr; + CK_OBJECT_CLASS klass; + P11KitUri *uri; + char *string; + int ret; + + uri = p11_kit_uri_new (); + CuAssertPtrNotNull (tc, uri); + + klass = CKO_PRIVATE_KEY; + attr.type = CKA_CLASS; + attr.pValue = &klass; + attr.ulValueLen = sizeof (klass); + 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); + + p11_kit_uri_free (uri); + free (string); +} + +static void +test_uri_build_object_type_public (CuTest *tc) +{ + CK_ATTRIBUTE attr; + CK_OBJECT_CLASS klass; + P11KitUri *uri; + char *string; + int ret; + + uri = p11_kit_uri_new (); + CuAssertPtrNotNull (tc, uri); + + klass = CKO_PUBLIC_KEY; + attr.type = CKA_CLASS; + attr.pValue = &klass; + attr.ulValueLen = sizeof (klass); + 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); + + p11_kit_uri_free (uri); + free (string); +} + +static void +test_uri_build_object_type_secret (CuTest *tc) +{ + CK_ATTRIBUTE attr; + CK_OBJECT_CLASS klass; + P11KitUri *uri; + char *string; + int ret; + + uri = p11_kit_uri_new (); + CuAssertPtrNotNull (tc, uri); + + klass = CKO_SECRET_KEY; + attr.type = CKA_CLASS; + attr.pValue = &klass; + attr.ulValueLen = sizeof (klass); + 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); + + p11_kit_uri_free (uri); + free (string); +} + +static void +test_uri_build_with_library (CuTest *tc) +{ + CK_INFO_PTR info; + P11KitUri *uri; + char *string; + int ret; + + uri = p11_kit_uri_new (); + CuAssertPtrNotNull (tc, 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); + + p11_kit_uri_free (uri); + free (string); +} + +static void +test_uri_build_library_version (CuTest *tc) +{ + CK_INFO_PTR info; + P11KitUri *uri; + char *string; + int ret; + + uri = p11_kit_uri_new (); + CuAssertPtrNotNull (tc, 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); + + p11_kit_uri_free (uri); + free (string); +} + +static void +test_uri_get_set_unrecognized (CuTest *tc) +{ + P11KitUri *uri; + int ret; + + uri = p11_kit_uri_new (); + CuAssertPtrNotNull (tc, uri); + + ret = p11_kit_uri_any_unrecognized (uri); + CuAssertIntEquals (tc, 0, ret); + + p11_kit_uri_set_unrecognized (uri, 1); + + ret = p11_kit_uri_any_unrecognized (uri); + CuAssertIntEquals (tc, 1, ret); + + p11_kit_uri_set_unrecognized (uri, 0); + + ret = p11_kit_uri_any_unrecognized (uri); + CuAssertIntEquals (tc, 0, ret); + + p11_kit_uri_free (uri); +} + +static void +test_uri_match_token (CuTest *tc) +{ + CK_TOKEN_INFO token; + P11KitUri *uri; + int ret; + + uri = p11_kit_uri_new (); + CuAssertPtrNotNull (tc, uri); + + ret = p11_kit_uri_parse ("pkcs11:model=Giselle", P11_KIT_URI_FOR_ANY, uri); + CuAssertIntEquals (tc, 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); + + set_space_string (token.label, sizeof (token.label), "Another label"); + + ret = p11_kit_uri_match_token_info (uri, &token); + CuAssertIntEquals (tc, 1, ret); + + set_space_string (token.model, sizeof (token.model), "Zoolander"); + + ret = p11_kit_uri_match_token_info (uri, &token); + CuAssertIntEquals (tc, 0, ret); + + p11_kit_uri_set_unrecognized (uri, 1); + + ret = p11_kit_uri_match_token_info (uri, &token); + CuAssertIntEquals (tc, 0, ret); + + p11_kit_uri_free (uri); +} + +static void +test_uri_match_module (CuTest *tc) +{ + CK_INFO info; + P11KitUri *uri; + int ret; + + uri = p11_kit_uri_new (); + CuAssertPtrNotNull (tc, uri); + + ret = p11_kit_uri_parse ("pkcs11:library-description=Quiet", P11_KIT_URI_FOR_ANY, uri); + CuAssertIntEquals (tc, 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); + + set_space_string (info.manufacturerID, sizeof (info.manufacturerID), "Someone else"); + + ret = p11_kit_uri_match_module_info (uri, &info); + CuAssertIntEquals (tc, 1, ret); + + set_space_string (info.libraryDescription, sizeof (info.libraryDescription), "Leise"); + + ret = p11_kit_uri_match_module_info (uri, &info); + CuAssertIntEquals (tc, 0, ret); + + p11_kit_uri_set_unrecognized (uri, 1); + + ret = p11_kit_uri_match_module_info (uri, &info); + CuAssertIntEquals (tc, 0, ret); + + p11_kit_uri_free (uri); +} + +static void +test_uri_match_attributes (CuTest *tc) +{ + CK_ATTRIBUTE attrs[4]; + CK_OBJECT_CLASS klass; + P11KitUri *uri; + int ret; + + attrs[0].type = CKA_ID; + attrs[0].pValue = "Blah"; + attrs[0].ulValueLen = 4; + + attrs[1].type = CKA_LABEL; + attrs[1].pValue = "Junk"; + attrs[1].ulValueLen = 4; + + attrs[2].type = CKA_COLOR; + attrs[2].pValue = "blue"; + attrs[2].ulValueLen = 4; + + klass = CKO_DATA; + attrs[3].type = CKA_CLASS; + attrs[3].pValue = &klass; + attrs[3].ulValueLen = sizeof (klass); + + uri = p11_kit_uri_new (); + CuAssertPtrNotNull (tc, 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); + + ret = p11_kit_uri_match_attributes (uri, attrs, 4); + CuAssertIntEquals (tc, 0, ret); + + attrs[1].pValue = "Fancy"; + attrs[1].ulValueLen = 5; + + ret = p11_kit_uri_match_attributes (uri, attrs, 4); + CuAssertIntEquals (tc, 1, ret); + + p11_kit_uri_clear_attribute (uri, CKA_CLASS); + + ret = p11_kit_uri_match_attributes (uri, attrs, 4); + CuAssertIntEquals (tc, 1, ret); + + attrs[2].pValue = "pink"; + + ret = p11_kit_uri_match_attributes (uri, attrs, 4); + CuAssertIntEquals (tc, 1, ret); + + p11_kit_uri_set_unrecognized (uri, 1); + + ret = p11_kit_uri_match_attributes (uri, attrs, 4); + CuAssertIntEquals (tc, 0, ret); + + p11_kit_uri_free (uri); +} + +static void +test_uri_get_set_attribute (CuTest *tc) +{ + CK_ATTRIBUTE attr; + CK_ATTRIBUTE_PTR ptr; + P11KitUri *uri; + int ret; + + uri = p11_kit_uri_new (); + CuAssertPtrNotNull (tc, uri); + + ptr = p11_kit_uri_get_attribute (uri, CKA_LABEL); + CuAssertPtrEquals (tc, NULL, ptr); + + ret = p11_kit_uri_clear_attribute (uri, CKA_LABEL); + CuAssertIntEquals (tc, P11_KIT_URI_OK, ret); + + ret = p11_kit_uri_clear_attribute (uri, CKA_COLOR); + CuAssertIntEquals (tc, 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); + + attr.type = CKA_COLOR; + ret = p11_kit_uri_set_attribute (uri, &attr); + CuAssertIntEquals (tc, P11_KIT_URI_NOT_FOUND, ret); + + ptr = p11_kit_uri_get_attribute (uri, CKA_COLOR); + CuAssertPtrEquals (tc, NULL, ptr); + + ptr = p11_kit_uri_get_attribute (uri, CKA_LABEL); + CuAssertPtrNotNull (tc, ptr); + + CuAssertTrue (tc, ptr->type == CKA_LABEL); + CuAssertTrue (tc, ptr->ulValueLen == 4); + CuAssertTrue (tc, memcmp (ptr->pValue, "Test", 4) == 0); + + ret = p11_kit_uri_clear_attribute (uri, CKA_LABEL); + CuAssertIntEquals (tc, P11_KIT_URI_OK, ret); + + ptr = p11_kit_uri_get_attribute (uri, CKA_LABEL); + CuAssertPtrEquals (tc, NULL, ptr); + + p11_kit_uri_free (uri); +} + +static void +test_uri_get_set_attributes (CuTest *tc) +{ + CK_ATTRIBUTE_PTR attrs; + CK_OBJECT_CLASS klass; + CK_ATTRIBUTE attr; + CK_ULONG n_attrs; + P11KitUri *uri; + int ret; + + uri = p11_kit_uri_new (); + CuAssertPtrNotNull (tc, uri); + + attrs = p11_kit_uri_get_attributes (uri, &n_attrs); + CuAssertPtrNotNull (tc, attrs); + CuAssertIntEquals (tc, 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); + + 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); + + 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); + + 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); + + klass = CKO_DATA; + attr.type = CKA_CLASS; + attr.pValue = &klass; + attr.ulValueLen = sizeof (klass); + + ret = p11_kit_uri_set_attribute (uri, &attr); + CuAssertIntEquals (tc, 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); + + ret = p11_kit_uri_clear_attribute (uri, CKA_LABEL); + CuAssertIntEquals (tc, 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); + + 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); + + 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); + + p11_kit_uri_clear_attributes (uri); + + attrs = p11_kit_uri_get_attributes (uri, &n_attrs); + CuAssertPtrNotNull (tc, attrs); + CuAssertIntEquals (tc, 0, n_attrs); + + p11_kit_uri_free (uri); +} +static void +test_uri_pin_source (CuTest *tc) +{ + P11KitUri *uri; + const char *pin_source; + char *string; + int ret; + + uri = p11_kit_uri_new (); + CuAssertPtrNotNull (tc, 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); + + pin_source = p11_kit_uri_get_pinfile (uri); + CuAssertStrEquals (tc, "|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); + + 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); + 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); + + pin_source = p11_kit_uri_get_pin_source (uri); + CuAssertStrEquals (tc, "blah/blah", pin_source); + + p11_kit_uri_free (uri); +} + +static void +test_uri_free_null (CuTest *tc) +{ + p11_kit_uri_free (NULL); +} + +static void +test_uri_message (CuTest *tc) +{ + 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)); +} + +int +main (void) +{ + CuString *output = CuStringNew (); + CuSuite* suite = CuSuiteNew (); + int ret; + + p11_library_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_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; +} diff --git a/p11-kit/uri.c b/p11-kit/uri.c index 752d677..1306fed 100644 --- a/p11-kit/uri.c +++ b/p11-kit/uri.c @@ -34,12 +34,12 @@ #include "config.h" -#define DEBUG_FLAG DEBUG_URI +#define P11_DEBUG_FLAG P11_DEBUG_URI #include "debug.h" +#include "library.h" #include "pkcs11.h" #include "p11-kit.h" #include "uri.h" -#include "util.h" #include <assert.h> #include <ctype.h> @@ -1419,7 +1419,7 @@ p11_kit_uri_message (int code) case P11_KIT_URI_NOT_FOUND: return "The URI component was not found"; default: - _p11_debug ("unknown error code: %d", code); + p11_debug ("unknown error code: %d", code); return "Unknown error"; } } diff --git a/p11-kit/util.c b/p11-kit/util.c index ccc954c..9c5d99b 100644 --- a/p11-kit/util.c +++ b/p11-kit/util.c @@ -38,11 +38,11 @@ #include "config.h" #include "compat.h" -#define DEBUG_FLAG DEBUG_LIB +#define P11_DEBUG_FLAG P11_DEBUG_LIB #include "debug.h" +#include "library.h" #include "p11-kit.h" #include "private.h" -#include "util.h" #include <assert.h> #include <stdarg.h> @@ -50,18 +50,6 @@ #include <stdio.h> #include <string.h> -/* - * This is the mutex that protects the global data of this library - * and the pkcs11 proxy module. Note that we *never* call into our - * underlying pkcs11 modules while holding this mutex. Therefore it - * doesn't have to be recursive and we can keep things simple. - */ -mutex_t _p11_mutex; - -#ifdef OS_UNIX -pthread_once_t _p11_once; -#endif - /** * SECTION:p11-kit-future * @title: Future @@ -72,8 +60,6 @@ pthread_once_t _p11_once; * MACRO. See the p11-kit.h header for more details. */ -static int print_messages = 1; - /** * p11_kit_space_strlen: * @string: Pointer to string block @@ -146,45 +132,6 @@ p11_kit_space_strdup (const unsigned char *string, size_t max_length) return result; } -static void -store_message_buffer (const char* msg, size_t length) -{ - p11_local *local; - - if (length > P11_MAX_MESSAGE - 1) - length = P11_MAX_MESSAGE - 1; - - local = _p11_library_get_thread_local (); - if (local != NULL) { - memcpy (local->message, msg, length); - local->message[length] = 0; - } -} - -void -_p11_message (const char* msg, ...) -{ - char buffer[P11_MAX_MESSAGE]; - va_list va; - size_t length; - - va_start (va, msg); - length = vsnprintf (buffer, P11_MAX_MESSAGE - 1, msg, va); - va_end (va); - - /* Was it truncated? */ - if (length > P11_MAX_MESSAGE - 1) - length = P11_MAX_MESSAGE - 1; - buffer[length] = 0; - - /* If printing is not disabled, just print out */ - if (print_messages) - fprintf (stderr, "p11-kit: %s\n", buffer); - - _p11_debug_message (DEBUG_LIB, "message: %s", buffer); - store_message_buffer (buffer, length); -} - /** * p11_kit_be_quiet: * @@ -194,9 +141,7 @@ _p11_message (const char* msg, ...) void p11_kit_be_quiet (void) { - _p11_lock (); - print_messages = 0; - _p11_unlock (); + p11_message_quiet (); } /** @@ -215,18 +160,7 @@ p11_kit_be_quiet (void) const char* p11_kit_message (void) { - p11_local *local; - local = _p11_library_get_thread_local (); - return local && local->message[0] ? local->message : NULL; -} - -void -_p11_kit_clear_message (void) -{ - p11_local *local; - local = _p11_library_get_thread_local (); - if (local != NULL) - local->message[0] = 0; + return p11_message_last (); } void @@ -236,231 +170,12 @@ _p11_kit_default_message (CK_RV rv) if (rv != CKR_OK) { msg = p11_kit_strerror (rv); - store_message_buffer (msg, strlen (msg)); + p11_message_store (msg, strlen (msg)); } } -static void -uninit_common (void) -{ - _p11_debug ("uninitializing library"); - - _p11_set_progname_unlocked (NULL); -} - -#ifdef OS_UNIX - -static pthread_key_t thread_local = 0; - -p11_local * -_p11_library_get_thread_local (void) -{ - p11_local *local; - - _p11_library_init_once (); - - local = pthread_getspecific (thread_local); - if (local == NULL) { - local = calloc (1, sizeof (p11_local)); - pthread_setspecific (thread_local, local); - } - - return local; -} - -#ifdef __GNUC__ -__attribute__((constructor)) -#endif -void -_p11_library_init (void) -{ - _p11_debug_init (); - _p11_debug ("initializing library"); - _p11_mutex_init (&_p11_mutex); - pthread_key_create (&thread_local, free); -} - -#ifdef __GNUC__ -__attribute__((destructor)) -#endif -void -_p11_library_uninit (void) -{ - uninit_common (); - - /* Some cleanup to pacify valgrind */ - free (pthread_getspecific (thread_local)); - pthread_setspecific (thread_local, NULL); - - pthread_key_delete (thread_local); - _p11_mutex_uninit (&_p11_mutex); -} - -void -_p11_mutex_init (mutex_t *mutex) -{ - pthread_mutexattr_t attr; - int ret; - - pthread_mutexattr_init (&attr); - pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_RECURSIVE); - ret = pthread_mutex_init (mutex, &attr); - assert (ret == 0); - pthread_mutexattr_destroy (&attr); -} - -#endif /* OS_UNIX */ - -#ifdef OS_WIN32 - -static DWORD thread_local = TLS_OUT_OF_INDEXES; - -BOOL WINAPI DllMain (HINSTANCE, DWORD, LPVOID); - -p11_local * -_p11_library_get_thread_local (void) -{ - LPVOID data; - - if (thread_local == TLS_OUT_OF_INDEXES) - return NULL; - - data = TlsGetValue (thread_local); - if (data == NULL) { - data = LocalAlloc (LPTR, sizeof (p11_local)); - TlsSetValue (thread_local, data); - } - - return (p11_local *)data; -} - -void -_p11_library_init (void) -{ - _p11_debug_init (); - _p11_debug ("initializing library"); - _p11_mutex_init (&_p11_mutex); - thread_local = TlsAlloc (); -} - -static void -free_tls_value (LPVOID data) -{ - p11_local *local = data; - if (local == NULL) - return; - if (local->last_error) - LocalFree (local->last_error); - LocalFree (data); -} - -void -_p11_library_uninit (void) -{ - LPVOID data; - - uninit_common (); - - if (thread_local != TLS_OUT_OF_INDEXES) { - data = TlsGetValue (thread_local); - free_tls_value (data); - TlsFree (thread_local); - } - _p11_mutex_uninit (&_p11_mutex); -} - -const char * -_p11_module_error (void) -{ - DWORD code = GetLastError(); - p11_local *local; - LPVOID msg_buf; - - local = _p11_library_get_thread_local (); - - FormatMessageA (FORMAT_MESSAGE_ALLOCATE_BUFFER | - FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, code, - MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT), - (LPSTR)&msg_buf, 0, NULL); - - if (local->last_error) - LocalFree (local->last_error); - local->last_error = msg_buf; - - return msg_buf; -} - -int -_p11_thread_create (thread_t *thread, - thread_routine routine, - void *arg) -{ - assert (thread); - - *thread = CreateThread (NULL, 0, - (LPTHREAD_START_ROUTINE)routine, - arg, 0, NULL); - - if (*thread == NULL) - return GetLastError (); - - return 0; -} - -int -_p11_thread_join (thread_t thread) -{ - DWORD res; - - res = WaitForSingleObject (thread, INFINITE); - if (res == WAIT_FAILED) - return GetLastError (); - - CloseHandle (thread); - return 0; -} - -BOOL WINAPI -DllMain (HINSTANCE instance, - DWORD reason, - LPVOID reserved) -{ - LPVOID data; - - switch (reason) { - case DLL_PROCESS_ATTACH: - _p11_library_init (); - if (thread_local == TLS_OUT_OF_INDEXES) { - _p11_debug ("couldn't setup tls"); - return FALSE; - } - break; - - case DLL_THREAD_DETACH: - if (thread_local != TLS_OUT_OF_INDEXES) { - _p11_debug ("thread stopped, freeing tls"); - data = TlsGetValue (thread_local); - free_tls_value (data); - } - break; - - case DLL_PROCESS_DETACH: - _p11_library_uninit (); - break; - - default: - break; - } - - return TRUE; -} - -#endif /* OS_WIN32 */ - /* This is the progname that we think of this process as. */ -char *_p11_my_progname = NULL; +char p11_my_progname[256] = { 0, }; /** * p11_kit_set_progname: @@ -475,25 +190,30 @@ char *_p11_my_progname = NULL; void p11_kit_set_progname (const char *progname) { - _p11_library_init_once (); + p11_library_init_once (); - _p11_lock (); + p11_lock (); _p11_set_progname_unlocked (progname); - _p11_unlock (); + p11_unlock (); } void _p11_set_progname_unlocked (const char *progname) { - /* We can be called with NULL, to cleanup memory usage */ - free (_p11_my_progname); - _p11_my_progname = progname ? strdup (progname) : NULL; + /* We can be called with NULL */ + if (progname == NULL) + progname = ""; + + strncpy (p11_my_progname, progname, sizeof (p11_my_progname)); + p11_my_progname[sizeof (p11_my_progname) - 1] = 0; } const char * _p11_get_progname_unlocked (void) { - if (_p11_my_progname == NULL) + if (p11_my_progname[0] == '\0') _p11_set_progname_unlocked (getprogname ()); - return _p11_my_progname; + if (p11_my_progname[0] == '\0') + return NULL; + return p11_my_progname; } diff --git a/p11-kit/util.h b/p11-kit/util.h deleted file mode 100644 index b8d4a15..0000000 --- a/p11-kit/util.h +++ /dev/null @@ -1,158 +0,0 @@ -/* - * Copyright (c) 2011 Collabora Ltd - * - * 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> - */ - -#ifndef __UTIL_H__ -#define __UTIL_H__ - -#include "config.h" - -#include <sys/types.h> - -/* ----------------------------------------------------------------------------- - * WIN32 - */ - -#ifdef OS_WIN32 - -#ifndef _WIN32_WINNT -#define _WIN32_WINNT 0x500 -#endif - -#ifndef _WIN32_IE -#define _WIN32_IE 0x500 -#endif - -#define WIN32_LEAN_AND_MEAN 1 -#include <windows.h> - -/* Oh ... my ... god */ -#undef CreateMutex - -typedef CRITICAL_SECTION mutex_t; - -typedef HANDLE thread_t; - -typedef DWORD thread_id_t; - -#define _p11_mutex_init(m) \ - (InitializeCriticalSection (m)) -#define _p11_mutex_lock(m) \ - (EnterCriticalSection (m)) -#define _p11_mutex_unlock(m) \ - (LeaveCriticalSection (m)) -#define _p11_mutex_uninit(m) \ - (DeleteCriticalSection (m)) - -typedef void * (*thread_routine) (void *arg); - -int _p11_thread_create (thread_t *thread, thread_routine, void *arg); - -int _p11_thread_join (thread_t thread); - -/* Returns a thread_id_t */ -#define _p11_thread_id_self() \ - (GetCurrentThreadId ()) - -typedef HMODULE dl_module_t; - -#define _p11_module_open(f) \ - (LoadLibrary (f)) -#define _p11_module_close(d) \ - (FreeLibrary (d)) -#define _p11_module_symbol(d, s) \ - ((void *)GetProcAddress ((d), (s))) - -const char * _p11_module_error (void); - -#define _p11_sleep_ms(ms) \ - (Sleep (ms)) - -#endif /* OS_WIN32 */ - -/* ---------------------------------------------------------------------------- - * UNIX - */ - -#ifdef OS_UNIX - -#include <pthread.h> -#include <dlfcn.h> -#include <time.h> - -typedef pthread_mutex_t mutex_t; - -void _p11_mutex_init (mutex_t *mutex); - -#define _p11_mutex_lock(m) \ - (pthread_mutex_lock (m)) -#define _p11_mutex_unlock(m) \ - (pthread_mutex_unlock (m)) -#define _p11_mutex_uninit(m) \ - (pthread_mutex_destroy(m)) - -typedef pthread_t thread_t; - -typedef pthread_t thread_id_t; - -typedef void * (*thread_routine) (void *arg); - -#define _p11_thread_create(t, r, a) \ - (pthread_create ((t), NULL, (r), (a))) -#define _p11_thread_join(t) \ - (pthread_join ((t), NULL)) -#define _p11_thread_id_self(m) \ - (pthread_self ()) - -typedef void * dl_module_t; - -#define _p11_module_open(f) \ - (dlopen ((f), RTLD_LOCAL | RTLD_NOW)) -#define _p11_module_close(d) \ - (dlclose(d)) -#define _p11_module_error() \ - (dlerror ()) -#define _p11_module_symbol(d, s) \ - (dlsym ((d), (s))) - -#define _p11_sleep_ms(ms) \ - do { int _ms = (ms); \ - struct timespec _ts = { _ms / 1000, (_ms % 1000) * 1000 * 1000 }; \ - nanosleep (&_ts, NULL); \ - } while(0) - -#endif /* OS_UNIX */ - -#endif /* __UTIL_H__ */ |