]> git.ipfire.org Git - thirdparty/openvpn.git/commitdiff
Use pkcs11-helper as external library, can be downloaded
authorjames <james@e7ae566f-a301-0410-adde-c780ea21d3b5>
Mon, 22 Oct 2007 20:06:14 +0000 (20:06 +0000)
committerjames <james@e7ae566f-a301-0410-adde-c780ea21d3b5>
Mon, 22 Oct 2007 20:06:14 +0000 (20:06 +0000)
from https://www.opensc-project.org/pkcs11-helper (Alon Bar-Lev).

git-svn-id: http://svn.openvpn.net/projects/openvpn/branches/BETA21/openvpn@2418 e7ae566f-a301-0410-adde-c780ea21d3b5

22 files changed:
COPYING
Makefile.am
configure.ac
cryptoki-win32.h [deleted file]
cryptoki.h [deleted file]
init.c
install-win32/openvpn.nsi
makefile.w32
makefile.w32-vc
openvpn.8
openvpn.spec.in
options.c
options.h
pkcs11-headers/pkcs11.h [deleted file]
pkcs11-headers/pkcs11f.h [deleted file]
pkcs11-headers/pkcs11t.h [deleted file]
pkcs11-helper-config.h [deleted file]
pkcs11-helper.c [deleted file]
pkcs11-helper.h [deleted file]
pkcs11.c
pkcs11.h
ssl.c

diff --git a/COPYING b/COPYING
index e52ce713b237a2c7d9ceaa2134be1e3e84720d9d..b9a90a70ca3d4b21c45a68ca2b3878fae579ce83 100644 (file)
--- a/COPYING
+++ b/COPYING
@@ -218,8 +218,3 @@ GNU Public License (GPL)
   In the Windows binary distribution of OpenVPN, the
   GPL is reproduced below.
 
-RSA Security Inc. License
-------------------------
-
-  This software is using RSA Security Inc. PKCS #11 Cryptographic Token Interface (Cryptoki).
-
index 36e2cf9a9e6b9e4c70baf87db7afd0b1afb016b7..e1d65194131c5fed38d8a5697e79d0f66a2d1ebe 100644 (file)
@@ -68,7 +68,7 @@ openvpn_SOURCES = \
        multi.c multi.h \
         ntlm.c ntlm.h \
        occ.c occ.h occ-inline.h \
-       pkcs11.c pkcs11.h pkcs11-helper.c pkcs11-helper.h pkcs11-helper-config.h cryptoki.h \
+       pkcs11.c pkcs11.h \
        openvpn.c openvpn.h \
        openvpn-plugin.h \
        options.c options.h \
@@ -127,9 +127,7 @@ EXTRA_DIST = \
        contrib \
        debug \
        plugin \
-        management \
-        pkcs11-headers \
-       cryptoki-win32.h
+        management
 
 dist-hook:
        cd $(distdir) && for i in $(EXTRA_DIST) ; do find $$i -name .svn -type d -prune -exec rm -rf '{}' ';' ; rm -f `find $$i -type f | grep -E '(^|\/)\.?\#|\~$$|\.s?o$$'` ; done
index af57577229561386f102e6fcbd048e8653d998e1..7155ae5cbe288f1719b2cb5225461410201b0fbe 100644 (file)
@@ -505,7 +505,7 @@ fi
 dnl
 dnl Check for dlopen -- first try libc then libdl.
 dnl
-if test "$PLUGINS" = "yes" || test "$PKCS11" = "yes"; then
+if test "$PLUGINS" = "yes"; then
    AC_CHECKING([for libdl Library and Header files])
    AC_CHECK_HEADER(dlfcn.h,
         [AC_CHECK_FUNC(dlopen,
@@ -625,6 +625,21 @@ dnl
    fi
 fi
 
+dnl enable pkcs11 capability
+if test "$PKCS11" = "yes"; then
+   AC_CHECKING([for pkcs11-helper Library and Header files])
+   AC_CHECK_HEADER(pkcs11-helper-1.0/pkcs11h-core.h,
+       [AC_CHECK_LIB(pkcs11-helper, pkcs11h_initialize,
+           [
+                  AC_DEFINE(USE_PKCS11, 1, [Enable PKCS11 capability])
+                  OPENVPN_ADD_LIBS(-lpkcs11-helper)
+           ],
+           [AC_MSG_RESULT([pkcs11-helper library not found.])]
+       )],
+       [AC_MSG_RESULT([pkcs11-helper headers not found.])]
+   )
+fi
+
 dnl enable multi-client mode
 if test "$MULTI" = "yes"; then
    AC_DEFINE(ENABLE_CLIENT_SERVER, 1, [Enable client/server capability])
@@ -640,11 +655,6 @@ if test "$MANAGEMENT" = "yes"; then
    AC_DEFINE(ENABLE_MANAGEMENT, 1, [Enable management server capability])
 fi
 
-dnl enable pkcs11 capability
-if test "$PKCS11" = "yes"; then
-   AC_DEFINE(USE_PKCS11, 1, [Enable PKCS11 capability])
-fi
-
 dnl enable socks 
 if test "$SOCKS" = "yes"; then
    AC_DEFINE(ENABLE_SOCKS, 1, [Enable Socks proxy support])
diff --git a/cryptoki-win32.h b/cryptoki-win32.h
deleted file mode 100644 (file)
index 8e62bbd..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-/* cryptoki.h include file for PKCS #11. */
-/* $Revision: 1.4 $ */
-
-/* License to copy and use this software is granted provided that it is
- * identified as "RSA Security Inc. PKCS #11 Cryptographic Token Interface
- * (Cryptoki)" in all material mentioning or referencing this software.
-
- * License is also granted to make and use derivative works provided that
- * such works are identified as "derived from the RSA Security Inc. PKCS #11
- * Cryptographic Token Interface (Cryptoki)" in all material mentioning or 
- * referencing the derived work.
-
- * RSA Security Inc. makes no representations concerning either the 
- * merchantability of this software or the suitability of this software for
- * any particular purpose. It is provided "as is" without express or implied
- * warranty of any kind.
- */
-
-/* This is a sample file containing the top level include directives
- * for building Win32 Cryptoki libraries and applications.
- */
-
-#ifndef ___CRYPTOKI_H_INC___
-#define ___CRYPTOKI_H_INC___
-
-#pragma pack(push, cryptoki, 1)
-
-/* Specifies that the function is a DLL entry point. */
-#define CK_IMPORT_SPEC __declspec(dllimport)
-
-/* Define CRYPTOKI_EXPORTS during the build of cryptoki libraries. Do
- * not define it in applications.
- */
-#ifdef CRYPTOKI_EXPORTS
-/* Specified that the function is an exported DLL entry point. */
-#define CK_EXPORT_SPEC __declspec(dllexport) 
-#else
-#define CK_EXPORT_SPEC CK_IMPORT_SPEC 
-#endif
-
-/* Ensures the calling convention for Win32 builds */
-#define CK_CALL_SPEC __cdecl
-
-#define CK_PTR *
-
-#define CK_DEFINE_FUNCTION(returnType, name) \
-  returnType CK_EXPORT_SPEC CK_CALL_SPEC name
-
-#define CK_DECLARE_FUNCTION(returnType, name) \
-  returnType CK_EXPORT_SPEC CK_CALL_SPEC name
-
-#define CK_DECLARE_FUNCTION_POINTER(returnType, name) \
-  returnType CK_IMPORT_SPEC (CK_CALL_SPEC CK_PTR name)
-
-#define CK_CALLBACK_FUNCTION(returnType, name) \
-  returnType (CK_CALL_SPEC CK_PTR name)
-
-#ifndef NULL_PTR
-#define NULL_PTR 0
-#endif
-
-#include "pkcs11-headers/pkcs11.h"
-
-#pragma pack(pop, cryptoki)
-
-#endif /* ___CRYPTOKI_H_INC___ */
diff --git a/cryptoki.h b/cryptoki.h
deleted file mode 100644 (file)
index 2975a67..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-/* cryptoki.h include file for PKCS #11. */
-/* $Revision: 1.4 $ */
-
-/* License to copy and use this software is granted provided that it is
- * identified as "RSA Security Inc. PKCS #11 Cryptographic Token Interface
- * (Cryptoki)" in all material mentioning or referencing this software.
-
- * License is also granted to make and use derivative works provided that
- * such works are identified as "derived from the RSA Security Inc. PKCS #11
- * Cryptographic Token Interface (Cryptoki)" in all material mentioning or 
- * referencing the derived work.
-
- * RSA Security Inc. makes no representations concerning either the 
- * merchantability of this software or the suitability of this software for
- * any particular purpose. It is provided "as is" without express or implied
- * warranty of any kind.
- */
-
-#ifndef ___CRYPTOKI_H_INC___
-#define ___CRYPTOKI_H_INC___
-
-#define CK_PTR *
-
-#define CK_DEFINE_FUNCTION(returnType, name) returnType name
-#define CK_DECLARE_FUNCTION(returnType, name) returnType name
-#define CK_DECLARE_FUNCTION_POINTER(returnType, name) returnType (* name)
-#define CK_CALLBACK_FUNCTION(returnType, name) returnType (* name)
-
-#ifndef NULL_PTR
-#define NULL_PTR 0
-#endif
-
-#include "pkcs11-headers/pkcs11.h"
-
-#endif /* ___CRYPTOKI_H_INC___ */
diff --git a/init.c b/init.c
index 65796af7f57631c4955efd46f9b9e5f4eb95883b..211effdfebcc77bbfc777e386e19e53b1b037ad2 100644 (file)
--- a/init.c
+++ b/init.c
@@ -144,7 +144,7 @@ context_init_1 (struct context *c)
     pkcs11_initialize (true, c->options.pkcs11_pin_cache_period);
     for (i=0;i<MAX_PARMS && c->options.pkcs11_providers[i] != NULL;i++)
      pkcs11_addProvider (c->options.pkcs11_providers[i], c->options.pkcs11_protected_authentication[i],
-       c->options.pkcs11_sign_mode[i], c->options.pkcs11_cert_private[i]);
+       c->options.pkcs11_private_mode[i], c->options.pkcs11_cert_private[i]);
   }
 #endif
 
index 5cbef9b2e4fd2335bce02f40c6bcfa0b669ff5d6..64d6f3ac6db51353d96bc4b4c0d30e3f13a734ee 100755 (executable)
 
   LangString DESC_SecOpenSSLDLLs ${LANG_ENGLISH} "Install OpenSSL DLLs locally (may be omitted if DLLs are already installed globally)."
 
+  LangString DESC_SecPKCS11LDLLs ${LANG_ENGLISH} "Install PKCS#11 helper DLLs locally (may be omitted if DLLs are already installed globally)."
+
   LangString DESC_SecTAP ${LANG_ENGLISH} "Install/Upgrade the TAP-Win32 virtual device driver.  Will not interfere with CIPE."
 
   LangString DESC_SecService ${LANG_ENGLISH} "Install the ${PRODUCT_NAME} service wrapper (${PRODUCT_UNIX_NAME}serv.exe)"
@@ -318,6 +320,14 @@ Section "OpenSSL Utilities" SecOpenSSLUtilities
 
 SectionEnd
 
+Section "PKCS#11 DLLs" SecPKCS11DLLs
+
+  SetOverwrite on
+  SetOutPath "$INSTDIR\bin"
+  File "${BIN}\libpkcs11-helper-1.dll"
+
+SectionEnd
+
 Section "TAP-Win32 Virtual Ethernet Adapter" SecTAP
 
   SetOverwrite on
@@ -566,6 +576,7 @@ SectionEnd
   !insertmacro MUI_DESCRIPTION_TEXT ${SecTAP} $(DESC_SecTAP)
   !insertmacro MUI_DESCRIPTION_TEXT ${SecOpenSSLUtilities} $(DESC_SecOpenSSLUtilities)
   !insertmacro MUI_DESCRIPTION_TEXT ${SecOpenSSLDLLs} $(DESC_SecOpenSSLDLLs)
+  !insertmacro MUI_DESCRIPTION_TEXT ${SecPKCS11DLLs} $(DESC_SecPKCS11DLLs)
   !insertmacro MUI_DESCRIPTION_TEXT ${SecAddPath} $(DESC_SecAddPath)
   !insertmacro MUI_DESCRIPTION_TEXT ${SecAddShortcuts} $(DESC_SecAddShortcuts)
   !insertmacro MUI_DESCRIPTION_TEXT ${SecService} $(DESC_SecService)
@@ -615,6 +626,7 @@ Section "Uninstall"
   Delete "$INSTDIR\bin\${PRODUCT_UNIX_NAME}serv.exe"
   Delete "$INSTDIR\bin\libeay32.dll"
   Delete "$INSTDIR\bin\libssl32.dll"
+  Delete "$INSTDIR\bin\libpkcs11-helper-1.dll"
   Delete "$INSTDIR\bin\tapinstall.exe"
   Delete "$INSTDIR\bin\addtap.bat"
   Delete "$INSTDIR\bin\deltapall.bat"
index 3179420dbec8912babd82e31d434df0dadb44eeb..1623ec8ee19e74e2ba89d821565783c063726439 100755 (executable)
 #OPENSSL_DIR = 
 #LZO_DIR = 
 #DMALLOC_DIR = 
+#PKCS11_HELPER_DIR =
+
 #########################################################
 
 CC = gcc -g -O2 -Wall -Wno-unused-function -Wno-unused-variable -mno-cygwin
 
 CC_DMALLOC = gcc -g -O2 -Wall -Wno-unused-function -Wno-unused-variable -mno-cygwin -fno-inline -DDMALLOC
 
-INCLUDE_DIRS = -I${OPENSSL_DIR}/include -I${LZO_DIR}/include
+INCLUDE_DIRS = -I${OPENSSL_DIR}/include -I${LZO_DIR}/include -I${PKCS11_HELPER_DIR}/include
 
 INCLUDE_DIRS_DMALLOC = ${INCLUDE_DIRS} -I${DMALLOC_DIR}
 
-LIBS = -llzo2 -lcrypt32 -lWinInet -lws2_32 -lgdi32 -liphlpapi -lwinmm
+LIBS = -llzo2 -lcrypt32 -lWinInet -lws2_32 -lgdi32 -liphlpapi -lwinmm -lpkcs11-helper
 
 LIBS_DMALLOC = ${LIBS} -ldmalloc
 
-LIB_DIRS = -L${OPENSSL_DIR}/out -L${LZO_DIR}
+LIB_DIRS = -L${OPENSSL_DIR}/out -L${LZO_DIR} -L${PKCS11_HELPER_DIR}/lib
 
 LIB_DIRS_DMALLOC = ${LIB_DIRS} -L${DMALLOC_DIR}
 
@@ -98,7 +100,7 @@ HEADERS = \
        ntlm.h \
        occ-inline.h \
        occ.h \
-       pkcs11.h pkcs11-helper.h cryptoki.h \
+       pkcs11.h \
         openvpn.h \
        openvpn-plugin.h \
        options.h \
@@ -154,7 +156,7 @@ OBJS =  base64.o \
        multi.o \
        ntlm.o \
        occ.o \
-       pkcs11.o pkcs11-helper.o \
+       pkcs11.o \
         openvpn.o \
        options.o \
        otime.o \
index 92f7013a08dee8c711490ada706a64a6f99b8a58..addf9da27e61af06c5bce7451ff8da0317162f90 100644 (file)
@@ -22,11 +22,13 @@ OPENSSL_DYNAMIC = libeay32.lib ssleay32.lib
 
 LZO = \src\lzo-1.08.vc
 
-INCLUDE_DIRS = -I$(OPENSSL)/include -I$(LZO)/include
+PKCS11_HELPER = \src\pkcs11-helper-1.02
 
-LIBS = lzo.lib ws2_32.lib crypt32.lib iphlpapi.lib winmm.lib user32.lib gdi32.lib advapi32.lib wininet.lib
+INCLUDE_DIRS = -I$(OPENSSL)/include -I$(LZO)/include -I$(PKCS11_HELPER)/include
 
-LIB_DIRS = -LIBPATH:$(OPENSSL)\out -LIBPATH:$(LZO)
+LIBS = lzo.lib libpkcs11-helper-1.lib ws2_32.lib crypt32.lib iphlpapi.lib winmm.lib user32.lib gdi32.lib advapi32.lib wininet.lib
+
+LIB_DIRS = -LIBPATH:$(OPENSSL)\out -LIBPATH:$(LZO) -LIBPATH:$(PKCS11_HELPER)\lib
 
 EXE = openvpn.exe
 
@@ -82,7 +84,7 @@ HEADERS = \
        ntlm.h \
        occ-inline.h \
        occ.h \
-       pkcs11.h pkcs11-helper.h cryptoki.h \
+       pkcs11.h \
         openvpn.h \
        openvpn-plugin.h \
        options.h \
@@ -138,7 +140,7 @@ OBJS =  base64.obj \
        multi.obj \
        ntlm.obj \
        occ.obj \
-       pkcs11.obj pkcs11-helper.obj \
+       pkcs11.obj \
         openvpn.obj \
        options.obj \
        otime.obj \
index 287e2e18ee76a5b2d00863ba59c8ad247815dc76..6446c5b317db4945e99af9f990ec3febd72df119 100644 (file)
--- a/openvpn.8
+++ b/openvpn.8
@@ -209,13 +209,10 @@ openvpn \- secure IP tunnel daemon.
 [\ \fB\-\-ping\fR\ \fIn\fR\ ]
 [\ \fB\-\-pkcs11\-cert\-private\fR\ \fI[0|1]...\fR\ ]
 [\ \fB\-\-pkcs11\-id\fR\ \fIname\fR\ ]
-[\ \fB\-\-pkcs11\-id\-type\fR\ \fItype\fR\ ]
 [\ \fB\-\-pkcs11\-pin\-cache\fR\ \fIseconds\fR\ ]
+[\ \fB\-\-pkcs11\-private\-mode\fR\ \fImode...\fR\ ]
 [\ \fB\-\-pkcs11\-protected\-authentication\fR\ \fI[0|1]...\fR\ ]
 [\ \fB\-\-pkcs11\-providers\fR\ \fIprovider...\fR\ ]
-[\ \fB\-\-pkcs11\-sign\-mode\fR\ \fImode...\fR\ ]
-[\ \fB\-\-pkcs11\-slot\fR\ \fIname\fR\ ]
-[\ \fB\-\-pkcs11\-slot\-type\fR\ \fItype\fR\ ]
 [\ \fB\-\-pkcs12\fR\ \fIfile\fR\ ]
 [\ \fB\-\-plugin\fR\ \fImodule\-pathname\ init\-string\fR\ ]
 [\ \fB\-\-port\fR\ \fIport\fR\ ]
@@ -260,8 +257,7 @@ openvpn \- secure IP tunnel daemon.
 [\ \fB\-\-show\-ciphers\fR\ ]
 [\ \fB\-\-show\-digests\fR\ ]
 [\ \fB\-\-show\-engines\fR\ ]
-[\ \fB\-\-show\-pkcs11\-objects\fR\ \fIprovider\ slot\fR\ ]
-[\ \fB\-\-show\-pkcs11\-slots\fR\ \fIprovider\fR\ ]
+[\ \fB\-\-show\-pkcs11\-ids\fR\ \fIprovider\ [cert_private]\fR\ ]
 [\ \fB\-\-show\-net\-up\fR\ ]
 [\ \fB\-\-show\-net\fR\ ]
 [\ \fB\-\-show\-tls\fR\ ]
@@ -3671,21 +3667,10 @@ Every provider has its own setting.
 .\"*********************************************************
 .TP
 .B --pkcs11-id name
-Specify a name of the object to search for.
-.\"*********************************************************
-.TP
-.B --pkcs11-id-type type
-Specify how to locate the correct objects. Type can be one of the following:
-
-.B 'id'
--- Locate by the id attribte, name should be hex encoded string.
-.br
-.B 'label'
--- Locate by the label attribute, name should be string.
-.br
-.B 'subject'
--- Locate by certificate subject attribute, name should be string.
-.br
+Specify the serialized certificate id to be used. The id can be gotten
+by the standalone
+.B --show-pkcs11-ids
+option.
 .\"*********************************************************
 .TP
 .B --pkcs11-pin-cache seconds
@@ -3707,43 +3692,25 @@ and
 .B --pkcs12.
 .\"*********************************************************
 .TP
-.B --pkcs11-sign-mode mode...
-Specify which method to use in order to sign data. A different mode can be specified
-for each provider. Mode can be one of the following:
+.B --pkcs11-private-mode mode...
+Specify which method to use in order to perform private key operations.
+A different mode can be specified for each provider.
+Mode is encoded as hex number, and can be a mask one of the following:
 
-.B 'auto'
+.B 0
 (default) -- Try to determind automatically.
 .br
-.B 'sign'
--- Use Sign.
-.br
-.B 'recover'
--- Use SignRecover.
-.br
-.B 'any'
--- Use Sign and if not supported use SignRecover.
+.B 1
+-- Use sign.
 .br
-.\"*********************************************************
-.TP
-.B --pkcs11-slot name
-Specify a name of the slot to search for.
-.\"*********************************************************
-.TP
-.B --pkcs11-slot-type type
-Specify how to locate the correct slot. Type can be one of the following:
-
-.B 'id'
--- Locate the slot by a numeric id. The format is [provider:]id, for example, slot 2 of provider a.so 
-should be encoded as a.so:2. If you have only one provider you can omit the provider name.
-The provider name is set by the name specified in the
-.B --pkcs11-providers
-option.
+.B 2
+-- Use sign recover.
 .br
-.B 'name'
--- Locate the slot by its name.
+.B 4
+-- Use decrypt.
 .br
-.B 'label'
--- Locate the slot by the label of the token that reside within.
+.B 8
+-- Use unwrap.
 .br
 .\"*********************************************************
 .TP
@@ -4649,14 +4616,13 @@ adapter list.
 .SS PKCS#11 Standalone Options:
 .\"*********************************************************
 .TP
-.B --show-pkcs11-slots provider
+.B --show-pkcs11-ids provider [cert_private]
 (Standalone)
-Show PKCS#11 provider slot list.
-.\"*********************************************************
-.TP
-.B --show-pkcs11-objects provider slot
-(Standalone)
-Show PKCS#11 token object list.
+Show PKCS#11 token object list. Specify cert_private as 1
+if certificates are stored as private objects.
+
+.B --verb
+option can be used BEFORE this option to produce debugging information.
 .\"*********************************************************
 .SH SCRIPTING AND ENVIRONMENTAL VARIABLES
 OpenVPN exports a series
index 041ffdd113acdbd145ffaea0d60d27c91307dd8f..9ce8b343e57b709fe778841272556ae93dcfc67c 100644 (file)
@@ -52,6 +52,9 @@ Requires:      openssl       >= 0.9.6
 %{!?without_pam:BuildRequires: pam-devel}
 %{!?without_pam:Requires:      pam}
 
+%{!?with_pkcs11:BuildRequires: pkcs11-helper-devel}
+%{!?with_pkcs11:Requires:      pkcs11-helper}
+
 #
 # Description
 #
@@ -223,6 +226,8 @@ fi
 %doc contrib/ easy-rsa/ management/ sample-*/ plugin/README.*
 
 %changelog
+* Thu Dec 14 2006 Alon Bar-Lev
+- Added with_pkcs11
 
 * Mon Aug 2 2005 James Yonan
 - Fixed build problem with --define 'without_pam 1'
index 5cc7f234cec53fda855a8b3a4df6efa7a66e007e..8c5a268efb7dfe36616b0d89a4e112941e0421b9 100644 (file)
--- a/options.c
+++ b/options.c
@@ -75,6 +75,9 @@ const char title_string[] =
 #endif
 #ifdef USE_PTHREAD
   " [PTHREAD]"
+#endif
+#ifdef ENABLE_PKCS11
+  " [PKCS11]"
 #endif
   " built on " __DATE__
 ;
@@ -501,25 +504,17 @@ static const char usage_message[] =
   "--pkcs11-providers provider ... : PKCS#11 provider to load.\n"
   "--pkcs11-protected-authentication [0|1] ... : Use PKCS#11 protected authentication\n"
   "                              path. Set for each provider.\n"
-  "--pkcs11-sign-mode mode ... : PKCS#11 signature method.\n"
-  "                              auto    : Try  to determind automatically (default).\n"
-  "                              sign    : Use Sign.\n"
-  "                              recover : Use SignRecover.\n"
-  "                              any     : Use Sign and then SignRecover.\n"
+  "--pkcs11-private-mode hex ...   : PKCS#11 private key mode mask.\n"
+  "                              0       : Try  to determind automatically (default).\n"
+  "                              1       : Use Sign.\n"
+  "                              2       : Use SignRecover.\n"
+  "                              4       : Use Decrypt.\n"
+  "                              8       : Use Unwrap.\n"
   "--pkcs11-cert-private [0|1] ... : Set if login should be performed before\n"
   "                              certificate can be accessed. Set for each provider.\n"
   "--pkcs11-pin-cache seconds  : Number of seconds to cache PIN. The default is -1\n"
   "                              cache until token is removed.\n"
-  "--pkcs11-slot-type method   : Slot locate method:\n"
-  "                              id      : By slot id (numeric [prov:]slot#).\n"
-  "                              name    : By slot name.\n"
-  "                              label   : By the card label that resides in slot.\n"
-  "--pkcs11-slot name          : The slot name.\n"
-  "--pkcs11-id-type method     : Certificate and key locate method:\n"
-  "                              id      : By the object id (hex format).\n"
-  "                              label   : By the object label (string).\n"
-  "                              subject : By certificate subject (String).\n"
-  "--pkcs11-id name            : The object name.\n"
+  "--pkcs11-id serialized-id   : Identity to use, get using standalone --show-pkcs11-ids\n"
 #endif                 /* ENABLE_PKCS11 */
  "\n"
   "SSL Library information:\n"
@@ -600,8 +595,8 @@ static const char usage_message[] =
 #ifdef ENABLE_PKCS11
   "\n"
   "PKCS#11 standalone options:\n"
-  "--show-pkcs11-slots provider        : Show PKCS#11 provider available slots.\n"
-  "--show-pkcs11-objects provider slot : Show PKCS#11 token objects.\n" 
+  "--show-pkcs11-ids provider [cert_private] : Show PKCS#11 available ids.\n" 
+  "                                            --verb option can be added *BEFORE* this.\n"
 #endif                         /* ENABLE_PKCS11 */
  ;
 
@@ -1280,8 +1275,8 @@ show_settings (const struct options *o)
   }
   {
     int i;
-    for (i=0;i<MAX_PARMS && o->pkcs11_sign_mode[i] != NULL;i++)
-      SHOW_PARM (pkcs11_sign_mode, o->pkcs11_sign_mode[i], "%s");
+    for (i=0;i<MAX_PARMS;i++)
+      SHOW_PARM (pkcs11_private_mode, o->pkcs11_private_mode[i], "%08x");
   }
   {
     int i;
@@ -1289,9 +1284,6 @@ show_settings (const struct options *o)
       SHOW_PARM (pkcs11_cert_private, o->pkcs11_cert_private[i] ? "ENABLED" : "DISABLED", "%s");
   }
   SHOW_INT (pkcs11_pin_cache_period);
-  SHOW_STR (pkcs11_slot_type);
-  SHOW_STR (pkcs11_slot);
-  SHOW_STR (pkcs11_id_type);
   SHOW_STR (pkcs11_id);
 #endif                 /* ENABLE_PKCS11 */
 
@@ -1764,35 +1756,7 @@ options_postprocess (struct options *options, bool first_time)
 #ifdef ENABLE_PKCS11
       if (options->pkcs11_providers[0])
        {
-        int j;
         notnull (options->ca_file, "CA file (--ca)");
-       
-       for (j=0;j<MAX_PARMS && options->pkcs11_sign_mode[j] != NULL;j++)
-        {
-         if (
-          !string_defined_equal (options->pkcs11_sign_mode[j], "auto") &&
-          !string_defined_equal (options->pkcs11_sign_mode[j], "recover") &&
-          !string_defined_equal (options->pkcs11_sign_mode[j], "sign")
-         )
-           msg(M_USAGE, "Parameter --pkcs11-sign-mode value is invalid.");
-        }
-
-       if (
-         !string_defined_equal (options->pkcs11_slot_type, "id") &&
-         !string_defined_equal (options->pkcs11_slot_type, "name") &&
-         !string_defined_equal (options->pkcs11_slot_type, "label")
-       )
-         msg(M_USAGE, "Parameter --pkcs11-slot-type value is invalid.");
-
-       notnull (options->pkcs11_slot, "PKCS#11 slot name (--pkcs11-slot)");
-
-       if (
-         !string_defined_equal (options->pkcs11_id_type, "id") &&
-         !string_defined_equal (options->pkcs11_id_type, "label") &&
-         !string_defined_equal (options->pkcs11_id_type, "subject")
-       )
-         msg(M_USAGE, "Parameter --pkcs11-id-type value is invalid.");
-
        notnull (options->pkcs11_id, "PKCS#11 id (--pkcs11-id)");
 
        if (options->cert_file)
@@ -1895,10 +1859,7 @@ options_postprocess (struct options *options, bool first_time)
       MUST_BE_UNDEF (remote_cert_eku);
 #ifdef ENABLE_PKCS11
       MUST_BE_UNDEF (pkcs11_providers[0]);
-      MUST_BE_UNDEF (pkcs11_sign_mode[0]);
-      MUST_BE_UNDEF (pkcs11_slot_type);
-      MUST_BE_UNDEF (pkcs11_slot);
-      MUST_BE_UNDEF (pkcs11_id_type);
+      MUST_BE_UNDEF (pkcs11_private_mode);
       MUST_BE_UNDEF (pkcs11_id);
 #endif
 
@@ -5098,31 +5059,15 @@ add_option (struct options *options,
 #endif /* USE_SSL */
 #endif /* USE_CRYPTO */
 #ifdef ENABLE_PKCS11
-  else if (streq (p[0], "show-pkcs11-slots") && p[1])
-    {
-      char *module =  p[1];
-      VERIFY_PERMISSION (OPT_P_GENERAL);
-      show_pkcs11_slots (module);
-      openvpn_exit (OPENVPN_EXIT_STATUS_GOOD); /* exit point */
-    }
-  else if (streq (p[0], "show-pkcs11-objects") && p[1] && p[2])
+  else if (streq (p[0], "show-pkcs11-ids") && p[1])
     {
       char *provider =  p[1];
-      char *slot = p[2];
-      struct gc_arena gc = gc_new ();
-      struct buffer pass_prompt = alloc_buf_gc (128, &gc);
-      char pin[256];
+      bool cert_private = (p[2] == NULL ? false : ( atoi (p[2]) != 0 ));
 
       VERIFY_PERMISSION (OPT_P_GENERAL);
 
-      buf_printf (&pass_prompt, "PIN:");
-
-      if (!get_console_input (BSTR (&pass_prompt), false, pin, sizeof (pin)))
-        msg (M_FATAL, "Cannot read password from stdin");
-      
-      gc_free (&gc);
-      
-      show_pkcs11_objects (provider, slot, pin);
+      set_debug_level (options->verbosity, SDL_CONSTRAIN);
+      show_pkcs11_ids (provider, cert_private);
       openvpn_exit (OPENVPN_EXIT_STATUS_GOOD); /* exit point */
     }
   else if (streq (p[0], "pkcs11-providers") && p[1])
@@ -5143,14 +5088,14 @@ add_option (struct options *options,
       for (j = 1; j < MAX_PARMS && p[j] != NULL; ++j)
         options->pkcs11_protected_authentication[j-1] = atoi (p[j]) != 0 ? 1 : 0;
     }
-  else if (streq (p[0], "pkcs11-sign-mode") && p[1])
+  else if (streq (p[0], "pkcs11-private-mode") && p[1])
     {
       int j;
       
       VERIFY_PERMISSION (OPT_P_GENERAL);
 
       for (j = 1; j < MAX_PARMS && p[j] != NULL; ++j)
-       options->pkcs11_sign_mode[j-1] = p[j];
+        sscanf (p[j], "%x", &(options->pkcs11_private_mode[j-1]));
     }
   else if (streq (p[0], "pkcs11-cert-private"))
     {
@@ -5166,21 +5111,6 @@ add_option (struct options *options,
       VERIFY_PERMISSION (OPT_P_GENERAL);
       options->pkcs11_pin_cache_period = atoi (p[1]);
     }
-  else if (streq (p[0], "pkcs11-slot-type") && p[1])
-    {
-      VERIFY_PERMISSION (OPT_P_GENERAL);
-      options->pkcs11_slot_type = p[1];
-    }
-  else if (streq (p[0], "pkcs11-slot") && p[1])
-    {
-      VERIFY_PERMISSION (OPT_P_GENERAL);
-      options->pkcs11_slot = p[1];
-    }
-  else if (streq (p[0], "pkcs11-id-type") && p[1])
-    {
-      VERIFY_PERMISSION (OPT_P_GENERAL);
-      options->pkcs11_id_type = p[1];
-    }
   else if (streq (p[0], "pkcs11-id") && p[1])
     {
       VERIFY_PERMISSION (OPT_P_GENERAL);
index ee13c8de3c15a492fb9065fd3615dc9665a8cf5c..805943eec94caa10e7b99c80c9deab9a36a2b942 100644 (file)
--- a/options.h
+++ b/options.h
@@ -413,13 +413,10 @@ struct options
 
 #ifdef ENABLE_PKCS11
   const char *pkcs11_providers[MAX_PARMS];
-  const char *pkcs11_sign_mode[MAX_PARMS];
+  unsigned pkcs11_private_mode[MAX_PARMS];
   bool pkcs11_protected_authentication[MAX_PARMS];
   bool pkcs11_cert_private[MAX_PARMS];
   int pkcs11_pin_cache_period;
-  const char *pkcs11_slot_type;
-  const char *pkcs11_slot;
-  const char *pkcs11_id_type;
   const char *pkcs11_id;
 #endif
 
diff --git a/pkcs11-headers/pkcs11.h b/pkcs11-headers/pkcs11.h
deleted file mode 100644 (file)
index 6c61220..0000000
+++ /dev/null
@@ -1,299 +0,0 @@
-/* pkcs11.h include file for PKCS #11. */
-/* $Revision: 1.4 $ */
-
-/* License to copy and use this software is granted provided that it is
- * identified as "RSA Security Inc. PKCS #11 Cryptographic Token Interface
- * (Cryptoki)" in all material mentioning or referencing this software.
-
- * License is also granted to make and use derivative works provided that
- * such works are identified as "derived from the RSA Security Inc. PKCS #11
- * Cryptographic Token Interface (Cryptoki)" in all material mentioning or 
- * referencing the derived work.
-
- * RSA Security Inc. makes no representations concerning either the 
- * merchantability of this software or the suitability of this software for
- * any particular purpose. It is provided "as is" without express or implied
- * warranty of any kind.
- */
-
-#ifndef _PKCS11_H_
-#define _PKCS11_H_ 1
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Before including this file (pkcs11.h) (or pkcs11t.h by
- * itself), 6 platform-specific macros must be defined.  These
- * macros are described below, and typical definitions for them
- * are also given.  Be advised that these definitions can depend
- * on both the platform and the compiler used (and possibly also
- * on whether a Cryptoki library is linked statically or
- * dynamically).
- *
- * In addition to defining these 6 macros, the packing convention
- * for Cryptoki structures should be set.  The Cryptoki
- * convention on packing is that structures should be 1-byte
- * aligned.
- *
- * If you're using Microsoft Developer Studio 5.0 to produce
- * Win32 stuff, this might be done by using the following
- * preprocessor directive before including pkcs11.h or pkcs11t.h:
- *
- * #pragma pack(push, cryptoki, 1)
- *
- * and using the following preprocessor directive after including
- * pkcs11.h or pkcs11t.h:
- *
- * #pragma pack(pop, cryptoki)
- *
- * If you're using an earlier version of Microsoft Developer
- * Studio to produce Win16 stuff, this might be done by using
- * the following preprocessor directive before including
- * pkcs11.h or pkcs11t.h:
- *
- * #pragma pack(1)
- *
- * In a UNIX environment, you're on your own for this.  You might
- * not need to do (or be able to do!) anything.
- *
- *
- * Now for the macros:
- *
- *
- * 1. CK_PTR: The indirection string for making a pointer to an
- * object.  It can be used like this:
- *
- * typedef CK_BYTE CK_PTR CK_BYTE_PTR;
- *
- * If you're using Microsoft Developer Studio 5.0 to produce
- * Win32 stuff, it might be defined by:
- *
- * #define CK_PTR *
- *
- * If you're using an earlier version of Microsoft Developer
- * Studio to produce Win16 stuff, it might be defined by:
- *
- * #define CK_PTR far *
- *
- * In a typical UNIX environment, it might be defined by:
- *
- * #define CK_PTR *
- *
- *
- * 2. CK_DEFINE_FUNCTION(returnType, name): A macro which makes
- * an exportable Cryptoki library function definition out of a
- * return type and a function name.  It should be used in the
- * following fashion to define the exposed Cryptoki functions in
- * a Cryptoki library:
- *
- * CK_DEFINE_FUNCTION(CK_RV, C_Initialize)(
- *   CK_VOID_PTR pReserved
- * )
- * {
- *   ...
- * }
- *
- * If you're using Microsoft Developer Studio 5.0 to define a
- * function in a Win32 Cryptoki .dll, it might be defined by:
- *
- * #define CK_DEFINE_FUNCTION(returnType, name) \
- *   returnType __declspec(dllexport) name
- *
- * If you're using an earlier version of Microsoft Developer
- * Studio to define a function in a Win16 Cryptoki .dll, it
- * might be defined by:
- *
- * #define CK_DEFINE_FUNCTION(returnType, name) \
- *   returnType __export _far _pascal name
- *
- * In a UNIX environment, it might be defined by:
- *
- * #define CK_DEFINE_FUNCTION(returnType, name) \
- *   returnType name
- *
- *
- * 3. CK_DECLARE_FUNCTION(returnType, name): A macro which makes
- * an importable Cryptoki library function declaration out of a
- * return type and a function name.  It should be used in the
- * following fashion:
- *
- * extern CK_DECLARE_FUNCTION(CK_RV, C_Initialize)(
- *   CK_VOID_PTR pReserved
- * );
- *
- * If you're using Microsoft Developer Studio 5.0 to declare a
- * function in a Win32 Cryptoki .dll, it might be defined by:
- *
- * #define CK_DECLARE_FUNCTION(returnType, name) \
- *   returnType __declspec(dllimport) name
- *
- * If you're using an earlier version of Microsoft Developer
- * Studio to declare a function in a Win16 Cryptoki .dll, it
- * might be defined by:
- *
- * #define CK_DECLARE_FUNCTION(returnType, name) \
- *   returnType __export _far _pascal name
- *
- * In a UNIX environment, it might be defined by:
- *
- * #define CK_DECLARE_FUNCTION(returnType, name) \
- *   returnType name
- *
- *
- * 4. CK_DECLARE_FUNCTION_POINTER(returnType, name): A macro
- * which makes a Cryptoki API function pointer declaration or
- * function pointer type declaration out of a return type and a
- * function name.  It should be used in the following fashion:
- *
- * // Define funcPtr to be a pointer to a Cryptoki API function
- * // taking arguments args and returning CK_RV.
- * CK_DECLARE_FUNCTION_POINTER(CK_RV, funcPtr)(args);
- *
- * or
- *
- * // Define funcPtrType to be the type of a pointer to a
- * // Cryptoki API function taking arguments args and returning
- * // CK_RV, and then define funcPtr to be a variable of type
- * // funcPtrType.
- * typedef CK_DECLARE_FUNCTION_POINTER(CK_RV, funcPtrType)(args);
- * funcPtrType funcPtr;
- *
- * If you're using Microsoft Developer Studio 5.0 to access
- * functions in a Win32 Cryptoki .dll, in might be defined by:
- *
- * #define CK_DECLARE_FUNCTION_POINTER(returnType, name) \
- *   returnType __declspec(dllimport) (* name)
- *
- * If you're using an earlier version of Microsoft Developer
- * Studio to access functions in a Win16 Cryptoki .dll, it might
- * be defined by:
- *
- * #define CK_DECLARE_FUNCTION_POINTER(returnType, name) \
- *   returnType __export _far _pascal (* name)
- *
- * In a UNIX environment, it might be defined by:
- *
- * #define CK_DECLARE_FUNCTION_POINTER(returnType, name) \
- *   returnType (* name)
- *
- *
- * 5. CK_CALLBACK_FUNCTION(returnType, name): A macro which makes
- * a function pointer type for an application callback out of
- * a return type for the callback and a name for the callback.
- * It should be used in the following fashion:
- *
- * CK_CALLBACK_FUNCTION(CK_RV, myCallback)(args);
- *
- * to declare a function pointer, myCallback, to a callback
- * which takes arguments args and returns a CK_RV.  It can also
- * be used like this:
- *
- * typedef CK_CALLBACK_FUNCTION(CK_RV, myCallbackType)(args);
- * myCallbackType myCallback;
- *
- * If you're using Microsoft Developer Studio 5.0 to do Win32
- * Cryptoki development, it might be defined by:
- *
- * #define CK_CALLBACK_FUNCTION(returnType, name) \
- *   returnType (* name)
- *
- * If you're using an earlier version of Microsoft Developer
- * Studio to do Win16 development, it might be defined by:
- *
- * #define CK_CALLBACK_FUNCTION(returnType, name) \
- *   returnType _far _pascal (* name)
- *
- * In a UNIX environment, it might be defined by:
- *
- * #define CK_CALLBACK_FUNCTION(returnType, name) \
- *   returnType (* name)
- *
- *
- * 6. NULL_PTR: This macro is the value of a NULL pointer.
- *
- * In any ANSI/ISO C environment (and in many others as well),
- * this should best be defined by
- *
- * #ifndef NULL_PTR
- * #define NULL_PTR 0
- * #endif
- */
-
-
-/* All the various Cryptoki types and #define'd values are in the
- * file pkcs11t.h. */
-#include "pkcs11t.h"
-
-#define __PASTE(x,y)      x##y
-
-
-/* ==============================================================
- * Define the "extern" form of all the entry points.
- * ==============================================================
- */
-
-#define CK_NEED_ARG_LIST  1
-#define CK_PKCS11_FUNCTION_INFO(name) \
-  extern CK_DECLARE_FUNCTION(CK_RV, name)
-
-/* pkcs11f.h has all the information about the Cryptoki
- * function prototypes. */
-#include "pkcs11f.h"
-
-#undef CK_NEED_ARG_LIST
-#undef CK_PKCS11_FUNCTION_INFO
-
-
-/* ==============================================================
- * Define the typedef form of all the entry points.  That is, for
- * each Cryptoki function C_XXX, define a type CK_C_XXX which is
- * a pointer to that kind of function.
- * ==============================================================
- */
-
-#define CK_NEED_ARG_LIST  1
-#define CK_PKCS11_FUNCTION_INFO(name) \
-  typedef CK_DECLARE_FUNCTION_POINTER(CK_RV, __PASTE(CK_,name))
-
-/* pkcs11f.h has all the information about the Cryptoki
- * function prototypes. */
-#include "pkcs11f.h"
-
-#undef CK_NEED_ARG_LIST
-#undef CK_PKCS11_FUNCTION_INFO
-
-
-/* ==============================================================
- * Define structed vector of entry points.  A CK_FUNCTION_LIST
- * contains a CK_VERSION indicating a library's Cryptoki version
- * and then a whole slew of function pointers to the routines in
- * the library.  This type was declared, but not defined, in
- * pkcs11t.h.
- * ==============================================================
- */
-
-#define CK_PKCS11_FUNCTION_INFO(name) \
-  __PASTE(CK_,name) name;
-  
-struct CK_FUNCTION_LIST {
-
-  CK_VERSION    version;  /* Cryptoki version */
-
-/* Pile all the function pointers into the CK_FUNCTION_LIST. */
-/* pkcs11f.h has all the information about the Cryptoki
- * function prototypes. */
-#include "pkcs11f.h"
-
-};
-
-#undef CK_PKCS11_FUNCTION_INFO
-
-
-#undef __PASTE
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/pkcs11-headers/pkcs11f.h b/pkcs11-headers/pkcs11f.h
deleted file mode 100644 (file)
index a479384..0000000
+++ /dev/null
@@ -1,912 +0,0 @@
-/* pkcs11f.h include file for PKCS #11. */
-/* $Revision: 1.4 $ */
-
-/* License to copy and use this software is granted provided that it is
- * identified as "RSA Security Inc. PKCS #11 Cryptographic Token Interface
- * (Cryptoki)" in all material mentioning or referencing this software.
-
- * License is also granted to make and use derivative works provided that
- * such works are identified as "derived from the RSA Security Inc. PKCS #11
- * Cryptographic Token Interface (Cryptoki)" in all material mentioning or 
- * referencing the derived work.
-
- * RSA Security Inc. makes no representations concerning either the 
- * merchantability of this software or the suitability of this software for
- * any particular purpose. It is provided "as is" without express or implied
- * warranty of any kind.
- */
-
-/* This header file contains pretty much everything about all the */
-/* Cryptoki function prototypes.  Because this information is */
-/* used for more than just declaring function prototypes, the */
-/* order of the functions appearing herein is important, and */
-/* should not be altered. */
-
-/* General-purpose */
-
-/* C_Initialize initializes the Cryptoki library. */
-CK_PKCS11_FUNCTION_INFO(C_Initialize)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_VOID_PTR   pInitArgs  /* if this is not NULL_PTR, it gets
-                            * cast to CK_C_INITIALIZE_ARGS_PTR
-                            * and dereferenced */
-);
-#endif
-
-
-/* C_Finalize indicates that an application is done with the
- * Cryptoki library. */
-CK_PKCS11_FUNCTION_INFO(C_Finalize)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_VOID_PTR   pReserved  /* reserved.  Should be NULL_PTR */
-);
-#endif
-
-
-/* C_GetInfo returns general information about Cryptoki. */
-CK_PKCS11_FUNCTION_INFO(C_GetInfo)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_INFO_PTR   pInfo  /* location that receives information */
-);
-#endif
-
-
-/* C_GetFunctionList returns the function list. */
-CK_PKCS11_FUNCTION_INFO(C_GetFunctionList)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_FUNCTION_LIST_PTR_PTR ppFunctionList  /* receives pointer to
-                                            * function list */
-);
-#endif
-
-
-
-/* Slot and token management */
-
-/* C_GetSlotList obtains a list of slots in the system. */
-CK_PKCS11_FUNCTION_INFO(C_GetSlotList)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_BBOOL       tokenPresent,  /* only slots with tokens? */
-  CK_SLOT_ID_PTR pSlotList,     /* receives array of slot IDs */
-  CK_ULONG_PTR   pulCount       /* receives number of slots */
-);
-#endif
-
-
-/* C_GetSlotInfo obtains information about a particular slot in
- * the system. */
-CK_PKCS11_FUNCTION_INFO(C_GetSlotInfo)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SLOT_ID       slotID,  /* the ID of the slot */
-  CK_SLOT_INFO_PTR pInfo    /* receives the slot information */
-);
-#endif
-
-
-/* C_GetTokenInfo obtains information about a particular token
- * in the system. */
-CK_PKCS11_FUNCTION_INFO(C_GetTokenInfo)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SLOT_ID        slotID,  /* ID of the token's slot */
-  CK_TOKEN_INFO_PTR pInfo    /* receives the token information */
-);
-#endif
-
-
-/* C_GetMechanismList obtains a list of mechanism types
- * supported by a token. */
-CK_PKCS11_FUNCTION_INFO(C_GetMechanismList)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SLOT_ID            slotID,          /* ID of token's slot */
-  CK_MECHANISM_TYPE_PTR pMechanismList,  /* gets mech. array */
-  CK_ULONG_PTR          pulCount         /* gets # of mechs. */
-);
-#endif
-
-
-/* C_GetMechanismInfo obtains information about a particular
- * mechanism possibly supported by a token. */
-CK_PKCS11_FUNCTION_INFO(C_GetMechanismInfo)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SLOT_ID            slotID,  /* ID of the token's slot */
-  CK_MECHANISM_TYPE     type,    /* type of mechanism */
-  CK_MECHANISM_INFO_PTR pInfo    /* receives mechanism info */
-);
-#endif
-
-
-/* C_InitToken initializes a token. */
-CK_PKCS11_FUNCTION_INFO(C_InitToken)
-#ifdef CK_NEED_ARG_LIST
-/* pLabel changed from CK_CHAR_PTR to CK_UTF8CHAR_PTR for v2.10 */
-(
-  CK_SLOT_ID      slotID,    /* ID of the token's slot */
-  CK_UTF8CHAR_PTR pPin,      /* the SO's initial PIN */
-  CK_ULONG        ulPinLen,  /* length in bytes of the PIN */
-  CK_UTF8CHAR_PTR pLabel     /* 32-byte token label (blank padded) */
-);
-#endif
-
-
-/* C_InitPIN initializes the normal user's PIN. */
-CK_PKCS11_FUNCTION_INFO(C_InitPIN)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE hSession,  /* the session's handle */
-  CK_UTF8CHAR_PTR   pPin,      /* the normal user's PIN */
-  CK_ULONG          ulPinLen   /* length in bytes of the PIN */
-);
-#endif
-
-
-/* C_SetPIN modifies the PIN of the user who is logged in. */
-CK_PKCS11_FUNCTION_INFO(C_SetPIN)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE hSession,  /* the session's handle */
-  CK_UTF8CHAR_PTR   pOldPin,   /* the old PIN */
-  CK_ULONG          ulOldLen,  /* length of the old PIN */
-  CK_UTF8CHAR_PTR   pNewPin,   /* the new PIN */
-  CK_ULONG          ulNewLen   /* length of the new PIN */
-);
-#endif
-
-
-
-/* Session management */
-
-/* C_OpenSession opens a session between an application and a
- * token. */
-CK_PKCS11_FUNCTION_INFO(C_OpenSession)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SLOT_ID            slotID,        /* the slot's ID */
-  CK_FLAGS              flags,         /* from CK_SESSION_INFO */
-  CK_VOID_PTR           pApplication,  /* passed to callback */
-  CK_NOTIFY             Notify,        /* callback function */
-  CK_SESSION_HANDLE_PTR phSession      /* gets session handle */
-);
-#endif
-
-
-/* C_CloseSession closes a session between an application and a
- * token. */
-CK_PKCS11_FUNCTION_INFO(C_CloseSession)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE hSession  /* the session's handle */
-);
-#endif
-
-
-/* C_CloseAllSessions closes all sessions with a token. */
-CK_PKCS11_FUNCTION_INFO(C_CloseAllSessions)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SLOT_ID     slotID  /* the token's slot */
-);
-#endif
-
-
-/* C_GetSessionInfo obtains information about the session. */
-CK_PKCS11_FUNCTION_INFO(C_GetSessionInfo)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE   hSession,  /* the session's handle */
-  CK_SESSION_INFO_PTR pInfo      /* receives session info */
-);
-#endif
-
-
-/* C_GetOperationState obtains the state of the cryptographic operation
- * in a session. */
-CK_PKCS11_FUNCTION_INFO(C_GetOperationState)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE hSession,             /* session's handle */
-  CK_BYTE_PTR       pOperationState,      /* gets state */
-  CK_ULONG_PTR      pulOperationStateLen  /* gets state length */
-);
-#endif
-
-
-/* C_SetOperationState restores the state of the cryptographic
- * operation in a session. */
-CK_PKCS11_FUNCTION_INFO(C_SetOperationState)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE hSession,            /* session's handle */
-  CK_BYTE_PTR      pOperationState,      /* holds state */
-  CK_ULONG         ulOperationStateLen,  /* holds state length */
-  CK_OBJECT_HANDLE hEncryptionKey,       /* en/decryption key */
-  CK_OBJECT_HANDLE hAuthenticationKey    /* sign/verify key */
-);
-#endif
-
-
-/* C_Login logs a user into a token. */
-CK_PKCS11_FUNCTION_INFO(C_Login)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE hSession,  /* the session's handle */
-  CK_USER_TYPE      userType,  /* the user type */
-  CK_UTF8CHAR_PTR   pPin,      /* the user's PIN */
-  CK_ULONG          ulPinLen   /* the length of the PIN */
-);
-#endif
-
-
-/* C_Logout logs a user out from a token. */
-CK_PKCS11_FUNCTION_INFO(C_Logout)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE hSession  /* the session's handle */
-);
-#endif
-
-
-
-/* Object management */
-
-/* C_CreateObject creates a new object. */
-CK_PKCS11_FUNCTION_INFO(C_CreateObject)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE hSession,    /* the session's handle */
-  CK_ATTRIBUTE_PTR  pTemplate,   /* the object's template */
-  CK_ULONG          ulCount,     /* attributes in template */
-  CK_OBJECT_HANDLE_PTR phObject  /* gets new object's handle. */
-);
-#endif
-
-
-/* C_CopyObject copies an object, creating a new object for the
- * copy. */
-CK_PKCS11_FUNCTION_INFO(C_CopyObject)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE    hSession,    /* the session's handle */
-  CK_OBJECT_HANDLE     hObject,     /* the object's handle */
-  CK_ATTRIBUTE_PTR     pTemplate,   /* template for new object */
-  CK_ULONG             ulCount,     /* attributes in template */
-  CK_OBJECT_HANDLE_PTR phNewObject  /* receives handle of copy */
-);
-#endif
-
-
-/* C_DestroyObject destroys an object. */
-CK_PKCS11_FUNCTION_INFO(C_DestroyObject)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE hSession,  /* the session's handle */
-  CK_OBJECT_HANDLE  hObject    /* the object's handle */
-);
-#endif
-
-
-/* C_GetObjectSize gets the size of an object in bytes. */
-CK_PKCS11_FUNCTION_INFO(C_GetObjectSize)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE hSession,  /* the session's handle */
-  CK_OBJECT_HANDLE  hObject,   /* the object's handle */
-  CK_ULONG_PTR      pulSize    /* receives size of object */
-);
-#endif
-
-
-/* C_GetAttributeValue obtains the value of one or more object
- * attributes. */
-CK_PKCS11_FUNCTION_INFO(C_GetAttributeValue)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE hSession,   /* the session's handle */
-  CK_OBJECT_HANDLE  hObject,    /* the object's handle */
-  CK_ATTRIBUTE_PTR  pTemplate,  /* specifies attrs; gets vals */
-  CK_ULONG          ulCount     /* attributes in template */
-);
-#endif
-
-
-/* C_SetAttributeValue modifies the value of one or more object
- * attributes */
-CK_PKCS11_FUNCTION_INFO(C_SetAttributeValue)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE hSession,   /* the session's handle */
-  CK_OBJECT_HANDLE  hObject,    /* the object's handle */
-  CK_ATTRIBUTE_PTR  pTemplate,  /* specifies attrs and values */
-  CK_ULONG          ulCount     /* attributes in template */
-);
-#endif
-
-
-/* C_FindObjectsInit initializes a search for token and session
- * objects that match a template. */
-CK_PKCS11_FUNCTION_INFO(C_FindObjectsInit)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE hSession,   /* the session's handle */
-  CK_ATTRIBUTE_PTR  pTemplate,  /* attribute values to match */
-  CK_ULONG          ulCount     /* attrs in search template */
-);
-#endif
-
-
-/* C_FindObjects continues a search for token and session
- * objects that match a template, obtaining additional object
- * handles. */
-CK_PKCS11_FUNCTION_INFO(C_FindObjects)
-#ifdef CK_NEED_ARG_LIST
-(
- CK_SESSION_HANDLE    hSession,          /* session's handle */
- CK_OBJECT_HANDLE_PTR phObject,          /* gets obj. handles */
- CK_ULONG             ulMaxObjectCount,  /* max handles to get */
- CK_ULONG_PTR         pulObjectCount     /* actual # returned */
-);
-#endif
-
-
-/* C_FindObjectsFinal finishes a search for token and session
- * objects. */
-CK_PKCS11_FUNCTION_INFO(C_FindObjectsFinal)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE hSession  /* the session's handle */
-);
-#endif
-
-
-
-/* Encryption and decryption */
-
-/* C_EncryptInit initializes an encryption operation. */
-CK_PKCS11_FUNCTION_INFO(C_EncryptInit)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE hSession,    /* the session's handle */
-  CK_MECHANISM_PTR  pMechanism,  /* the encryption mechanism */
-  CK_OBJECT_HANDLE  hKey         /* handle of encryption key */
-);
-#endif
-
-
-/* C_Encrypt encrypts single-part data. */
-CK_PKCS11_FUNCTION_INFO(C_Encrypt)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE hSession,            /* session's handle */
-  CK_BYTE_PTR       pData,               /* the plaintext data */
-  CK_ULONG          ulDataLen,           /* bytes of plaintext */
-  CK_BYTE_PTR       pEncryptedData,      /* gets ciphertext */
-  CK_ULONG_PTR      pulEncryptedDataLen  /* gets c-text size */
-);
-#endif
-
-
-/* C_EncryptUpdate continues a multiple-part encryption
- * operation. */
-CK_PKCS11_FUNCTION_INFO(C_EncryptUpdate)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE hSession,           /* session's handle */
-  CK_BYTE_PTR       pPart,              /* the plaintext data */
-  CK_ULONG          ulPartLen,          /* plaintext data len */
-  CK_BYTE_PTR       pEncryptedPart,     /* gets ciphertext */
-  CK_ULONG_PTR      pulEncryptedPartLen /* gets c-text size */
-);
-#endif
-
-
-/* C_EncryptFinal finishes a multiple-part encryption
- * operation. */
-CK_PKCS11_FUNCTION_INFO(C_EncryptFinal)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE hSession,                /* session handle */
-  CK_BYTE_PTR       pLastEncryptedPart,      /* last c-text */
-  CK_ULONG_PTR      pulLastEncryptedPartLen  /* gets last size */
-);
-#endif
-
-
-/* C_DecryptInit initializes a decryption operation. */
-CK_PKCS11_FUNCTION_INFO(C_DecryptInit)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE hSession,    /* the session's handle */
-  CK_MECHANISM_PTR  pMechanism,  /* the decryption mechanism */
-  CK_OBJECT_HANDLE  hKey         /* handle of decryption key */
-);
-#endif
-
-
-/* C_Decrypt decrypts encrypted data in a single part. */
-CK_PKCS11_FUNCTION_INFO(C_Decrypt)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE hSession,           /* session's handle */
-  CK_BYTE_PTR       pEncryptedData,     /* ciphertext */
-  CK_ULONG          ulEncryptedDataLen, /* ciphertext length */
-  CK_BYTE_PTR       pData,              /* gets plaintext */
-  CK_ULONG_PTR      pulDataLen          /* gets p-text size */
-);
-#endif
-
-
-/* C_DecryptUpdate continues a multiple-part decryption
- * operation. */
-CK_PKCS11_FUNCTION_INFO(C_DecryptUpdate)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE hSession,            /* session's handle */
-  CK_BYTE_PTR       pEncryptedPart,      /* encrypted data */
-  CK_ULONG          ulEncryptedPartLen,  /* input length */
-  CK_BYTE_PTR       pPart,               /* gets plaintext */
-  CK_ULONG_PTR      pulPartLen           /* p-text size */
-);
-#endif
-
-
-/* C_DecryptFinal finishes a multiple-part decryption
- * operation. */
-CK_PKCS11_FUNCTION_INFO(C_DecryptFinal)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE hSession,       /* the session's handle */
-  CK_BYTE_PTR       pLastPart,      /* gets plaintext */
-  CK_ULONG_PTR      pulLastPartLen  /* p-text size */
-);
-#endif
-
-
-
-/* Message digesting */
-
-/* C_DigestInit initializes a message-digesting operation. */
-CK_PKCS11_FUNCTION_INFO(C_DigestInit)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE hSession,   /* the session's handle */
-  CK_MECHANISM_PTR  pMechanism  /* the digesting mechanism */
-);
-#endif
-
-
-/* C_Digest digests data in a single part. */
-CK_PKCS11_FUNCTION_INFO(C_Digest)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE hSession,     /* the session's handle */
-  CK_BYTE_PTR       pData,        /* data to be digested */
-  CK_ULONG          ulDataLen,    /* bytes of data to digest */
-  CK_BYTE_PTR       pDigest,      /* gets the message digest */
-  CK_ULONG_PTR      pulDigestLen  /* gets digest length */
-);
-#endif
-
-
-/* C_DigestUpdate continues a multiple-part message-digesting
- * operation. */
-CK_PKCS11_FUNCTION_INFO(C_DigestUpdate)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE hSession,  /* the session's handle */
-  CK_BYTE_PTR       pPart,     /* data to be digested */
-  CK_ULONG          ulPartLen  /* bytes of data to be digested */
-);
-#endif
-
-
-/* C_DigestKey continues a multi-part message-digesting
- * operation, by digesting the value of a secret key as part of
- * the data already digested. */
-CK_PKCS11_FUNCTION_INFO(C_DigestKey)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE hSession,  /* the session's handle */
-  CK_OBJECT_HANDLE  hKey       /* secret key to digest */
-);
-#endif
-
-
-/* C_DigestFinal finishes a multiple-part message-digesting
- * operation. */
-CK_PKCS11_FUNCTION_INFO(C_DigestFinal)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE hSession,     /* the session's handle */
-  CK_BYTE_PTR       pDigest,      /* gets the message digest */
-  CK_ULONG_PTR      pulDigestLen  /* gets byte count of digest */
-);
-#endif
-
-
-
-/* Signing and MACing */
-
-/* C_SignInit initializes a signature (private key encryption)
- * operation, where the signature is (will be) an appendix to
- * the data, and plaintext cannot be recovered from the
- *signature. */
-CK_PKCS11_FUNCTION_INFO(C_SignInit)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE hSession,    /* the session's handle */
-  CK_MECHANISM_PTR  pMechanism,  /* the signature mechanism */
-  CK_OBJECT_HANDLE  hKey         /* handle of signature key */
-);
-#endif
-
-
-/* C_Sign signs (encrypts with private key) data in a single
- * part, where the signature is (will be) an appendix to the
- * data, and plaintext cannot be recovered from the signature. */
-CK_PKCS11_FUNCTION_INFO(C_Sign)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE hSession,        /* the session's handle */
-  CK_BYTE_PTR       pData,           /* the data to sign */
-  CK_ULONG          ulDataLen,       /* count of bytes to sign */
-  CK_BYTE_PTR       pSignature,      /* gets the signature */
-  CK_ULONG_PTR      pulSignatureLen  /* gets signature length */
-);
-#endif
-
-
-/* C_SignUpdate continues a multiple-part signature operation,
- * where the signature is (will be) an appendix to the data, 
- * and plaintext cannot be recovered from the signature. */
-CK_PKCS11_FUNCTION_INFO(C_SignUpdate)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE hSession,  /* the session's handle */
-  CK_BYTE_PTR       pPart,     /* the data to sign */
-  CK_ULONG          ulPartLen  /* count of bytes to sign */
-);
-#endif
-
-
-/* C_SignFinal finishes a multiple-part signature operation, 
- * returning the signature. */
-CK_PKCS11_FUNCTION_INFO(C_SignFinal)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE hSession,        /* the session's handle */
-  CK_BYTE_PTR       pSignature,      /* gets the signature */
-  CK_ULONG_PTR      pulSignatureLen  /* gets signature length */
-);
-#endif
-
-
-/* C_SignRecoverInit initializes a signature operation, where
- * the data can be recovered from the signature. */
-CK_PKCS11_FUNCTION_INFO(C_SignRecoverInit)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE hSession,   /* the session's handle */
-  CK_MECHANISM_PTR  pMechanism, /* the signature mechanism */
-  CK_OBJECT_HANDLE  hKey        /* handle of the signature key */
-);
-#endif
-
-
-/* C_SignRecover signs data in a single operation, where the
- * data can be recovered from the signature. */
-CK_PKCS11_FUNCTION_INFO(C_SignRecover)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE hSession,        /* the session's handle */
-  CK_BYTE_PTR       pData,           /* the data to sign */
-  CK_ULONG          ulDataLen,       /* count of bytes to sign */
-  CK_BYTE_PTR       pSignature,      /* gets the signature */
-  CK_ULONG_PTR      pulSignatureLen  /* gets signature length */
-);
-#endif
-
-
-
-/* Verifying signatures and MACs */
-
-/* C_VerifyInit initializes a verification operation, where the
- * signature is an appendix to the data, and plaintext cannot
- *  cannot be recovered from the signature (e.g. DSA). */
-CK_PKCS11_FUNCTION_INFO(C_VerifyInit)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE hSession,    /* the session's handle */
-  CK_MECHANISM_PTR  pMechanism,  /* the verification mechanism */
-  CK_OBJECT_HANDLE  hKey         /* verification key */ 
-);
-#endif
-
-
-/* C_Verify verifies a signature in a single-part operation, 
- * where the signature is an appendix to the data, and plaintext
- * cannot be recovered from the signature. */
-CK_PKCS11_FUNCTION_INFO(C_Verify)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE hSession,       /* the session's handle */
-  CK_BYTE_PTR       pData,          /* signed data */
-  CK_ULONG          ulDataLen,      /* length of signed data */
-  CK_BYTE_PTR       pSignature,     /* signature */
-  CK_ULONG          ulSignatureLen  /* signature length*/
-);
-#endif
-
-
-/* C_VerifyUpdate continues a multiple-part verification
- * operation, where the signature is an appendix to the data, 
- * and plaintext cannot be recovered from the signature. */
-CK_PKCS11_FUNCTION_INFO(C_VerifyUpdate)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE hSession,  /* the session's handle */
-  CK_BYTE_PTR       pPart,     /* signed data */
-  CK_ULONG          ulPartLen  /* length of signed data */
-);
-#endif
-
-
-/* C_VerifyFinal finishes a multiple-part verification
- * operation, checking the signature. */
-CK_PKCS11_FUNCTION_INFO(C_VerifyFinal)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE hSession,       /* the session's handle */
-  CK_BYTE_PTR       pSignature,     /* signature to verify */
-  CK_ULONG          ulSignatureLen  /* signature length */
-);
-#endif
-
-
-/* C_VerifyRecoverInit initializes a signature verification
- * operation, where the data is recovered from the signature. */
-CK_PKCS11_FUNCTION_INFO(C_VerifyRecoverInit)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE hSession,    /* the session's handle */
-  CK_MECHANISM_PTR  pMechanism,  /* the verification mechanism */
-  CK_OBJECT_HANDLE  hKey         /* verification key */
-);
-#endif
-
-
-/* C_VerifyRecover verifies a signature in a single-part
- * operation, where the data is recovered from the signature. */
-CK_PKCS11_FUNCTION_INFO(C_VerifyRecover)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE hSession,        /* the session's handle */
-  CK_BYTE_PTR       pSignature,      /* signature to verify */
-  CK_ULONG          ulSignatureLen,  /* signature length */
-  CK_BYTE_PTR       pData,           /* gets signed data */
-  CK_ULONG_PTR      pulDataLen       /* gets signed data len */
-);
-#endif
-
-
-
-/* Dual-function cryptographic operations */
-
-/* C_DigestEncryptUpdate continues a multiple-part digesting
- * and encryption operation. */
-CK_PKCS11_FUNCTION_INFO(C_DigestEncryptUpdate)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE hSession,            /* session's handle */
-  CK_BYTE_PTR       pPart,               /* the plaintext data */
-  CK_ULONG          ulPartLen,           /* plaintext length */
-  CK_BYTE_PTR       pEncryptedPart,      /* gets ciphertext */
-  CK_ULONG_PTR      pulEncryptedPartLen  /* gets c-text length */
-);
-#endif
-
-
-/* C_DecryptDigestUpdate continues a multiple-part decryption and
- * digesting operation. */
-CK_PKCS11_FUNCTION_INFO(C_DecryptDigestUpdate)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE hSession,            /* session's handle */
-  CK_BYTE_PTR       pEncryptedPart,      /* ciphertext */
-  CK_ULONG          ulEncryptedPartLen,  /* ciphertext length */
-  CK_BYTE_PTR       pPart,               /* gets plaintext */
-  CK_ULONG_PTR      pulPartLen           /* gets plaintext len */
-);
-#endif
-
-
-/* C_SignEncryptUpdate continues a multiple-part signing and
- * encryption operation. */
-CK_PKCS11_FUNCTION_INFO(C_SignEncryptUpdate)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE hSession,            /* session's handle */
-  CK_BYTE_PTR       pPart,               /* the plaintext data */
-  CK_ULONG          ulPartLen,           /* plaintext length */
-  CK_BYTE_PTR       pEncryptedPart,      /* gets ciphertext */
-  CK_ULONG_PTR      pulEncryptedPartLen  /* gets c-text length */
-);
-#endif
-
-
-/* C_DecryptVerifyUpdate continues a multiple-part decryption and
- * verify operation. */
-CK_PKCS11_FUNCTION_INFO(C_DecryptVerifyUpdate)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE hSession,            /* session's handle */
-  CK_BYTE_PTR       pEncryptedPart,      /* ciphertext */
-  CK_ULONG          ulEncryptedPartLen,  /* ciphertext length */
-  CK_BYTE_PTR       pPart,               /* gets plaintext */
-  CK_ULONG_PTR      pulPartLen           /* gets p-text length */
-);
-#endif
-
-
-
-/* Key management */
-
-/* C_GenerateKey generates a secret key, creating a new key
- * object. */
-CK_PKCS11_FUNCTION_INFO(C_GenerateKey)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE    hSession,    /* the session's handle */
-  CK_MECHANISM_PTR     pMechanism,  /* key generation mech. */
-  CK_ATTRIBUTE_PTR     pTemplate,   /* template for new key */
-  CK_ULONG             ulCount,     /* # of attrs in template */
-  CK_OBJECT_HANDLE_PTR phKey        /* gets handle of new key */
-);
-#endif
-
-
-/* C_GenerateKeyPair generates a public-key/private-key pair, 
- * creating new key objects. */
-CK_PKCS11_FUNCTION_INFO(C_GenerateKeyPair)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE    hSession,                    /* session
-                                                     * handle */
-  CK_MECHANISM_PTR     pMechanism,                  /* key-gen
-                                                     * mech. */
-  CK_ATTRIBUTE_PTR     pPublicKeyTemplate,          /* template
-                                                     * for pub.
-                                                     * key */
-  CK_ULONG             ulPublicKeyAttributeCount,   /* # pub.
-                                                     * attrs. */
-  CK_ATTRIBUTE_PTR     pPrivateKeyTemplate,         /* template
-                                                     * for priv.
-                                                     * key */
-  CK_ULONG             ulPrivateKeyAttributeCount,  /* # priv.
-                                                     * attrs. */
-  CK_OBJECT_HANDLE_PTR phPublicKey,                 /* gets pub.
-                                                     * key
-                                                     * handle */
-  CK_OBJECT_HANDLE_PTR phPrivateKey                 /* gets
-                                                     * priv. key
-                                                     * handle */
-);
-#endif
-
-
-/* C_WrapKey wraps (i.e., encrypts) a key. */
-CK_PKCS11_FUNCTION_INFO(C_WrapKey)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE hSession,        /* the session's handle */
-  CK_MECHANISM_PTR  pMechanism,      /* the wrapping mechanism */
-  CK_OBJECT_HANDLE  hWrappingKey,    /* wrapping key */
-  CK_OBJECT_HANDLE  hKey,            /* key to be wrapped */
-  CK_BYTE_PTR       pWrappedKey,     /* gets wrapped key */
-  CK_ULONG_PTR      pulWrappedKeyLen /* gets wrapped key size */
-);
-#endif
-
-
-/* C_UnwrapKey unwraps (decrypts) a wrapped key, creating a new
- * key object. */
-CK_PKCS11_FUNCTION_INFO(C_UnwrapKey)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE    hSession,          /* session's handle */
-  CK_MECHANISM_PTR     pMechanism,        /* unwrapping mech. */
-  CK_OBJECT_HANDLE     hUnwrappingKey,    /* unwrapping key */
-  CK_BYTE_PTR          pWrappedKey,       /* the wrapped key */
-  CK_ULONG             ulWrappedKeyLen,   /* wrapped key len */
-  CK_ATTRIBUTE_PTR     pTemplate,         /* new key template */
-  CK_ULONG             ulAttributeCount,  /* template length */
-  CK_OBJECT_HANDLE_PTR phKey              /* gets new handle */
-);
-#endif
-
-
-/* C_DeriveKey derives a key from a base key, creating a new key
- * object. */
-CK_PKCS11_FUNCTION_INFO(C_DeriveKey)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE    hSession,          /* session's handle */
-  CK_MECHANISM_PTR     pMechanism,        /* key deriv. mech. */
-  CK_OBJECT_HANDLE     hBaseKey,          /* base key */
-  CK_ATTRIBUTE_PTR     pTemplate,         /* new key template */
-  CK_ULONG             ulAttributeCount,  /* template length */
-  CK_OBJECT_HANDLE_PTR phKey              /* gets new handle */
-);
-#endif
-
-
-
-/* Random number generation */
-
-/* C_SeedRandom mixes additional seed material into the token's
- * random number generator. */
-CK_PKCS11_FUNCTION_INFO(C_SeedRandom)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE hSession,  /* the session's handle */
-  CK_BYTE_PTR       pSeed,     /* the seed material */
-  CK_ULONG          ulSeedLen  /* length of seed material */
-);
-#endif
-
-
-/* C_GenerateRandom generates random data. */
-CK_PKCS11_FUNCTION_INFO(C_GenerateRandom)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE hSession,    /* the session's handle */
-  CK_BYTE_PTR       RandomData,  /* receives the random data */
-  CK_ULONG          ulRandomLen  /* # of bytes to generate */
-);
-#endif
-
-
-
-/* Parallel function management */
-
-/* C_GetFunctionStatus is a legacy function; it obtains an
- * updated status of a function running in parallel with an
- * application. */
-CK_PKCS11_FUNCTION_INFO(C_GetFunctionStatus)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE hSession  /* the session's handle */
-);
-#endif
-
-
-/* C_CancelFunction is a legacy function; it cancels a function
- * running in parallel. */
-CK_PKCS11_FUNCTION_INFO(C_CancelFunction)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_SESSION_HANDLE hSession  /* the session's handle */
-);
-#endif
-
-
-
-/* Functions added in for Cryptoki Version 2.01 or later */
-
-/* C_WaitForSlotEvent waits for a slot event (token insertion,
- * removal, etc.) to occur. */
-CK_PKCS11_FUNCTION_INFO(C_WaitForSlotEvent)
-#ifdef CK_NEED_ARG_LIST
-(
-  CK_FLAGS flags,        /* blocking/nonblocking flag */
-  CK_SLOT_ID_PTR pSlot,  /* location that receives the slot ID */
-  CK_VOID_PTR pRserved   /* reserved.  Should be NULL_PTR */
-);
-#endif
diff --git a/pkcs11-headers/pkcs11t.h b/pkcs11-headers/pkcs11t.h
deleted file mode 100644 (file)
index b1a231a..0000000
+++ /dev/null
@@ -1,1685 +0,0 @@
-/* pkcs11t.h include file for PKCS #11. */
-/* $Revision: 1.6 $ */
-
-/* License to copy and use this software is granted provided that it is
- * identified as "RSA Security Inc. PKCS #11 Cryptographic Token Interface
- * (Cryptoki)" in all material mentioning or referencing this software.
-
- * License is also granted to make and use derivative works provided that
- * such works are identified as "derived from the RSA Security Inc. PKCS #11
- * Cryptographic Token Interface (Cryptoki)" in all material mentioning or
- * referencing the derived work.
-
- * RSA Security Inc. makes no representations concerning either the
- * merchantability of this software or the suitability of this software for
- * any particular purpose. It is provided "as is" without express or implied
- * warranty of any kind.
- */
-
-/* See top of pkcs11.h for information about the macros that
- * must be defined and the structure-packing conventions that
- * must be set before including this file. */
-
-#ifndef _PKCS11T_H_
-#define _PKCS11T_H_ 1
-
-#define CK_TRUE 1
-#define CK_FALSE 0
-
-#ifndef CK_DISABLE_TRUE_FALSE
-#ifndef FALSE
-#define FALSE CK_FALSE
-#endif
-
-#ifndef TRUE
-#define TRUE CK_TRUE
-#endif
-#endif
-
-/* an unsigned 8-bit value */
-typedef unsigned char     CK_BYTE;
-
-/* an unsigned 8-bit character */
-typedef CK_BYTE           CK_CHAR;
-
-/* an 8-bit UTF-8 character */
-typedef CK_BYTE           CK_UTF8CHAR;
-
-/* a BYTE-sized Boolean flag */
-typedef CK_BYTE           CK_BBOOL;
-
-/* an unsigned value, at least 32 bits long */
-typedef unsigned long int CK_ULONG;
-
-/* a signed value, the same size as a CK_ULONG */
-/* CK_LONG is new for v2.0 */
-typedef long int          CK_LONG;
-
-/* at least 32 bits; each bit is a Boolean flag */
-typedef CK_ULONG          CK_FLAGS;
-
-
-/* some special values for certain CK_ULONG variables */
-#define CK_UNAVAILABLE_INFORMATION (~0UL)
-#define CK_EFFECTIVELY_INFINITE    0
-
-
-typedef CK_BYTE     CK_PTR   CK_BYTE_PTR;
-typedef CK_CHAR     CK_PTR   CK_CHAR_PTR;
-typedef CK_UTF8CHAR CK_PTR   CK_UTF8CHAR_PTR;
-typedef CK_ULONG    CK_PTR   CK_ULONG_PTR;
-typedef void        CK_PTR   CK_VOID_PTR;
-
-/* Pointer to a CK_VOID_PTR-- i.e., pointer to pointer to void */
-typedef CK_VOID_PTR CK_PTR CK_VOID_PTR_PTR;
-
-
-/* The following value is always invalid if used as a session */
-/* handle or object handle */
-#define CK_INVALID_HANDLE 0
-
-
-typedef struct CK_VERSION {
-  CK_BYTE       major;  /* integer portion of version number */
-  CK_BYTE       minor;  /* 1/100ths portion of version number */
-} CK_VERSION;
-
-typedef CK_VERSION CK_PTR CK_VERSION_PTR;
-
-
-typedef struct CK_INFO {
-  /* manufacturerID and libraryDecription have been changed from
-   * CK_CHAR to CK_UTF8CHAR for v2.10 */
-  CK_VERSION    cryptokiVersion;     /* Cryptoki interface ver */
-  CK_UTF8CHAR   manufacturerID[32];  /* blank padded */
-  CK_FLAGS      flags;               /* must be zero */
-
-  /* libraryDescription and libraryVersion are new for v2.0 */
-  CK_UTF8CHAR   libraryDescription[32];  /* blank padded */
-  CK_VERSION    libraryVersion;          /* version of library */
-} CK_INFO;
-
-typedef CK_INFO CK_PTR    CK_INFO_PTR;
-
-
-/* CK_NOTIFICATION enumerates the types of notifications that
- * Cryptoki provides to an application */
-/* CK_NOTIFICATION has been changed from an enum to a CK_ULONG
- * for v2.0 */
-typedef CK_ULONG CK_NOTIFICATION;
-#define CKN_SURRENDER       0
-
-
-typedef CK_ULONG          CK_SLOT_ID;
-
-typedef CK_SLOT_ID CK_PTR CK_SLOT_ID_PTR;
-
-
-/* CK_SLOT_INFO provides information about a slot */
-typedef struct CK_SLOT_INFO {
-  /* slotDescription and manufacturerID have been changed from
-   * CK_CHAR to CK_UTF8CHAR for v2.10 */
-  CK_UTF8CHAR   slotDescription[64];  /* blank padded */
-  CK_UTF8CHAR   manufacturerID[32];   /* blank padded */
-  CK_FLAGS      flags;
-
-  /* hardwareVersion and firmwareVersion are new for v2.0 */
-  CK_VERSION    hardwareVersion;  /* version of hardware */
-  CK_VERSION    firmwareVersion;  /* version of firmware */
-} CK_SLOT_INFO;
-
-/* flags: bit flags that provide capabilities of the slot
- *      Bit Flag              Mask        Meaning
- */
-#define CKF_TOKEN_PRESENT     0x00000001  /* a token is there */
-#define CKF_REMOVABLE_DEVICE  0x00000002  /* removable devices*/
-#define CKF_HW_SLOT           0x00000004  /* hardware slot */
-
-typedef CK_SLOT_INFO CK_PTR CK_SLOT_INFO_PTR;
-
-
-/* CK_TOKEN_INFO provides information about a token */
-typedef struct CK_TOKEN_INFO {
-  /* label, manufacturerID, and model have been changed from
-   * CK_CHAR to CK_UTF8CHAR for v2.10 */
-  CK_UTF8CHAR   label[32];           /* blank padded */
-  CK_UTF8CHAR   manufacturerID[32];  /* blank padded */
-  CK_UTF8CHAR   model[16];           /* blank padded */
-  CK_CHAR       serialNumber[16];    /* blank padded */
-  CK_FLAGS      flags;               /* see below */
-
-  /* ulMaxSessionCount, ulSessionCount, ulMaxRwSessionCount,
-   * ulRwSessionCount, ulMaxPinLen, and ulMinPinLen have all been
-   * changed from CK_USHORT to CK_ULONG for v2.0 */
-  CK_ULONG      ulMaxSessionCount;     /* max open sessions */
-  CK_ULONG      ulSessionCount;        /* sess. now open */
-  CK_ULONG      ulMaxRwSessionCount;   /* max R/W sessions */
-  CK_ULONG      ulRwSessionCount;      /* R/W sess. now open */
-  CK_ULONG      ulMaxPinLen;           /* in bytes */
-  CK_ULONG      ulMinPinLen;           /* in bytes */
-  CK_ULONG      ulTotalPublicMemory;   /* in bytes */
-  CK_ULONG      ulFreePublicMemory;    /* in bytes */
-  CK_ULONG      ulTotalPrivateMemory;  /* in bytes */
-  CK_ULONG      ulFreePrivateMemory;   /* in bytes */
-
-  /* hardwareVersion, firmwareVersion, and time are new for
-   * v2.0 */
-  CK_VERSION    hardwareVersion;       /* version of hardware */
-  CK_VERSION    firmwareVersion;       /* version of firmware */
-  CK_CHAR       utcTime[16];           /* time */
-} CK_TOKEN_INFO;
-
-/* The flags parameter is defined as follows:
- *      Bit Flag                    Mask        Meaning
- */
-#define CKF_RNG                     0x00000001  /* has random #
-                                                 * generator */
-#define CKF_WRITE_PROTECTED         0x00000002  /* token is
-                                                 * write-
-                                                 * protected */
-#define CKF_LOGIN_REQUIRED          0x00000004  /* user must
-                                                 * login */
-#define CKF_USER_PIN_INITIALIZED    0x00000008  /* normal user's
-                                                 * PIN is set */
-
-/* CKF_RESTORE_KEY_NOT_NEEDED is new for v2.0.  If it is set,
- * that means that *every* time the state of cryptographic
- * operations of a session is successfully saved, all keys
- * needed to continue those operations are stored in the state */
-#define CKF_RESTORE_KEY_NOT_NEEDED  0x00000020
-
-/* CKF_CLOCK_ON_TOKEN is new for v2.0.  If it is set, that means
- * that the token has some sort of clock.  The time on that
- * clock is returned in the token info structure */
-#define CKF_CLOCK_ON_TOKEN          0x00000040
-
-/* CKF_PROTECTED_AUTHENTICATION_PATH is new for v2.0.  If it is
- * set, that means that there is some way for the user to login
- * without sending a PIN through the Cryptoki library itself */
-#define CKF_PROTECTED_AUTHENTICATION_PATH 0x00000100
-
-/* CKF_DUAL_CRYPTO_OPERATIONS is new for v2.0.  If it is true,
- * that means that a single session with the token can perform
- * dual simultaneous cryptographic operations (digest and
- * encrypt; decrypt and digest; sign and encrypt; and decrypt
- * and sign) */
-#define CKF_DUAL_CRYPTO_OPERATIONS  0x00000200
-
-/* CKF_TOKEN_INITIALIZED if new for v2.10. If it is true, the
- * token has been initialized using C_InitializeToken or an
- * equivalent mechanism outside the scope of PKCS #11.
- * Calling C_InitializeToken when this flag is set will cause
- * the token to be reinitialized. */
-#define CKF_TOKEN_INITIALIZED       0x00000400
-
-/* CKF_SECONDARY_AUTHENTICATION if new for v2.10. If it is
- * true, the token supports secondary authentication for
- * private key objects. This flag is deprecated in v2.11 and
-   onwards. */
-#define CKF_SECONDARY_AUTHENTICATION  0x00000800
-
-/* CKF_USER_PIN_COUNT_LOW if new for v2.10. If it is true, an
- * incorrect user login PIN has been entered at least once
- * since the last successful authentication. */
-#define CKF_USER_PIN_COUNT_LOW       0x00010000
-
-/* CKF_USER_PIN_FINAL_TRY if new for v2.10. If it is true,
- * supplying an incorrect user PIN will it to become locked. */
-#define CKF_USER_PIN_FINAL_TRY       0x00020000
-
-/* CKF_USER_PIN_LOCKED if new for v2.10. If it is true, the
- * user PIN has been locked. User login to the token is not
- * possible. */
-#define CKF_USER_PIN_LOCKED          0x00040000
-
-/* CKF_USER_PIN_TO_BE_CHANGED if new for v2.10. If it is true,
- * the user PIN value is the default value set by token
- * initialization or manufacturing, or the PIN has been
- * expired by the card. */
-#define CKF_USER_PIN_TO_BE_CHANGED   0x00080000
-
-/* CKF_SO_PIN_COUNT_LOW if new for v2.10. If it is true, an
- * incorrect SO login PIN has been entered at least once since
- * the last successful authentication. */
-#define CKF_SO_PIN_COUNT_LOW         0x00100000
-
-/* CKF_SO_PIN_FINAL_TRY if new for v2.10. If it is true,
- * supplying an incorrect SO PIN will it to become locked. */
-#define CKF_SO_PIN_FINAL_TRY         0x00200000
-
-/* CKF_SO_PIN_LOCKED if new for v2.10. If it is true, the SO
- * PIN has been locked. SO login to the token is not possible.
- */
-#define CKF_SO_PIN_LOCKED            0x00400000
-
-/* CKF_SO_PIN_TO_BE_CHANGED if new for v2.10. If it is true,
- * the SO PIN value is the default value set by token
- * initialization or manufacturing, or the PIN has been
- * expired by the card. */
-#define CKF_SO_PIN_TO_BE_CHANGED     0x00800000
-
-typedef CK_TOKEN_INFO CK_PTR CK_TOKEN_INFO_PTR;
-
-
-/* CK_SESSION_HANDLE is a Cryptoki-assigned value that
- * identifies a session */
-typedef CK_ULONG          CK_SESSION_HANDLE;
-
-typedef CK_SESSION_HANDLE CK_PTR CK_SESSION_HANDLE_PTR;
-
-
-/* CK_USER_TYPE enumerates the types of Cryptoki users */
-/* CK_USER_TYPE has been changed from an enum to a CK_ULONG for
- * v2.0 */
-typedef CK_ULONG          CK_USER_TYPE;
-/* Security Officer */
-#define CKU_SO    0
-/* Normal user */
-#define CKU_USER  1
-/* Context specific (added in v2.20) */
-#define CKU_CONTEXT_SPECIFIC   2
-
-/* CK_STATE enumerates the session states */
-/* CK_STATE has been changed from an enum to a CK_ULONG for
- * v2.0 */
-typedef CK_ULONG          CK_STATE;
-#define CKS_RO_PUBLIC_SESSION  0
-#define CKS_RO_USER_FUNCTIONS  1
-#define CKS_RW_PUBLIC_SESSION  2
-#define CKS_RW_USER_FUNCTIONS  3
-#define CKS_RW_SO_FUNCTIONS    4
-
-
-/* CK_SESSION_INFO provides information about a session */
-typedef struct CK_SESSION_INFO {
-  CK_SLOT_ID    slotID;
-  CK_STATE      state;
-  CK_FLAGS      flags;          /* see below */
-
-  /* ulDeviceError was changed from CK_USHORT to CK_ULONG for
-   * v2.0 */
-  CK_ULONG      ulDeviceError;  /* device-dependent error code */
-} CK_SESSION_INFO;
-
-/* The flags are defined in the following table:
- *      Bit Flag                Mask        Meaning
- */
-#define CKF_RW_SESSION          0x00000002  /* session is r/w */
-#define CKF_SERIAL_SESSION      0x00000004  /* no parallel */
-
-typedef CK_SESSION_INFO CK_PTR CK_SESSION_INFO_PTR;
-
-
-/* CK_OBJECT_HANDLE is a token-specific identifier for an
- * object  */
-typedef CK_ULONG          CK_OBJECT_HANDLE;
-
-typedef CK_OBJECT_HANDLE CK_PTR CK_OBJECT_HANDLE_PTR;
-
-
-/* CK_OBJECT_CLASS is a value that identifies the classes (or
- * types) of objects that Cryptoki recognizes.  It is defined
- * as follows: */
-/* CK_OBJECT_CLASS was changed from CK_USHORT to CK_ULONG for
- * v2.0 */
-typedef CK_ULONG          CK_OBJECT_CLASS;
-
-/* The following classes of objects are defined: */
-/* CKO_HW_FEATURE is new for v2.10 */
-/* CKO_DOMAIN_PARAMETERS is new for v2.11 */
-/* CKO_MECHANISM is new for v2.20 */
-#define CKO_DATA              0x00000000
-#define CKO_CERTIFICATE       0x00000001
-#define CKO_PUBLIC_KEY        0x00000002
-#define CKO_PRIVATE_KEY       0x00000003
-#define CKO_SECRET_KEY        0x00000004
-#define CKO_HW_FEATURE        0x00000005
-#define CKO_DOMAIN_PARAMETERS 0x00000006
-#define CKO_MECHANISM         0x00000007
-#define CKO_VENDOR_DEFINED    0x80000000
-
-typedef CK_OBJECT_CLASS CK_PTR CK_OBJECT_CLASS_PTR;
-
-/* CK_HW_FEATURE_TYPE is new for v2.10. CK_HW_FEATURE_TYPE is a
- * value that identifies the hardware feature type of an object
- * with CK_OBJECT_CLASS equal to CKO_HW_FEATURE. */
-typedef CK_ULONG          CK_HW_FEATURE_TYPE;
-
-/* The following hardware feature types are defined */
-/* CKH_USER_INTERFACE is new for v2.20 */
-#define CKH_MONOTONIC_COUNTER  0x00000001
-#define CKH_CLOCK           0x00000002
-#define CKH_USER_INTERFACE  0x00000003
-#define CKH_VENDOR_DEFINED  0x80000000
-
-/* CK_KEY_TYPE is a value that identifies a key type */
-/* CK_KEY_TYPE was changed from CK_USHORT to CK_ULONG for v2.0 */
-typedef CK_ULONG          CK_KEY_TYPE;
-
-/* the following key types are defined: */
-#define CKK_RSA             0x00000000
-#define CKK_DSA             0x00000001
-#define CKK_DH              0x00000002
-
-/* CKK_ECDSA and CKK_KEA are new for v2.0 */
-/* CKK_ECDSA is deprecated in v2.11, CKK_EC is preferred. */
-#define CKK_ECDSA           0x00000003
-#define CKK_EC              0x00000003
-#define CKK_X9_42_DH        0x00000004
-#define CKK_KEA             0x00000005
-
-#define CKK_GENERIC_SECRET  0x00000010
-#define CKK_RC2             0x00000011
-#define CKK_RC4             0x00000012
-#define CKK_DES             0x00000013
-#define CKK_DES2            0x00000014
-#define CKK_DES3            0x00000015
-
-/* all these key types are new for v2.0 */
-#define CKK_CAST            0x00000016
-#define CKK_CAST3           0x00000017
-/* CKK_CAST5 is deprecated in v2.11, CKK_CAST128 is preferred. */
-#define CKK_CAST5           0x00000018
-#define CKK_CAST128         0x00000018
-#define CKK_RC5             0x00000019
-#define CKK_IDEA            0x0000001A
-#define CKK_SKIPJACK        0x0000001B
-#define CKK_BATON           0x0000001C
-#define CKK_JUNIPER         0x0000001D
-#define CKK_CDMF            0x0000001E
-#define CKK_AES             0x0000001F
-
-/* BlowFish and TwoFish are new for v2.20 */
-#define CKK_BLOWFISH        0x00000020
-#define CKK_TWOFISH         0x00000021
-
-#define CKK_VENDOR_DEFINED  0x80000000
-
-
-/* CK_CERTIFICATE_TYPE is a value that identifies a certificate
- * type */
-/* CK_CERTIFICATE_TYPE was changed from CK_USHORT to CK_ULONG
- * for v2.0 */
-typedef CK_ULONG          CK_CERTIFICATE_TYPE;
-
-/* The following certificate types are defined: */
-/* CKC_X_509_ATTR_CERT is new for v2.10 */
-/* CKC_WTLS is new for v2.20 */
-#define CKC_X_509           0x00000000
-#define CKC_X_509_ATTR_CERT 0x00000001
-#define CKC_WTLS            0x00000002
-#define CKC_VENDOR_DEFINED  0x80000000
-
-
-/* CK_ATTRIBUTE_TYPE is a value that identifies an attribute
- * type */
-/* CK_ATTRIBUTE_TYPE was changed from CK_USHORT to CK_ULONG for
- * v2.0 */
-typedef CK_ULONG          CK_ATTRIBUTE_TYPE;
-
-/* The CKF_ARRAY_ATTRIBUTE flag identifies an attribute which
-   consists of an array of values. */
-#define CKF_ARRAY_ATTRIBUTE    0x40000000
-
-/* The following attribute types are defined: */
-#define CKA_CLASS              0x00000000
-#define CKA_TOKEN              0x00000001
-#define CKA_PRIVATE            0x00000002
-#define CKA_LABEL              0x00000003
-#define CKA_APPLICATION        0x00000010
-#define CKA_VALUE              0x00000011
-
-/* CKA_OBJECT_ID is new for v2.10 */
-#define CKA_OBJECT_ID          0x00000012
-
-#define CKA_CERTIFICATE_TYPE   0x00000080
-#define CKA_ISSUER             0x00000081
-#define CKA_SERIAL_NUMBER      0x00000082
-
-/* CKA_AC_ISSUER, CKA_OWNER, and CKA_ATTR_TYPES are new
- * for v2.10 */
-#define CKA_AC_ISSUER          0x00000083
-#define CKA_OWNER              0x00000084
-#define CKA_ATTR_TYPES         0x00000085
-
-/* CKA_TRUSTED is new for v2.11 */
-#define CKA_TRUSTED            0x00000086
-
-/* CKA_CERTIFICATE_CATEGORY ...
- * CKA_CHECK_VALUE are new for v2.20 */
-#define CKA_CERTIFICATE_CATEGORY        0x00000087
-#define CKA_JAVA_MIDP_SECURITY_DOMAIN   0x00000088
-#define CKA_URL                         0x00000089
-#define CKA_HASH_OF_SUBJECT_PUBLIC_KEY  0x0000008A
-#define CKA_HASH_OF_ISSUER_PUBLIC_KEY   0x0000008B
-#define CKA_CHECK_VALUE                 0x00000090
-
-#define CKA_KEY_TYPE           0x00000100
-#define CKA_SUBJECT            0x00000101
-#define CKA_ID                 0x00000102
-#define CKA_SENSITIVE          0x00000103
-#define CKA_ENCRYPT            0x00000104
-#define CKA_DECRYPT            0x00000105
-#define CKA_WRAP               0x00000106
-#define CKA_UNWRAP             0x00000107
-#define CKA_SIGN               0x00000108
-#define CKA_SIGN_RECOVER       0x00000109
-#define CKA_VERIFY             0x0000010A
-#define CKA_VERIFY_RECOVER     0x0000010B
-#define CKA_DERIVE             0x0000010C
-#define CKA_START_DATE         0x00000110
-#define CKA_END_DATE           0x00000111
-#define CKA_MODULUS            0x00000120
-#define CKA_MODULUS_BITS       0x00000121
-#define CKA_PUBLIC_EXPONENT    0x00000122
-#define CKA_PRIVATE_EXPONENT   0x00000123
-#define CKA_PRIME_1            0x00000124
-#define CKA_PRIME_2            0x00000125
-#define CKA_EXPONENT_1         0x00000126
-#define CKA_EXPONENT_2         0x00000127
-#define CKA_COEFFICIENT        0x00000128
-#define CKA_PRIME              0x00000130
-#define CKA_SUBPRIME           0x00000131
-#define CKA_BASE               0x00000132
-
-/* CKA_PRIME_BITS and CKA_SUB_PRIME_BITS are new for v2.11 */
-#define CKA_PRIME_BITS         0x00000133
-#define CKA_SUBPRIME_BITS      0x00000134
-#define CKA_SUB_PRIME_BITS     CKA_SUBPRIME_BITS
-/* (To retain backwards-compatibility) */
-
-#define CKA_VALUE_BITS         0x00000160
-#define CKA_VALUE_LEN          0x00000161
-
-/* CKA_EXTRACTABLE, CKA_LOCAL, CKA_NEVER_EXTRACTABLE,
- * CKA_ALWAYS_SENSITIVE, CKA_MODIFIABLE, CKA_ECDSA_PARAMS,
- * and CKA_EC_POINT are new for v2.0 */
-#define CKA_EXTRACTABLE        0x00000162
-#define CKA_LOCAL              0x00000163
-#define CKA_NEVER_EXTRACTABLE  0x00000164
-#define CKA_ALWAYS_SENSITIVE   0x00000165
-
-/* CKA_KEY_GEN_MECHANISM is new for v2.11 */
-#define CKA_KEY_GEN_MECHANISM  0x00000166
-
-#define CKA_MODIFIABLE         0x00000170
-
-/* CKA_ECDSA_PARAMS is deprecated in v2.11,
- * CKA_EC_PARAMS is preferred. */
-#define CKA_ECDSA_PARAMS       0x00000180
-#define CKA_EC_PARAMS          0x00000180
-
-#define CKA_EC_POINT           0x00000181
-
-/* CKA_SECONDARY_AUTH, CKA_AUTH_PIN_FLAGS,
- * are new for v2.10. Deprecated in v2.11 and onwards. */
-#define CKA_SECONDARY_AUTH     0x00000200
-#define CKA_AUTH_PIN_FLAGS     0x00000201
-
-/* CKA_ALWAYS_AUTHENTICATE ...
- * CKA_UNWRAP_TEMPLATE are new for v2.20 */
-#define CKA_ALWAYS_AUTHENTICATE  0x00000202
-
-#define CKA_WRAP_WITH_TRUSTED    0x00000210
-#define CKA_WRAP_TEMPLATE        (CKF_ARRAY_ATTRIBUTE|0x00000211)
-#define CKA_UNWRAP_TEMPLATE      (CKF_ARRAY_ATTRIBUTE|0x00000212)
-
-/* CKA_HW_FEATURE_TYPE, CKA_RESET_ON_INIT, and CKA_HAS_RESET
- * are new for v2.10 */
-#define CKA_HW_FEATURE_TYPE    0x00000300
-#define CKA_RESET_ON_INIT      0x00000301
-#define CKA_HAS_RESET          0x00000302
-
-/* The following attributes are new for v2.20 */
-#define CKA_PIXEL_X                     0x00000400
-#define CKA_PIXEL_Y                     0x00000401
-#define CKA_RESOLUTION                  0x00000402
-#define CKA_CHAR_ROWS                   0x00000403
-#define CKA_CHAR_COLUMNS                0x00000404
-#define CKA_COLOR                       0x00000405
-#define CKA_BITS_PER_PIXEL              0x00000406
-#define CKA_CHAR_SETS                   0x00000480
-#define CKA_ENCODING_METHODS            0x00000481
-#define CKA_MIME_TYPES                  0x00000482
-#define CKA_MECHANISM_TYPE              0x00000500
-#define CKA_REQUIRED_CMS_ATTRIBUTES     0x00000501
-#define CKA_DEFAULT_CMS_ATTRIBUTES      0x00000502
-#define CKA_SUPPORTED_CMS_ATTRIBUTES    0x00000503
-#define CKA_ALLOWED_MECHANISMS          (CKF_ARRAY_ATTRIBUTE|0x00000600)
-
-#define CKA_VENDOR_DEFINED     0x80000000
-
-
-/* CK_ATTRIBUTE is a structure that includes the type, length
- * and value of an attribute */
-typedef struct CK_ATTRIBUTE {
-  CK_ATTRIBUTE_TYPE type;
-  CK_VOID_PTR       pValue;
-
-  /* ulValueLen went from CK_USHORT to CK_ULONG for v2.0 */
-  CK_ULONG          ulValueLen;  /* in bytes */
-} CK_ATTRIBUTE;
-
-typedef CK_ATTRIBUTE CK_PTR CK_ATTRIBUTE_PTR;
-
-
-/* CK_DATE is a structure that defines a date */
-typedef struct CK_DATE{
-  CK_CHAR       year[4];   /* the year ("1900" - "9999") */
-  CK_CHAR       month[2];  /* the month ("01" - "12") */
-  CK_CHAR       day[2];    /* the day   ("01" - "31") */
-} CK_DATE;
-
-
-/* CK_MECHANISM_TYPE is a value that identifies a mechanism
- * type */
-/* CK_MECHANISM_TYPE was changed from CK_USHORT to CK_ULONG for
- * v2.0 */
-typedef CK_ULONG          CK_MECHANISM_TYPE;
-
-/* the following mechanism types are defined: */
-#define CKM_RSA_PKCS_KEY_PAIR_GEN      0x00000000
-#define CKM_RSA_PKCS                   0x00000001
-#define CKM_RSA_9796                   0x00000002
-#define CKM_RSA_X_509                  0x00000003
-
-/* CKM_MD2_RSA_PKCS, CKM_MD5_RSA_PKCS, and CKM_SHA1_RSA_PKCS
- * are new for v2.0.  They are mechanisms which hash and sign */
-#define CKM_MD2_RSA_PKCS               0x00000004
-#define CKM_MD5_RSA_PKCS               0x00000005
-#define CKM_SHA1_RSA_PKCS              0x00000006
-
-/* CKM_RIPEMD128_RSA_PKCS, CKM_RIPEMD160_RSA_PKCS, and
- * CKM_RSA_PKCS_OAEP are new for v2.10 */
-#define CKM_RIPEMD128_RSA_PKCS         0x00000007
-#define CKM_RIPEMD160_RSA_PKCS         0x00000008
-#define CKM_RSA_PKCS_OAEP              0x00000009
-
-/* CKM_RSA_X9_31_KEY_PAIR_GEN, CKM_RSA_X9_31, CKM_SHA1_RSA_X9_31,
- * CKM_RSA_PKCS_PSS, and CKM_SHA1_RSA_PKCS_PSS are new for v2.11 */
-#define CKM_RSA_X9_31_KEY_PAIR_GEN     0x0000000A
-#define CKM_RSA_X9_31                  0x0000000B
-#define CKM_SHA1_RSA_X9_31             0x0000000C
-#define CKM_RSA_PKCS_PSS               0x0000000D
-#define CKM_SHA1_RSA_PKCS_PSS          0x0000000E
-
-#define CKM_DSA_KEY_PAIR_GEN           0x00000010
-#define CKM_DSA                        0x00000011
-#define CKM_DSA_SHA1                   0x00000012
-#define CKM_DH_PKCS_KEY_PAIR_GEN       0x00000020
-#define CKM_DH_PKCS_DERIVE             0x00000021
-
-/* CKM_X9_42_DH_KEY_PAIR_GEN, CKM_X9_42_DH_DERIVE,
- * CKM_X9_42_DH_HYBRID_DERIVE, and CKM_X9_42_MQV_DERIVE are new for
- * v2.11 */
-#define CKM_X9_42_DH_KEY_PAIR_GEN      0x00000030
-#define CKM_X9_42_DH_DERIVE            0x00000031
-#define CKM_X9_42_DH_HYBRID_DERIVE     0x00000032
-#define CKM_X9_42_MQV_DERIVE           0x00000033
-
-/* CKM_SHA256/384/512 are new for v2.20 */
-#define CKM_SHA256_RSA_PKCS            0x00000040
-#define CKM_SHA384_RSA_PKCS            0x00000041
-#define CKM_SHA512_RSA_PKCS            0x00000042
-#define CKM_SHA256_RSA_PKCS_PSS        0x00000043
-#define CKM_SHA384_RSA_PKCS_PSS        0x00000044
-#define CKM_SHA512_RSA_PKCS_PSS        0x00000045
-
-#define CKM_RC2_KEY_GEN                0x00000100
-#define CKM_RC2_ECB                    0x00000101
-#define CKM_RC2_CBC                    0x00000102
-#define CKM_RC2_MAC                    0x00000103
-
-/* CKM_RC2_MAC_GENERAL and CKM_RC2_CBC_PAD are new for v2.0 */
-#define CKM_RC2_MAC_GENERAL            0x00000104
-#define CKM_RC2_CBC_PAD                0x00000105
-
-#define CKM_RC4_KEY_GEN                0x00000110
-#define CKM_RC4                        0x00000111
-#define CKM_DES_KEY_GEN                0x00000120
-#define CKM_DES_ECB                    0x00000121
-#define CKM_DES_CBC                    0x00000122
-#define CKM_DES_MAC                    0x00000123
-
-/* CKM_DES_MAC_GENERAL and CKM_DES_CBC_PAD are new for v2.0 */
-#define CKM_DES_MAC_GENERAL            0x00000124
-#define CKM_DES_CBC_PAD                0x00000125
-
-#define CKM_DES2_KEY_GEN               0x00000130
-#define CKM_DES3_KEY_GEN               0x00000131
-#define CKM_DES3_ECB                   0x00000132
-#define CKM_DES3_CBC                   0x00000133
-#define CKM_DES3_MAC                   0x00000134
-
-/* CKM_DES3_MAC_GENERAL, CKM_DES3_CBC_PAD, CKM_CDMF_KEY_GEN,
- * CKM_CDMF_ECB, CKM_CDMF_CBC, CKM_CDMF_MAC,
- * CKM_CDMF_MAC_GENERAL, and CKM_CDMF_CBC_PAD are new for v2.0 */
-#define CKM_DES3_MAC_GENERAL           0x00000135
-#define CKM_DES3_CBC_PAD               0x00000136
-#define CKM_CDMF_KEY_GEN               0x00000140
-#define CKM_CDMF_ECB                   0x00000141
-#define CKM_CDMF_CBC                   0x00000142
-#define CKM_CDMF_MAC                   0x00000143
-#define CKM_CDMF_MAC_GENERAL           0x00000144
-#define CKM_CDMF_CBC_PAD               0x00000145
-
-/* the following four DES mechanisms are new for v2.20 */
-#define CKM_DES_OFB64                  0x00000150
-#define CKM_DES_OFB8                   0x00000151
-#define CKM_DES_CFB64                  0x00000152
-#define CKM_DES_CFB8                   0x00000153
-
-#define CKM_MD2                        0x00000200
-
-/* CKM_MD2_HMAC and CKM_MD2_HMAC_GENERAL are new for v2.0 */
-#define CKM_MD2_HMAC                   0x00000201
-#define CKM_MD2_HMAC_GENERAL           0x00000202
-
-#define CKM_MD5                        0x00000210
-
-/* CKM_MD5_HMAC and CKM_MD5_HMAC_GENERAL are new for v2.0 */
-#define CKM_MD5_HMAC                   0x00000211
-#define CKM_MD5_HMAC_GENERAL           0x00000212
-
-#define CKM_SHA_1                      0x00000220
-
-/* CKM_SHA_1_HMAC and CKM_SHA_1_HMAC_GENERAL are new for v2.0 */
-#define CKM_SHA_1_HMAC                 0x00000221
-#define CKM_SHA_1_HMAC_GENERAL         0x00000222
-
-/* CKM_RIPEMD128, CKM_RIPEMD128_HMAC,
- * CKM_RIPEMD128_HMAC_GENERAL, CKM_RIPEMD160, CKM_RIPEMD160_HMAC,
- * and CKM_RIPEMD160_HMAC_GENERAL are new for v2.10 */
-#define CKM_RIPEMD128                  0x00000230
-#define CKM_RIPEMD128_HMAC             0x00000231
-#define CKM_RIPEMD128_HMAC_GENERAL     0x00000232
-#define CKM_RIPEMD160                  0x00000240
-#define CKM_RIPEMD160_HMAC             0x00000241
-#define CKM_RIPEMD160_HMAC_GENERAL     0x00000242
-
-/* CKM_SHA256/384/512 are new for v2.20 */
-#define CKM_SHA256                     0x00000250
-#define CKM_SHA256_HMAC                0x00000251
-#define CKM_SHA256_HMAC_GENERAL        0x00000252
-#define CKM_SHA384                     0x00000260
-#define CKM_SHA384_HMAC                0x00000261
-#define CKM_SHA384_HMAC_GENERAL        0x00000262
-#define CKM_SHA512                     0x00000270
-#define CKM_SHA512_HMAC                0x00000271
-#define CKM_SHA512_HMAC_GENERAL        0x00000272
-
-/* All of the following mechanisms are new for v2.0 */
-/* Note that CAST128 and CAST5 are the same algorithm */
-#define CKM_CAST_KEY_GEN               0x00000300
-#define CKM_CAST_ECB                   0x00000301
-#define CKM_CAST_CBC                   0x00000302
-#define CKM_CAST_MAC                   0x00000303
-#define CKM_CAST_MAC_GENERAL           0x00000304
-#define CKM_CAST_CBC_PAD               0x00000305
-#define CKM_CAST3_KEY_GEN              0x00000310
-#define CKM_CAST3_ECB                  0x00000311
-#define CKM_CAST3_CBC                  0x00000312
-#define CKM_CAST3_MAC                  0x00000313
-#define CKM_CAST3_MAC_GENERAL          0x00000314
-#define CKM_CAST3_CBC_PAD              0x00000315
-#define CKM_CAST5_KEY_GEN              0x00000320
-#define CKM_CAST128_KEY_GEN            0x00000320
-#define CKM_CAST5_ECB                  0x00000321
-#define CKM_CAST128_ECB                0x00000321
-#define CKM_CAST5_CBC                  0x00000322
-#define CKM_CAST128_CBC                0x00000322
-#define CKM_CAST5_MAC                  0x00000323
-#define CKM_CAST128_MAC                0x00000323
-#define CKM_CAST5_MAC_GENERAL          0x00000324
-#define CKM_CAST128_MAC_GENERAL        0x00000324
-#define CKM_CAST5_CBC_PAD              0x00000325
-#define CKM_CAST128_CBC_PAD            0x00000325
-#define CKM_RC5_KEY_GEN                0x00000330
-#define CKM_RC5_ECB                    0x00000331
-#define CKM_RC5_CBC                    0x00000332
-#define CKM_RC5_MAC                    0x00000333
-#define CKM_RC5_MAC_GENERAL            0x00000334
-#define CKM_RC5_CBC_PAD                0x00000335
-#define CKM_IDEA_KEY_GEN               0x00000340
-#define CKM_IDEA_ECB                   0x00000341
-#define CKM_IDEA_CBC                   0x00000342
-#define CKM_IDEA_MAC                   0x00000343
-#define CKM_IDEA_MAC_GENERAL           0x00000344
-#define CKM_IDEA_CBC_PAD               0x00000345
-#define CKM_GENERIC_SECRET_KEY_GEN     0x00000350
-#define CKM_CONCATENATE_BASE_AND_KEY   0x00000360
-#define CKM_CONCATENATE_BASE_AND_DATA  0x00000362
-#define CKM_CONCATENATE_DATA_AND_BASE  0x00000363
-#define CKM_XOR_BASE_AND_DATA          0x00000364
-#define CKM_EXTRACT_KEY_FROM_KEY       0x00000365
-#define CKM_SSL3_PRE_MASTER_KEY_GEN    0x00000370
-#define CKM_SSL3_MASTER_KEY_DERIVE     0x00000371
-#define CKM_SSL3_KEY_AND_MAC_DERIVE    0x00000372
-
-/* CKM_SSL3_MASTER_KEY_DERIVE_DH, CKM_TLS_PRE_MASTER_KEY_GEN,
- * CKM_TLS_MASTER_KEY_DERIVE, CKM_TLS_KEY_AND_MAC_DERIVE, and
- * CKM_TLS_MASTER_KEY_DERIVE_DH are new for v2.11 */
-#define CKM_SSL3_MASTER_KEY_DERIVE_DH  0x00000373
-#define CKM_TLS_PRE_MASTER_KEY_GEN     0x00000374
-#define CKM_TLS_MASTER_KEY_DERIVE      0x00000375
-#define CKM_TLS_KEY_AND_MAC_DERIVE     0x00000376
-#define CKM_TLS_MASTER_KEY_DERIVE_DH   0x00000377
-
-/* CKM_TLS_PRF is new for v2.20 */
-#define CKM_TLS_PRF                    0x00000378
-
-#define CKM_SSL3_MD5_MAC               0x00000380
-#define CKM_SSL3_SHA1_MAC              0x00000381
-#define CKM_MD5_KEY_DERIVATION         0x00000390
-#define CKM_MD2_KEY_DERIVATION         0x00000391
-#define CKM_SHA1_KEY_DERIVATION        0x00000392
-
-/* CKM_SHA256/384/512 are new for v2.20 */
-#define CKM_SHA256_KEY_DERIVATION      0x00000393
-#define CKM_SHA384_KEY_DERIVATION      0x00000394
-#define CKM_SHA512_KEY_DERIVATION      0x00000395
-
-#define CKM_PBE_MD2_DES_CBC            0x000003A0
-#define CKM_PBE_MD5_DES_CBC            0x000003A1
-#define CKM_PBE_MD5_CAST_CBC           0x000003A2
-#define CKM_PBE_MD5_CAST3_CBC          0x000003A3
-#define CKM_PBE_MD5_CAST5_CBC          0x000003A4
-#define CKM_PBE_MD5_CAST128_CBC        0x000003A4
-#define CKM_PBE_SHA1_CAST5_CBC         0x000003A5
-#define CKM_PBE_SHA1_CAST128_CBC       0x000003A5
-#define CKM_PBE_SHA1_RC4_128           0x000003A6
-#define CKM_PBE_SHA1_RC4_40            0x000003A7
-#define CKM_PBE_SHA1_DES3_EDE_CBC      0x000003A8
-#define CKM_PBE_SHA1_DES2_EDE_CBC      0x000003A9
-#define CKM_PBE_SHA1_RC2_128_CBC       0x000003AA
-#define CKM_PBE_SHA1_RC2_40_CBC        0x000003AB
-
-/* CKM_PKCS5_PBKD2 is new for v2.10 */
-#define CKM_PKCS5_PBKD2                0x000003B0
-
-#define CKM_PBA_SHA1_WITH_SHA1_HMAC    0x000003C0
-
-/* WTLS mechanisms are new for v2.20 */
-#define CKM_WTLS_PRE_MASTER_KEY_GEN         0x000003D0
-#define CKM_WTLS_MASTER_KEY_DERIVE          0x000003D1
-#define CKM_WTLS_MASTER_KEY_DERIVE_DH_ECC   0x000003D2
-#define CKM_WTLS_PRF                        0x000003D3
-#define CKM_WTLS_SERVER_KEY_AND_MAC_DERIVE  0x000003D4
-#define CKM_WTLS_CLIENT_KEY_AND_MAC_DERIVE  0x000003D5
-
-#define CKM_KEY_WRAP_LYNKS             0x00000400
-#define CKM_KEY_WRAP_SET_OAEP          0x00000401
-
-/* CKM_CMS_SIG is new for v2.20 */
-#define CKM_CMS_SIG                    0x00000500
-
-/* Fortezza mechanisms */
-#define CKM_SKIPJACK_KEY_GEN           0x00001000
-#define CKM_SKIPJACK_ECB64             0x00001001
-#define CKM_SKIPJACK_CBC64             0x00001002
-#define CKM_SKIPJACK_OFB64             0x00001003
-#define CKM_SKIPJACK_CFB64             0x00001004
-#define CKM_SKIPJACK_CFB32             0x00001005
-#define CKM_SKIPJACK_CFB16             0x00001006
-#define CKM_SKIPJACK_CFB8              0x00001007
-#define CKM_SKIPJACK_WRAP              0x00001008
-#define CKM_SKIPJACK_PRIVATE_WRAP      0x00001009
-#define CKM_SKIPJACK_RELAYX            0x0000100a
-#define CKM_KEA_KEY_PAIR_GEN           0x00001010
-#define CKM_KEA_KEY_DERIVE             0x00001011
-#define CKM_FORTEZZA_TIMESTAMP         0x00001020
-#define CKM_BATON_KEY_GEN              0x00001030
-#define CKM_BATON_ECB128               0x00001031
-#define CKM_BATON_ECB96                0x00001032
-#define CKM_BATON_CBC128               0x00001033
-#define CKM_BATON_COUNTER              0x00001034
-#define CKM_BATON_SHUFFLE              0x00001035
-#define CKM_BATON_WRAP                 0x00001036
-
-/* CKM_ECDSA_KEY_PAIR_GEN is deprecated in v2.11,
- * CKM_EC_KEY_PAIR_GEN is preferred */
-#define CKM_ECDSA_KEY_PAIR_GEN         0x00001040
-#define CKM_EC_KEY_PAIR_GEN            0x00001040
-
-#define CKM_ECDSA                      0x00001041
-#define CKM_ECDSA_SHA1                 0x00001042
-
-/* CKM_ECDH1_DERIVE, CKM_ECDH1_COFACTOR_DERIVE, and CKM_ECMQV_DERIVE
- * are new for v2.11 */
-#define CKM_ECDH1_DERIVE               0x00001050
-#define CKM_ECDH1_COFACTOR_DERIVE      0x00001051
-#define CKM_ECMQV_DERIVE               0x00001052
-
-#define CKM_JUNIPER_KEY_GEN            0x00001060
-#define CKM_JUNIPER_ECB128             0x00001061
-#define CKM_JUNIPER_CBC128             0x00001062
-#define CKM_JUNIPER_COUNTER            0x00001063
-#define CKM_JUNIPER_SHUFFLE            0x00001064
-#define CKM_JUNIPER_WRAP               0x00001065
-#define CKM_FASTHASH                   0x00001070
-
-/* CKM_AES_KEY_GEN, CKM_AES_ECB, CKM_AES_CBC, CKM_AES_MAC,
- * CKM_AES_MAC_GENERAL, CKM_AES_CBC_PAD, CKM_DSA_PARAMETER_GEN,
- * CKM_DH_PKCS_PARAMETER_GEN, and CKM_X9_42_DH_PARAMETER_GEN are
- * new for v2.11 */
-#define CKM_AES_KEY_GEN                0x00001080
-#define CKM_AES_ECB                    0x00001081
-#define CKM_AES_CBC                    0x00001082
-#define CKM_AES_MAC                    0x00001083
-#define CKM_AES_MAC_GENERAL            0x00001084
-#define CKM_AES_CBC_PAD                0x00001085
-
-/* BlowFish and TwoFish are new for v2.20 */
-#define CKM_BLOWFISH_KEY_GEN           0x00001090
-#define CKM_BLOWFISH_CBC               0x00001091
-#define CKM_TWOFISH_KEY_GEN            0x00001092
-#define CKM_TWOFISH_CBC                0x00001093
-
-
-/* CKM_xxx_ENCRYPT_DATA mechanisms are new for v2.20 */
-#define CKM_DES_ECB_ENCRYPT_DATA       0x00001100
-#define CKM_DES_CBC_ENCRYPT_DATA       0x00001101
-#define CKM_DES3_ECB_ENCRYPT_DATA      0x00001102
-#define CKM_DES3_CBC_ENCRYPT_DATA      0x00001103
-#define CKM_AES_ECB_ENCRYPT_DATA       0x00001104
-#define CKM_AES_CBC_ENCRYPT_DATA       0x00001105
-
-#define CKM_DSA_PARAMETER_GEN          0x00002000
-#define CKM_DH_PKCS_PARAMETER_GEN      0x00002001
-#define CKM_X9_42_DH_PARAMETER_GEN     0x00002002
-
-#define CKM_VENDOR_DEFINED             0x80000000
-
-typedef CK_MECHANISM_TYPE CK_PTR CK_MECHANISM_TYPE_PTR;
-
-
-/* CK_MECHANISM is a structure that specifies a particular
- * mechanism  */
-typedef struct CK_MECHANISM {
-  CK_MECHANISM_TYPE mechanism;
-  CK_VOID_PTR       pParameter;
-
-  /* ulParameterLen was changed from CK_USHORT to CK_ULONG for
-   * v2.0 */
-  CK_ULONG          ulParameterLen;  /* in bytes */
-} CK_MECHANISM;
-
-typedef CK_MECHANISM CK_PTR CK_MECHANISM_PTR;
-
-
-/* CK_MECHANISM_INFO provides information about a particular
- * mechanism */
-typedef struct CK_MECHANISM_INFO {
-    CK_ULONG    ulMinKeySize;
-    CK_ULONG    ulMaxKeySize;
-    CK_FLAGS    flags;
-} CK_MECHANISM_INFO;
-
-/* The flags are defined as follows:
- *      Bit Flag               Mask        Meaning */
-#define CKF_HW                 0x00000001  /* performed by HW */
-
-/* The flags CKF_ENCRYPT, CKF_DECRYPT, CKF_DIGEST, CKF_SIGN,
- * CKG_SIGN_RECOVER, CKF_VERIFY, CKF_VERIFY_RECOVER,
- * CKF_GENERATE, CKF_GENERATE_KEY_PAIR, CKF_WRAP, CKF_UNWRAP,
- * and CKF_DERIVE are new for v2.0.  They specify whether or not
- * a mechanism can be used for a particular task */
-#define CKF_ENCRYPT            0x00000100
-#define CKF_DECRYPT            0x00000200
-#define CKF_DIGEST             0x00000400
-#define CKF_SIGN               0x00000800
-#define CKF_SIGN_RECOVER       0x00001000
-#define CKF_VERIFY             0x00002000
-#define CKF_VERIFY_RECOVER     0x00004000
-#define CKF_GENERATE           0x00008000
-#define CKF_GENERATE_KEY_PAIR  0x00010000
-#define CKF_WRAP               0x00020000
-#define CKF_UNWRAP             0x00040000
-#define CKF_DERIVE             0x00080000
-
-/* CKF_EC_F_P, CKF_EC_F_2M, CKF_EC_ECPARAMETERS, CKF_EC_NAMEDCURVE,
- * CKF_EC_UNCOMPRESS, and CKF_EC_COMPRESS are new for v2.11. They
- * describe a token's EC capabilities not available in mechanism
- * information. */
-#define CKF_EC_F_P             0x00100000
-#define CKF_EC_F_2M            0x00200000
-#define CKF_EC_ECPARAMETERS    0x00400000
-#define CKF_EC_NAMEDCURVE      0x00800000
-#define CKF_EC_UNCOMPRESS      0x01000000
-#define CKF_EC_COMPRESS        0x02000000
-
-#define CKF_EXTENSION          0x80000000 /* FALSE for this version */
-
-typedef CK_MECHANISM_INFO CK_PTR CK_MECHANISM_INFO_PTR;
-
-
-/* CK_RV is a value that identifies the return value of a
- * Cryptoki function */
-/* CK_RV was changed from CK_USHORT to CK_ULONG for v2.0 */
-typedef CK_ULONG          CK_RV;
-
-#define CKR_OK                                0x00000000
-#define CKR_CANCEL                            0x00000001
-#define CKR_HOST_MEMORY                       0x00000002
-#define CKR_SLOT_ID_INVALID                   0x00000003
-
-/* CKR_FLAGS_INVALID was removed for v2.0 */
-
-/* CKR_GENERAL_ERROR and CKR_FUNCTION_FAILED are new for v2.0 */
-#define CKR_GENERAL_ERROR                     0x00000005
-#define CKR_FUNCTION_FAILED                   0x00000006
-
-/* CKR_ARGUMENTS_BAD, CKR_NO_EVENT, CKR_NEED_TO_CREATE_THREADS,
- * and CKR_CANT_LOCK are new for v2.01 */
-#define CKR_ARGUMENTS_BAD                     0x00000007
-#define CKR_NO_EVENT                          0x00000008
-#define CKR_NEED_TO_CREATE_THREADS            0x00000009
-#define CKR_CANT_LOCK                         0x0000000A
-
-#define CKR_ATTRIBUTE_READ_ONLY               0x00000010
-#define CKR_ATTRIBUTE_SENSITIVE               0x00000011
-#define CKR_ATTRIBUTE_TYPE_INVALID            0x00000012
-#define CKR_ATTRIBUTE_VALUE_INVALID           0x00000013
-#define CKR_DATA_INVALID                      0x00000020
-#define CKR_DATA_LEN_RANGE                    0x00000021
-#define CKR_DEVICE_ERROR                      0x00000030
-#define CKR_DEVICE_MEMORY                     0x00000031
-#define CKR_DEVICE_REMOVED                    0x00000032
-#define CKR_ENCRYPTED_DATA_INVALID            0x00000040
-#define CKR_ENCRYPTED_DATA_LEN_RANGE          0x00000041
-#define CKR_FUNCTION_CANCELED                 0x00000050
-#define CKR_FUNCTION_NOT_PARALLEL             0x00000051
-
-/* CKR_FUNCTION_NOT_SUPPORTED is new for v2.0 */
-#define CKR_FUNCTION_NOT_SUPPORTED            0x00000054
-
-#define CKR_KEY_HANDLE_INVALID                0x00000060
-
-/* CKR_KEY_SENSITIVE was removed for v2.0 */
-
-#define CKR_KEY_SIZE_RANGE                    0x00000062
-#define CKR_KEY_TYPE_INCONSISTENT             0x00000063
-
-/* CKR_KEY_NOT_NEEDED, CKR_KEY_CHANGED, CKR_KEY_NEEDED,
- * CKR_KEY_INDIGESTIBLE, CKR_KEY_FUNCTION_NOT_PERMITTED,
- * CKR_KEY_NOT_WRAPPABLE, and CKR_KEY_UNEXTRACTABLE are new for
- * v2.0 */
-#define CKR_KEY_NOT_NEEDED                    0x00000064
-#define CKR_KEY_CHANGED                       0x00000065
-#define CKR_KEY_NEEDED                        0x00000066
-#define CKR_KEY_INDIGESTIBLE                  0x00000067
-#define CKR_KEY_FUNCTION_NOT_PERMITTED        0x00000068
-#define CKR_KEY_NOT_WRAPPABLE                 0x00000069
-#define CKR_KEY_UNEXTRACTABLE                 0x0000006A
-
-#define CKR_MECHANISM_INVALID                 0x00000070
-#define CKR_MECHANISM_PARAM_INVALID           0x00000071
-
-/* CKR_OBJECT_CLASS_INCONSISTENT and CKR_OBJECT_CLASS_INVALID
- * were removed for v2.0 */
-#define CKR_OBJECT_HANDLE_INVALID             0x00000082
-#define CKR_OPERATION_ACTIVE                  0x00000090
-#define CKR_OPERATION_NOT_INITIALIZED         0x00000091
-#define CKR_PIN_INCORRECT                     0x000000A0
-#define CKR_PIN_INVALID                       0x000000A1
-#define CKR_PIN_LEN_RANGE                     0x000000A2
-
-/* CKR_PIN_EXPIRED and CKR_PIN_LOCKED are new for v2.0 */
-#define CKR_PIN_EXPIRED                       0x000000A3
-#define CKR_PIN_LOCKED                        0x000000A4
-
-#define CKR_SESSION_CLOSED                    0x000000B0
-#define CKR_SESSION_COUNT                     0x000000B1
-#define CKR_SESSION_HANDLE_INVALID            0x000000B3
-#define CKR_SESSION_PARALLEL_NOT_SUPPORTED    0x000000B4
-#define CKR_SESSION_READ_ONLY                 0x000000B5
-#define CKR_SESSION_EXISTS                    0x000000B6
-
-/* CKR_SESSION_READ_ONLY_EXISTS and
- * CKR_SESSION_READ_WRITE_SO_EXISTS are new for v2.0 */
-#define CKR_SESSION_READ_ONLY_EXISTS          0x000000B7
-#define CKR_SESSION_READ_WRITE_SO_EXISTS      0x000000B8
-
-#define CKR_SIGNATURE_INVALID                 0x000000C0
-#define CKR_SIGNATURE_LEN_RANGE               0x000000C1
-#define CKR_TEMPLATE_INCOMPLETE               0x000000D0
-#define CKR_TEMPLATE_INCONSISTENT             0x000000D1
-#define CKR_TOKEN_NOT_PRESENT                 0x000000E0
-#define CKR_TOKEN_NOT_RECOGNIZED              0x000000E1
-#define CKR_TOKEN_WRITE_PROTECTED             0x000000E2
-#define CKR_UNWRAPPING_KEY_HANDLE_INVALID     0x000000F0
-#define CKR_UNWRAPPING_KEY_SIZE_RANGE         0x000000F1
-#define CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT  0x000000F2
-#define CKR_USER_ALREADY_LOGGED_IN            0x00000100
-#define CKR_USER_NOT_LOGGED_IN                0x00000101
-#define CKR_USER_PIN_NOT_INITIALIZED          0x00000102
-#define CKR_USER_TYPE_INVALID                 0x00000103
-
-/* CKR_USER_ANOTHER_ALREADY_LOGGED_IN and CKR_USER_TOO_MANY_TYPES
- * are new to v2.01 */
-#define CKR_USER_ANOTHER_ALREADY_LOGGED_IN    0x00000104
-#define CKR_USER_TOO_MANY_TYPES               0x00000105
-
-#define CKR_WRAPPED_KEY_INVALID               0x00000110
-#define CKR_WRAPPED_KEY_LEN_RANGE             0x00000112
-#define CKR_WRAPPING_KEY_HANDLE_INVALID       0x00000113
-#define CKR_WRAPPING_KEY_SIZE_RANGE           0x00000114
-#define CKR_WRAPPING_KEY_TYPE_INCONSISTENT    0x00000115
-#define CKR_RANDOM_SEED_NOT_SUPPORTED         0x00000120
-
-/* These are new to v2.0 */
-#define CKR_RANDOM_NO_RNG                     0x00000121
-
-/* These are new to v2.11 */
-#define CKR_DOMAIN_PARAMS_INVALID             0x00000130
-
-/* These are new to v2.0 */
-#define CKR_BUFFER_TOO_SMALL                  0x00000150
-#define CKR_SAVED_STATE_INVALID               0x00000160
-#define CKR_INFORMATION_SENSITIVE             0x00000170
-#define CKR_STATE_UNSAVEABLE                  0x00000180
-
-/* These are new to v2.01 */
-#define CKR_CRYPTOKI_NOT_INITIALIZED          0x00000190
-#define CKR_CRYPTOKI_ALREADY_INITIALIZED      0x00000191
-#define CKR_MUTEX_BAD                         0x000001A0
-#define CKR_MUTEX_NOT_LOCKED                  0x000001A1
-
-/* This is new to v2.20 */
-#define CKR_FUNCTION_REJECTED                 0x00000200
-
-#define CKR_VENDOR_DEFINED                    0x80000000
-
-
-/* CK_NOTIFY is an application callback that processes events */
-typedef CK_CALLBACK_FUNCTION(CK_RV, CK_NOTIFY)(
-  CK_SESSION_HANDLE hSession,     /* the session's handle */
-  CK_NOTIFICATION   event,
-  CK_VOID_PTR       pApplication  /* passed to C_OpenSession */
-);
-
-
-/* CK_FUNCTION_LIST is a structure holding a Cryptoki spec
- * version and pointers of appropriate types to all the
- * Cryptoki functions */
-/* CK_FUNCTION_LIST is new for v2.0 */
-typedef struct CK_FUNCTION_LIST CK_FUNCTION_LIST;
-
-typedef CK_FUNCTION_LIST CK_PTR CK_FUNCTION_LIST_PTR;
-
-typedef CK_FUNCTION_LIST_PTR CK_PTR CK_FUNCTION_LIST_PTR_PTR;
-
-
-/* CK_CREATEMUTEX is an application callback for creating a
- * mutex object */
-typedef CK_CALLBACK_FUNCTION(CK_RV, CK_CREATEMUTEX)(
-  CK_VOID_PTR_PTR ppMutex  /* location to receive ptr to mutex */
-);
-
-
-/* CK_DESTROYMUTEX is an application callback for destroying a
- * mutex object */
-typedef CK_CALLBACK_FUNCTION(CK_RV, CK_DESTROYMUTEX)(
-  CK_VOID_PTR pMutex  /* pointer to mutex */
-);
-
-
-/* CK_LOCKMUTEX is an application callback for locking a mutex */
-typedef CK_CALLBACK_FUNCTION(CK_RV, CK_LOCKMUTEX)(
-  CK_VOID_PTR pMutex  /* pointer to mutex */
-);
-
-
-/* CK_UNLOCKMUTEX is an application callback for unlocking a
- * mutex */
-typedef CK_CALLBACK_FUNCTION(CK_RV, CK_UNLOCKMUTEX)(
-  CK_VOID_PTR pMutex  /* pointer to mutex */
-);
-
-
-/* CK_C_INITIALIZE_ARGS provides the optional arguments to
- * C_Initialize */
-typedef struct CK_C_INITIALIZE_ARGS {
-  CK_CREATEMUTEX CreateMutex;
-  CK_DESTROYMUTEX DestroyMutex;
-  CK_LOCKMUTEX LockMutex;
-  CK_UNLOCKMUTEX UnlockMutex;
-  CK_FLAGS flags;
-  CK_VOID_PTR pReserved;
-} CK_C_INITIALIZE_ARGS;
-
-/* flags: bit flags that provide capabilities of the slot
- *      Bit Flag                           Mask       Meaning
- */
-#define CKF_LIBRARY_CANT_CREATE_OS_THREADS 0x00000001
-#define CKF_OS_LOCKING_OK                  0x00000002
-
-typedef CK_C_INITIALIZE_ARGS CK_PTR CK_C_INITIALIZE_ARGS_PTR;
-
-
-/* additional flags for parameters to functions */
-
-/* CKF_DONT_BLOCK is for the function C_WaitForSlotEvent */
-#define CKF_DONT_BLOCK     1
-
-/* CK_RSA_PKCS_OAEP_MGF_TYPE is new for v2.10.
- * CK_RSA_PKCS_OAEP_MGF_TYPE  is used to indicate the Message
- * Generation Function (MGF) applied to a message block when
- * formatting a message block for the PKCS #1 OAEP encryption
- * scheme. */
-typedef CK_ULONG CK_RSA_PKCS_MGF_TYPE;
-
-typedef CK_RSA_PKCS_MGF_TYPE CK_PTR CK_RSA_PKCS_MGF_TYPE_PTR;
-
-/* The following MGFs are defined */
-/* CKG_MGF1_SHA256, CKG_MGF1_SHA384, and CKG_MGF1_SHA512
- * are new for v2.20 */
-#define CKG_MGF1_SHA1         0x00000001
-#define CKG_MGF1_SHA256       0x00000002
-#define CKG_MGF1_SHA384       0x00000003
-#define CKG_MGF1_SHA512       0x00000004
-
-/* CK_RSA_PKCS_OAEP_SOURCE_TYPE is new for v2.10.
- * CK_RSA_PKCS_OAEP_SOURCE_TYPE  is used to indicate the source
- * of the encoding parameter when formatting a message block
- * for the PKCS #1 OAEP encryption scheme. */
-typedef CK_ULONG CK_RSA_PKCS_OAEP_SOURCE_TYPE;
-
-typedef CK_RSA_PKCS_OAEP_SOURCE_TYPE CK_PTR CK_RSA_PKCS_OAEP_SOURCE_TYPE_PTR;
-
-/* The following encoding parameter sources are defined */
-#define CKZ_DATA_SPECIFIED    0x00000001
-
-/* CK_RSA_PKCS_OAEP_PARAMS is new for v2.10.
- * CK_RSA_PKCS_OAEP_PARAMS provides the parameters to the
- * CKM_RSA_PKCS_OAEP mechanism. */
-typedef struct CK_RSA_PKCS_OAEP_PARAMS {
-        CK_MECHANISM_TYPE hashAlg;
-        CK_RSA_PKCS_MGF_TYPE mgf;
-        CK_RSA_PKCS_OAEP_SOURCE_TYPE source;
-        CK_VOID_PTR pSourceData;
-        CK_ULONG ulSourceDataLen;
-} CK_RSA_PKCS_OAEP_PARAMS;
-
-typedef CK_RSA_PKCS_OAEP_PARAMS CK_PTR CK_RSA_PKCS_OAEP_PARAMS_PTR;
-
-/* CK_RSA_PKCS_PSS_PARAMS is new for v2.11.
- * CK_RSA_PKCS_PSS_PARAMS provides the parameters to the
- * CKM_RSA_PKCS_PSS mechanism(s). */
-typedef struct CK_RSA_PKCS_PSS_PARAMS {
-        CK_MECHANISM_TYPE    hashAlg;
-        CK_RSA_PKCS_MGF_TYPE mgf;
-        CK_ULONG             sLen;
-} CK_RSA_PKCS_PSS_PARAMS;
-
-typedef CK_RSA_PKCS_PSS_PARAMS CK_PTR CK_RSA_PKCS_PSS_PARAMS_PTR;
-
-/* CK_EC_KDF_TYPE is new for v2.11. */
-typedef CK_ULONG CK_EC_KDF_TYPE;
-
-/* The following EC Key Derivation Functions are defined */
-#define CKD_NULL                 0x00000001
-#define CKD_SHA1_KDF             0x00000002
-
-/* CK_ECDH1_DERIVE_PARAMS is new for v2.11.
- * CK_ECDH1_DERIVE_PARAMS provides the parameters to the
- * CKM_ECDH1_DERIVE and CKM_ECDH1_COFACTOR_DERIVE mechanisms,
- * where each party contributes one key pair.
- */
-typedef struct CK_ECDH1_DERIVE_PARAMS {
-  CK_EC_KDF_TYPE kdf;
-  CK_ULONG ulSharedDataLen;
-  CK_BYTE_PTR pSharedData;
-  CK_ULONG ulPublicDataLen;
-  CK_BYTE_PTR pPublicData;
-} CK_ECDH1_DERIVE_PARAMS;
-
-typedef CK_ECDH1_DERIVE_PARAMS CK_PTR CK_ECDH1_DERIVE_PARAMS_PTR;
-
-
-/* CK_ECDH2_DERIVE_PARAMS is new for v2.11.
- * CK_ECDH2_DERIVE_PARAMS provides the parameters to the
- * CKM_ECMQV_DERIVE mechanism, where each party contributes two key pairs. */
-typedef struct CK_ECDH2_DERIVE_PARAMS {
-  CK_EC_KDF_TYPE kdf;
-  CK_ULONG ulSharedDataLen;
-  CK_BYTE_PTR pSharedData;
-  CK_ULONG ulPublicDataLen;
-  CK_BYTE_PTR pPublicData;
-  CK_ULONG ulPrivateDataLen;
-  CK_OBJECT_HANDLE hPrivateData;
-  CK_ULONG ulPublicDataLen2;
-  CK_BYTE_PTR pPublicData2;
-} CK_ECDH2_DERIVE_PARAMS;
-
-typedef CK_ECDH2_DERIVE_PARAMS CK_PTR CK_ECDH2_DERIVE_PARAMS_PTR;
-
-typedef struct CK_ECMQV_DERIVE_PARAMS {
-  CK_EC_KDF_TYPE kdf;
-  CK_ULONG ulSharedDataLen;
-  CK_BYTE_PTR pSharedData;
-  CK_ULONG ulPublicDataLen;
-  CK_BYTE_PTR pPublicData;
-  CK_ULONG ulPrivateDataLen;
-  CK_OBJECT_HANDLE hPrivateData;
-  CK_ULONG ulPublicDataLen2;
-  CK_BYTE_PTR pPublicData2;
-  CK_OBJECT_HANDLE publicKey;
-} CK_ECMQV_DERIVE_PARAMS;
-
-typedef CK_ECMQV_DERIVE_PARAMS CK_PTR CK_ECMQV_DERIVE_PARAMS_PTR;
-
-/* Typedefs and defines for the CKM_X9_42_DH_KEY_PAIR_GEN and the
- * CKM_X9_42_DH_PARAMETER_GEN mechanisms (new for PKCS #11 v2.11) */
-typedef CK_ULONG CK_X9_42_DH_KDF_TYPE;
-typedef CK_X9_42_DH_KDF_TYPE CK_PTR CK_X9_42_DH_KDF_TYPE_PTR;
-
-/* The following X9.42 DH key derivation functions are defined
-   (besides CKD_NULL already defined : */
-#define CKD_SHA1_KDF_ASN1        0x00000003
-#define CKD_SHA1_KDF_CONCATENATE 0x00000004
-
-/* CK_X9_42_DH1_DERIVE_PARAMS is new for v2.11.
- * CK_X9_42_DH1_DERIVE_PARAMS provides the parameters to the
- * CKM_X9_42_DH_DERIVE key derivation mechanism, where each party
- * contributes one key pair */
-typedef struct CK_X9_42_DH1_DERIVE_PARAMS {
-  CK_X9_42_DH_KDF_TYPE kdf;
-  CK_ULONG ulOtherInfoLen;
-  CK_BYTE_PTR pOtherInfo;
-  CK_ULONG ulPublicDataLen;
-  CK_BYTE_PTR pPublicData;
-} CK_X9_42_DH1_DERIVE_PARAMS;
-
-typedef struct CK_X9_42_DH1_DERIVE_PARAMS CK_PTR CK_X9_42_DH1_DERIVE_PARAMS_PTR;
-
-/* CK_X9_42_DH2_DERIVE_PARAMS is new for v2.11.
- * CK_X9_42_DH2_DERIVE_PARAMS provides the parameters to the
- * CKM_X9_42_DH_HYBRID_DERIVE and CKM_X9_42_MQV_DERIVE key derivation
- * mechanisms, where each party contributes two key pairs */
-typedef struct CK_X9_42_DH2_DERIVE_PARAMS {
-  CK_X9_42_DH_KDF_TYPE kdf;
-  CK_ULONG ulOtherInfoLen;
-  CK_BYTE_PTR pOtherInfo;
-  CK_ULONG ulPublicDataLen;
-  CK_BYTE_PTR pPublicData;
-  CK_ULONG ulPrivateDataLen;
-  CK_OBJECT_HANDLE hPrivateData;
-  CK_ULONG ulPublicDataLen2;
-  CK_BYTE_PTR pPublicData2;
-} CK_X9_42_DH2_DERIVE_PARAMS;
-
-typedef CK_X9_42_DH2_DERIVE_PARAMS CK_PTR CK_X9_42_DH2_DERIVE_PARAMS_PTR;
-
-typedef struct CK_X9_42_MQV_DERIVE_PARAMS {
-  CK_X9_42_DH_KDF_TYPE kdf;
-  CK_ULONG ulOtherInfoLen;
-  CK_BYTE_PTR pOtherInfo;
-  CK_ULONG ulPublicDataLen;
-  CK_BYTE_PTR pPublicData;
-  CK_ULONG ulPrivateDataLen;
-  CK_OBJECT_HANDLE hPrivateData;
-  CK_ULONG ulPublicDataLen2;
-  CK_BYTE_PTR pPublicData2;
-  CK_OBJECT_HANDLE publicKey;
-} CK_X9_42_MQV_DERIVE_PARAMS;
-
-typedef CK_X9_42_MQV_DERIVE_PARAMS CK_PTR CK_X9_42_MQV_DERIVE_PARAMS_PTR;
-
-/* CK_KEA_DERIVE_PARAMS provides the parameters to the
- * CKM_KEA_DERIVE mechanism */
-/* CK_KEA_DERIVE_PARAMS is new for v2.0 */
-typedef struct CK_KEA_DERIVE_PARAMS {
-  CK_BBOOL      isSender;
-  CK_ULONG      ulRandomLen;
-  CK_BYTE_PTR   pRandomA;
-  CK_BYTE_PTR   pRandomB;
-  CK_ULONG      ulPublicDataLen;
-  CK_BYTE_PTR   pPublicData;
-} CK_KEA_DERIVE_PARAMS;
-
-typedef CK_KEA_DERIVE_PARAMS CK_PTR CK_KEA_DERIVE_PARAMS_PTR;
-
-
-/* CK_RC2_PARAMS provides the parameters to the CKM_RC2_ECB and
- * CKM_RC2_MAC mechanisms.  An instance of CK_RC2_PARAMS just
- * holds the effective keysize */
-typedef CK_ULONG          CK_RC2_PARAMS;
-
-typedef CK_RC2_PARAMS CK_PTR CK_RC2_PARAMS_PTR;
-
-
-/* CK_RC2_CBC_PARAMS provides the parameters to the CKM_RC2_CBC
- * mechanism */
-typedef struct CK_RC2_CBC_PARAMS {
-  /* ulEffectiveBits was changed from CK_USHORT to CK_ULONG for
-   * v2.0 */
-  CK_ULONG      ulEffectiveBits;  /* effective bits (1-1024) */
-
-  CK_BYTE       iv[8];            /* IV for CBC mode */
-} CK_RC2_CBC_PARAMS;
-
-typedef CK_RC2_CBC_PARAMS CK_PTR CK_RC2_CBC_PARAMS_PTR;
-
-
-/* CK_RC2_MAC_GENERAL_PARAMS provides the parameters for the
- * CKM_RC2_MAC_GENERAL mechanism */
-/* CK_RC2_MAC_GENERAL_PARAMS is new for v2.0 */
-typedef struct CK_RC2_MAC_GENERAL_PARAMS {
-  CK_ULONG      ulEffectiveBits;  /* effective bits (1-1024) */
-  CK_ULONG      ulMacLength;      /* Length of MAC in bytes */
-} CK_RC2_MAC_GENERAL_PARAMS;
-
-typedef CK_RC2_MAC_GENERAL_PARAMS CK_PTR \
-  CK_RC2_MAC_GENERAL_PARAMS_PTR;
-
-
-/* CK_RC5_PARAMS provides the parameters to the CKM_RC5_ECB and
- * CKM_RC5_MAC mechanisms */
-/* CK_RC5_PARAMS is new for v2.0 */
-typedef struct CK_RC5_PARAMS {
-  CK_ULONG      ulWordsize;  /* wordsize in bits */
-  CK_ULONG      ulRounds;    /* number of rounds */
-} CK_RC5_PARAMS;
-
-typedef CK_RC5_PARAMS CK_PTR CK_RC5_PARAMS_PTR;
-
-
-/* CK_RC5_CBC_PARAMS provides the parameters to the CKM_RC5_CBC
- * mechanism */
-/* CK_RC5_CBC_PARAMS is new for v2.0 */
-typedef struct CK_RC5_CBC_PARAMS {
-  CK_ULONG      ulWordsize;  /* wordsize in bits */
-  CK_ULONG      ulRounds;    /* number of rounds */
-  CK_BYTE_PTR   pIv;         /* pointer to IV */
-  CK_ULONG      ulIvLen;     /* length of IV in bytes */
-} CK_RC5_CBC_PARAMS;
-
-typedef CK_RC5_CBC_PARAMS CK_PTR CK_RC5_CBC_PARAMS_PTR;
-
-
-/* CK_RC5_MAC_GENERAL_PARAMS provides the parameters for the
- * CKM_RC5_MAC_GENERAL mechanism */
-/* CK_RC5_MAC_GENERAL_PARAMS is new for v2.0 */
-typedef struct CK_RC5_MAC_GENERAL_PARAMS {
-  CK_ULONG      ulWordsize;   /* wordsize in bits */
-  CK_ULONG      ulRounds;     /* number of rounds */
-  CK_ULONG      ulMacLength;  /* Length of MAC in bytes */
-} CK_RC5_MAC_GENERAL_PARAMS;
-
-typedef CK_RC5_MAC_GENERAL_PARAMS CK_PTR \
-  CK_RC5_MAC_GENERAL_PARAMS_PTR;
-
-
-/* CK_MAC_GENERAL_PARAMS provides the parameters to most block
- * ciphers' MAC_GENERAL mechanisms.  Its value is the length of
- * the MAC */
-/* CK_MAC_GENERAL_PARAMS is new for v2.0 */
-typedef CK_ULONG          CK_MAC_GENERAL_PARAMS;
-
-typedef CK_MAC_GENERAL_PARAMS CK_PTR CK_MAC_GENERAL_PARAMS_PTR;
-
-/* CK_DES/AES_ECB/CBC_ENCRYPT_DATA_PARAMS are new for v2.20 */
-typedef struct CK_DES_CBC_ENCRYPT_DATA_PARAMS {
-  CK_BYTE      iv[8];
-  CK_BYTE_PTR  pData;
-  CK_ULONG     length;
-} CK_DES_CBC_ENCRYPT_DATA_PARAMS;
-
-typedef CK_DES_CBC_ENCRYPT_DATA_PARAMS CK_PTR CK_DES_CBC_ENCRYPT_DATA_PARAMS_PTR;
-
-typedef struct CK_AES_CBC_ENCRYPT_DATA_PARAMS {
-  CK_BYTE      iv[16];
-  CK_BYTE_PTR  pData;
-  CK_ULONG     length;
-} CK_AES_CBC_ENCRYPT_DATA_PARAMS;
-
-typedef CK_AES_CBC_ENCRYPT_DATA_PARAMS CK_PTR CK_AES_CBC_ENCRYPT_DATA_PARAMS_PTR;
-
-/* CK_SKIPJACK_PRIVATE_WRAP_PARAMS provides the parameters to the
- * CKM_SKIPJACK_PRIVATE_WRAP mechanism */
-/* CK_SKIPJACK_PRIVATE_WRAP_PARAMS is new for v2.0 */
-typedef struct CK_SKIPJACK_PRIVATE_WRAP_PARAMS {
-  CK_ULONG      ulPasswordLen;
-  CK_BYTE_PTR   pPassword;
-  CK_ULONG      ulPublicDataLen;
-  CK_BYTE_PTR   pPublicData;
-  CK_ULONG      ulPAndGLen;
-  CK_ULONG      ulQLen;
-  CK_ULONG      ulRandomLen;
-  CK_BYTE_PTR   pRandomA;
-  CK_BYTE_PTR   pPrimeP;
-  CK_BYTE_PTR   pBaseG;
-  CK_BYTE_PTR   pSubprimeQ;
-} CK_SKIPJACK_PRIVATE_WRAP_PARAMS;
-
-typedef CK_SKIPJACK_PRIVATE_WRAP_PARAMS CK_PTR \
-  CK_SKIPJACK_PRIVATE_WRAP_PTR;
-
-
-/* CK_SKIPJACK_RELAYX_PARAMS provides the parameters to the
- * CKM_SKIPJACK_RELAYX mechanism */
-/* CK_SKIPJACK_RELAYX_PARAMS is new for v2.0 */
-typedef struct CK_SKIPJACK_RELAYX_PARAMS {
-  CK_ULONG      ulOldWrappedXLen;
-  CK_BYTE_PTR   pOldWrappedX;
-  CK_ULONG      ulOldPasswordLen;
-  CK_BYTE_PTR   pOldPassword;
-  CK_ULONG      ulOldPublicDataLen;
-  CK_BYTE_PTR   pOldPublicData;
-  CK_ULONG      ulOldRandomLen;
-  CK_BYTE_PTR   pOldRandomA;
-  CK_ULONG      ulNewPasswordLen;
-  CK_BYTE_PTR   pNewPassword;
-  CK_ULONG      ulNewPublicDataLen;
-  CK_BYTE_PTR   pNewPublicData;
-  CK_ULONG      ulNewRandomLen;
-  CK_BYTE_PTR   pNewRandomA;
-} CK_SKIPJACK_RELAYX_PARAMS;
-
-typedef CK_SKIPJACK_RELAYX_PARAMS CK_PTR \
-  CK_SKIPJACK_RELAYX_PARAMS_PTR;
-
-
-typedef struct CK_PBE_PARAMS {
-  CK_BYTE_PTR      pInitVector;
-  CK_UTF8CHAR_PTR  pPassword;
-  CK_ULONG         ulPasswordLen;
-  CK_BYTE_PTR      pSalt;
-  CK_ULONG         ulSaltLen;
-  CK_ULONG         ulIteration;
-} CK_PBE_PARAMS;
-
-typedef CK_PBE_PARAMS CK_PTR CK_PBE_PARAMS_PTR;
-
-
-/* CK_KEY_WRAP_SET_OAEP_PARAMS provides the parameters to the
- * CKM_KEY_WRAP_SET_OAEP mechanism */
-/* CK_KEY_WRAP_SET_OAEP_PARAMS is new for v2.0 */
-typedef struct CK_KEY_WRAP_SET_OAEP_PARAMS {
-  CK_BYTE       bBC;     /* block contents byte */
-  CK_BYTE_PTR   pX;      /* extra data */
-  CK_ULONG      ulXLen;  /* length of extra data in bytes */
-} CK_KEY_WRAP_SET_OAEP_PARAMS;
-
-typedef CK_KEY_WRAP_SET_OAEP_PARAMS CK_PTR \
-  CK_KEY_WRAP_SET_OAEP_PARAMS_PTR;
-
-
-typedef struct CK_SSL3_RANDOM_DATA {
-  CK_BYTE_PTR  pClientRandom;
-  CK_ULONG     ulClientRandomLen;
-  CK_BYTE_PTR  pServerRandom;
-  CK_ULONG     ulServerRandomLen;
-} CK_SSL3_RANDOM_DATA;
-
-
-typedef struct CK_SSL3_MASTER_KEY_DERIVE_PARAMS {
-  CK_SSL3_RANDOM_DATA RandomInfo;
-  CK_VERSION_PTR pVersion;
-} CK_SSL3_MASTER_KEY_DERIVE_PARAMS;
-
-typedef struct CK_SSL3_MASTER_KEY_DERIVE_PARAMS CK_PTR \
-  CK_SSL3_MASTER_KEY_DERIVE_PARAMS_PTR;
-
-
-typedef struct CK_SSL3_KEY_MAT_OUT {
-  CK_OBJECT_HANDLE hClientMacSecret;
-  CK_OBJECT_HANDLE hServerMacSecret;
-  CK_OBJECT_HANDLE hClientKey;
-  CK_OBJECT_HANDLE hServerKey;
-  CK_BYTE_PTR      pIVClient;
-  CK_BYTE_PTR      pIVServer;
-} CK_SSL3_KEY_MAT_OUT;
-
-typedef CK_SSL3_KEY_MAT_OUT CK_PTR CK_SSL3_KEY_MAT_OUT_PTR;
-
-
-typedef struct CK_SSL3_KEY_MAT_PARAMS {
-  CK_ULONG                ulMacSizeInBits;
-  CK_ULONG                ulKeySizeInBits;
-  CK_ULONG                ulIVSizeInBits;
-  CK_BBOOL                bIsExport;
-  CK_SSL3_RANDOM_DATA     RandomInfo;
-  CK_SSL3_KEY_MAT_OUT_PTR pReturnedKeyMaterial;
-} CK_SSL3_KEY_MAT_PARAMS;
-
-typedef CK_SSL3_KEY_MAT_PARAMS CK_PTR CK_SSL3_KEY_MAT_PARAMS_PTR;
-
-/* CK_TLS_PRF_PARAMS is new for version 2.20 */
-typedef struct CK_TLS_PRF_PARAMS {
-  CK_BYTE_PTR  pSeed;
-  CK_ULONG     ulSeedLen;
-  CK_BYTE_PTR  pLabel;
-  CK_ULONG     ulLabelLen;
-  CK_BYTE_PTR  pOutput;
-  CK_ULONG_PTR pulOutputLen;
-} CK_TLS_PRF_PARAMS;
-
-typedef CK_TLS_PRF_PARAMS CK_PTR CK_TLS_PRF_PARAMS_PTR;
-
-/* WTLS is new for version 2.20 */
-typedef struct CK_WTLS_RANDOM_DATA {
-  CK_BYTE_PTR pClientRandom;
-  CK_ULONG    ulClientRandomLen;
-  CK_BYTE_PTR pServerRandom;
-  CK_ULONG    ulServerRandomLen;
-} CK_WTLS_RANDOM_DATA;
-
-typedef CK_WTLS_RANDOM_DATA CK_PTR CK_WTLS_RANDOM_DATA_PTR;
-
-typedef struct CK_WTLS_MASTER_KEY_DERIVE_PARAMS {
-  CK_MECHANISM_TYPE   DigestMechanism;
-  CK_WTLS_RANDOM_DATA RandomInfo;
-  CK_BYTE_PTR         pVersion;
-} CK_WTLS_MASTER_KEY_DERIVE_PARAMS;
-
-typedef CK_WTLS_MASTER_KEY_DERIVE_PARAMS CK_PTR \
-  CK_WTLS_MASTER_KEY_DERIVE_PARAMS_PTR;
-
-typedef struct CK_WTLS_PRF_PARAMS {
-  CK_MECHANISM_TYPE DigestMechanism;
-  CK_BYTE_PTR       pSeed;
-  CK_ULONG          ulSeedLen;
-  CK_BYTE_PTR       pLabel;
-  CK_ULONG          ulLabelLen;
-  CK_BYTE_PTR       pOutput;
-  CK_ULONG_PTR      pulOutputLen;
-} CK_WTLS_PRF_PARAMS;
-
-typedef CK_WTLS_PRF_PARAMS CK_PTR CK_WTLS_PRF_PARAMS_PTR;
-
-typedef struct CK_WTLS_KEY_MAT_OUT {
-  CK_OBJECT_HANDLE hMacSecret;
-  CK_OBJECT_HANDLE hKey;
-  CK_BYTE_PTR      pIV;
-} CK_WTLS_KEY_MAT_OUT;
-
-typedef CK_WTLS_KEY_MAT_OUT CK_PTR CK_WTLS_KEY_MAT_OUT_PTR;
-
-typedef struct CK_WTLS_KEY_MAT_PARAMS {
-  CK_MECHANISM_TYPE       DigestMechanism;
-  CK_ULONG                ulMacSizeInBits;
-  CK_ULONG                ulKeySizeInBits;
-  CK_ULONG                ulIVSizeInBits;
-  CK_ULONG                ulSequenceNumber;
-  CK_BBOOL                bIsExport;
-  CK_WTLS_RANDOM_DATA     RandomInfo;
-  CK_WTLS_KEY_MAT_OUT_PTR pReturnedKeyMaterial;
-} CK_WTLS_KEY_MAT_PARAMS;
-
-typedef CK_WTLS_KEY_MAT_PARAMS CK_PTR CK_WTLS_KEY_MAT_PARAMS_PTR;
-
-/* CMS is new for version 2.20 */
-typedef struct CK_CMS_SIG_PARAMS {
-  CK_OBJECT_HANDLE      certificateHandle;
-  CK_MECHANISM_PTR      pSigningMechanism;
-  CK_MECHANISM_PTR      pDigestMechanism;
-  CK_UTF8CHAR_PTR       pContentType;
-  CK_BYTE_PTR           pRequestedAttributes;
-  CK_ULONG              ulRequestedAttributesLen;
-  CK_BYTE_PTR           pRequiredAttributes;
-  CK_ULONG              ulRequiredAttributesLen;
-} CK_CMS_SIG_PARAMS;
-
-typedef CK_CMS_SIG_PARAMS CK_PTR CK_CMS_SIG_PARAMS_PTR;
-
-typedef struct CK_KEY_DERIVATION_STRING_DATA {
-  CK_BYTE_PTR pData;
-  CK_ULONG    ulLen;
-} CK_KEY_DERIVATION_STRING_DATA;
-
-typedef CK_KEY_DERIVATION_STRING_DATA CK_PTR \
-  CK_KEY_DERIVATION_STRING_DATA_PTR;
-
-
-/* The CK_EXTRACT_PARAMS is used for the
- * CKM_EXTRACT_KEY_FROM_KEY mechanism.  It specifies which bit
- * of the base key should be used as the first bit of the
- * derived key */
-/* CK_EXTRACT_PARAMS is new for v2.0 */
-typedef CK_ULONG CK_EXTRACT_PARAMS;
-
-typedef CK_EXTRACT_PARAMS CK_PTR CK_EXTRACT_PARAMS_PTR;
-
-/* CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE is new for v2.10.
- * CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE is used to
- * indicate the Pseudo-Random Function (PRF) used to generate
- * key bits using PKCS #5 PBKDF2. */
-typedef CK_ULONG CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE;
-
-typedef CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE CK_PTR CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE_PTR;
-
-/* The following PRFs are defined in PKCS #5 v2.0. */
-#define CKP_PKCS5_PBKD2_HMAC_SHA1 0x00000001
-
-
-/* CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE is new for v2.10.
- * CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE is used to indicate the
- * source of the salt value when deriving a key using PKCS #5
- * PBKDF2. */
-typedef CK_ULONG CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE;
-
-typedef CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE CK_PTR CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE_PTR;
-
-/* The following salt value sources are defined in PKCS #5 v2.0. */
-#define CKZ_SALT_SPECIFIED        0x00000001
-
-/* CK_PKCS5_PBKD2_PARAMS is new for v2.10.
- * CK_PKCS5_PBKD2_PARAMS is a structure that provides the
- * parameters to the CKM_PKCS5_PBKD2 mechanism. */
-typedef struct CK_PKCS5_PBKD2_PARAMS {
-        CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE           saltSource;
-        CK_VOID_PTR                                pSaltSourceData;
-        CK_ULONG                                   ulSaltSourceDataLen;
-        CK_ULONG                                   iterations;
-        CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE prf;
-        CK_VOID_PTR                                pPrfData;
-        CK_ULONG                                   ulPrfDataLen;
-        CK_UTF8CHAR_PTR                            pPassword;
-        CK_ULONG_PTR                               ulPasswordLen;
-} CK_PKCS5_PBKD2_PARAMS;
-
-typedef CK_PKCS5_PBKD2_PARAMS CK_PTR CK_PKCS5_PBKD2_PARAMS_PTR;
-
-#endif
diff --git a/pkcs11-helper-config.h b/pkcs11-helper-config.h
deleted file mode 100644 (file)
index d3276ed..0000000
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
-*  OpenVPN -- An application to securely tunnel IP networks
-*             over a single TCP/UDP port, with support for SSL/TLS-based
-*             session authentication and key exchange,
-*             packet encryption, packet authentication, and
-*             packet compression.
-*
-*  Copyright (C) 2002-2005 OpenVPN Solutions LLC <info@openvpn.net>
-*
-*  This program is free software; you can redistribute it and/or modify
-*  it under the terms of the GNU General Public License version 2
-*  as published by the Free Software Foundation.
-*
-*  This program 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 General Public License for more details.
-*
-*  You should have received a copy of the GNU General Public License
-*  along with this program (see the file COPYING included with this
-*  distribution); if not, write to the Free Software Foundation, Inc.,
-*  59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-*/
-
-#ifndef __PKCS11H_HELPER_CONFIG_H
-#define __PKCS11H_HELPER_CONFIG_H
-
-#if !defined(PKCS11H_NO_NEED_INCLUDE_CONFIG)
-
-#if defined(WIN32)
-#include "config-win32.h"
-#else
-#include "config.h"
-#endif
-
-#include "syshead.h"
-
-#endif /* PKCS11H_NO_NEED_INCLUDE_CONFIG */
-
-#ifdef ENABLE_PKCS11
-#define ENABLE_PKCS11H_HELPER
-#endif
-
-#ifdef ENABLE_PKCS11H_HELPER
-
-#include "error.h"
-#include "misc.h"
-#include "ssl.h"
-
-#undef PKCS11H_USE_CYGWIN      /* cygwin is not supported in openvpn */
-
-#if !defined(FALSE)
-#define FALSE false
-#endif
-#if !defined(TRUE)
-#define TRUE true
-#endif
-
-typedef bool PKCS11H_BOOL;
-
-#if !defined(IN)
-#define IN
-#endif
-#if !defined(OUT)
-#define OUT
-#endif
-
-#ifdef ENABLE_DEBUG
-#define ENABLE_PKCS11H_DEBUG
-#endif
-#ifdef USE_PTHREAD
-#define ENABLE_PKCS11H_THREADING
-#endif
-#undef  ENABLE_PKCS11H_TOKEN
-#undef  ENABLE_PKCS11H_DATA
-#define ENABLE_PKCS11H_CERTIFICATE
-#define ENABLE_PKCS11H_LOCATE
-#undef  ENABLE_PKCS11H_ENUM
-#undef  ENABLE_PKCS11H_SLOTEVENT
-#define ENABLE_PKCS11H_OPENSSL
-#define ENABLE_PKCS11H_STANDALONE
-
-#define PKCS11H_PRM_SLOT_TYPE  "--pkcs11-slot-type"
-#define PKCS11H_PRM_SLOT_ID    "--pkcs11-slot"
-#define PKCS11H_PRM_OBJ_TYPE   "--pkcs11-id-type"
-#define PKCS11H_PRM_OBJ_ID     "--pkcs11-id"
-
-#define PKCS11H_ASSERT         ASSERT
-#define PKCS11H_TIME           openvpn_time
-
-#if defined(WIN32) || defined(PKCS11H_USE_CYGWIN)
-#include "cryptoki-win32.h"
-#else
-#include "cryptoki.h"
-#endif
-
-#endif         /* PKCS11_ENABLE_HELPER */
-#endif         /* __PKCS11H_HELPER_CONFIG_H */
diff --git a/pkcs11-helper.c b/pkcs11-helper.c
deleted file mode 100644 (file)
index 4dd798e..0000000
+++ /dev/null
@@ -1,9991 +0,0 @@
-/*
- * Copyright (c) 2005-2006 Alon Bar-Lev <alon.barlev@gmail.com>
- * All rights reserved.
- *
- * This software is available to you under a choice of one of two
- * licenses.  You may choose to be licensed under the terms of the GNU
- * General Public License (GPL) Version 2, or the OpenIB.org BSD license.
- *
- * GNU General Public License (GPL) Version 2
- * ===========================================
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License version 2
- *  as published by the Free Software Foundation.
- *
- *  This program 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 General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program (see the file COPYING[.GPL2] included with this
- *  distribution); if not, write to the Free Software Foundation, Inc.,
- *  59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- * OpenIB.org BSD license
- * =======================
- * Redistribution and use in source and binary forms, with or without modifi-
- * cation, are permitted provided that the following conditions are met:
- *
- *   o  Redistributions of source code must retain the above copyright notice,
- *      this list of conditions and the following disclaimer.
- *
- *   o  Redistributions in binary form must reproduce the above copyright no-
- *      tice, this list of conditions and the following disclaimer in the do-
- *      cumentation and/or other materials provided with the distribution.
- *
- *   o  The names of the contributors 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 REGENTS OR CONTRIBUTORS BE LI-
- * ABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUEN-
- * TIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEV-
- * ER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABI-
- * LITY, 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.
- */
-
-/*
- * The routines in this file deal with providing private key cryptography
- * using RSA Security Inc. PKCS #11 Cryptographic Token Interface (Cryptoki).
- *
- */
-
-/*
- * Changelog
- *
- * 2006.06.26
- *     - (alonbl) Fix handling mutiple providers.
- *     - (alonbl) Release 01.01.
- *
- * 2006.05.14
- *     - (alonbl) First stable release.
- *     - (alonbl) Release 01.00.
- *
- */
-
-#include "pkcs11-helper-config.h"
-
-#if defined(ENABLE_PKCS11H_HELPER)
-
-#include "pkcs11-helper.h"
-
-/*===========================================
- * Constants
- */
-
-#if OPENSSL_VERSION_NUMBER < 0x00907000L && defined(CRYPTO_LOCK_ENGINE)
-# define RSA_get_default_method RSA_get_default_openssl_method
-#else
-# ifdef HAVE_ENGINE_GET_DEFAULT_RSA
-#  include <openssl/engine.h>
-#  if OPENSSL_VERSION_NUMBER < 0x0090704fL
-#   define BROKEN_OPENSSL_ENGINE
-#  endif
-# endif
-#endif
-
-#if OPENSSL_VERSION_NUMBER < 0x00907000L
-#if !defined(RSA_PKCS1_PADDING_SIZE)
-#define RSA_PKCS1_PADDING_SIZE 11
-#endif
-#endif
-
-#define PKCS11H_INVALID_SLOT_ID                ((CK_SLOT_ID)-1)
-#define PKCS11H_INVALID_SESSION_HANDLE ((CK_SESSION_HANDLE)-1)
-#define PKCS11H_INVALID_OBJECT_HANDLE  ((CK_OBJECT_HANDLE)-1)
-
-#define PKCS11H_DEFAULT_SLOTEVENT_POLL         5000
-#define PKCS11H_DEFAULT_MAX_LOGIN_RETRY                3
-#define PKCS11H_DEFAULT_PIN_CACHE_PERIOD       PKCS11H_PIN_CACHE_INFINITE
-
-enum _pkcs11h_private_op_e {
-       _pkcs11h_private_op_sign=0,
-       _pkcs11h_private_op_sign_recover,
-       _pkcs11h_private_op_decrypt
-};
-
-/*===========================================
- * Macros
- */
-
-#define PKCS11H_MSG_LEVEL_TEST(flags) (((unsigned int)flags) <= s_pkcs11h_loglevel)
-
-#if defined(HAVE_CPP_VARARG_MACRO_ISO) && !defined(__LCLINT__)
-# define PKCS11H_LOG(flags, ...) do { if (PKCS11H_MSG_LEVEL_TEST(flags)) _pkcs11h_log((flags), __VA_ARGS__); } while (FALSE)
-# ifdef ENABLE_PKCS11H_DEBUG
-#  define PKCS11H_DEBUG(flags, ...) do { if (PKCS11H_MSG_LEVEL_TEST(flags)) _pkcs11h_log((flags), __VA_ARGS__); } while (FALSE)
-# else
-#  define PKCS11H_DEBUG(flags, ...)
-# endif
-#elif defined(HAVE_CPP_VARARG_MACRO_GCC) && !defined(__LCLINT__)
-# define PKCS11H_LOG(flags, args...) do { if (PKCS11H_MSG_LEVEL_TEST(flags)) _pkcs11h_log((flags), args); } while (FALSE)
-# ifdef ENABLE_PKCS11H_DEBUG
-#  define PKCS11H_DEBUG(flags, args...) do { if (PKCS11H_MSG_LEVEL_TEST(flags)) _pkcs11h_log((flags), args); } while (FALSE)
-# else
-#  define PKCS11H_DEBUG(flags, args...)
-# endif
-#else
-# define PKCS11H_LOG _pkcs11h_log
-# define PKCS11H_DEBUG _pkcs11h_log
-#endif
-
-/*===========================================
- * Types
- */
-
-struct pkcs11h_provider_s;
-struct pkcs11h_session_s;
-struct pkcs11h_data_s;
-typedef struct pkcs11h_provider_s *pkcs11h_provider_t;
-typedef struct pkcs11h_session_s *pkcs11h_session_t;
-typedef struct pkcs11h_data_s *pkcs11h_data_t;
-
-#if OPENSSL_VERSION_NUMBER < 0x00908000L
-typedef unsigned char *pkcs11_openssl_d2i_t;
-#else
-typedef const unsigned char *pkcs11_openssl_d2i_t;
-#endif
-
-#if defined(ENABLE_PKCS11H_THREADING)
-
-#define PKCS11H_COND_INFINITE  0xffffffff
-
-#if defined(WIN32)
-#define PKCS11H_THREAD_NULL    NULL
-typedef HANDLE pkcs11h_cond_t;
-typedef HANDLE pkcs11h_mutex_t;
-typedef HANDLE pkcs11h_thread_t;
-#else
-#define PKCS11H_THREAD_NULL    0l
-typedef pthread_mutex_t pkcs11h_mutex_t;
-typedef pthread_t pkcs11h_thread_t;
-
-typedef struct {
-       pthread_cond_t cond;
-       pthread_mutex_t mut;
-} pkcs11h_cond_t;
-
-typedef struct __pkcs11h_mutex_entry_s {
-       struct __pkcs11h_mutex_entry_s *next;
-       pkcs11h_mutex_t *p_mutex;
-       PKCS11H_BOOL fLocked;
-} *__pkcs11h_mutex_entry_t;
-#endif
-
-typedef void * (*pkcs11h_thread_start_t)(void *);
-
-typedef struct {
-       pkcs11h_thread_start_t start;
-       void *data;
-} __pkcs11h_thread_data_t;
-
-#endif                         /* ENABLE_PKCS11H_THREADING */
-
-struct pkcs11h_provider_s {
-       pkcs11h_provider_t next;
-
-       PKCS11H_BOOL fEnabled;
-       char szReferenceName[1024];
-       char manufacturerID[sizeof (((CK_TOKEN_INFO *)NULL)->manufacturerID)+1];
-       
-#if defined(WIN32)
-       HANDLE hLibrary;
-#else
-       void *hLibrary;
-#endif
-
-       CK_FUNCTION_LIST_PTR f;
-       PKCS11H_BOOL fShouldFinalize;
-       PKCS11H_BOOL fProtectedAuthentication;
-       PKCS11H_BOOL fCertIsPrivate;
-       unsigned maskSignMode;
-       int nSlotEventMethod;
-       int nSlotEventPollInterval;
-
-#if defined(ENABLE_PKCS11H_SLOTEVENT)
-       pkcs11h_thread_t threadSlotEvent;
-#endif
-};
-
-struct pkcs11h_session_s {
-       pkcs11h_session_t next;
-
-       int nReferenceCount;
-       PKCS11H_BOOL fValid;
-
-       pkcs11h_provider_t provider;
-
-       pkcs11h_token_id_t token_id;
-
-       CK_SESSION_HANDLE hSession;
-
-       PKCS11H_BOOL fProtectedAuthenticationSupported;
-       int nPINCachePeriod;
-       time_t timePINExpire;
-
-#if defined(ENABLE_PKCS11H_ENUM)
-#if defined(ENABLE_PKCS11H_CERTIFICATE)
-       pkcs11h_certificate_id_list_t cached_certs;
-       PKCS11H_BOOL fTouch;
-#endif
-#endif
-
-#if defined(ENABLE_PKCS11H_THREADING)
-       pkcs11h_mutex_t mutexSession;
-#endif
-};
-
-#if defined (ENABLE_PKCS11H_CERTIFICATE)
-
-struct pkcs11h_certificate_s {
-
-       pkcs11h_certificate_id_t id;
-       int nPINCachePeriod;
-
-       unsigned maskSignMode;
-
-       pkcs11h_session_t session;
-       CK_OBJECT_HANDLE hKey;
-
-       PKCS11H_BOOL fOperationActive;
-
-#if defined(ENABLE_PKCS11H_THREADING)
-       pkcs11h_mutex_t mutexCertificate;
-#endif
-};
-
-#endif                         /* ENABLE_PKCS11H_CERTIFICATE */
-
-struct pkcs11h_data_s {
-       PKCS11H_BOOL fInitialized;
-       int nPINCachePeriod;
-
-       pkcs11h_provider_t providers;
-       pkcs11h_session_t sessions;
-
-       struct {
-               void *log_data;
-               void *slotevent_data;
-               void *token_prompt_data;
-               void *pin_prompt_data;
-               pkcs11h_hook_log_t log;
-               pkcs11h_hook_slotevent_t slotevent;
-               pkcs11h_hook_token_prompt_t token_prompt;
-               pkcs11h_hook_pin_prompt_t pin_prompt;
-       } hooks;
-
-       PKCS11H_BOOL fProtectedAuthentication;
-       unsigned nMaxLoginRetries;
-
-#if defined(ENABLE_PKCS11H_THREADING)
-       pkcs11h_mutex_t mutexGlobal;
-       pkcs11h_mutex_t mutexSession;
-       pkcs11h_mutex_t mutexCache;
-#endif
-
-#if defined(ENABLE_PKCS11H_SLOTEVENT)
-       PKCS11H_BOOL fSlotEventInitialized;
-       PKCS11H_BOOL fSlotEventShouldTerminate;
-       PKCS11H_BOOL fSlotEventSkipEvent;
-       pkcs11h_cond_t condSlotEvent;
-       pkcs11h_thread_t threadSlotEvent;
-#endif
-};
-
-#if defined(ENABLE_PKCS11H_OPENSSL)
-struct pkcs11h_openssl_session_s {
-       int nReferenceCount;
-       PKCS11H_BOOL fInitialized;
-       X509 *x509;
-       RSA_METHOD smart_rsa;
-       int (*orig_finish)(RSA *rsa);
-       pkcs11h_certificate_t certificate;
-};
-#endif
-
-/*======================================================================*
- * MEMORY INTERFACE
- *======================================================================*/
-
-static
-CK_RV
-_pkcs11h_malloc (
-       OUT const void ** const p,
-       IN const size_t s
-);
-static
-CK_RV
-_pkcs11h_free (
-       IN const void ** const p
-);
-static
-CK_RV
-_pkcs11h_dupmem (
-       OUT const void ** const dest,
-       OUT size_t * const dest_size,
-       IN const void * const src,
-       IN const size_t mem_size
-);
-
-#if defined(ENABLE_PKCS11H_THREADING)
-/*======================================================================*
- * THREADING INTERFACE
- *======================================================================*/
-
-static
-void
-_pkcs11h_sleep (
-       IN const unsigned milli
-);
-static
-CK_RV
-_pkcs11h_mutexInit (
-       OUT pkcs11h_mutex_t * const mutex
-);
-static
-CK_RV
-_pkcs11h_mutexLock (
-       IN OUT pkcs11h_mutex_t *const mutex
-);
-static
-CK_RV
-_pkcs11h_mutexRelease (
-       IN OUT pkcs11h_mutex_t *const mutex
-);
-static
-CK_RV
-_pkcs11h_mutexFree (
-       IN OUT pkcs11h_mutex_t *const mutex
-);
-#if !defined(WIN32)
-static
-void
-__pkcs1h_mutexLockAll ();
-static
-void
-__pkcs1h_mutexReleaseAll ();
-#endif
-static
-CK_RV
-_pkcs11h_condSignal (
-       IN OUT pkcs11h_cond_t *const cond
-);
-static
-CK_RV
-_pkcs11h_condInit (
-       OUT pkcs11h_cond_t * const cond
-);
-static
-CK_RV
-_pkcs11h_condWait (
-       IN OUT pkcs11h_cond_t *const cond,
-       IN const unsigned milli
-);
-static
-CK_RV
-_pkcs11h_condFree (
-       IN OUT pkcs11h_cond_t *const cond
-);
-static
-CK_RV
-_pkcs11h_threadStart (
-       OUT pkcs11h_thread_t * const thread,
-       IN pkcs11h_thread_start_t const start,
-       IN void * data
-);
-static
-CK_RV
-_pkcs11h_threadJoin (
-       IN pkcs11h_thread_t * const thread
-);
-#endif                         /* ENABLE_PKCS11H_THREADING */
-
-/*======================================================================*
- * COMMON INTERNAL INTERFACE
- *======================================================================*/
-
-static
-void
-_pkcs11h_fixupFixedString (
-       OUT char * const szTarget,                      /* MUST BE >= nLength+1 */
-       IN const char * const szSource,
-       IN const size_t nLength                         /* FIXED STRING LENGTH */
-);
-static
-void
-_pkcs11h_log (
-       IN const unsigned flags,
-       IN const char * const szFormat,
-       IN ...
-)
-#ifdef __GNUC__
-    __attribute__ ((format (printf, 2, 3)))
-#endif
-    ;
-
-static
-CK_RV
-_pkcs11h_getSlotList (
-       IN const pkcs11h_provider_t provider,
-       IN const CK_BBOOL tokenPresent,
-       OUT CK_SLOT_ID_PTR * const pSlotList,
-       OUT CK_ULONG_PTR pulCount
-);
-static
-CK_RV
-_pkcs11h_getObjectAttributes (
-       IN const pkcs11h_session_t session,
-       IN const CK_OBJECT_HANDLE object,
-       IN OUT const CK_ATTRIBUTE_PTR attrs,
-       IN const unsigned count
-);
-static
-CK_RV
-_pkcs11h_freeObjectAttributes (
-       IN OUT const CK_ATTRIBUTE_PTR attrs,
-       IN const unsigned count
-);
-static
-CK_RV
-_pkcs11h_findObjects (
-       IN const pkcs11h_session_t session,
-       IN const CK_ATTRIBUTE * const filter,
-       IN const CK_ULONG filter_attrs,
-       OUT CK_OBJECT_HANDLE **const p_objects,
-       OUT CK_ULONG *p_objects_found
-);
-static
-CK_RV
-_pkcs11h_getTokenId (
-       IN const CK_TOKEN_INFO_PTR info,
-       OUT pkcs11h_token_id_t * const p_token_id
-);
-static
-CK_RV
-_pkcs11h_newTokenId (
-       OUT pkcs11h_token_id_t * const token_id
-);
-static
-CK_RV
-_pkcs11h_getSessionByTokenId (
-       IN const pkcs11h_token_id_t token_id,
-       OUT pkcs11h_session_t * const p_session
-);
-static
-CK_RV
-_pkcs11h_releaseSession (
-       IN const pkcs11h_session_t session
-);
-static
-CK_RV
-_pkcs11h_resetSession (
-       IN const pkcs11h_session_t session,
-       IN const unsigned maskPrompt,
-       OUT CK_SLOT_ID * const p_slot
-);
-static
-CK_RV
-_pkcs11h_getObjectById (
-       IN const pkcs11h_session_t certificate,
-       IN const CK_OBJECT_CLASS class,
-       IN const CK_BYTE_PTR id,
-       IN const size_t id_size,
-       OUT CK_OBJECT_HANDLE * const p_handle
-);
-static
-CK_RV
-_pkcs11h_validateSession (
-       IN const pkcs11h_session_t session
-);
-static
-CK_RV
-_pkcs11h_login (
-       IN const pkcs11h_session_t session,
-       IN const PKCS11H_BOOL fPublicOnly,
-       IN const PKCS11H_BOOL fReadOnly,
-       IN const unsigned maskPrompt
-);
-static
-CK_RV
-_pkcs11h_logout (
-       IN const pkcs11h_session_t session
-);
-
-static
-void
-_pkcs11h_hooks_default_log (
-       IN const void * pData,
-       IN const unsigned flags,
-       IN const char * const szFormat,
-       IN va_list args
-);
-
-static
-PKCS11H_BOOL
-_pkcs11h_hooks_default_token_prompt (
-       IN const void * pData,
-       IN const pkcs11h_token_id_t token,
-       IN const unsigned retry
-);
-
-static
-PKCS11H_BOOL
-_pkcs11h_hooks_default_pin_prompt (
-       IN const void * pData,
-       IN const pkcs11h_token_id_t token,
-       IN const unsigned retry,
-       OUT char * const szPIN,
-       IN const size_t nMaxPIN
-);
-
-#if !defined(WIN32)
-#if defined(ENABLE_PKCS11H_THREADING)
-static
-void
-__pkcs11h_atfork_prepare  ();
-static
-void
-__pkcs11h_atfork_parent ();
-static
-void
-__pkcs11h_atfork_child ();
-#endif
-static
-CK_RV
-_pkcs11h_forkFixup ();
-#endif
-
-#if defined(ENABLE_PKCS11H_CERTIFICATE)
-/*======================================================================*
- * CERTIFICATE INTERFACE
- *======================================================================*/
-
-static
-void
-_pkcs11h_isBetterCertificate_getExpiration (
-       IN const unsigned char * const pCertificate,
-       IN const size_t nCertificateSize,
-       OUT char * const szNotBefore,
-       IN const int nNotBeforeSize
-);
-static
-PKCS11H_BOOL
-_pkcs11h_isBetterCertificate (
-       IN const unsigned char * const pCurrent,
-       IN const size_t nCurrentSize,
-       IN const unsigned char * const pNew,
-       IN const size_t nNewSize
-);
-static
-CK_RV
-_pkcs11h_newCertificateId (
-       OUT pkcs11h_certificate_id_t * const certificate_id
-);
-static
-CK_RV
-_pkcs11h_loadCertificate (
-       IN const pkcs11h_certificate_t certificate
-);
-static
-CK_RV
-_pkcs11h_updateCertificateIdDescription (
-       IN OUT pkcs11h_certificate_id_t certificate_id
-);
-static
-CK_RV
-_pkcs11h_ensureCertificateBlob (
-       IN const pkcs11h_certificate_t certificate
-);
-static
-CK_RV
-_pkcs11h_getCertificateKeyAttributes (
-       IN const pkcs11h_certificate_t certificate
-);
-static
-CK_RV
-_pkcs11h_validateCertificateSession (
-       IN const pkcs11h_certificate_t certificate
-);
-static
-CK_RV
-_pkcs11h_resetCertificateSession (
-       IN const pkcs11h_certificate_t certificate,
-       IN const PKCS11H_BOOL fPublicOnly,
-       IN const unsigned maskPrompt
-);
-static
-CK_RV
-_pkcs11h_certificate_private_op (
-       IN const pkcs11h_certificate_t certificate,
-       IN const enum _pkcs11h_private_op_e op,
-       IN const CK_MECHANISM_TYPE mech_type,
-       IN const unsigned char * const source,
-       IN const size_t source_size,
-       OUT unsigned char * const target,
-       IN OUT size_t * const p_target_size
-);
-#endif                         /* ENABLE_PKCS11H_CERTIFICATE */
-
-#if defined(ENABLE_PKCS11H_LOCATE)
-/*======================================================================*
- * LOCATE INTERFACE
- *======================================================================*/
-
-static
-CK_RV
-_pkcs11h_locate_getTokenIdBySlotId (
-       IN const char * const szSlot,
-       OUT pkcs11h_token_id_t * const p_token_id
-);
-static
-CK_RV
-_pkcs11h_locate_getTokenIdBySlotName (
-       IN const char * const szName,
-       OUT pkcs11h_token_id_t * const p_token_id
-);
-static
-CK_RV
-_pkcs11h_locate_getTokenIdByLabel (
-       IN const char * const szLabel,
-       OUT pkcs11h_token_id_t * const p_token_id
-);
-
-#if defined(ENABLE_PKCS11H_CERTIFICATE)
-
-static
-void
-_pkcs11h_locate_hexToBinary (
-       OUT unsigned char * const target,
-       IN const char * const szSource,
-       IN OUT size_t * const p_target_size
-);
-static
-CK_RV
-_pkcs11h_locate_getCertificateIdByLabel (
-       IN const pkcs11h_session_t session,
-       IN OUT const pkcs11h_certificate_id_t certificate_id,
-       IN const char * const szLabel
-);
-static
-CK_RV
-_pkcs11h_locate_getCertificateIdBySubject (
-       IN const pkcs11h_session_t session,
-       IN OUT const pkcs11h_certificate_id_t certificate_id,
-       IN const char * const szSubject
-);
-
-#endif                         /* ENABLE_PKCS11H_CERTIFICATE */
-#endif                         /* ENABLE_PKCS11H_LOCATE */
-
-#if defined(ENABLE_PKCS11H_ENUM)
-/*======================================================================*
- * ENUM INTERFACE
- *======================================================================*/
-
-#if defined(ENABLE_PKCS11H_CERTIFICATE)
-
-static
-CK_RV
-_pkcs11h_enum_getSessionCertificates (
-       IN const pkcs11h_session_t session
-);
-static
-CK_RV
-_pkcs11h_enum_splitCertificateIdList (
-       IN const pkcs11h_certificate_id_list_t cert_id_all,
-       OUT pkcs11h_certificate_id_list_t * const p_cert_id_issuers_list,
-       OUT pkcs11h_certificate_id_list_t * const p_cert_id_end_list
-);
-
-#endif                         /* ENABLE_PKCS11H_CERTIFICATE */
-
-#endif                         /* ENABLE_PKCS11H_ENUM */
-
-#if defined(ENABLE_PKCS11H_SLOTEVENT)
-/*======================================================================*
- * SLOTEVENT INTERFACE
- *======================================================================*/
-
-static
-unsigned long
-_pkcs11h_slotevent_checksum (
-       IN const unsigned char * const p,
-       IN const size_t s
-);
-static
-void *
-_pkcs11h_slotevent_provider (
-       IN void *p
-);
-static
-void *
-_pkcs11h_slotevent_manager (
-       IN void *p
-);
-static
-CK_RV
-_pkcs11h_slotevent_init ();
-static
-CK_RV
-_pkcs11h_slotevent_notify ();
-static
-CK_RV
-_pkcs11h_slotevent_terminate ();
-
-#endif                         /* ENABLE_PKCS11H_SLOTEVENT */
-
-#if defined(ENABLE_PKCS11H_OPENSSL)
-/*======================================================================*
- * OPENSSL INTERFACE
- *======================================================================*/
-
-static
-int
-_pkcs11h_openssl_finish (
-       IN OUT RSA *rsa
-);
-#if OPENSSL_VERSION_NUMBER < 0x00907000L
-static
-int
-_pkcs11h_openssl_dec (
-       IN int flen,
-       IN unsigned char *from,
-       OUT unsigned char *to,
-       IN OUT RSA *rsa,
-       IN int padding
-);
-static
-int
-_pkcs11h_openssl_sign (
-       IN int type,
-       IN unsigned char *m,
-       IN unsigned int m_len,
-       OUT unsigned char *sigret,
-       OUT unsigned int *siglen,
-       IN OUT RSA *rsa
-);
-#else
-static
-int
-_pkcs11h_openssl_dec (
-       IN int flen,
-       IN const unsigned char *from,
-       OUT unsigned char *to,
-       IN OUT RSA *rsa,
-       IN int padding
-);
-static
-int
-_pkcs11h_openssl_sign (
-       IN int type,
-       IN const unsigned char *m,
-       IN unsigned int m_len,
-       OUT unsigned char *sigret,
-       OUT unsigned int *siglen,
-       IN OUT const RSA *rsa
-);
-#endif
-static
-pkcs11h_openssl_session_t
-_pkcs11h_openssl_get_openssl_session (
-       IN OUT const RSA *rsa
-);  
-static
-pkcs11h_certificate_t
-_pkcs11h_openssl_get_pkcs11h_certificate (
-       IN OUT const RSA *rsa
-);  
-#endif                         /* ENABLE_PKCS11H_OPENSSL */
-
-/*==========================================
- * Static data
- */
-
-#if defined(ENABLE_PKCS11H_THREADING)
-#if !defined(WIN32)
-static struct {
-       pkcs11h_mutex_t mutex;
-       __pkcs11h_mutex_entry_t head;
-} __s_pkcs11h_mutex_list = {
-       PTHREAD_MUTEX_INITIALIZER,
-       NULL
-};
-#endif
-#endif
-
-pkcs11h_data_t s_pkcs11h_data = NULL;
-unsigned int s_pkcs11h_loglevel = PKCS11H_LOG_INFO;
-
-/*======================================================================*
- * PUBLIC INTERFACE
- *======================================================================*/
-
-char *
-pkcs11h_getMessage (
-       IN const int rv
-) {
-       switch (rv) {
-               case CKR_OK: return "CKR_OK";
-               case CKR_CANCEL: return "CKR_CANCEL";
-               case CKR_HOST_MEMORY: return "CKR_HOST_MEMORY";
-               case CKR_SLOT_ID_INVALID: return "CKR_SLOT_ID_INVALID";
-               case CKR_GENERAL_ERROR: return "CKR_GENERAL_ERROR";
-               case CKR_FUNCTION_FAILED: return "CKR_FUNCTION_FAILED";
-               case CKR_ARGUMENTS_BAD: return "CKR_ARGUMENTS_BAD";
-               case CKR_NO_EVENT: return "CKR_NO_EVENT";
-               case CKR_NEED_TO_CREATE_THREADS: return "CKR_NEED_TO_CREATE_THREADS";
-               case CKR_CANT_LOCK: return "CKR_CANT_LOCK";
-               case CKR_ATTRIBUTE_READ_ONLY: return "CKR_ATTRIBUTE_READ_ONLY";
-               case CKR_ATTRIBUTE_SENSITIVE: return "CKR_ATTRIBUTE_SENSITIVE";
-               case CKR_ATTRIBUTE_TYPE_INVALID: return "CKR_ATTRIBUTE_TYPE_INVALID";
-               case CKR_ATTRIBUTE_VALUE_INVALID: return "CKR_ATTRIBUTE_VALUE_INVALID";
-               case CKR_DATA_INVALID: return "CKR_DATA_INVALID";
-               case CKR_DATA_LEN_RANGE: return "CKR_DATA_LEN_RANGE";
-               case CKR_DEVICE_ERROR: return "CKR_DEVICE_ERROR";
-               case CKR_DEVICE_MEMORY: return "CKR_DEVICE_MEMORY";
-               case CKR_DEVICE_REMOVED: return "CKR_DEVICE_REMOVED";
-               case CKR_ENCRYPTED_DATA_INVALID: return "CKR_ENCRYPTED_DATA_INVALID";
-               case CKR_ENCRYPTED_DATA_LEN_RANGE: return "CKR_ENCRYPTED_DATA_LEN_RANGE";
-               case CKR_FUNCTION_CANCELED: return "CKR_FUNCTION_CANCELED";
-               case CKR_FUNCTION_NOT_PARALLEL: return "CKR_FUNCTION_NOT_PARALLEL";
-               case CKR_FUNCTION_NOT_SUPPORTED: return "CKR_FUNCTION_NOT_SUPPORTED";
-               case CKR_KEY_HANDLE_INVALID: return "CKR_KEY_HANDLE_INVALID";
-               case CKR_KEY_SIZE_RANGE: return "CKR_KEY_SIZE_RANGE";
-               case CKR_KEY_TYPE_INCONSISTENT: return "CKR_KEY_TYPE_INCONSISTENT";
-               case CKR_KEY_NOT_NEEDED: return "CKR_KEY_NOT_NEEDED";
-               case CKR_KEY_CHANGED: return "CKR_KEY_CHANGED";
-               case CKR_KEY_NEEDED: return "CKR_KEY_NEEDED";
-               case CKR_KEY_INDIGESTIBLE: return "CKR_KEY_INDIGESTIBLE";
-               case CKR_KEY_FUNCTION_NOT_PERMITTED: return "CKR_KEY_FUNCTION_NOT_PERMITTED";
-               case CKR_KEY_NOT_WRAPPABLE: return "CKR_KEY_NOT_WRAPPABLE";
-               case CKR_KEY_UNEXTRACTABLE: return "CKR_KEY_UNEXTRACTABLE";
-               case CKR_MECHANISM_INVALID: return "CKR_MECHANISM_INVALID";
-               case CKR_MECHANISM_PARAM_INVALID: return "CKR_MECHANISM_PARAM_INVALID";
-               case CKR_OBJECT_HANDLE_INVALID: return "CKR_OBJECT_HANDLE_INVALID";
-               case CKR_OPERATION_ACTIVE: return "CKR_OPERATION_ACTIVE";
-               case CKR_OPERATION_NOT_INITIALIZED: return "CKR_OPERATION_NOT_INITIALIZED";
-               case CKR_PIN_INCORRECT: return "CKR_PIN_INCORRECT";
-               case CKR_PIN_INVALID: return "CKR_PIN_INVALID";
-               case CKR_PIN_LEN_RANGE: return "CKR_PIN_LEN_RANGE";
-               case CKR_PIN_EXPIRED: return "CKR_PIN_EXPIRED";
-               case CKR_PIN_LOCKED: return "CKR_PIN_LOCKED";
-               case CKR_SESSION_CLOSED: return "CKR_SESSION_CLOSED";
-               case CKR_SESSION_COUNT: return "CKR_SESSION_COUNT";
-               case CKR_SESSION_HANDLE_INVALID: return "CKR_SESSION_HANDLE_INVALID";
-               case CKR_SESSION_PARALLEL_NOT_SUPPORTED: return "CKR_SESSION_PARALLEL_NOT_SUPPORTED";
-               case CKR_SESSION_READ_ONLY: return "CKR_SESSION_READ_ONLY";
-               case CKR_SESSION_EXISTS: return "CKR_SESSION_EXISTS";
-               case CKR_SESSION_READ_ONLY_EXISTS: return "CKR_SESSION_READ_ONLY_EXISTS";
-               case CKR_SESSION_READ_WRITE_SO_EXISTS: return "CKR_SESSION_READ_WRITE_SO_EXISTS";
-               case CKR_SIGNATURE_INVALID: return "CKR_SIGNATURE_INVALID";
-               case CKR_SIGNATURE_LEN_RANGE: return "CKR_SIGNATURE_LEN_RANGE";
-               case CKR_TEMPLATE_INCOMPLETE: return "CKR_TEMPLATE_INCOMPLETE";
-               case CKR_TEMPLATE_INCONSISTENT: return "CKR_TEMPLATE_INCONSISTENT";
-               case CKR_TOKEN_NOT_PRESENT: return "CKR_TOKEN_NOT_PRESENT";
-               case CKR_TOKEN_NOT_RECOGNIZED: return "CKR_TOKEN_NOT_RECOGNIZED";
-               case CKR_TOKEN_WRITE_PROTECTED: return "CKR_TOKEN_WRITE_PROTECTED";
-               case CKR_UNWRAPPING_KEY_HANDLE_INVALID: return "CKR_UNWRAPPING_KEY_HANDLE_INVALID";
-               case CKR_UNWRAPPING_KEY_SIZE_RANGE: return "CKR_UNWRAPPING_KEY_SIZE_RANGE";
-               case CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT: return "CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT";
-               case CKR_USER_ALREADY_LOGGED_IN: return "CKR_USER_ALREADY_LOGGED_IN";
-               case CKR_USER_NOT_LOGGED_IN: return "CKR_USER_NOT_LOGGED_IN";
-               case CKR_USER_PIN_NOT_INITIALIZED: return "CKR_USER_PIN_NOT_INITIALIZED";
-               case CKR_USER_TYPE_INVALID: return "CKR_USER_TYPE_INVALID";
-               case CKR_USER_ANOTHER_ALREADY_LOGGED_IN: return "CKR_USER_ANOTHER_ALREADY_LOGGED_IN";
-               case CKR_USER_TOO_MANY_TYPES: return "CKR_USER_TOO_MANY_TYPES";
-               case CKR_WRAPPED_KEY_INVALID: return "CKR_WRAPPED_KEY_INVALID";
-               case CKR_WRAPPED_KEY_LEN_RANGE: return "CKR_WRAPPED_KEY_LEN_RANGE";
-               case CKR_WRAPPING_KEY_HANDLE_INVALID: return "CKR_WRAPPING_KEY_HANDLE_INVALID";
-               case CKR_WRAPPING_KEY_SIZE_RANGE: return "CKR_WRAPPING_KEY_SIZE_RANGE";
-               case CKR_WRAPPING_KEY_TYPE_INCONSISTENT: return "CKR_WRAPPING_KEY_TYPE_INCONSISTENT";
-               case CKR_RANDOM_SEED_NOT_SUPPORTED: return "CKR_RANDOM_SEED_NOT_SUPPORTED";
-               case CKR_RANDOM_NO_RNG: return "CKR_RANDOM_NO_RNG";
-               case CKR_DOMAIN_PARAMS_INVALID: return "CKR_DOMAIN_PARAMS_INVALID";
-               case CKR_BUFFER_TOO_SMALL: return "CKR_BUFFER_TOO_SMALL";
-               case CKR_SAVED_STATE_INVALID: return "CKR_SAVED_STATE_INVALID";
-               case CKR_INFORMATION_SENSITIVE: return "CKR_INFORMATION_SENSITIVE";
-               case CKR_STATE_UNSAVEABLE: return "CKR_STATE_UNSAVEABLE";
-               case CKR_CRYPTOKI_NOT_INITIALIZED: return "CKR_CRYPTOKI_NOT_INITIALIZED";
-               case CKR_CRYPTOKI_ALREADY_INITIALIZED: return "CKR_CRYPTOKI_ALREADY_INITIALIZED";
-               case CKR_MUTEX_BAD: return "CKR_MUTEX_BAD";
-               case CKR_MUTEX_NOT_LOCKED: return "CKR_MUTEX_NOT_LOCKED";
-               case CKR_FUNCTION_REJECTED: return "CKR_FUNCTION_REJECTED";
-               case CKR_VENDOR_DEFINED: return "CKR_VENDOR_DEFINED";
-               default: return "Unknown PKCS#11 error";
-       }
-}
-
-CK_RV
-pkcs11h_initialize () {
-
-#if defined(ENABLE_PKCS11H_THREADING)
-       PKCS11H_BOOL fMutexLocked = FALSE;
-#endif
-       CK_RV rv = CKR_OK;
-
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: pkcs11h_initialize entry"
-       );
-
-       pkcs11h_terminate ();
-
-       if (rv == CKR_OK) {
-               rv = _pkcs11h_malloc ((void*)&s_pkcs11h_data, sizeof (struct pkcs11h_data_s));
-       }
-
-#if defined(ENABLE_PKCS11H_THREADING)
-       if (rv == CKR_OK) {
-               rv = _pkcs11h_mutexInit (&s_pkcs11h_data->mutexGlobal); 
-       }
-       if (rv == CKR_OK) {
-               rv = _pkcs11h_mutexInit (&s_pkcs11h_data->mutexSession); 
-       }
-       if (rv == CKR_OK) {
-               rv = _pkcs11h_mutexInit (&s_pkcs11h_data->mutexCache); 
-       }
-#if !defined(WIN32)
-       if (
-               rv == CKR_OK &&
-               pthread_atfork (
-                       __pkcs11h_atfork_prepare,
-                       __pkcs11h_atfork_parent,
-                       __pkcs11h_atfork_child
-               )
-       ) {
-               rv = CKR_FUNCTION_FAILED;
-       }
-#endif
-       if (
-               rv == CKR_OK &&
-               (rv = _pkcs11h_mutexLock (&s_pkcs11h_data->mutexGlobal)) == CKR_OK
-       ) {
-               fMutexLocked = TRUE;
-       }
-#endif
-
-       if (rv == CKR_OK) {
-               s_pkcs11h_data->nMaxLoginRetries = PKCS11H_DEFAULT_MAX_LOGIN_RETRY;
-               s_pkcs11h_data->fProtectedAuthentication = TRUE;
-               s_pkcs11h_data->nPINCachePeriod = PKCS11H_DEFAULT_PIN_CACHE_PERIOD;
-               s_pkcs11h_data->fInitialized = TRUE;
-       }
-
-       if (rv == CKR_OK) {
-               pkcs11h_setLogHook (_pkcs11h_hooks_default_log, NULL);
-               pkcs11h_setTokenPromptHook (_pkcs11h_hooks_default_token_prompt, NULL);
-               pkcs11h_setPINPromptHook (_pkcs11h_hooks_default_pin_prompt, NULL);
-       }
-       
-#if defined(ENABLE_PKCS11H_THREADING)
-       if (fMutexLocked) {
-               _pkcs11h_mutexRelease (&s_pkcs11h_data->mutexGlobal);
-               fMutexLocked = FALSE;
-       }
-#endif
-
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: pkcs11h_initialize return rv=%ld-'%s'",
-               rv,
-               pkcs11h_getMessage (rv)
-       );
-
-       return rv;
-}
-
-CK_RV
-pkcs11h_terminate () {
-
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: pkcs11h_terminate entry"
-       );
-
-       if (s_pkcs11h_data != NULL) {
-               pkcs11h_provider_t current_provider = NULL;
-
-               PKCS11H_DEBUG (
-                       PKCS11H_LOG_DEBUG1,
-                       "PKCS#11: Removing providers"
-               );
-
-               for (
-                       current_provider = s_pkcs11h_data->providers;
-                       current_provider != NULL;
-                       current_provider = current_provider->next
-               ) {
-                       pkcs11h_removeProvider (current_provider->szReferenceName);
-               }
-
-#if defined(ENABLE_PKCS11H_THREADING)
-               _pkcs11h_mutexLock (&s_pkcs11h_data->mutexCache);
-               _pkcs11h_mutexLock (&s_pkcs11h_data->mutexSession);
-               _pkcs11h_mutexLock (&s_pkcs11h_data->mutexGlobal);
-#endif
-
-               PKCS11H_DEBUG (
-                       PKCS11H_LOG_DEBUG1,
-                       "PKCS#11: Releasing sessions"
-               );
-
-               while (s_pkcs11h_data->sessions != NULL) {
-                       pkcs11h_session_t current = s_pkcs11h_data->sessions;
-                       s_pkcs11h_data->sessions = s_pkcs11h_data->sessions->next;
-
-#if defined(ENABLE_PKCS11H_THREADING)
-                       _pkcs11h_mutexLock (&current->mutexSession);
-#endif
-
-                       current->fValid = FALSE;
-
-                       if (current->nReferenceCount != 0) {
-                               PKCS11H_DEBUG (
-                                       PKCS11H_LOG_DEBUG1,
-                                       "PKCS#11: Warning: Found session with references"
-                               );
-                       }
-
-                       if (current->token_id != NULL) {
-                               pkcs11h_freeTokenId (current->token_id);
-                               current->token_id = NULL;
-                       }
-
-#if defined(ENABLE_PKCS11H_ENUM)
-#if defined(ENABLE_PKCS11H_CERTIFICATE)
-                       pkcs11h_freeCertificateIdList (current->cached_certs);
-#endif
-#endif
-
-                       current->provider = NULL;
-
-#if defined(ENABLE_PKCS11H_THREADING)
-                       _pkcs11h_mutexFree (&current->mutexSession);
-#endif
-
-                       _pkcs11h_free ((void *)&current);
-               }
-
-#if defined(ENABLE_PKCS11H_SLOTEVENT)
-               PKCS11H_DEBUG (
-                       PKCS11H_LOG_DEBUG1,
-                       "PKCS#11: Terminating slotevent"
-               );
-
-               _pkcs11h_slotevent_terminate ();
-#endif
-               PKCS11H_DEBUG (
-                       PKCS11H_LOG_DEBUG1,
-                       "PKCS#11: Marking as uninitialized"
-               );
-               
-               s_pkcs11h_data->fInitialized = FALSE;
-
-               while (s_pkcs11h_data->providers != NULL) {
-                       pkcs11h_provider_t current = s_pkcs11h_data->providers;
-                       s_pkcs11h_data->providers = s_pkcs11h_data->providers->next;
-
-                       _pkcs11h_free ((void *)&current);
-               }
-
-#if defined(ENABLE_PKCS11H_THREADING)
-               _pkcs11h_mutexFree (&s_pkcs11h_data->mutexCache);
-               _pkcs11h_mutexFree (&s_pkcs11h_data->mutexGlobal); 
-               _pkcs11h_mutexFree (&s_pkcs11h_data->mutexSession); 
-#endif
-
-               _pkcs11h_free ((void *)&s_pkcs11h_data);
-       }
-
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: pkcs11h_terminate return"
-       );
-
-       return CKR_OK;
-}
-
-void
-pkcs11h_setLogLevel (
-       IN const unsigned flags
-) {
-       s_pkcs11h_loglevel = flags;
-}
-
-unsigned
-pkcs11h_getLogLevel () {
-       PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
-       PKCS11H_ASSERT (s_pkcs11h_data->fInitialized);
-
-       return s_pkcs11h_loglevel;
-}
-
-CK_RV
-pkcs11h_setLogHook (
-       IN const pkcs11h_hook_log_t hook,
-       IN void * const pData
-) {
-       PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
-       PKCS11H_ASSERT (s_pkcs11h_data->fInitialized);
-       PKCS11H_ASSERT (hook!=NULL);
-
-       s_pkcs11h_data->hooks.log = hook;
-       s_pkcs11h_data->hooks.log_data = pData;
-
-       return CKR_OK;
-}
-
-CK_RV
-pkcs11h_setSlotEventHook (
-       IN const pkcs11h_hook_slotevent_t hook,
-       IN void * const pData
-) {
-       PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
-       PKCS11H_ASSERT (s_pkcs11h_data->fInitialized);
-       PKCS11H_ASSERT (hook!=NULL);
-
-#if defined(ENABLE_PKCS11H_SLOTEVENT)
-       s_pkcs11h_data->hooks.slotevent = hook;
-       s_pkcs11h_data->hooks.slotevent_data = pData;
-
-       return _pkcs11h_slotevent_init ();
-#else
-       return CKR_FUNCTION_NOT_SUPPORTED;
-#endif
-}
-
-CK_RV
-pkcs11h_setPINPromptHook (
-       IN const pkcs11h_hook_pin_prompt_t hook,
-       IN void * const pData
-) {
-       PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
-       PKCS11H_ASSERT (s_pkcs11h_data->fInitialized);
-       PKCS11H_ASSERT (hook!=NULL);
-
-       s_pkcs11h_data->hooks.pin_prompt = hook;
-       s_pkcs11h_data->hooks.pin_prompt_data = pData;
-
-       return CKR_OK;
-}
-
-CK_RV
-pkcs11h_setTokenPromptHook (
-       IN const pkcs11h_hook_token_prompt_t hook,
-       IN void * const pData
-) {
-       PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
-       PKCS11H_ASSERT (s_pkcs11h_data->fInitialized);
-       PKCS11H_ASSERT (hook!=NULL);
-
-       s_pkcs11h_data->hooks.token_prompt = hook;
-       s_pkcs11h_data->hooks.token_prompt_data = pData;
-
-       return CKR_OK;
-}
-
-CK_RV
-pkcs11h_setPINCachePeriod (
-       IN const int nPINCachePeriod
-) {
-       PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
-       PKCS11H_ASSERT (s_pkcs11h_data->fInitialized);
-
-       s_pkcs11h_data->nPINCachePeriod = nPINCachePeriod;
-
-       return CKR_OK;
-}
-
-CK_RV
-pkcs11h_setMaxLoginRetries (
-       IN const unsigned nMaxLoginRetries
-) {
-       PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
-       PKCS11H_ASSERT (s_pkcs11h_data->fInitialized);
-
-       s_pkcs11h_data->nMaxLoginRetries = nMaxLoginRetries;
-
-       return CKR_OK;
-}
-
-CK_RV
-pkcs11h_setProtectedAuthentication (
-       IN const PKCS11H_BOOL fProtectedAuthentication
-) {
-       PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
-       PKCS11H_ASSERT (s_pkcs11h_data->fInitialized);
-
-       s_pkcs11h_data->fProtectedAuthentication = fProtectedAuthentication;
-
-       return CKR_OK;
-}
-
-CK_RV
-pkcs11h_addProvider (
-       IN const char * const szReferenceName,
-       IN const char * const szProvider,
-       IN const PKCS11H_BOOL fProtectedAuthentication,
-       IN const unsigned maskSignMode,
-       IN const int nSlotEventMethod,
-       IN const int nSlotEventPollInterval,
-       IN const PKCS11H_BOOL fCertIsPrivate
-) {
-#if defined(ENABLE_PKCS11H_THREADING)
-       PKCS11H_BOOL fMutexLocked = FALSE;
-#endif
-#if defined(WIN32)
-       int mypid = 0;
-#else
-       pid_t mypid = getpid ();
-#endif
-       pkcs11h_provider_t provider = NULL;
-       CK_C_GetFunctionList gfl = NULL;
-       CK_INFO info;
-       CK_RV rv = CKR_OK;
-
-       PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
-       PKCS11H_ASSERT (s_pkcs11h_data->fInitialized);
-       PKCS11H_ASSERT (szProvider!=NULL);
-       /*PKCS11H_ASSERT (szSignMode!=NULL); NOT NEEDED*/
-
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: pkcs11h_addProvider entry pid=%d, szReferenceName=%s, szProvider='%s', fProtectedAuthentication=%d, maskSignMode=%08x, fCertIsPrivate=%d",
-               mypid,
-               szReferenceName,
-               szProvider,
-               fProtectedAuthentication ? 1 : 0,
-               maskSignMode,
-               fCertIsPrivate ? 1 : 0
-       );
-
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG1,
-               "PKCS#11: Adding provider '%s'-'%s'",
-               szReferenceName,
-               szProvider
-       );
-
-#if defined(ENABLE_PKCS11H_THREADING)
-       if (
-               rv == CKR_OK &&
-               (rv = _pkcs11h_mutexLock (&s_pkcs11h_data->mutexGlobal)) == CKR_OK
-       ) {
-               fMutexLocked = TRUE;
-       }
-#endif
-
-       if (
-               rv == CKR_OK &&
-               (rv = _pkcs11h_malloc ((void *)&provider, sizeof (struct pkcs11h_provider_s))) == CKR_OK
-       ) {
-               strncpy (
-                       provider->szReferenceName,
-                       szReferenceName,
-                       sizeof (provider->szReferenceName)-1
-               );
-               provider->szReferenceName[sizeof (provider->szReferenceName)-1] = '\x0';
-               strncpy (
-                       provider->manufacturerID,
-                       (
-                               strlen (szProvider) < sizeof (provider->manufacturerID) ?
-                               szProvider :
-                               szProvider+strlen (szProvider)-sizeof (provider->manufacturerID)+1
-                       ),
-                       sizeof (provider->manufacturerID)-1
-               );
-               provider->manufacturerID[sizeof (provider->manufacturerID)-1] = '\x0';
-               provider->fProtectedAuthentication = fProtectedAuthentication;
-               provider->maskSignMode = maskSignMode;
-               provider->nSlotEventMethod = nSlotEventMethod;
-               provider->nSlotEventPollInterval = nSlotEventPollInterval;
-               provider->fCertIsPrivate = fCertIsPrivate;
-       }
-               
-       if (rv == CKR_OK) {
-#if defined(WIN32)
-               provider->hLibrary = LoadLibraryA (szProvider);
-#else
-               provider->hLibrary = dlopen (szProvider, RTLD_NOW);
-#endif
-               if (provider->hLibrary == NULL) {
-                       rv = CKR_FUNCTION_FAILED;
-               }
-       }
-
-       if (rv == CKR_OK) {
-#if defined(WIN32)
-               gfl = (CK_C_GetFunctionList)GetProcAddress (
-                       provider->hLibrary,
-                       "C_GetFunctionList"
-               );
-#else
-               /*
-                * Make compiler happy!
-                */
-               void *p = dlsym (
-                       provider->hLibrary,
-                       "C_GetFunctionList"
-               );
-               memmove (
-                       &gfl, 
-                       &p,
-                       sizeof (void *)
-               );
-#endif
-               if (gfl == NULL) {
-                       rv = CKR_FUNCTION_FAILED;
-               }
-       }
-
-       if (rv == CKR_OK) {
-               rv = gfl (&provider->f);
-       }
-
-       if (rv == CKR_OK) {
-               if ((rv = provider->f->C_Initialize (NULL)) != CKR_OK) {
-                       if (rv == CKR_CRYPTOKI_ALREADY_INITIALIZED) {
-                               rv = CKR_OK;
-                       }
-               }
-               else {
-                       provider->fShouldFinalize = TRUE;
-               }
-       }
-
-       if (
-               rv == CKR_OK &&
-               (rv = provider->f->C_GetInfo (&info)) == CKR_OK
-       ) {
-               _pkcs11h_fixupFixedString (
-                       provider->manufacturerID,
-                       (char *)info.manufacturerID,
-                       sizeof (info.manufacturerID)
-               );
-       }
-
-       if (rv == CKR_OK) {
-               provider->fEnabled = TRUE;
-       }
-
-       if (provider != NULL) {
-               if (s_pkcs11h_data->providers == NULL) {
-                       s_pkcs11h_data->providers = provider;
-               }
-               else {
-                       pkcs11h_provider_t last = NULL;
-       
-                       for (
-                               last = s_pkcs11h_data->providers;
-                               last->next != NULL;
-                               last = last->next
-                       );
-                       last->next = provider;
-               }
-       }
-
-#if defined(ENABLE_PKCS11H_THREADING)
-       if (fMutexLocked) {
-               _pkcs11h_mutexRelease (&s_pkcs11h_data->mutexGlobal);
-               fMutexLocked = FALSE;
-       }
-#endif
-
-#if defined(ENABLE_PKCS11H_SLOTEVENT)
-       _pkcs11h_slotevent_notify ();
-#endif
-
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG1,
-               "PKCS#11: Provider '%s' added rv=%ld-'%s'",
-               szReferenceName,
-               rv,
-               pkcs11h_getMessage (rv)
-       );
-
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: pkcs11h_addProvider return rv=%ld-'%s'",
-               rv,
-               pkcs11h_getMessage (rv)
-       );
-
-       return rv;
-}
-
-CK_RV
-pkcs11h_removeProvider (
-       IN const char * const szReferenceName
-) {
-#if defined(ENABLE_PKCS11H_THREADING)
-       pkcs11h_session_t current_session = NULL;
-#endif
-       pkcs11h_provider_t provider = NULL;
-       CK_RV rv = CKR_OK;
-
-       PKCS11H_ASSERT (szReferenceName!=NULL);
-
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: pkcs11h_removeProvider entry szReferenceName='%s'",
-               szReferenceName
-       );
-
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG1,
-               "PKCS#11: Removing provider '%s'",
-               szReferenceName
-       );
-
-#if defined(ENABLE_PKCS11H_THREADING)
-       _pkcs11h_mutexLock (&s_pkcs11h_data->mutexCache);
-       _pkcs11h_mutexLock (&s_pkcs11h_data->mutexSession);
-       _pkcs11h_mutexLock (&s_pkcs11h_data->mutexGlobal);
-
-       for (
-               current_session = s_pkcs11h_data->sessions;
-               current_session != NULL;
-               current_session = current_session->next
-       ) {
-               _pkcs11h_mutexLock (&current_session->mutexSession);
-       }
-#endif
-
-       provider = s_pkcs11h_data->providers;
-       while (
-               rv == CKR_OK &&
-               provider != NULL &&
-               strcmp (szReferenceName, provider->szReferenceName)
-       ) {
-               provider = provider->next;
-       }
-
-       if (rv == CKR_OK && provider == NULL) {
-               rv = CKR_OBJECT_HANDLE_INVALID;
-       }
-
-       if (rv == CKR_OK) {
-               provider->fEnabled = FALSE;
-               provider->szReferenceName[0] = '\0';
-
-               if (provider->fShouldFinalize) {
-                       provider->f->C_Finalize (NULL);
-                       provider->fShouldFinalize = FALSE;
-               }
-
-#if defined(ENABLE_PKCS11H_SLOTEVENT)
-               _pkcs11h_slotevent_notify ();
-               
-               /*
-                * Wait until manager join this thread
-                * this happens saldom so I can poll
-                */
-               while (provider->threadSlotEvent != PKCS11H_THREAD_NULL) {
-                       _pkcs11h_sleep (500);
-               }
-#endif
-
-               if (provider->f != NULL) {
-                       provider->f = NULL;
-               }
-
-               if (provider->hLibrary != NULL) {
-#if defined(WIN32)
-                       FreeLibrary (provider->hLibrary);
-#else
-                       dlclose (provider->hLibrary);
-#endif
-                       provider->hLibrary = NULL;
-               }
-       }
-
-#if defined(ENABLE_PKCS11H_THREADING)
-       for (
-               current_session = s_pkcs11h_data->sessions;
-               current_session != NULL;
-               current_session = current_session->next
-       ) {
-               _pkcs11h_mutexRelease (&current_session->mutexSession);
-       }
-
-       _pkcs11h_mutexRelease (&s_pkcs11h_data->mutexCache);
-       _pkcs11h_mutexRelease (&s_pkcs11h_data->mutexSession);
-       _pkcs11h_mutexRelease (&s_pkcs11h_data->mutexGlobal);
-#endif
-       
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: pkcs11h_removeProvider return rv=%ld-'%s'",
-               rv,
-               pkcs11h_getMessage (rv)
-       );
-
-       return rv;
-}
-
-CK_RV
-pkcs11h_forkFixup () {
-#if defined(WIN32)
-       return CKR_OK;
-#else
-#if defined(ENABLE_PKCS11H_THREADING)
-       return CKR_OK;
-#else
-       return _pkcs11h_forkFixup ();
-#endif
-#endif
-}
-
-CK_RV
-pkcs11h_plugAndPlay () {
-#if defined(WIN32)
-       int mypid = 0;
-#else
-       pid_t mypid = getpid ();
-#endif
-
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: pkcs11h_forkFixup entry pid=%d",
-               mypid
-       );
-
-       if (s_pkcs11h_data != NULL && s_pkcs11h_data->fInitialized) {
-               pkcs11h_provider_t current;
-#if defined(ENABLE_PKCS11H_SLOTEVENT)
-               PKCS11H_BOOL fSlotEventActive = FALSE;
-#endif
-
-#if defined(ENABLE_PKCS11H_THREADING)
-               _pkcs11h_mutexLock (&s_pkcs11h_data->mutexGlobal);
-#endif
-               for (
-                       current = s_pkcs11h_data->providers;
-                       current != NULL;
-                       current = current->next
-               ) {
-                       if (current->fEnabled) {
-                               current->f->C_Finalize (NULL);
-                       }
-               }
-
-#if defined(ENABLE_PKCS11H_SLOTEVENT)
-               if (s_pkcs11h_data->fSlotEventInitialized) {
-                       fSlotEventActive = TRUE;
-                       _pkcs11h_slotevent_terminate ();
-               }
-#endif
-
-               for (
-                       current = s_pkcs11h_data->providers;
-                       current != NULL;
-                       current = current->next
-               ) {
-                       if (current->fEnabled) {
-                               current->f->C_Initialize (NULL);
-                       }
-               }
-
-#if defined(ENABLE_PKCS11H_SLOTEVENT)
-               if (fSlotEventActive) {
-                       _pkcs11h_slotevent_init ();
-               }
-#endif
-
-#if defined(ENABLE_PKCS11H_THREADING)
-               _pkcs11h_mutexRelease (&s_pkcs11h_data->mutexGlobal);
-#endif
-       }
-
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: pkcs11h_forkFixup return"
-       );
-
-       return CKR_OK;
-}
-
-CK_RV
-pkcs11h_freeTokenId (
-       IN pkcs11h_token_id_t token_id
-) {
-       PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
-       PKCS11H_ASSERT (s_pkcs11h_data->fInitialized);
-       PKCS11H_ASSERT (token_id!=NULL);
-
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: pkcs11h_freeTokenId entry certificate_id=%p",
-               (void *)token_id
-       );
-
-       _pkcs11h_free ((void *)&token_id);
-
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: pkcs11h_freeTokenId return"
-       );
-
-       return CKR_OK;
-}
-
-CK_RV
-pkcs11h_duplicateTokenId (
-       OUT pkcs11h_token_id_t * const to,
-       IN const pkcs11h_token_id_t from
-) {
-       CK_RV rv = CKR_OK;
-
-       PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
-       PKCS11H_ASSERT (s_pkcs11h_data->fInitialized);
-       PKCS11H_ASSERT (to!=NULL);
-       PKCS11H_ASSERT (from!=NULL);
-
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: pkcs11h_duplicateTokenId entry to=%p form=%p",
-               (void *)to,
-               (void *)from
-       );
-
-       *to = NULL;
-
-       if (rv == CKR_OK) {
-               rv = _pkcs11h_dupmem (
-                       (void*)to,
-                       NULL,
-                       from,
-                       sizeof (struct pkcs11h_token_id_s)
-               );
-       }
-
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: pkcs11h_duplicateTokenId return rv=%ld-'%s', *to=%p",
-               rv,
-               pkcs11h_getMessage (rv),
-               (void *)*to
-       );
-       
-       return rv;
-}
-
-PKCS11H_BOOL
-pkcs11h_sameTokenId (
-       IN const pkcs11h_token_id_t a,
-       IN const pkcs11h_token_id_t b
-) {
-       PKCS11H_ASSERT (a!=NULL);
-       PKCS11H_ASSERT (b!=NULL);
-
-       return (
-               !strcmp (a->manufacturerID, b->manufacturerID) &&
-               !strcmp (a->model, b->model) &&
-               !strcmp (a->serialNumber, b->serialNumber)
-       );
-}
-
-/*======================================================================*
- * MEMORY INTERFACE
- *======================================================================*/
-
-static
-CK_RV
-_pkcs11h_malloc (
-       OUT const void ** const p,
-       IN const size_t s
-) {
-       CK_RV rv = CKR_OK;
-
-       PKCS11H_ASSERT (p!=NULL);
-       PKCS11H_ASSERT (s!=0);
-
-       *p = NULL;
-
-       if (s > 0) {
-               if (
-                       (*p = (void *)malloc (s)) == NULL
-               ) {
-                       rv = CKR_HOST_MEMORY;
-               }
-               else {
-                       memset ((void *)*p, 0, s);
-               }
-       }
-
-       return rv;
-}
-
-static
-CK_RV
-_pkcs11h_free (
-       IN const void ** const p
-) {
-       PKCS11H_ASSERT (p!=NULL);
-
-       free ((void *)*p);
-       *p = NULL;
-
-       return CKR_OK;
-}
-
-static
-CK_RV
-_pkcs11h_dupmem (
-       OUT const void ** const dest,
-       OUT size_t * const p_dest_size,
-       IN const void * const src,
-       IN const size_t mem_size
-) {
-       CK_RV rv = CKR_OK;
-
-       PKCS11H_ASSERT (dest!=NULL);
-       /*PKCS11H_ASSERT (dest_size!=NULL); NOT NEEDED*/
-       PKCS11H_ASSERT (!(mem_size!=0&&src==NULL));
-
-       *dest = NULL;
-       if (p_dest_size != NULL) {
-               *p_dest_size = 0;
-       }
-
-       if (src != NULL) {
-               if (
-                       rv == CKR_OK &&
-                       (rv = _pkcs11h_malloc (dest, mem_size)) == CKR_OK
-               ) {
-                       if (p_dest_size != NULL) {
-                               *p_dest_size = mem_size;
-                       }
-                       memmove ((void*)*dest, src, mem_size);
-               }
-       }
-
-       return rv;
-}
-
-#if defined(ENABLE_PKCS11H_THREADING)
-/*======================================================================*
- * THREADING INTERFACE
- *======================================================================*/
-
-static
-void
-_pkcs11h_sleep (
-       IN const unsigned milli
-) {
-#if defined(WIN32)
-       Sleep (milli);
-#else
-       usleep (milli*1000);
-#endif
-}
-
-static
-CK_RV
-_pkcs11h_mutexInit (
-       OUT pkcs11h_mutex_t * const mutex
-) {
-       CK_RV rv = CKR_OK;
-#if defined(WIN32)
-       if (
-               rv == CKR_OK &&
-               (*mutex = CreateMutex (NULL, FALSE, NULL)) == NULL
-       ) {
-               rv = CKR_FUNCTION_FAILED;
-       }
-#else
-       {
-               __pkcs11h_mutex_entry_t entry = NULL;
-               PKCS11H_BOOL fMutexLocked = FALSE;
-
-               if (
-                       rv == CKR_OK &&
-                       (rv = _pkcs11h_mutexLock (&__s_pkcs11h_mutex_list.mutex)) == CKR_OK
-               ) {
-                       fMutexLocked = TRUE;
-               }
-               
-               if (rv == CKR_OK) {
-                       rv = _pkcs11h_malloc (
-                               (void *)&entry,
-                               sizeof (struct __pkcs11h_mutex_entry_s)
-                       );
-               }
-
-               if (
-                       rv == CKR_OK &&
-                       pthread_mutex_init (mutex, NULL)
-               ) {
-                       rv = CKR_FUNCTION_FAILED;
-               }
-
-               if (rv == CKR_OK) {
-                       entry->p_mutex = mutex;
-                       entry->next = __s_pkcs11h_mutex_list.head;
-                       __s_pkcs11h_mutex_list.head = entry;
-                       entry = NULL;
-               }
-
-               if (entry != NULL) {
-                       _pkcs11h_free ((void *)&entry);
-               }
-
-               if (fMutexLocked) {
-                       _pkcs11h_mutexRelease (&__s_pkcs11h_mutex_list.mutex);
-                       fMutexLocked = FALSE;
-               }
-       }
-#endif
-       return rv;
-}
-
-static
-CK_RV
-_pkcs11h_mutexLock (
-       IN OUT pkcs11h_mutex_t *const mutex
-) {
-       CK_RV rv = CKR_OK;
-#if defined(WIN32)
-       if (
-               rv == CKR_OK &&
-               WaitForSingleObject (*mutex, INFINITE) == WAIT_FAILED
-       ) {
-               rv = CKR_FUNCTION_FAILED;
-       }
-#else
-       if (
-               rv == CKR_OK &&
-               pthread_mutex_lock (mutex)
-       ) {
-               rv = CKR_FUNCTION_FAILED;
-       }
-#endif
-       return rv;
-}
-
-static
-CK_RV
-_pkcs11h_mutexRelease (
-       IN OUT pkcs11h_mutex_t *const mutex
-) {
-       CK_RV rv = CKR_OK;
-#if defined(WIN32)
-       if (
-               rv == CKR_OK &&
-               !ReleaseMutex (*mutex)
-       ) {
-               rv = CKR_FUNCTION_FAILED;
-       }
-#else
-       if (
-               rv == CKR_OK &&
-               pthread_mutex_unlock (mutex)
-       ) {
-               rv = CKR_FUNCTION_FAILED;
-       }
-#endif
-       return rv;
-}
-
-static
-CK_RV
-_pkcs11h_mutexFree (
-       IN OUT pkcs11h_mutex_t *const mutex
-) {
-#if defined(WIN32)
-       if (*mutex != NULL) {
-               CloseHandle (*mutex);
-               *mutex = NULL;
-       }
-#else
-       {
-               __pkcs11h_mutex_entry_t last = NULL;
-               __pkcs11h_mutex_entry_t entry = NULL;
-               PKCS11H_BOOL fMutexLocked = FALSE;
-
-               if (_pkcs11h_mutexLock (&__s_pkcs11h_mutex_list.mutex) == CKR_OK) {
-                       fMutexLocked = TRUE;
-               }
-
-               entry =  __s_pkcs11h_mutex_list.head;
-               while (
-                       entry != NULL &&
-                       entry->p_mutex != mutex
-               ) {
-                       last = entry;
-                       entry = entry->next;
-               }
-
-               if (entry != NULL) {
-                       if (last == NULL) {
-                               __s_pkcs11h_mutex_list.head = entry->next;
-                       }
-                       else {
-                               last->next = entry->next;
-                       }
-                       _pkcs11h_free ((void *)&entry);
-               }
-
-               pthread_mutex_destroy (mutex);
-
-               if (fMutexLocked) {
-                       _pkcs11h_mutexRelease (&__s_pkcs11h_mutex_list.mutex);
-                       fMutexLocked = FALSE;
-               }
-       }
-#endif
-       return CKR_OK;
-}
-
-#if !defined(WIN32)
-/*
- * This function is required in order
- * to lock all mutexes before fork is called,
- * and to avoid dedlocks.
- * The loop is required because there is no
- * way to lock all mutex in one system call...
- */
-static
-void
-__pkcs1h_mutexLockAll () {
-       __pkcs11h_mutex_entry_t entry = NULL;
-       PKCS11H_BOOL fMutexLocked = FALSE;
-       PKCS11H_BOOL fAllLocked = FALSE;
-
-       if (_pkcs11h_mutexLock (&__s_pkcs11h_mutex_list.mutex) == CKR_OK) {
-               fMutexLocked = TRUE;
-       }
-
-       for (
-               entry = __s_pkcs11h_mutex_list.head;
-               entry != NULL;
-               entry = entry->next
-       ) {
-               entry->fLocked = FALSE;
-       }
-
-       while (!fAllLocked) {
-               PKCS11H_BOOL fOK = TRUE;
-               
-               for (
-                       entry = __s_pkcs11h_mutex_list.head;
-                       entry != NULL && fOK;
-                       entry = entry->next
-               ) {
-                       if (!pthread_mutex_trylock (entry->p_mutex)) {
-                               entry->fLocked = TRUE;
-                       }
-                       else {
-                               fOK = FALSE;
-                       }
-               }
-
-               if (!fOK) {
-                       for (
-                               entry = __s_pkcs11h_mutex_list.head;
-                               entry != NULL;
-                               entry = entry->next
-                       ) {
-                               if (entry->fLocked == TRUE) {
-                                       pthread_mutex_unlock (entry->p_mutex);
-                                       entry->fLocked = FALSE;
-                               }
-                       }
-
-                       _pkcs11h_mutexRelease (&__s_pkcs11h_mutex_list.mutex);
-                       _pkcs11h_sleep (1000);
-                       _pkcs11h_mutexLock (&__s_pkcs11h_mutex_list.mutex);
-               }
-               else {
-                       fAllLocked  = TRUE;
-               }
-       }
-
-       if (fMutexLocked) {
-               _pkcs11h_mutexRelease (&__s_pkcs11h_mutex_list.mutex);
-               fMutexLocked = FALSE;
-       }
-}
-
-static
-void
-__pkcs1h_mutexReleaseAll () {
-       __pkcs11h_mutex_entry_t entry = NULL;
-       PKCS11H_BOOL fMutexLocked = FALSE;
-
-       if (_pkcs11h_mutexLock (&__s_pkcs11h_mutex_list.mutex) == CKR_OK) {
-               fMutexLocked = TRUE;
-       }
-
-       for (
-               entry = __s_pkcs11h_mutex_list.head;
-               entry != NULL;
-               entry = entry->next
-       ) {
-               pthread_mutex_unlock (entry->p_mutex);
-               entry->fLocked = FALSE;
-       }
-
-       if (fMutexLocked) {
-               _pkcs11h_mutexRelease (&__s_pkcs11h_mutex_list.mutex);
-               fMutexLocked = FALSE;
-       }
-}
-#endif
-
-CK_RV
-_pkcs11h_condSignal (
-       IN OUT pkcs11h_cond_t *const cond
-) {
-       CK_RV rv = CKR_OK;
-#if defined(WIN32)
-       if (
-               rv == CKR_OK &&
-               !SetEvent (*cond)
-       ) {
-               rv = CKR_FUNCTION_FAILED;
-       }
-#else
-       if (
-               rv == CKR_OK &&
-               (
-                       pthread_mutex_lock (&cond->mut) ||
-                       pthread_cond_signal (&cond->cond) ||
-                       pthread_mutex_unlock (&cond->mut)
-               )
-       ) {
-               rv = CKR_FUNCTION_FAILED;
-       }
-#endif
-
-       return rv;
-}
-
-static
-CK_RV
-_pkcs11h_condInit (
-       OUT pkcs11h_cond_t * const cond
-) {
-       CK_RV rv = CKR_OK;
-#if defined(WIN32)
-       if (
-               rv == CKR_OK &&
-               (*cond = CreateEvent (NULL, FALSE, FALSE, NULL)) == NULL
-       ) {
-               rv = CKR_FUNCTION_FAILED;
-       }
-#else
-       if (
-               rv == CKR_OK &&
-               (
-                       pthread_mutex_init (&cond->mut, NULL) ||
-                       pthread_cond_init (&cond->cond, NULL) ||
-                       pthread_mutex_lock (&cond->mut)
-               )
-       ) {
-               rv = CKR_FUNCTION_FAILED;
-       }
-#endif
-       return rv;
-}
-
-static
-CK_RV
-_pkcs11h_condWait (
-       IN OUT pkcs11h_cond_t *const cond,
-       IN const unsigned milli
-) {
-       CK_RV rv = CKR_OK;
-
-#if defined(WIN32)
-       DWORD dwMilli;
-
-       if (milli == PKCS11H_COND_INFINITE) {
-               dwMilli = INFINITE;
-       }
-       else {
-               dwMilli = milli;
-       }
-
-       if (
-               rv == CKR_OK &&
-               WaitForSingleObject (*cond, dwMilli) == WAIT_FAILED
-       ) {
-               rv = CKR_FUNCTION_FAILED;
-       }
-#else
-       if (milli == PKCS11H_COND_INFINITE) {
-               if (
-                       rv == CKR_OK &&
-                       pthread_cond_wait (&cond->cond, &cond->mut)
-               ) {
-                       rv = CKR_FUNCTION_FAILED;
-               }
-       }
-       else {
-               struct timeval now;
-               struct timespec timeout;
-
-               if (
-                       rv == CKR_OK &&
-                       gettimeofday (&now, NULL)
-               ) {
-                       rv = CKR_FUNCTION_FAILED;
-               }
-               
-               if (rv == CKR_OK) {
-                       timeout.tv_sec = now.tv_sec + milli/1000;
-                       timeout.tv_nsec = now.tv_usec*1000 + milli%1000;
-               }
-               
-               if (
-                       rv == CKR_OK &&
-                       pthread_cond_timedwait (&cond->cond, &cond->mut, &timeout)
-               ) {
-                       rv = CKR_FUNCTION_FAILED;
-               }
-       }
-#endif
-       return rv;
-}
-
-static
-CK_RV
-_pkcs11h_condFree (
-       IN OUT pkcs11h_cond_t *const cond
-) {
-#if defined(WIN32)
-       CloseHandle (*cond);
-       *cond = NULL;
-#else
-       pthread_mutex_unlock (&cond->mut);
-#endif
-       return CKR_OK;
-}
-
-#if defined(WIN32)
-static
-unsigned
-__stdcall
-__pkcs11h_thread_start (void *p) {
-       __pkcs11h_thread_data_t *_data = (__pkcs11h_thread_data_t *)p;
-       unsigned ret;
-
-       ret = (unsigned)_data->start (_data->data);
-
-       _pkcs11h_free ((void *)&_data);
-
-       return ret;
-}
-#else
-static
-void *
-__pkcs11h_thread_start (void *p) {
-       __pkcs11h_thread_data_t *_data = (__pkcs11h_thread_data_t *)p;
-       void *ret;
-       int i;
-
-       /*
-        * Ignore any signal in
-        * this thread
-        */
-       for (i=1;i<16;i++) {
-               signal (i, SIG_IGN);
-       }
-
-       ret = _data->start (_data->data);
-
-       _pkcs11h_free ((void *)&_data);
-
-       return ret;
-}
-#endif
-
-static
-CK_RV
-_pkcs11h_threadStart (
-       OUT pkcs11h_thread_t * const thread,
-       IN pkcs11h_thread_start_t const start,
-       IN void * data
-) {
-       __pkcs11h_thread_data_t *_data = NULL;
-       CK_RV rv = CKR_OK;
-
-       if (rv == CKR_OK) {
-               rv = _pkcs11h_malloc (
-                       (void *)&_data,
-                       sizeof (__pkcs11h_thread_data_t)
-               );
-       }
-
-       if (rv == CKR_OK) {
-               _data->start = start;
-               _data->data = data;
-       }
-
-#if defined(WIN32)
-       {
-               unsigned tmp;
-
-               if (
-                       rv == CKR_OK &&
-                       (*thread = (HANDLE)_beginthreadex (
-                               NULL,
-                               0,
-                               __pkcs11h_thread_start,
-                               _data,
-                               0,
-                               &tmp
-                       )) == NULL
-               ) {
-                       rv = CKR_FUNCTION_FAILED;
-               }
-       }
-#else
-       if (
-               rv == CKR_OK &&
-               pthread_create (thread, NULL, __pkcs11h_thread_start, _data)
-       ) {
-               rv = CKR_FUNCTION_FAILED;
-       }
-#endif
-       return rv;
-}
-
-static
-CK_RV
-_pkcs11h_threadJoin (
-       IN pkcs11h_thread_t * const thread
-) {
-#if defined(WIN32)
-       WaitForSingleObject (*thread, INFINITE);
-       CloseHandle (*thread);
-       *thread = NULL;
-#else
-       pthread_join (*thread, NULL);
-       *thread = 0l;
-#endif
-       return CKR_OK;
-}
-
-#endif         /* ENABLE_PKCS11H_THREADING */
-
-/*======================================================================*
- * COMMON INTERNAL INTERFACE
- *======================================================================*/
-
-static
-void
-_pkcs11h_fixupFixedString (
-       OUT char * const szTarget,                      /* MUST BE >= nLength+1 */
-       IN const char * const szSource,
-       IN const size_t nLength                         /* FIXED STRING LENGTH */
-) {
-       char *p;
-
-       PKCS11H_ASSERT (szSource!=NULL);
-       PKCS11H_ASSERT (szTarget!=NULL);
-       
-       p = szTarget+nLength;
-       memmove (szTarget, szSource, nLength);
-       *p = '\0';
-       p--;
-       while (p >= szTarget && *p == ' ') {
-               *p = '\0';
-               p--;
-       }
-}
-
-static
-void
-_pkcs11h_log (
-       IN const unsigned flags,
-       IN const char * const szFormat,
-       IN ...
-) {
-       va_list args;
-
-       PKCS11H_ASSERT (szFormat!=NULL);
-
-       va_start (args, szFormat);
-
-       if (
-               s_pkcs11h_data != NULL &&
-               s_pkcs11h_data->fInitialized
-       ) { 
-               if (PKCS11H_MSG_LEVEL_TEST (flags)) {
-                       if (s_pkcs11h_data->hooks.log == NULL) {
-                               _pkcs11h_hooks_default_log (
-                                       NULL,
-                                       flags,
-                                       szFormat,
-                                       args
-                               );
-                       }
-                       else {
-                               s_pkcs11h_data->hooks.log (
-                                       s_pkcs11h_data->hooks.log_data,
-                                       flags,
-                                       szFormat,
-                                       args
-                               );
-                       }
-               }
-       }
-
-       va_end (args);
-}
-
-static
-CK_RV
-_pkcs11h_getSlotList (
-       IN const pkcs11h_provider_t provider,
-       IN const CK_BBOOL tokenPresent,
-       OUT CK_SLOT_ID_PTR * const pSlotList,
-       OUT CK_ULONG_PTR pulCount
-) {
-       CK_SLOT_ID_PTR _slots = NULL;
-       CK_ULONG _slotnum = 0;
-       CK_RV rv = CKR_OK;
-
-       PKCS11H_ASSERT (provider!=NULL);
-       PKCS11H_ASSERT (pSlotList!=NULL);
-       PKCS11H_ASSERT (pulCount!=NULL);
-
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: _pkcs11h_getSlotList entry provider=%p, tokenPresent=%d, pSlotList=%p, pulCount=%p",
-               (void *)provider,
-               tokenPresent,
-               (void *)pSlotList,
-               (void *)pulCount
-       );
-
-       *pSlotList = NULL;
-       *pulCount = 0;
-
-       if (
-               rv == CKR_OK &&
-               !provider->fEnabled
-       ) {
-               rv = CKR_CRYPTOKI_NOT_INITIALIZED;
-       }
-
-       if (rv == CKR_OK) {
-               rv = provider->f->C_GetSlotList (
-                       tokenPresent,
-                       NULL_PTR,
-                       &_slotnum
-               );
-       }
-
-       if (rv == CKR_OK && _slotnum > 0) {
-               rv = _pkcs11h_malloc ((void *)&_slots, _slotnum * sizeof (CK_SLOT_ID));
-       }
-
-       if (rv == CKR_OK && _slotnum > 0) {
-               rv = provider->f->C_GetSlotList (
-                       tokenPresent,
-                       _slots,
-                       &_slotnum
-               );
-       }
-
-       if (rv == CKR_OK) {
-               *pSlotList = _slots;
-               _slots = NULL;
-               *pulCount = _slotnum;
-       }
-
-       if (_slots != NULL) {
-               _pkcs11h_free ((void *)&_slots);
-       }
-
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: _pkcs11h_getSlotList return rv=%ld-'%s' *pulCount=%ld",
-               rv,
-               pkcs11h_getMessage (rv),
-               *pulCount
-       );
-
-       return rv;
-}
-
-static
-CK_RV
-_pkcs11h_getObjectAttributes (
-       IN const pkcs11h_session_t session,
-       IN const CK_OBJECT_HANDLE object,
-       IN OUT const CK_ATTRIBUTE_PTR attrs,
-       IN const unsigned count
-) {
-#if defined(ENABLE_PKCS11H_THREADING)
-       PKCS11H_BOOL fMutexLocked = FALSE;
-#endif
-       CK_RV rv = CKR_OK;
-
-       PKCS11H_ASSERT (attrs!=NULL);
-
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: _pkcs11h_getObjectAttributes entry session=%p, object=%ld, attrs=%p, count=%d",
-               (void *)session,
-               object,
-               (void *)attrs,
-               count
-       );
-
-#if defined(ENABLE_PKCS11H_THREADING)
-       if (
-               rv == CKR_OK &&
-               (rv = _pkcs11h_mutexLock (&session->mutexSession)) == CKR_OK
-       ) {
-               fMutexLocked = TRUE;
-       }
-#endif
-
-       if (
-               rv == CKR_OK &&
-               (rv = session->provider->f->C_GetAttributeValue (
-                       session->hSession,
-                       object,
-                       attrs,
-                       count
-               )) == CKR_OK
-       ) {
-               unsigned i;
-               for (i=0;rv == CKR_OK && i<count;i++) {
-                       if (attrs[i].ulValueLen == (CK_ULONG)-1) {
-                               rv = CKR_ATTRIBUTE_VALUE_INVALID;
-                       }
-                       else if (attrs[i].ulValueLen == 0) {
-                               attrs[i].pValue = NULL;
-                       }
-                       else {
-                               rv = _pkcs11h_malloc (
-                                       (void *)&attrs[i].pValue,
-                                       attrs[i].ulValueLen
-                               );
-                       }
-               }
-       }
-
-       if (rv == CKR_OK) {
-               rv = session->provider->f->C_GetAttributeValue (
-                       session->hSession,
-                       object,
-                       attrs,
-                       count
-               );
-       }
-
-#if defined(ENABLE_PKCS11H_THREADING)
-       if (fMutexLocked) {
-               _pkcs11h_mutexRelease (&session->mutexSession);
-               fMutexLocked = FALSE;
-       }
-#endif
-
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: _pkcs11h_getObjectAttributes return rv=%ld-'%s'",
-               rv,
-               pkcs11h_getMessage (rv)
-       );
-
-       return rv;
-}
-
-static
-CK_RV
-_pkcs11h_freeObjectAttributes (
-       IN OUT const CK_ATTRIBUTE_PTR attrs,
-       IN const unsigned count
-) {
-       unsigned i;
-
-       CK_RV rv = CKR_OK;
-
-       PKCS11H_ASSERT (attrs!=NULL);
-
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: _pkcs11h_freeObjectAttributes entry attrs=%p, count=%d",
-               (void *)attrs,
-               count
-       );
-
-       for (i=0;i<count;i++) {
-               if (attrs[i].pValue != NULL) {
-                       _pkcs11h_free ((void *)&attrs[i].pValue);
-                       attrs[i].pValue = NULL;
-               }
-       }
-
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: _pkcs11h_freeObjectAttributes return rv=%ld-'%s'",
-               rv,
-               pkcs11h_getMessage (rv)
-       );
-
-       return rv;
-}
-
-static
-CK_RV
-_pkcs11h_findObjects (
-       IN const pkcs11h_session_t session,
-       IN const CK_ATTRIBUTE * const filter,
-       IN const CK_ULONG filter_attrs,
-       OUT CK_OBJECT_HANDLE **const p_objects,
-       OUT CK_ULONG *p_objects_found
-) {
-#if defined(ENABLE_PKCS11H_THREADING)
-       PKCS11H_BOOL fMutexLocked = FALSE;
-#endif
-       PKCS11H_BOOL fShouldFindObjectFinal = FALSE;
-
-       CK_OBJECT_HANDLE *objects = NULL;
-       CK_ULONG objects_size = 0;
-       CK_OBJECT_HANDLE objects_buffer[100];
-       CK_ULONG objects_found;
-       CK_OBJECT_HANDLE oLast = PKCS11H_INVALID_OBJECT_HANDLE;
-       CK_RV rv = CKR_OK;
-
-       PKCS11H_ASSERT (session!=NULL);
-       PKCS11H_ASSERT (!(filter==NULL && filter_attrs!=0) || filter!=NULL);
-       PKCS11H_ASSERT (p_objects!=NULL);
-       PKCS11H_ASSERT (p_objects_found!=NULL);
-       
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: _pkcs11h_findObjects entry session=%p, filter=%p, filter_attrs=%ld, p_objects=%p, p_objects_found=%p",
-               (void *)session,
-               (void *)filter,
-               filter_attrs,
-               (void *)p_objects,
-               (void *)p_objects_found
-       );
-
-       *p_objects = NULL;
-       *p_objects_found = 0;
-
-#if defined(ENABLE_PKCS11H_THREADING)
-       if (
-               rv == CKR_OK &&
-               (rv = _pkcs11h_mutexLock (&session->mutexSession)) == CKR_OK
-       ) {
-               fMutexLocked = TRUE;
-       }
-#endif
-
-       if (
-               rv == CKR_OK &&
-               (rv = session->provider->f->C_FindObjectsInit (
-                       session->hSession,
-                       (CK_ATTRIBUTE *)filter,
-                       filter_attrs
-               )) == CKR_OK
-       ) {
-               fShouldFindObjectFinal = TRUE;
-       }
-
-       while (
-               rv == CKR_OK &&
-               (rv = session->provider->f->C_FindObjects (
-                       session->hSession,
-                       objects_buffer,
-                       sizeof (objects_buffer) / sizeof (CK_OBJECT_HANDLE),
-                       &objects_found
-               )) == CKR_OK &&
-               objects_found > 0
-       ) { 
-               CK_OBJECT_HANDLE *temp = NULL;
-               
-               /*
-                * Begin workaround
-                *
-                * Workaround iKey bug
-                * It returns the same objects over and over
-                */
-               if (oLast == objects_buffer[0]) {
-                       PKCS11H_LOG (
-                               PKCS11H_LOG_WARN,
-                               "PKCS#11: Bad PKCS#11 C_FindObjects implementation detected, workaround applied"
-                       );
-                       break;
-               }
-               oLast = objects_buffer[0];
-               /* End workaround */
-               
-               if (
-                       (rv = _pkcs11h_malloc (
-                               (void *)&temp,
-                               (objects_size+objects_found) * sizeof (CK_OBJECT_HANDLE)
-                       )) == CKR_OK
-               ) {
-                       if (objects != NULL) {
-                               memmove (
-                                       temp,
-                                       objects,
-                                       objects_size * sizeof (CK_OBJECT_HANDLE)
-                               );
-                       }
-                       memmove (
-                               temp + objects_size,
-                               objects_buffer,
-                               objects_found * sizeof (CK_OBJECT_HANDLE)
-                       );
-               }
-
-               if (rv == CKR_OK) {
-                       _pkcs11h_free ((void *)&objects);
-                       objects = temp;
-                       objects_size += objects_found;
-                       temp = NULL;
-               }
-
-               if (temp != NULL) {
-                       _pkcs11h_free ((void *)&temp);
-                       temp = NULL;
-               }
-       }
-
-       if (fShouldFindObjectFinal) {
-               session->provider->f->C_FindObjectsFinal (
-                       session->hSession
-               );
-               fShouldFindObjectFinal = FALSE;
-       }
-       
-#if defined(ENABLE_PKCS11H_THREADING)
-       if (fMutexLocked) {
-               _pkcs11h_mutexRelease (&session->mutexSession);
-               fMutexLocked = FALSE;
-       }
-#endif
-
-       if (rv == CKR_OK) {
-               *p_objects = objects;
-               *p_objects_found = objects_size;
-               objects = NULL;
-               objects_size = 0;
-       }
-
-       if (objects != NULL) {
-               _pkcs11h_free ((void *)&objects);
-               objects = NULL;
-               objects_size = 0;
-       }
-
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: _pkcs11h_findObjects return rv=%ld-'%s', *p_objects_found=%ld",
-               rv,
-               pkcs11h_getMessage (rv),
-               *p_objects_found
-       );
-
-       return rv;
-}
-
-static
-CK_RV
-_pkcs11h_getTokenId (
-       IN const CK_TOKEN_INFO_PTR info,
-       OUT pkcs11h_token_id_t * const p_token_id
-) {
-       pkcs11h_token_id_t token_id;
-       CK_RV rv = CKR_OK;
-       
-       PKCS11H_ASSERT (info!=NULL);
-       PKCS11H_ASSERT (p_token_id!=NULL);
-       
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: _pkcs11h_getTokenId entry p_token_id=%p",
-               (void *)p_token_id
-       );
-
-       *p_token_id = NULL;
-
-       if (
-               rv == CKR_OK &&
-               (rv = _pkcs11h_newTokenId (&token_id)) == CKR_OK
-       ) {
-               _pkcs11h_fixupFixedString (
-                       token_id->label,
-                       (char *)info->label,
-                       sizeof (info->label)
-               );
-               _pkcs11h_fixupFixedString (
-                       token_id->manufacturerID,
-                       (char *)info->manufacturerID,
-                       sizeof (info->manufacturerID)
-               );
-               _pkcs11h_fixupFixedString (
-                       token_id->model,
-                       (char *)info->model,
-                       sizeof (info->model)
-               );
-               _pkcs11h_fixupFixedString (
-                       token_id->serialNumber,
-                       (char *)info->serialNumber,
-                       sizeof (info->serialNumber)
-               );
-       }
-
-       if (rv == CKR_OK) {
-               *p_token_id = token_id;
-               token_id = NULL;
-       }
-
-       if (token_id != NULL) {
-               _pkcs11h_free ((void *)&token_id);
-       }
-
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: _pkcs11h_getTokenId return rv=%ld-'%s', *p_token_id=%p",
-               rv,
-               pkcs11h_getMessage (rv),
-               (void *)*p_token_id
-       );
-
-       return rv;
-}
-
-static
-CK_RV
-_pkcs11h_newTokenId (
-       OUT pkcs11h_token_id_t * const p_token_id
-) {
-       CK_RV rv = CKR_OK;
-
-       PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
-       PKCS11H_ASSERT (s_pkcs11h_data->fInitialized);
-       PKCS11H_ASSERT (p_token_id!=NULL);
-
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: _pkcs11h_newTokenId entry p_token_id=%p",
-               (void *)p_token_id
-       );
-
-       *p_token_id = NULL;
-
-       if (rv == CKR_OK) {
-               rv = _pkcs11h_malloc ((void *)p_token_id, sizeof (struct pkcs11h_token_id_s));
-       }
-
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: _pkcs11h_newTokenId return rv=%ld-'%s', *p_token_id=%p",
-               rv,
-               pkcs11h_getMessage (rv),
-               (void *)*p_token_id
-       );
-
-       return rv;
-}
-
-static
-CK_RV
-_pkcs11h_getSessionByTokenId (
-       IN const pkcs11h_token_id_t token_id,
-       OUT pkcs11h_session_t * const p_session
-) {
-#if defined(ENABLE_PKCS11H_THREADING)
-       PKCS11H_BOOL fMutexLocked = FALSE;
-#endif
-       pkcs11h_session_t session = NULL;
-       PKCS11H_BOOL fNewSession = FALSE;
-       CK_RV rv = CKR_OK;
-
-       PKCS11H_ASSERT (token_id!=NULL);
-       PKCS11H_ASSERT (p_session!=NULL);
-
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: _pkcs11h_getSessionByTokenId entry token_id=%p, p_session=%p",
-               (void *)token_id,
-               (void *)p_session
-       );
-
-       *p_session = NULL;
-
-#if defined(ENABLE_PKCS11H_THREADING)
-       if (
-               rv == CKR_OK &&
-               (rv = _pkcs11h_mutexLock (&s_pkcs11h_data->mutexSession)) == CKR_OK
-       ) {
-               fMutexLocked = TRUE;
-       }
-#endif
-
-       if (rv == CKR_OK) {
-               pkcs11h_session_t current_session;
-
-               for (
-                       current_session = s_pkcs11h_data->sessions;
-                       current_session != NULL && session == NULL;
-                       current_session = current_session->next
-               ) {
-                       if (
-                               pkcs11h_sameTokenId (
-                                       current_session->token_id,
-                                       token_id
-                               )
-                       ) {
-                               PKCS11H_DEBUG (
-                                       PKCS11H_LOG_DEBUG1,
-                                       "PKCS#11: Using cached session"
-                               );
-                               session = current_session;
-                               session->nReferenceCount++;
-                       }
-               }
-       }
-
-       if (
-               rv == CKR_OK &&
-               session == NULL
-       ) {
-               fNewSession = TRUE;
-       }
-
-       if (fNewSession) {
-               PKCS11H_DEBUG (
-                       PKCS11H_LOG_DEBUG1,
-                       "PKCS#11: Creating a new session"
-               );
-
-               if (
-                       rv == CKR_OK &&
-                       (rv = _pkcs11h_malloc ((void *)&session, sizeof (struct pkcs11h_session_s))) == CKR_OK
-               ) {
-                       session->nReferenceCount = 1;
-                       session->hSession = PKCS11H_INVALID_SESSION_HANDLE;
-                       
-                       session->nPINCachePeriod = s_pkcs11h_data->nPINCachePeriod;
-
-               }
-
-               if (rv == CKR_OK) {
-                       rv = pkcs11h_duplicateTokenId (
-                               &session->token_id,
-                               token_id
-                       );
-               }
-
-#if defined(ENABLE_PKCS11H_THREADING)
-               if (rv == CKR_OK) {
-                       rv = _pkcs11h_mutexInit (&session->mutexSession);
-               }
-#endif
-
-               if (rv == CKR_OK) {
-                       session->fValid = TRUE;
-                       session->next = s_pkcs11h_data->sessions;
-                       s_pkcs11h_data->sessions = session;
-               }
-               else {
-#if defined(ENABLE_PKCS11H_THREADING)
-                       _pkcs11h_mutexFree (&session->mutexSession);
-#endif
-                       _pkcs11h_free ((void *)&session);
-               }
-       }
-
-       if (rv == CKR_OK) {
-               *p_session = session;
-               session = NULL;
-       }
-
-#if defined(ENABLE_PKCS11H_THREADING)
-       if (fMutexLocked) {
-               _pkcs11h_mutexRelease (&s_pkcs11h_data->mutexSession);
-               fMutexLocked = FALSE;
-       }
-#endif
-
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: _pkcs11h_getSessionByTokenId return rv=%ld-'%s', *p_session=%p",
-               rv,
-               pkcs11h_getMessage (rv),
-               (void *)*p_session
-       );
-
-       return rv;
-}
-
-static
-CK_RV
-_pkcs11h_releaseSession (
-       IN const pkcs11h_session_t session
-) {
-#if defined(ENABLE_PKCS11H_THREADING)
-       PKCS11H_BOOL fMutexLocked = FALSE;
-#endif
-       CK_RV rv = CKR_OK;
-
-       PKCS11H_ASSERT (session!=NULL);
-       PKCS11H_ASSERT (session->nReferenceCount>=0);
-
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: _pkcs11h_releaseSession entry session=%p",
-               (void *)session
-       );
-
-#if defined(ENABLE_PKCS11H_THREADING)
-       if (
-               rv == CKR_OK &&
-               (rv = _pkcs11h_mutexLock (&session->mutexSession)) == CKR_OK
-       ) {
-               fMutexLocked = TRUE;
-       }
-#endif
-
-       /*
-        * Never logout for now
-        */
-       if (rv == CKR_OK) {
-               if (session->nReferenceCount > 0) {
-                       session->nReferenceCount--;
-               }
-       }
-
-#if defined(ENABLE_PKCS11H_THREADING)
-       if (fMutexLocked) {
-               _pkcs11h_mutexRelease (&session->mutexSession);
-               fMutexLocked = FALSE;
-       }
-#endif
-
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: _pkcs11h_releaseSession return rv=%ld-'%s'",
-               rv,
-               pkcs11h_getMessage (rv)
-       );
-
-       return rv;
-}
-
-static
-CK_RV
-_pkcs11h_resetSession (
-       IN const pkcs11h_session_t session,
-       IN const unsigned maskPrompt,
-       OUT CK_SLOT_ID * const p_slot
-) {
-       /*
-        * This function MUST NOT touch session
-        */
-       PKCS11H_BOOL fFound = FALSE;
-
-       CK_RV rv = CKR_OK;
-
-       unsigned nRetry = 0;
-
-       PKCS11H_ASSERT (session!=NULL);
-       PKCS11H_ASSERT (p_slot!=NULL);
-
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: _pkcs11h_resetSession entry session=%p, maskPrompt=%08x, p_slot=%p",
-               (void *)session,
-               maskPrompt,
-               (void *)p_slot
-       );
-
-       *p_slot = PKCS11H_INVALID_SLOT_ID;
-
-       while (
-               rv == CKR_OK &&
-               !fFound
-       ) {
-               pkcs11h_provider_t current_provider = NULL;
-#if defined(ENABLE_PKCS11H_THREADING)
-               PKCS11H_BOOL fMutexLocked = FALSE;
-#endif
-
-#if defined(ENABLE_PKCS11H_THREADING)
-               if (
-                       rv == CKR_OK &&
-                       (rv = _pkcs11h_mutexLock (&session->mutexSession)) == CKR_OK
-               ) {
-                       fMutexLocked = TRUE;
-               }
-#endif
-
-               for (
-                       current_provider = s_pkcs11h_data->providers;
-                       (
-                               rv == CKR_OK &&
-                               current_provider != NULL &&
-                               !fFound
-                       );
-                       current_provider = current_provider->next
-               ) {
-                       CK_SLOT_ID_PTR slots = NULL;
-                       CK_ULONG slotnum;
-                       CK_SLOT_ID slot_index;
-
-                       /*
-                        * Skip all other providers,
-                        * if one was set in the past
-                        */
-                       if (
-                               session->provider != NULL &&
-                               session->provider != current_provider
-                       ) {
-                               rv = CKR_CANCEL;
-                       }
-               
-                       if (rv == CKR_OK) {
-                               rv = _pkcs11h_getSlotList (
-                                       current_provider,
-                                       CK_TRUE,
-                                       &slots,
-                                       &slotnum
-                               );
-                       }
-
-                       for (
-                               slot_index=0;
-                               (
-                                       slot_index < slotnum &&
-                                       rv == CKR_OK && 
-                                       !fFound
-                               );
-                               slot_index++
-                       ) {
-                               pkcs11h_token_id_t token_id = NULL;
-                               CK_TOKEN_INFO info;
-
-                               if (rv == CKR_OK) {
-                                       rv = current_provider->f->C_GetTokenInfo (
-                                               slots[slot_index],
-                                               &info
-                                       );
-                               }
-
-                               if (
-                                       rv == CKR_OK &&
-                                       (rv = _pkcs11h_getTokenId (
-                                               &info,
-                                               &token_id
-                                       )) == CKR_OK &&
-                                       pkcs11h_sameTokenId (
-                                               session->token_id,
-                                               token_id
-                                       )
-                               ) {
-                                       fFound = TRUE;
-                                       *p_slot = slots[slot_index];
-                                       if (session->provider == NULL) {
-                                               session->provider = current_provider;
-                                               _pkcs11h_fixupFixedString (
-                                                       token_id->label,
-                                                       (char *)info.label,
-                                                       sizeof (info.label)
-                                               );
-                                               session->fProtectedAuthenticationSupported = (info.flags & CKF_PROTECTED_AUTHENTICATION_PATH) != 0;
-                                       }
-                               }
-
-                               if (rv != CKR_OK) {
-                                       PKCS11H_DEBUG (
-                                               PKCS11H_LOG_DEBUG1,
-                                               "PKCS#11: Cannot get token information for provider '%s' slot %ld rv=%ld-'%s'",
-                                               current_provider->manufacturerID,
-                                               slots[slot_index],
-                                               rv,
-                                               pkcs11h_getMessage (rv)
-                                       );
-
-                                       /*
-                                        * Ignore error
-                                        */
-                                       rv = CKR_OK;
-                               }
-
-                               if (token_id != NULL) {
-                                       pkcs11h_freeTokenId (token_id);
-                               }
-                       }
-
-                       if (rv != CKR_OK) {
-                               PKCS11H_DEBUG (
-                                       PKCS11H_LOG_DEBUG1,
-                                       "PKCS#11: Cannot get slot list for provider '%s' rv=%ld-'%s'",
-                                       current_provider->manufacturerID,
-                                       rv,
-                                       pkcs11h_getMessage (rv)
-                               );
-
-                               /*
-                                * Ignore error
-                                */
-                               rv = CKR_OK;
-                       }
-
-                       if (slots != NULL) {
-                               _pkcs11h_free ((void *)&slots);
-                               slots = NULL;
-                       }
-               }
-
-#if defined(ENABLE_PKCS11H_THREADING)
-               if (fMutexLocked) {
-                       _pkcs11h_mutexRelease (&session->mutexSession);
-                       fMutexLocked = FALSE;
-               }
-#endif
-
-               if (
-                       rv == CKR_OK &&
-                       !fFound
-               ) {
-                       if ((maskPrompt & PKCS11H_PROMPT_MAST_ALLOW_CARD_PROMPT) != 0) {
-                               PKCS11H_DEBUG (
-                                       PKCS11H_LOG_DEBUG1,
-                                       "PKCS#11: Calling token_prompt hook for '%s'",
-                                       session->token_id->label
-                               );
-               
-                               if (
-                                       !s_pkcs11h_data->hooks.token_prompt (
-                                               s_pkcs11h_data->hooks.token_prompt_data,
-                                               session->token_id,
-                                               nRetry++
-                                       )
-                               ) {
-                                       rv = CKR_CANCEL;
-                               }
-
-                               PKCS11H_DEBUG (
-                                       PKCS11H_LOG_DEBUG1,
-                                       "PKCS#11: token_prompt returned %ld",
-                                       rv
-                               );
-                       }
-                       else {
-                               rv = CKR_TOKEN_NOT_PRESENT;
-                       }
-               }
-       }
-
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: _pkcs11h_resetSession return rv=%ld-'%s', *p_slot=%ld",
-               rv,
-               pkcs11h_getMessage (rv),
-               *p_slot
-       );
-
-       return rv;
-}
-
-static
-CK_RV
-_pkcs11h_getObjectById (
-       IN const pkcs11h_session_t session,
-       IN const CK_OBJECT_CLASS class,
-       IN const CK_BYTE_PTR id,
-       IN const size_t id_size,
-       OUT CK_OBJECT_HANDLE * const p_handle
-) {
-       CK_ATTRIBUTE filter[] = {
-               {CKA_CLASS, (void *)&class, sizeof (class)},
-               {CKA_ID, (void *)id, id_size}
-       };
-       CK_OBJECT_HANDLE *objects = NULL;
-       CK_ULONG objects_found = 0;
-       CK_RV rv = CKR_OK;
-       
-       /*PKCS11H_ASSERT (session!=NULL); NOT NEEDED*/
-       PKCS11H_ASSERT (id!=NULL);
-       PKCS11H_ASSERT (p_handle!=NULL);
-
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: _pkcs11h_getObjectById entry session=%p, class=%ld, id=%p, id_size=%u, p_handle=%p",
-               (void *)session,
-               class,
-               id,
-               id_size,
-               (void *)p_handle
-       );
-
-       *p_handle = PKCS11H_INVALID_OBJECT_HANDLE;
-
-       if (rv == CKR_OK) {
-               rv = _pkcs11h_validateSession (session);
-       }
-
-       if (rv == CKR_OK) { 
-               rv = _pkcs11h_findObjects (
-                       session,
-                       filter,
-                       sizeof (filter) / sizeof (CK_ATTRIBUTE),
-                       &objects,
-                       &objects_found
-               );
-       }
-
-       if (
-               rv == CKR_OK &&
-               objects_found == 0
-       ) {
-               rv = CKR_FUNCTION_REJECTED;
-       }
-
-       if (rv == CKR_OK) {
-               *p_handle = objects[0];
-       }
-
-       if (objects != NULL) {
-               _pkcs11h_free ((void *)&objects);
-       }
-
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: _pkcs11h_getObjectById return rv=%ld-'%s', *p_handle=%p",
-               rv,
-               pkcs11h_getMessage (rv),
-               (void *)*p_handle
-       );
-
-       return rv;
-}
-
-static
-CK_RV
-_pkcs11h_validateSession (
-       IN const pkcs11h_session_t session
-) {
-#if defined(ENABLE_PKCS11H_THREADING)
-       PKCS11H_BOOL fMutexLocked = FALSE;
-#endif
-       CK_RV rv = CKR_OK;
-
-       /*PKCS11H_ASSERT (session!=NULL); NOT NEEDED*/
-
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: _pkcs11h_validateSession entry session=%p",
-               (void *)session
-       );
-
-       if (
-               rv == CKR_OK &&
-               session == NULL
-       ) {
-               rv = CKR_SESSION_HANDLE_INVALID;
-       }
-
-#if defined(ENABLE_PKCS11H_THREADING)
-       if (
-               rv == CKR_OK &&
-               (rv = _pkcs11h_mutexLock (&session->mutexSession)) == CKR_OK
-       ) {
-               fMutexLocked = TRUE;
-       }
-#endif
-
-       if (
-               rv == CKR_OK &&
-               (
-                       session->provider == NULL ||
-                       !session->provider->fEnabled ||
-                       session->hSession == PKCS11H_INVALID_SESSION_HANDLE
-               )
-       ) {
-               rv = CKR_SESSION_HANDLE_INVALID;
-       }
-
-       if (
-               rv == CKR_OK &&
-               session->timePINExpire != (time_t)0 &&
-               session->timePINExpire < PKCS11H_TIME (NULL)
-       ) {
-               PKCS11H_DEBUG (
-                       PKCS11H_LOG_DEBUG1,
-                       "PKCS#11: Forcing logout due to pin timeout"
-               );
-               _pkcs11h_logout (session);
-               rv = CKR_SESSION_HANDLE_INVALID;
-       }
-
-#if defined(ENABLE_PKCS11H_THREADING)
-       if (fMutexLocked) {
-               _pkcs11h_mutexRelease (&session->mutexSession);
-               fMutexLocked = FALSE;
-       }
-#endif
-
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: _pkcs11h_validateSession return rv=%ld-'%s'",
-               rv,
-               pkcs11h_getMessage (rv)
-       );
-
-       return rv;
-}
-
-static
-CK_RV
-_pkcs11h_login (
-       IN const pkcs11h_session_t session,
-       IN const PKCS11H_BOOL fPublicOnly,
-       IN const PKCS11H_BOOL fReadOnly,
-       IN const unsigned maskPrompt
-) {
-#if defined(ENABLE_PKCS11H_THREADING)
-       PKCS11H_BOOL fMutexLocked = FALSE;
-#endif
-       CK_SLOT_ID slot = PKCS11H_INVALID_SLOT_ID;
-       CK_RV rv = CKR_OK;
-
-       PKCS11H_ASSERT (session!=NULL);
-
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: _pkcs11h_login entry session=%p, fPublicOnly=%d, fReadOnly=%d, maskPrompt=%08x",
-               (void *)session,
-               fPublicOnly ? 1 : 0,
-               fReadOnly ? 1 : 0,
-               maskPrompt
-       );
-
-       if (rv == CKR_OK) {
-               rv = _pkcs11h_logout (session);
-       }
-
-       if (rv == CKR_OK) {
-               rv = _pkcs11h_resetSession (session, maskPrompt, &slot);
-       }
-
-#if defined(ENABLE_PKCS11H_THREADING)
-       if (
-               rv == CKR_OK &&
-               (rv = _pkcs11h_mutexLock (&session->mutexSession)) == CKR_OK
-       ) {
-               fMutexLocked = TRUE;
-       }
-#endif
-
-       if (rv == CKR_OK) {
-               rv = session->provider->f->C_OpenSession (
-                       slot,
-                       (
-                               CKF_SERIAL_SESSION |
-                               (fReadOnly ? 0 : CKF_RW_SESSION)
-                       ),
-                       NULL_PTR,
-                       NULL_PTR,
-                       &session->hSession
-               );
-       }
-
-       if (
-               rv == CKR_OK &&
-               (
-                       !fPublicOnly ||
-                       session->provider->fCertIsPrivate
-               )
-       ) {
-               PKCS11H_BOOL fSuccessLogin = FALSE;
-               unsigned nRetryCount = 0;
-
-               if ((maskPrompt & PKCS11H_PROMPT_MASK_ALLOW_PIN_PROMPT) == 0) {
-                       rv = CKR_USER_NOT_LOGGED_IN;
-
-                       PKCS11H_DEBUG (
-                               PKCS11H_LOG_DEBUG1,
-                               "PKCS#11: Calling pin_prompt hook denied because of prompt mask"
-                       );
-               }
-
-               while (
-                       rv == CKR_OK &&
-                       !fSuccessLogin &&
-                       nRetryCount < s_pkcs11h_data->nMaxLoginRetries 
-               ) {
-                       CK_UTF8CHAR_PTR utfPIN = NULL;
-                       CK_ULONG lPINLength = 0;
-                       char szPIN[1024];
-
-                       if (
-                               rv == CKR_OK &&
-                               !(
-                                       s_pkcs11h_data->fProtectedAuthentication  &&
-                                       session->provider->fProtectedAuthentication &&
-                                       session->fProtectedAuthenticationSupported
-                               )
-                       ) {
-                               PKCS11H_DEBUG (
-                                       PKCS11H_LOG_DEBUG1,
-                                       "PKCS#11: Calling pin_prompt hook for '%s'",
-                                       session->token_id->label
-                               );
-
-                               if (
-                                       !s_pkcs11h_data->hooks.pin_prompt (
-                                               s_pkcs11h_data->hooks.pin_prompt_data,
-                                               session->token_id,
-                                               nRetryCount,
-                                               szPIN,
-                                               sizeof (szPIN)
-                                       )
-                               ) {
-                                       rv = CKR_CANCEL;
-                               }
-                               else {
-                                       utfPIN = (CK_UTF8CHAR_PTR)szPIN;
-                                       lPINLength = strlen (szPIN);
-                               }
-
-                               PKCS11H_DEBUG (
-                                       PKCS11H_LOG_DEBUG1,
-                                       "PKCS#11: pin_prompt hook return rv=%ld",
-                                       rv
-                               );
-                       }
-
-                       if (rv == CKR_OK) {
-                               if (session->nPINCachePeriod == PKCS11H_PIN_CACHE_INFINITE) {
-                                       session->timePINExpire = 0;
-                               }
-                               else {
-                                       session->timePINExpire = (
-                                               PKCS11H_TIME (NULL) +
-                                               (time_t)session->nPINCachePeriod
-                                       );
-                               }
-                       }
-
-                       if (
-                               rv == CKR_OK &&
-                               (rv = session->provider->f->C_Login (
-                                       session->hSession,
-                                       CKU_USER,
-                                       utfPIN,
-                                       lPINLength
-                               )) != CKR_OK
-                       ) {
-                               if (rv == CKR_USER_ALREADY_LOGGED_IN) {
-                                       rv = CKR_OK;
-                               }
-                       }
-
-                       /*
-                        * Clean PIN buffer
-                        */
-                       memset (szPIN, 0, sizeof (szPIN));
-
-                       if (rv == CKR_OK) {
-                               fSuccessLogin = TRUE;
-                       }
-                       else if (
-                               rv == CKR_PIN_INCORRECT ||
-                               rv == CKR_PIN_INVALID
-                       ) {
-                               /*
-                                * Ignore these errors
-                                * so retry can be performed
-                                */
-                               rv = CKR_OK;
-                       }
-
-                       nRetryCount++;
-               }
-
-               /*
-                * Retry limit
-                */
-               if (!fSuccessLogin && rv == CKR_OK) {
-                       rv = CKR_PIN_INCORRECT;
-               }
-       }
-
-#if defined(ENABLE_PKCS11H_THREADING)
-       if (fMutexLocked) {
-               _pkcs11h_mutexRelease (&session->mutexSession);
-               fMutexLocked = FALSE;
-       }
-#endif
-
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: _pkcs11h_login return rv=%ld-'%s'",
-               rv,
-               pkcs11h_getMessage (rv)
-       );
-
-       return rv;
-}
-
-static
-CK_RV
-_pkcs11h_logout (
-       IN const pkcs11h_session_t session
-) {
-       /*PKCS11H_ASSERT (session!=NULL); NOT NEEDED*/
-
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: _pkcs11h_logout entry session=%p",
-               (void *)session
-       );
-
-       if (
-               session != NULL &&
-               session->hSession != PKCS11H_INVALID_SESSION_HANDLE
-       ) {
-#if defined(ENABLE_PKCS11H_THREADING)
-               PKCS11H_BOOL fMutexLocked = FALSE;
-#endif
-               CK_RV rv = CKR_OK;
-
-#if defined(ENABLE_PKCS11H_THREADING)
-               if (
-                       rv == CKR_OK &&
-                       (rv = _pkcs11h_mutexLock (&session->mutexSession)) == CKR_OK
-               ) {
-                       fMutexLocked = TRUE;
-               }
-#endif
-
-               if (rv == CKR_OK) {
-                       if (session->provider != NULL) {
-                               session->provider->f->C_Logout (session->hSession);
-                               session->provider->f->C_CloseSession (session->hSession);
-                       }
-                       session->hSession = PKCS11H_INVALID_SESSION_HANDLE;
-               }
-
-#if defined(ENABLE_PKCS11H_THREADING)
-               if (fMutexLocked) {
-                       _pkcs11h_mutexRelease (&session->mutexSession);
-                       fMutexLocked = FALSE;
-               }
-#endif
-       }
-
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: _pkcs11h_logout return"
-       );
-
-       return CKR_OK;
-}
-
-static
-void
-_pkcs11h_hooks_default_log (
-       IN const void * pData,
-       IN const unsigned flags,
-       IN const char * const szFormat,
-       IN va_list args
-) {
-       (void)pData;
-       (void)flags;
-       (void)szFormat;
-       (void)args;
-}
-
-static
-PKCS11H_BOOL
-_pkcs11h_hooks_default_token_prompt (
-       IN const void * pData,
-       IN const pkcs11h_token_id_t token,
-       IN const unsigned retry
-) {
-       PKCS11H_ASSERT (token!=NULL);
-
-       (void)pData;
-       (void)retry;
-
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: _pkcs11h_hooks_default_token_prompt pData=%p, szLabel='%s'",
-               pData,
-               token->label
-       );
-
-       return FALSE;
-}
-
-static
-PKCS11H_BOOL
-_pkcs11h_hooks_default_pin_prompt (
-       IN const void * pData,
-       IN const pkcs11h_token_id_t token,
-       IN const unsigned retry,
-       OUT char * const szPIN,
-       IN const size_t nMaxPIN
-) {
-       PKCS11H_ASSERT (token!=NULL);
-
-       (void)pData;
-       (void)retry;
-       (void)szPIN;
-       (void)nMaxPIN;
-
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: _pkcs11h_hooks_default_pin_prompt pData=%p, szLabel='%s'",
-               pData,
-               token->label
-       );
-       
-       return FALSE;
-}
-
-#if !defined(WIN32)
-#if defined(ENABLE_PKCS11H_THREADING)
-
-static
-void
-__pkcs11h_atfork_prepare  () {
-       __pkcs1h_mutexLockAll ();
-}
-static
-void
-__pkcs11h_atfork_parent () {
-       __pkcs1h_mutexReleaseAll ();
-}
-static
-void
-__pkcs11h_atfork_child () {
-       __pkcs1h_mutexReleaseAll ();
-       _pkcs11h_forkFixup ();
-}
-
-#endif                         /* ENABLE_PKCS11H_THREADING */
-
-static
-CK_RV
-_pkcs11h_forkFixup () {
-#if defined(ENABLE_PKCS11H_THREADING)
-       PKCS11H_BOOL fMutexLocked = FALSE;
-#endif
-       pid_t mypid = getpid ();
-
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: pkcs11h_forkFixup entry pid=%d",
-               mypid
-       );
-
-       if (s_pkcs11h_data != NULL && s_pkcs11h_data->fInitialized) {
-               pkcs11h_provider_t current;
-
-#if defined(ENABLE_PKCS11H_THREADING)
-               if (_pkcs11h_mutexLock (&s_pkcs11h_data->mutexGlobal) == CKR_OK) {
-                       fMutexLocked = TRUE;
-               }
-#endif
-
-               for (
-                       current = s_pkcs11h_data->providers;
-                       current != NULL;
-                       current = current->next
-               ) {
-                       if (current->fEnabled) {
-                               current->f->C_Initialize (NULL);
-                       }
-
-#if defined(ENABLE_PKCS11H_SLOTEVENT)
-                       /*
-                        * After fork we have no threads...
-                        * So just initialized.
-                        */
-                       if (s_pkcs11h_data->fSlotEventInitialized) {
-                               s_pkcs11h_data->fSlotEventInitialized = FALSE;
-                               _pkcs11h_slotevent_init ();
-                       }
-#endif
-               }
-       }
-
-#if defined(ENABLE_PKCS11H_THREADING)
-       if (fMutexLocked) {
-               _pkcs11h_mutexRelease (&s_pkcs11h_data->mutexGlobal);
-               fMutexLocked = FALSE;
-       }
-#endif
-
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: pkcs11h_forkFixup return"
-       );
-
-       return CKR_OK;
-}
-
-#endif                         /* !WIN32 */
-
-#if defined(ENABLE_PKCS11H_TOKEN)
-/*======================================================================*
- * TOKEN INTERFACE
- *======================================================================*/
-
-CK_RV
-pkcs11h_token_ensureAccess (
-       IN const pkcs11h_token_id_t token_id,
-       IN const unsigned maskPrompt
-) {
-       pkcs11h_session_t session = NULL;
-       CK_RV rv = CKR_OK;
-
-       PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
-       PKCS11H_ASSERT (s_pkcs11h_data->fInitialized);
-       PKCS11H_ASSERT (token_id!=NULL);
-
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: pkcs11h_token_ensureAccess entry token_id=%p, maskPrompt=%08x",
-               (void *)token_id,
-               maskPrompt
-       );
-
-       if (rv == CKR_OK) {
-               rv = _pkcs11h_getSessionByTokenId (
-                       token_id,
-                       &session
-               );
-       }
-
-       if (rv == CKR_OK) {
-               CK_SLOT_ID slot;
-
-               rv = _pkcs11h_resetSession (
-                       session,
-                       maskPrompt,
-                       &slot
-               );
-       }
-
-       if (session != NULL) {
-               _pkcs11h_releaseSession (session);
-               session = NULL;
-       }
-
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: pkcs11h_token_ensureAccess return rv=%ld-'%s'",
-               rv,
-               pkcs11h_getMessage (rv)
-       );
-
-       return rv;
-}
-
-#endif                         /* ENABLE_PKCS11H_TOKEN */
-
-#if defined(ENABLE_PKCS11H_DATA)
-/*======================================================================*
- * DATA INTERFACE
- *======================================================================*/
-
-static
-CK_RV
-_pkcs11h_data_getObject (
-       IN const pkcs11h_session_t session,
-       IN const char * const szApplication,
-       IN const char * const szLabel,
-       OUT CK_OBJECT_HANDLE * const p_handle
-) {
-       CK_OBJECT_CLASS class = CKO_DATA;
-       CK_ATTRIBUTE filter[] = {
-               {CKA_CLASS, (void *)&class, sizeof (class)},
-               {CKA_APPLICATION, (void *)szApplication, szApplication == NULL ? 0 : strlen (szApplication)},
-               {CKA_LABEL, (void *)szLabel, szLabel == NULL ? 0 : strlen (szLabel)}
-       };
-       CK_OBJECT_HANDLE *objects = NULL;
-       CK_ULONG objects_found = 0;
-       CK_RV rv = CKR_OK;
-       
-       /*PKCS11H_ASSERT (session!=NULL); NOT NEEDED*/
-       PKCS11H_ASSERT (szApplication!=NULL);
-       PKCS11H_ASSERT (szLabel!=NULL);
-
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: _pkcs11h_data_getObject entry session=%p, szApplication='%s', szLabel='%s', p_handle=%p",
-               (void *)session,
-               szApplication,
-               szLabel,
-               (void *)p_handle
-       );
-
-       *p_handle = PKCS11H_INVALID_OBJECT_HANDLE;
-
-       if (rv == CKR_OK) {
-               rv = _pkcs11h_validateSession (session);
-       }
-
-       if (rv == CKR_OK) {
-               rv = _pkcs11h_findObjects (
-                       session,
-                       filter,
-                       sizeof (filter) / sizeof (CK_ATTRIBUTE),
-                       &objects,
-                       &objects_found
-               );
-       }
-
-       if (
-               rv == CKR_OK &&
-               objects_found == 0
-       ) {
-               rv = CKR_FUNCTION_REJECTED;
-       }
-
-       if (rv == CKR_OK) {
-               *p_handle = objects[0];
-       }
-
-       if (objects != NULL) {
-               _pkcs11h_free ((void *)&objects);
-       }
-
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: _pkcs11h_data_getObject return rv=%ld-'%s', *p_handle=%p",
-               rv,
-               pkcs11h_getMessage (rv),
-               (void *)*p_handle
-       );
-
-       return rv;
-}
-
-CK_RV
-pkcs11h_data_get (
-       IN const pkcs11h_token_id_t token_id,
-       IN const PKCS11H_BOOL fPublic,
-       IN const char * const szApplication,
-       IN const char * const szLabel,
-       OUT char * const blob,
-       IN OUT size_t * const p_blob_size
-) {
-       CK_ATTRIBUTE attrs[] = {
-               {CKA_VALUE, NULL, 0}
-       };
-       CK_OBJECT_HANDLE handle = PKCS11H_INVALID_OBJECT_HANDLE;
-       CK_RV rv = CKR_OK;
-
-       pkcs11h_session_t session = NULL;
-       size_t blob_size_max;
-       PKCS11H_BOOL fOpSuccess = FALSE;
-       PKCS11H_BOOL fLoginRetry = FALSE;
-       PKCS11H_BOOL fMutexLocked = FALSE;
-
-       PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
-       PKCS11H_ASSERT (s_pkcs11h_data->fInitialized);
-       PKCS11H_ASSERT (token_id!=NULL);
-       PKCS11H_ASSERT (szApplication!=NULL);
-       PKCS11H_ASSERT (szLabel!=NULL);
-       /*PKCS11H_ASSERT (blob!=NULL); NOT NEEDED*/
-       PKCS11H_ASSERT (p_blob_size!=NULL);
-
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: pkcs11h_data_get entry token_id=%p, szApplication='%s', szLabel='%s', blob=%p, p_blob_size=%p",
-               (void *)token_id,
-               szApplication,
-               szLabel,
-               blob,
-               (void *)p_blob_size
-       );
-
-       blob_size_max = *p_blob_size;
-       *p_blob_size = 0;
-
-       if (rv == CKR_OK) {
-               rv = _pkcs11h_getSessionByTokenId (
-                       token_id,
-                       &session
-               );
-       }
-
-       while (rv == CKR_OK && !fOpSuccess) {
-
-               if (rv == CKR_OK) {
-                       rv = _pkcs11h_validateSession (session);
-               }
-
-#if defined(ENABLE_PKCS11H_THREADING)
-               if (
-                       rv == CKR_OK &&
-                       (rv = _pkcs11h_mutexLock (&session->mutexSession)) == CKR_OK
-               ) {
-                       fMutexLocked = TRUE;
-               }
-#endif
-
-               if (rv == CKR_OK) {
-                       rv = _pkcs11h_data_getObject (
-                               session,
-                               szApplication,
-                               szLabel,
-                               &handle
-                       );
-               }
-
-               if (rv == CKR_OK) {
-                       rv = _pkcs11h_getObjectAttributes (
-                               session,
-                               handle,
-                               attrs,
-                               sizeof (attrs)/sizeof (CK_ATTRIBUTE)
-                       );
-               }
-
-#if defined(ENABLE_PKCS11H_THREADING)
-               if (fMutexLocked) {
-                       _pkcs11h_mutexRelease (&session->mutexSession);
-                       fMutexLocked = FALSE;
-               }
-#endif
-
-               if (rv == CKR_OK) {
-                       fOpSuccess = TRUE;
-               }
-               else {
-                       if (!fLoginRetry) {
-                               PKCS11H_DEBUG (
-                                       PKCS11H_LOG_DEBUG1,
-                                       "PKCS#11: Read data object failed rv=%ld-'%s'",
-                                       rv,
-                                       pkcs11h_getMessage (rv)
-                               );
-                               fLoginRetry = TRUE;
-                               rv = _pkcs11h_login (
-                                       session,
-                                       fPublic,
-                                       TRUE,
-                                       (
-                                               PKCS11H_PROMPT_MASK_ALLOW_PIN_PROMPT |
-                                               PKCS11H_PROMPT_MAST_ALLOW_CARD_PROMPT 
-                                       )
-                               );
-                       }
-               }
-       }
-
-       if (rv == CKR_OK) {
-               *p_blob_size = attrs[0].ulValueLen;
-       }
-
-       if (rv == CKR_OK) {
-               if (blob != NULL) {
-                       if (*p_blob_size > blob_size_max) {
-                               rv = CKR_BUFFER_TOO_SMALL;
-                       }
-                       else {
-                               memmove (blob, attrs[0].pValue, *p_blob_size);
-                       }
-               }
-       }
-
-       _pkcs11h_freeObjectAttributes (
-               attrs,
-               sizeof (attrs)/sizeof (CK_ATTRIBUTE)
-       );
-
-       if (session != NULL) {
-               _pkcs11h_releaseSession (session);
-               session = NULL;
-       }
-
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: pkcs11h_data_get return rv=%ld-'%s', *p_blob_size=%d",
-               rv,
-               pkcs11h_getMessage (rv),
-               *p_blob_size
-       );
-
-       return rv;
-}
-
-CK_RV
-pkcs11h_data_put (
-       IN const pkcs11h_token_id_t token_id,
-       IN const PKCS11H_BOOL fPublic,
-       IN const char * const szApplication,
-       IN const char * const szLabel,
-       OUT char * const blob,
-       IN const size_t blob_size
-) {
-       CK_OBJECT_CLASS class = CKO_DATA;
-       CK_BBOOL ck_true = CK_TRUE;
-       CK_BBOOL ck_false = CK_FALSE;
-
-       CK_ATTRIBUTE attrs[] = {
-               {CKA_CLASS, &class, sizeof (class)},
-               {CKA_TOKEN, &ck_true, sizeof (ck_true)},
-               {CKA_PRIVATE, fPublic ? &ck_false : &ck_true, sizeof (CK_BBOOL)},
-               {CKA_APPLICATION, (void *)szApplication, strlen (szApplication)},
-               {CKA_LABEL, (void *)szLabel, strlen (szLabel)},
-               {CKA_VALUE, blob, blob_size}
-       };
-
-       CK_OBJECT_HANDLE handle = PKCS11H_INVALID_OBJECT_HANDLE;
-       CK_RV rv = CKR_OK;
-
-       pkcs11h_session_t session = NULL;
-       PKCS11H_BOOL fOpSuccess = FALSE;
-       PKCS11H_BOOL fLoginRetry = FALSE;
-       PKCS11H_BOOL fMutexLocked = FALSE;
-
-       PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
-       PKCS11H_ASSERT (s_pkcs11h_data->fInitialized);
-       PKCS11H_ASSERT (token_id!=NULL);
-       PKCS11H_ASSERT (szApplication!=NULL);
-       PKCS11H_ASSERT (szLabel!=NULL);
-       PKCS11H_ASSERT (blob!=NULL);
-
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: pkcs11h_data_put entry token_id=%p, szApplication='%s', szLabel='%s', blob=%p, blob_size=%d",
-               (void *)token_id,
-               szApplication,
-               szLabel,
-               blob,
-               blob_size
-       );
-
-       if (rv == CKR_OK) {
-               rv = _pkcs11h_getSessionByTokenId (
-                       token_id,
-                       &session
-               );
-       }
-
-       while (rv == CKR_OK && !fOpSuccess) {
-
-               if (rv == CKR_OK) {
-                       rv = _pkcs11h_validateSession (session);
-               }
-
-#if defined(ENABLE_PKCS11H_THREADING)
-               if (
-                       rv == CKR_OK &&
-                       (rv = _pkcs11h_mutexLock (&session->mutexSession)) == CKR_OK
-               ) {
-                       fMutexLocked = TRUE;
-               }
-#endif
-
-               if (rv == CKR_OK) {
-                       rv = session->provider->f->C_CreateObject (
-                               session->hSession,
-                               attrs,
-                               sizeof (attrs)/sizeof (CK_ATTRIBUTE),
-                               &handle
-                       );
-               }
-
-#if defined(ENABLE_PKCS11H_THREADING)
-               if (fMutexLocked) {
-                       _pkcs11h_mutexRelease (&session->mutexSession);
-                       fMutexLocked = FALSE;
-               }
-#endif
-
-               if (rv == CKR_OK) {
-                       fOpSuccess = TRUE;
-               }
-               else {
-                       if (!fLoginRetry) {
-                               PKCS11H_DEBUG (
-                                       PKCS11H_LOG_DEBUG1,
-                                       "PKCS#11: Write data object failed rv=%ld-'%s'",
-                                       rv,
-                                       pkcs11h_getMessage (rv)
-                               );
-                               fLoginRetry = TRUE;
-                               rv = _pkcs11h_login (
-                                       session,
-                                       fPublic,
-                                       FALSE,
-                                       (
-                                               PKCS11H_PROMPT_MASK_ALLOW_PIN_PROMPT |
-                                               PKCS11H_PROMPT_MAST_ALLOW_CARD_PROMPT 
-                                       )
-                               );
-                       }
-               }
-       }
-
-       if (session != NULL) {
-               _pkcs11h_releaseSession (session);
-               session = NULL;
-       }
-
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: pkcs11h_data_put return rv=%ld-'%s'",
-               rv,
-               pkcs11h_getMessage (rv)
-       );
-
-       return rv;
-}
-
-CK_RV
-pkcs11h_data_del (
-       IN const pkcs11h_token_id_t token_id,
-       IN const PKCS11H_BOOL fPublic,
-       IN const char * const szApplication,
-       IN const char * const szLabel
-) {
-       CK_OBJECT_HANDLE handle = PKCS11H_INVALID_OBJECT_HANDLE;
-       CK_RV rv = CKR_OK;
-
-       pkcs11h_session_t session = NULL;
-       PKCS11H_BOOL fOpSuccess = FALSE;
-       PKCS11H_BOOL fLoginRetry = FALSE;
-       PKCS11H_BOOL fMutexLocked = FALSE;
-
-       PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
-       PKCS11H_ASSERT (s_pkcs11h_data->fInitialized);
-       PKCS11H_ASSERT (token_id!=NULL);
-       PKCS11H_ASSERT (szApplication!=NULL);
-       PKCS11H_ASSERT (szLabel!=NULL);
-
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: pkcs11h_data_del entry token_id=%p, szApplication='%s', szLabel='%s'",
-               (void *)token_id,
-               szApplication,
-               szLabel
-       );
-
-       if (rv == CKR_OK) {
-               rv = _pkcs11h_getSessionByTokenId (
-                       token_id,
-                       &session
-               );
-       }
-
-       while (rv == CKR_OK && !fOpSuccess) {
-
-               if (rv == CKR_OK) {
-                       rv = _pkcs11h_validateSession (session);
-               }
-
-               if (rv == CKR_OK) {
-                       rv = _pkcs11h_data_getObject (
-                               session,
-                               szApplication,
-                               szLabel,
-                               &handle
-                       );
-               }
-
-#if defined(ENABLE_PKCS11H_THREADING)
-               if (
-                       rv == CKR_OK &&
-                       (rv = _pkcs11h_mutexLock (&session->mutexSession)) == CKR_OK
-               ) {
-                       fMutexLocked = TRUE;
-               }
-#endif
-
-               if (rv == CKR_OK) {
-                       rv = session->provider->f->C_DestroyObject (
-                               session->hSession,
-                               handle
-                       );
-               }
-
-#if defined(ENABLE_PKCS11H_THREADING)
-               if (fMutexLocked) {
-                       _pkcs11h_mutexRelease (&session->mutexSession);
-                       fMutexLocked = FALSE;
-               }
-#endif
-
-               if (rv == CKR_OK) {
-                       fOpSuccess = TRUE;
-               }
-               else {
-                       if (!fLoginRetry) {
-                               PKCS11H_DEBUG (
-                                       PKCS11H_LOG_DEBUG1,
-                                       "PKCS#11: Remove data object failed rv=%ld-'%s'",
-                                       rv,
-                                       pkcs11h_getMessage (rv)
-                               );
-                               fLoginRetry = TRUE;
-                               rv = _pkcs11h_login (
-                                       session,
-                                       fPublic,
-                                       FALSE,
-                                       (
-                                               PKCS11H_PROMPT_MASK_ALLOW_PIN_PROMPT |
-                                               PKCS11H_PROMPT_MAST_ALLOW_CARD_PROMPT 
-                                       )
-                               );
-                       }
-               }
-       }
-
-       if (session != NULL) {
-               _pkcs11h_releaseSession (session);
-               session = NULL;
-       }
-
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: pkcs11h_data_del return rv=%ld-'%s'",
-               rv,
-               pkcs11h_getMessage (rv)
-       );
-
-       return rv;
-}
-
-#endif                         /* ENABLE_PKCS11H_DATA */
-
-#if defined(ENABLE_PKCS11H_CERTIFICATE)
-/*======================================================================*
- * CERTIFICATE INTERFACE
- *======================================================================*/
-
-static
-void
-_pkcs11h_isBetterCertificate_getExpiration (
-       IN const unsigned char * const pCertificate,
-       IN const size_t nCertificateSize,
-       OUT char * const szNotBefore,
-       IN const int nNotBeforeSize
-) {
-       /*
-        * This function compare the notBefore
-        * and select the most recent certificate
-        * it does not deal with timezones...
-        * When openssl will have ASN1_TIME compare function
-        * it should be used.
-        */
-
-       X509 *x509 = NULL;
-
-       PKCS11H_ASSERT (pCertificate!=NULL);
-       PKCS11H_ASSERT (szNotBefore!=NULL);
-       PKCS11H_ASSERT (nNotBeforeSize>0);
-
-       szNotBefore[0] = '\0';
-
-       x509 = X509_new ();
-
-       if (x509 != NULL) {
-               pkcs11_openssl_d2i_t d2i = (pkcs11_openssl_d2i_t)pCertificate;
-
-               if (
-                       d2i_X509 (&x509, &d2i, nCertificateSize)
-               ) {
-                       ASN1_TIME *notBefore = X509_get_notBefore (x509);
-                       ASN1_TIME *notAfter = X509_get_notAfter (x509);
-
-                       if (
-                               notBefore != NULL &&
-                               X509_cmp_current_time (notBefore) <= 0 &&
-                               X509_cmp_current_time (notAfter) >= 0 &&
-                               notBefore->length < nNotBeforeSize - 1
-                       ) {
-                               memmove (szNotBefore, notBefore->data, notBefore->length);
-                               szNotBefore[notBefore->length] = '\0';
-                       }
-               }
-       }
-
-       if (x509 != NULL) {
-               X509_free (x509);
-               x509 = NULL;
-       }
-}
-
-static
-PKCS11H_BOOL
-_pkcs11h_isBetterCertificate (
-       IN const unsigned char * const pCurrent,
-       IN const size_t nCurrentSize,
-       IN const unsigned char * const pNew,
-       IN const size_t nNewSize
-) {
-       /*
-        * This function compare the notBefore
-        * and select the most recent certificate
-        * it does not deal with timezones...
-        * When openssl will have ASN1_TIME compare function
-        * it should be used.
-        */
-
-       PKCS11H_BOOL fBetter = FALSE;
-
-       /*PKCS11H_ASSERT (pCurrent!=NULL); NOT NEEDED */
-       PKCS11H_ASSERT (pNew!=NULL);
-
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: _pkcs11h_isBetterCertificate entry pCurrent=%p, nCurrentSize=%u, pNew=%p, nNewSize=%u",
-               pCurrent,
-               nCurrentSize,
-               pNew,
-               nNewSize
-       );
-
-       /*
-        * First certificae
-        * always select
-        */
-       if (nCurrentSize == 0 || pCurrent == NULL) {
-               fBetter = TRUE;
-       }
-       else {
-               char szNotBeforeCurrent[1024], szNotBeforeNew[1024];
-
-               _pkcs11h_isBetterCertificate_getExpiration (
-                       pCurrent,
-                       nCurrentSize,
-                       szNotBeforeCurrent,
-                       sizeof (szNotBeforeCurrent)
-               );
-               _pkcs11h_isBetterCertificate_getExpiration (
-                       pNew,
-                       nNewSize,
-                       szNotBeforeNew,
-                       sizeof (szNotBeforeNew)
-               );
-
-               PKCS11H_DEBUG (
-                       PKCS11H_LOG_DEBUG2,
-                       "PKCS#11: _pkcs11h_isBetterCertificate szNotBeforeCurrent='%s', szNotBeforeNew='%s'",
-                       szNotBeforeCurrent,
-                       szNotBeforeNew
-               );
-
-               fBetter = strcmp (szNotBeforeCurrent, szNotBeforeNew) < 0;
-       }
-
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: _pkcs11h_isBetterCertificate return fBetter=%d",
-               fBetter ? 1 : 0
-       );
-       
-       return fBetter;
-}
-
-static
-CK_RV
-_pkcs11h_newCertificateId (
-       OUT pkcs11h_certificate_id_t * const p_certificate_id
-) {
-       CK_RV rv = CKR_OK;
-
-       PKCS11H_ASSERT (p_certificate_id!=NULL);
-
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: _pkcs11h_newCertificateId entry p_certificate_id=%p",
-               (void *)p_certificate_id
-       );
-
-       *p_certificate_id = NULL;
-
-       if (rv == CKR_OK) {
-               rv = _pkcs11h_malloc ((void *)p_certificate_id, sizeof (struct pkcs11h_certificate_id_s));
-       }
-
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: _pkcs11h_newCertificateId return rv=%ld-'%s', *p_certificate_id=%p",
-               rv,
-               pkcs11h_getMessage (rv),
-               (void *)*p_certificate_id
-       );
-
-       return rv;
-}
-
-static
-CK_RV
-_pkcs11h_loadCertificate (
-       IN const pkcs11h_certificate_t certificate
-) {
-#if defined(ENABLE_PKCS11H_THREADING)
-       PKCS11H_BOOL fMutexLocked = FALSE;
-#endif
-       CK_OBJECT_CLASS cert_filter_class = CKO_CERTIFICATE;
-       CK_ATTRIBUTE cert_filter[] = {
-               {CKA_CLASS, &cert_filter_class, sizeof (cert_filter_class)},
-               {CKA_ID, NULL, 0}
-       };
-
-       CK_OBJECT_HANDLE *objects = NULL;
-       CK_ULONG objects_found = 0;
-       CK_RV rv = CKR_OK;
-
-       CK_ULONG i;
-
-       PKCS11H_ASSERT (certificate!=NULL);
-       PKCS11H_ASSERT (certificate->id!=NULL);
-       
-       /* Must be after assert */
-       cert_filter[1].pValue = certificate->id->attrCKA_ID;
-       cert_filter[1].ulValueLen = certificate->id->attrCKA_ID_size;
-
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: _pkcs11h_loadCertificate entry certificate=%p",
-               (void *)certificate
-       );
-
-       if (rv == CKR_OK) {
-               rv = _pkcs11h_validateSession (certificate->session);
-       }
-
-#if defined(ENABLE_PKCS11H_THREADING)
-       if (
-               rv == CKR_OK &&
-               (rv = _pkcs11h_mutexLock (&certificate->mutexCertificate)) == CKR_OK
-       ) {
-               fMutexLocked = TRUE;
-       }
-#endif
-
-       if (rv == CKR_OK) {
-               rv = _pkcs11h_findObjects (
-                       certificate->session,
-                       cert_filter,
-                       sizeof (cert_filter) / sizeof (CK_ATTRIBUTE),
-                       &objects,
-                       &objects_found
-               );
-       }
-
-       for (i=0;rv == CKR_OK && i < objects_found;i++) {
-               CK_ATTRIBUTE attrs[] = {
-                       {CKA_VALUE, NULL, 0}
-               };
-
-               if (
-                       rv == CKR_OK &&
-                       (rv = _pkcs11h_getObjectAttributes (
-                               certificate->session,
-                               objects[i],
-                               attrs,
-                               sizeof (attrs) / sizeof (CK_ATTRIBUTE)
-                       )) == CKR_OK
-               ) {
-                       if (
-                               _pkcs11h_isBetterCertificate (
-                                       certificate->id->certificate_blob,
-                                       certificate->id->certificate_blob_size,
-                                       attrs[0].pValue,
-                                       attrs[0].ulValueLen
-                               )
-                       ) {
-                               if (certificate->id->certificate_blob != NULL) {
-                                       _pkcs11h_free ((void *)&certificate->id->certificate_blob);
-                               }
-
-                               rv = _pkcs11h_dupmem (
-                                       (void*)&certificate->id->certificate_blob,
-                                       &certificate->id->certificate_blob_size,
-                                       attrs[0].pValue,
-                                       attrs[0].ulValueLen
-                               );
-                       }
-               }
-
-               if (rv != CKR_OK) {
-                       PKCS11H_DEBUG (
-                               PKCS11H_LOG_DEBUG1,
-                               "PKCS#11: Cannot get object attribute for provider '%s' object %ld rv=%ld-'%s'",
-                               certificate->session->provider->manufacturerID,
-                               objects[i],
-                               rv,
-                               pkcs11h_getMessage (rv)
-                       );
-
-                       /*
-                        * Ignore error
-                        */
-                       rv = CKR_OK;
-               }
-
-               _pkcs11h_freeObjectAttributes (
-                       attrs,
-                       sizeof (attrs) / sizeof (CK_ATTRIBUTE)
-               );
-       }
-       
-       if (
-               rv == CKR_OK &&
-               certificate->id->certificate_blob == NULL
-       ) {
-               rv = CKR_ATTRIBUTE_VALUE_INVALID;
-       }
-
-       if (objects != NULL) {
-               _pkcs11h_free ((void *)&objects);
-       }
-
-#if defined(ENABLE_PKCS11H_THREADING)
-       if (fMutexLocked) {
-               _pkcs11h_mutexRelease (&certificate->mutexCertificate);
-               fMutexLocked = FALSE;
-       }
-#endif
-
-       /*
-        * No need to free allocated objects
-        * on error, since the certificate_id
-        * should be free by caller.
-        */
-
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: _pkcs11h_loadCertificate return rv=%ld-'%s'",
-               rv,
-               pkcs11h_getMessage (rv)
-       );
-
-       return rv;
-}
-
-static
-CK_RV
-_pkcs11h_updateCertificateIdDescription (
-       IN OUT pkcs11h_certificate_id_t certificate_id
-) {
-       static const char * szSeparator = " on ";
-       static const char * szUnknown = "UNKNOWN";
-       X509 *x509 = NULL;
-       pkcs11_openssl_d2i_t d2i1;
-
-       PKCS11H_ASSERT (certificate_id!=NULL);
-
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: _pkcs11h_updateCertificateIdDescription entry certificate_id=%p",
-               (void *)certificate_id
-       );
-
-       x509 = X509_new ();
-
-       d2i1 = (pkcs11_openssl_d2i_t)certificate_id->certificate_blob;
-       if (d2i_X509 (&x509, &d2i1, certificate_id->certificate_blob_size)) {
-               X509_NAME_oneline (
-                       X509_get_subject_name (x509),
-                       certificate_id->displayName,
-                       sizeof (certificate_id->displayName)
-               );
-       }
-       else {
-               strncpy (
-                       certificate_id->displayName,
-                       szUnknown,
-                       sizeof (certificate_id->displayName)-1
-               );
-       }
-
-       if (x509 != NULL) {
-               X509_free (x509);
-               x509 = NULL;
-       }
-
-       /*
-        * Try to avoid using snprintf,
-        * may be unavailable
-        */
-       strncat (
-               certificate_id->displayName,
-               szSeparator,
-               sizeof (certificate_id->displayName)-1-strlen (certificate_id->displayName)
-       );
-       strncat (
-               certificate_id->displayName,
-               certificate_id->token_id->label,
-               sizeof (certificate_id->displayName)-1-strlen (certificate_id->displayName)
-       );
-       certificate_id->displayName[sizeof (certificate_id->displayName) - 1] = '\0';
-
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: _pkcs11h_updateCertificateIdDescription return displayName=%s",
-               certificate_id->displayName
-       );
-
-       return CKR_OK;
-}
-
-static
-CK_RV
-_pkcs11h_ensureCertificateBlob (
-       IN const pkcs11h_certificate_t certificate
-) {
-#if defined(ENABLE_PKCS11H_THREADING)
-       PKCS11H_BOOL fMutexLocked = FALSE;
-#endif
-       PKCS11H_BOOL fOpSuccess = FALSE;
-       PKCS11H_BOOL fLoginRetry = FALSE;
-
-       CK_RV rv = CKR_OK;
-       
-       PKCS11H_ASSERT (certificate!=NULL);
-
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: _pkcs11h_ensureCertificateBlob entry certificate=%p",
-               (void *)certificate
-       );
-
-#if defined(ENABLE_PKCS11H_THREADING)
-       if (
-               rv == CKR_OK &&
-               (rv = _pkcs11h_mutexLock (&certificate->mutexCertificate)) == CKR_OK
-       ) {
-               fMutexLocked = TRUE;
-       }
-#endif
-
-       if (certificate->id->certificate_blob == NULL) {
-               fOpSuccess = FALSE;
-               fLoginRetry = FALSE;
-               while (rv == CKR_OK && !fOpSuccess) {
-                       if (rv == CKR_OK) {
-                               rv = _pkcs11h_loadCertificate (certificate);
-                       }
-
-                       if (rv == CKR_OK) {
-                               fOpSuccess = TRUE;
-                       }
-                       else {
-                               if (!fLoginRetry) {
-                                       fLoginRetry = TRUE;
-                                       rv = _pkcs11h_resetCertificateSession (
-                                               certificate,
-                                               TRUE,
-                                               (
-                                                       PKCS11H_PROMPT_MASK_ALLOW_PIN_PROMPT |
-                                                       PKCS11H_PROMPT_MAST_ALLOW_CARD_PROMPT 
-                                               )
-                                       );
-                               }
-                       }
-               }
-       }
-       
-       if (
-               rv == CKR_OK &&
-               certificate->id->certificate_blob == NULL
-       ) {
-               rv = CKR_FUNCTION_REJECTED;
-       }
-
-       if (rv == CKR_OK) {
-               _pkcs11h_updateCertificateIdDescription (certificate->id);
-       }
-
-#if defined(ENABLE_PKCS11H_THREADING)
-       if (fMutexLocked) {
-               _pkcs11h_mutexRelease (&certificate->mutexCertificate);
-               fMutexLocked = FALSE;
-       }
-#endif
-
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: _pkcs11h_ensureCertificateBlob return rv=%ld-'%s'",
-               rv,
-               pkcs11h_getMessage (rv)
-       );
-
-       return rv;
-}
-
-static
-CK_RV
-_pkcs11h_getCertificateKeyAttributes (
-       IN const pkcs11h_certificate_t certificate
-) {
-       CK_RV rv = CKR_OK;
-
-       PKCS11H_BOOL fOpSuccess = FALSE;
-       PKCS11H_BOOL fLoginRetry = FALSE;
-
-       PKCS11H_ASSERT (certificate!=NULL);
-
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: _pkcs11h_getCertificateKeyAttributes entry certificate=%p",
-               (void *)certificate
-       );
-
-       certificate->maskSignMode = 0;
-
-       while (rv == CKR_OK && !fOpSuccess) {
-#if defined(ENABLE_PKCS11H_THREADING)
-               PKCS11H_BOOL fMutexLocked = FALSE;
-#endif
-               CK_ATTRIBUTE key_attrs[] = {
-                       {CKA_SIGN, NULL, 0},
-                       {CKA_SIGN_RECOVER, NULL, 0}
-               };
-
-#if defined(ENABLE_PKCS11H_THREADING)
-               if (
-                       rv == CKR_OK &&
-                       (rv = _pkcs11h_mutexLock (&certificate->mutexCertificate)) == CKR_OK
-               ) {
-                       fMutexLocked = TRUE;
-               }
-#endif
-
-               /*
-                * Don't try invalid object
-                */
-               if (
-                       rv == CKR_OK &&
-                       certificate->hKey == PKCS11H_INVALID_OBJECT_HANDLE
-               ) {
-                       rv = CKR_OBJECT_HANDLE_INVALID;
-               }
-
-               if (rv == CKR_OK) {
-                       if (certificate->session->provider->maskSignMode != 0) {
-                               certificate->maskSignMode = certificate->session->provider->maskSignMode;
-                               fOpSuccess = TRUE;
-                               PKCS11H_DEBUG (
-                                       PKCS11H_LOG_DEBUG1,
-                                       "PKCS#11: Key attributes enforced by provider (%08x)",
-                                       certificate->maskSignMode
-                               );
-                       }
-               }
-
-               if (rv == CKR_OK && !fOpSuccess) {
-                       rv = _pkcs11h_getObjectAttributes (
-                               certificate->session,
-                               certificate->hKey,
-                               key_attrs,
-                               sizeof (key_attrs) / sizeof (CK_ATTRIBUTE)
-                       );
-               }
-
-               if (rv == CKR_OK && !fOpSuccess) {
-                       CK_BBOOL *key_attrs_sign = (CK_BBOOL *)key_attrs[0].pValue;
-                       CK_BBOOL *key_attrs_sign_recover = (CK_BBOOL *)key_attrs[1].pValue;
-
-                       if (key_attrs_sign != NULL && *key_attrs_sign != CK_FALSE) {
-                               certificate->maskSignMode |= PKCS11H_SIGNMODE_MASK_SIGN;
-                       }
-                       if (key_attrs_sign_recover != NULL && *key_attrs_sign_recover != CK_FALSE) {
-                               certificate->maskSignMode |= PKCS11H_SIGNMODE_MASK_RECOVER;
-                       }
-                       if (certificate->maskSignMode == 0) {
-                               rv = CKR_KEY_TYPE_INCONSISTENT;
-                       }
-                       PKCS11H_DEBUG (
-                               PKCS11H_LOG_DEBUG1,
-                               "PKCS#11: Key attributes loaded (%08x)",
-                               certificate->maskSignMode
-                       );
-               }
-
-               _pkcs11h_freeObjectAttributes (
-                       key_attrs,
-                       sizeof (key_attrs) / sizeof (CK_ATTRIBUTE)
-               );
-
-#if defined(ENABLE_PKCS11H_THREADING)
-               if (fMutexLocked) {
-                       _pkcs11h_mutexRelease (&certificate->mutexCertificate);
-                       fMutexLocked = FALSE;
-               }
-#endif
-       
-               if (rv == CKR_OK) {
-                       fOpSuccess = TRUE;
-               }
-               else {
-                       if (!fLoginRetry) {
-                               PKCS11H_DEBUG (
-                                       PKCS11H_LOG_DEBUG1,
-                                       "PKCS#11: Get private key attributes failed: %ld:'%s'",
-                                       rv,
-                                       pkcs11h_getMessage (rv)
-                               );
-
-                               rv = _pkcs11h_resetCertificateSession (
-                                       certificate,
-                                       FALSE,
-                                       (
-                                               PKCS11H_PROMPT_MASK_ALLOW_PIN_PROMPT |
-                                               PKCS11H_PROMPT_MAST_ALLOW_CARD_PROMPT 
-                                       )
-                               );
-
-                               fLoginRetry = TRUE;
-                       }
-               }
-       }
-
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: _pkcs11h_getCertificateKeyAttributes return rv=%ld-'%s'",
-               rv,
-               pkcs11h_getMessage (rv)
-       );
-
-       return rv;
-}
-
-static
-CK_RV
-_pkcs11h_validateCertificateSession (
-       IN const pkcs11h_certificate_t certificate
-) {
-       CK_RV rv = CKR_OK;
-
-       PKCS11H_ASSERT (certificate!=NULL);
-
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: _pkcs11h_validateCertificateSession entry certificate=%p",
-               (void *)certificate
-       );
-
-       if (rv == CKR_OK) {
-               rv = _pkcs11h_validateSession (certificate->session);
-       }
-
-       if (rv == CKR_OK) {
-               if (certificate->hKey == PKCS11H_INVALID_OBJECT_HANDLE) {
-                       rv = CKR_OBJECT_HANDLE_INVALID;
-               }
-       }
-
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: _pkcs11h_validateCertificateSession return rv=%ld-'%s'",
-               rv,
-               pkcs11h_getMessage (rv)
-       );
-
-       return rv;
-}
-
-CK_RV
-_pkcs11h_resetCertificateSession (
-       IN const pkcs11h_certificate_t certificate,
-       IN const PKCS11H_BOOL fPublicOnly,
-       IN const unsigned maskPrompt
-) {
-#if defined(ENABLE_PKCS11H_THREADING)
-       PKCS11H_BOOL fMutexLocked = FALSE;
-#endif
-       PKCS11H_BOOL fKeyValid = FALSE;
-       CK_RV rv = CKR_OK;
-
-       PKCS11H_ASSERT (certificate!=NULL);
-       
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: pkcs11h_resetCertificateSession entry certificate=%p, fPublicOnly=%d, maskPrompt=%08x",
-               (void *)certificate,
-               fPublicOnly ? 1 : 0,
-               maskPrompt
-       );
-
-#if defined(ENABLE_PKCS11H_THREADING)
-       if (
-               rv == CKR_OK &&
-               (rv = _pkcs11h_mutexLock (&certificate->mutexCertificate)) == CKR_OK
-       ) {
-               fMutexLocked = TRUE;
-       }
-#endif
-
-       if (
-               !fKeyValid &&
-               rv == CKR_OK &&
-               certificate->session == NULL &&
-               (rv = _pkcs11h_getSessionByTokenId (certificate->id->token_id, &certificate->session)) == CKR_OK
-       ) {
-               if (certificate->nPINCachePeriod != PKCS11H_PIN_CACHE_INFINITE) {
-                       if (certificate->session->nPINCachePeriod != PKCS11H_PIN_CACHE_INFINITE) {
-                               if (certificate->session->nPINCachePeriod > certificate->nPINCachePeriod) {
-                                       certificate->session->timePINExpire = (
-                                               certificate->session->timePINExpire -
-                                               (time_t)certificate->session->nPINCachePeriod +
-                                               (time_t)certificate->nPINCachePeriod
-                                       );
-                                       certificate->session->nPINCachePeriod = certificate->nPINCachePeriod;
-                               }
-                       }
-                       else {
-                               certificate->session->timePINExpire = (
-                                       PKCS11H_TIME (NULL) +
-                                       (time_t)certificate->nPINCachePeriod
-                               );
-                               certificate->session->nPINCachePeriod = certificate->nPINCachePeriod;
-                       }
-               }       
-       }
-
-       /*
-        * First, if session seems to be valid
-        * and key handle is invalid (hard-set),
-        * try to fetch key handle,
-        * maybe the token is already logged in
-        */
-       if (rv == CKR_OK) {
-               if (
-                       certificate->session->hSession != PKCS11H_INVALID_SESSION_HANDLE && 
-                       certificate->hKey == PKCS11H_INVALID_OBJECT_HANDLE &&
-                       !fPublicOnly
-               ) {
-                       if (
-                               (rv = _pkcs11h_getObjectById (
-                                       certificate->session,
-                                       CKO_PRIVATE_KEY,
-                                       certificate->id->attrCKA_ID,
-                                       certificate->id->attrCKA_ID_size,
-                                       &certificate->hKey
-                               )) == CKR_OK
-                       ) {
-                               fKeyValid = TRUE;
-                       }
-                       else {
-                               /*
-                                * Ignore error
-                                */
-                               rv = CKR_OK;
-                               certificate->hKey = PKCS11H_INVALID_OBJECT_HANDLE;
-                       }
-               }
-       }
-
-       if (
-               !fKeyValid &&
-               rv == CKR_OK &&
-               (rv = _pkcs11h_login (
-                       certificate->session,
-                       fPublicOnly,
-                       TRUE,
-                       maskPrompt
-               )) == CKR_OK
-       ) {
-               rv = _pkcs11h_updateCertificateIdDescription (certificate->id);
-       }
-
-       if (
-               !fKeyValid &&
-               rv == CKR_OK &&
-               !fPublicOnly &&
-               (rv = _pkcs11h_getObjectById (
-                       certificate->session,
-                       CKO_PRIVATE_KEY,
-                       certificate->id->attrCKA_ID,
-                       certificate->id->attrCKA_ID_size,
-                       &certificate->hKey
-               )) == CKR_OK
-       ) {
-               fKeyValid = TRUE;
-       }
-
-       if (
-               rv == CKR_OK &&
-               !fPublicOnly &&
-               !fKeyValid
-       ) {
-               rv = CKR_FUNCTION_REJECTED;
-       }
-
-#if defined(ENABLE_PKCS11H_THREADING)
-       if (fMutexLocked) {
-               _pkcs11h_mutexRelease (&certificate->mutexCertificate);
-               fMutexLocked = FALSE;
-       }
-#endif
-
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: _pkcs11h_resetCertificateSession return rv=%ld-'%s'",
-               rv,
-               pkcs11h_getMessage (rv)
-       );
-
-       return rv;
-}
-
-static
-CK_RV
-_pkcs11h_certificate_private_op (
-       IN const pkcs11h_certificate_t certificate,
-       IN const enum _pkcs11h_private_op_e op,
-       IN const CK_MECHANISM_TYPE mech_type,
-       IN const unsigned char * const source,
-       IN const size_t source_size,
-       OUT unsigned char * const target,
-       IN OUT size_t * const p_target_size
-) {
-       CK_MECHANISM mech = {
-               mech_type, NULL, 0
-       };
-       
-       CK_RV rv = CKR_OK;
-       PKCS11H_BOOL fLoginRetry = FALSE;
-       PKCS11H_BOOL fOpSuccess = FALSE;
-
-       PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
-       PKCS11H_ASSERT (s_pkcs11h_data->fInitialized);
-       PKCS11H_ASSERT (certificate!=NULL);
-       PKCS11H_ASSERT (source!=NULL);
-       /*PKCS11H_ASSERT (target); NOT NEEDED*/
-       PKCS11H_ASSERT (p_target_size!=NULL);
-
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: _pkcs11h_certificate_private_op entry certificate=%p, op=%d, mech_type=%ld, source=%p, source_size=%u, target=%p, p_target_size=%p",
-               (void *)certificate,
-               op,
-               mech_type,
-               source,
-               source_size,
-               target,
-               (void *)p_target_size
-       );
-
-       if (target == NULL) {
-               *p_target_size = 0;
-       }
-
-       while (rv == CKR_OK && !fOpSuccess) {
-#if defined(ENABLE_PKCS11H_THREADING)
-               PKCS11H_BOOL fMutexLocked = FALSE;
-#endif
-
-               if (rv == CKR_OK && !certificate->fOperationActive) {
-                       rv = _pkcs11h_validateCertificateSession (certificate);
-               }
-
-#if defined(ENABLE_PKCS11H_THREADING)
-               if (
-                       rv == CKR_OK &&
-                       (rv = _pkcs11h_mutexLock (&certificate->session->mutexSession)) == CKR_OK
-               ) {
-                       fMutexLocked = TRUE;
-               }
-#endif
-
-               if (rv == CKR_OK && !certificate->fOperationActive) {
-                       switch (op) {
-                               case _pkcs11h_private_op_sign:
-                                       rv = certificate->session->provider->f->C_SignInit (
-                                               certificate->session->hSession,
-                                               &mech,
-                                               certificate->hKey
-                                       );
-                               break;
-                               case _pkcs11h_private_op_sign_recover:
-                                       rv = certificate->session->provider->f->C_SignRecoverInit (
-                                               certificate->session->hSession,
-                                               &mech,
-                                               certificate->hKey
-                                       );
-                               break;
-                               case _pkcs11h_private_op_decrypt:
-                                       rv = certificate->session->provider->f->C_DecryptInit (
-                                               certificate->session->hSession,
-                                               &mech,
-                                               certificate->hKey
-                                       );
-                               break;
-                               default:
-                                       rv = CKR_ARGUMENTS_BAD;
-                               break;
-                       }
-               }
-
-               if (rv == CKR_OK) {
-                       CK_ULONG size = *p_target_size;
-
-                       switch (op) {
-                               case _pkcs11h_private_op_sign:
-                                       rv = certificate->session->provider->f->C_Sign (
-                                               certificate->session->hSession,
-                                               (CK_BYTE_PTR)source,
-                                               source_size,
-                                               (CK_BYTE_PTR)target,
-                                               &size
-                                       );
-                               break;
-                               case _pkcs11h_private_op_sign_recover:
-                                       rv = certificate->session->provider->f->C_SignRecover (
-                                               certificate->session->hSession,
-                                               (CK_BYTE_PTR)source,
-                                               source_size,
-                                               (CK_BYTE_PTR)target,
-                                               &size
-                                       );
-                               break;
-                               case _pkcs11h_private_op_decrypt:
-                                       rv = certificate->session->provider->f->C_Decrypt (
-                                               certificate->session->hSession,
-                                               (CK_BYTE_PTR)source,
-                                               source_size,
-                                               (CK_BYTE_PTR)target,
-                                               &size
-                                       );
-                               break;
-                               default:
-                                       rv = CKR_ARGUMENTS_BAD;
-                               break;
-                       }
-
-                       *p_target_size = size;
-               }
-               
-               if (
-                       target == NULL &&
-                       (
-                               rv == CKR_BUFFER_TOO_SMALL ||
-                               rv == CKR_OK
-                       )
-               ) {
-                       certificate->fOperationActive = TRUE;
-                       rv = CKR_OK;
-               }
-               else {
-                       certificate->fOperationActive = FALSE;
-               }
-
-#if defined(ENABLE_PKCS11H_THREADING)
-               if (fMutexLocked) {
-                       _pkcs11h_mutexRelease (&certificate->session->mutexSession);
-                       fMutexLocked = FALSE;
-               }
-#endif
-
-               if (rv == CKR_OK) {
-                       fOpSuccess = TRUE;
-               }
-               else {
-                       /*
-                        * OpenSC workaround
-                        * It still allows C_FindObjectsInit when
-                        * token is removed/inserted but fails
-                        * private key operation.
-                        * So we force logout.
-                        * bug#108 at OpenSC trac
-                        */
-                       if (fLoginRetry && rv == CKR_DEVICE_REMOVED) {
-                               fLoginRetry = FALSE;
-                               _pkcs11h_logout (certificate->session);
-                       }
-
-                       if (!fLoginRetry) {
-                               PKCS11H_DEBUG (
-                                       PKCS11H_LOG_DEBUG1,
-                                       "PKCS#11: Private key operation failed rv=%ld-'%s'",
-                                       rv,
-                                       pkcs11h_getMessage (rv)
-                               );
-                               fLoginRetry = TRUE;
-                               rv = _pkcs11h_resetCertificateSession (
-                                       certificate,
-                                       FALSE,
-                                       (
-                                               PKCS11H_PROMPT_MASK_ALLOW_PIN_PROMPT |
-                                               PKCS11H_PROMPT_MAST_ALLOW_CARD_PROMPT 
-                                       )
-                               );
-                       }
-               }
-       }
-
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: _pkcs11h_certificate_private_op return rv=%ld-'%s', *p_target_size=%d",
-               rv,
-               pkcs11h_getMessage (rv),
-               *p_target_size
-       );
-       
-       return rv;
-}
-
-CK_RV
-pkcs11h_freeCertificateId (
-       IN pkcs11h_certificate_id_t certificate_id
-) {
-       PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
-       PKCS11H_ASSERT (s_pkcs11h_data->fInitialized);
-       PKCS11H_ASSERT (certificate_id!=NULL);
-
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: pkcs11h_freeCertificateId entry certificate_id=%p",
-               (void *)certificate_id
-       );
-
-       if (certificate_id->attrCKA_ID != NULL) {
-               _pkcs11h_free ((void *)&certificate_id->attrCKA_ID);
-       }
-       if (certificate_id->certificate_blob != NULL) {
-               _pkcs11h_free ((void *)&certificate_id->certificate_blob);
-       }
-       if (certificate_id->token_id != NULL) {
-               pkcs11h_freeTokenId (certificate_id->token_id);
-               certificate_id->token_id = NULL;
-       }
-       _pkcs11h_free ((void *)&certificate_id);
-
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: pkcs11h_freeCertificateId return"
-       );
-
-       return CKR_OK;
-}
-
-CK_RV
-pkcs11h_duplicateCertificateId (
-       OUT pkcs11h_certificate_id_t * const to,
-       IN const pkcs11h_certificate_id_t from
-) {
-       CK_RV rv = CKR_OK;
-
-       PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
-       PKCS11H_ASSERT (s_pkcs11h_data->fInitialized);
-       PKCS11H_ASSERT (to!=NULL);
-       PKCS11H_ASSERT (from!=NULL);
-
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: pkcs11h_duplicateCertificateId entry to=%p form=%p",
-               (void *)to,
-               (void *)from
-       );
-
-       *to = NULL;
-
-       if (rv == CKR_OK) {
-               rv = _pkcs11h_dupmem (
-                       (void*)to,
-                       NULL,
-                       from,
-                       sizeof (struct pkcs11h_certificate_id_s)
-               );
-       }
-
-       if (rv == CKR_OK) {
-               rv = _pkcs11h_dupmem (
-                       (void*)&(*to)->token_id,
-                       NULL,
-                       from->token_id,
-                       sizeof (struct pkcs11h_token_id_s)
-               );
-       }
-
-       if (rv == CKR_OK) {
-               rv = _pkcs11h_dupmem (
-                       (void*)&(*to)->attrCKA_ID,
-                       &(*to)->attrCKA_ID_size,
-                       from->attrCKA_ID,
-                       from->attrCKA_ID_size
-               );
-       }
-
-       if (rv == CKR_OK) {
-               rv = _pkcs11h_dupmem (
-                       (void*)&(*to)->certificate_blob,
-                       &(*to)->certificate_blob_size,
-                       from->certificate_blob,
-                       from->certificate_blob_size
-               );
-       }
-
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: pkcs11h_duplicateCertificateId return rv=%ld-'%s', *to=%p",
-               rv,
-               pkcs11h_getMessage (rv),
-               (void *)*to
-       );
-       
-       return rv;
-}
-
-CK_RV
-pkcs11h_freeCertificate (
-       IN pkcs11h_certificate_t certificate
-) {
-       PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
-       PKCS11H_ASSERT (s_pkcs11h_data->fInitialized);
-
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: pkcs11h_freeCertificate entry certificate=%p",
-               (void *)certificate
-       );
-
-       if (certificate != NULL) {
-               if (certificate->session != NULL) {
-                       _pkcs11h_releaseSession (certificate->session);
-               }
-               pkcs11h_freeCertificateId (certificate->id);
-               certificate->id = NULL;
-
-#if defined(ENABLE_PKCS11H_THREADING)
-               _pkcs11h_mutexFree (&certificate->mutexCertificate);
-#endif
-
-               _pkcs11h_free ((void *)&certificate);
-       }
-
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: pkcs11h_freeCertificate return"
-       );
-
-       return CKR_OK;
-}
-
-CK_RV
-pkcs11h_certificate_sign (
-       IN const pkcs11h_certificate_t certificate,
-       IN const CK_MECHANISM_TYPE mech_type,
-       IN const unsigned char * const source,
-       IN const size_t source_size,
-       OUT unsigned char * const target,
-       IN OUT size_t * const p_target_size
-) {
-       CK_RV rv = CKR_OK;
-
-       PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
-       PKCS11H_ASSERT (s_pkcs11h_data->fInitialized);
-       PKCS11H_ASSERT (certificate!=NULL);
-       PKCS11H_ASSERT (source!=NULL);
-       /*PKCS11H_ASSERT (target); NOT NEEDED*/
-       PKCS11H_ASSERT (p_target_size!=NULL);
-
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: pkcs11h_certificate_sign entry certificate=%p, mech_type=%ld, source=%p, source_size=%u, target=%p, p_target_size=%p",
-               (void *)certificate,
-               mech_type,
-               source,
-               source_size,
-               target,
-               (void *)p_target_size
-       );
-
-       if (target == NULL) {
-               *p_target_size = 0;
-       }
-
-       if (rv == CKR_OK) {
-               rv = _pkcs11h_certificate_private_op (
-                       certificate,
-                       _pkcs11h_private_op_sign,
-                       mech_type,
-                       source,
-                       source_size,
-                       target,
-                       p_target_size
-               );
-       }
-
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: pkcs11h_certificate_sign return rv=%ld-'%s', *p_target_size=%d",
-               rv,
-               pkcs11h_getMessage (rv),
-               *p_target_size
-       );
-       
-       return rv;
-}
-
-CK_RV
-pkcs11h_certificate_signRecover (
-       IN const pkcs11h_certificate_t certificate,
-       IN const CK_MECHANISM_TYPE mech_type,
-       IN const unsigned char * const source,
-       IN const size_t source_size,
-       OUT unsigned char * const target,
-       IN OUT size_t * const p_target_size
-) {
-       CK_RV rv = CKR_OK;
-
-       PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
-       PKCS11H_ASSERT (s_pkcs11h_data->fInitialized);
-       PKCS11H_ASSERT (certificate!=NULL);
-       PKCS11H_ASSERT (source!=NULL);
-       /*PKCS11H_ASSERT (target); NOT NEEDED*/
-       PKCS11H_ASSERT (p_target_size!=NULL);
-
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: pkcs11h_certificate_signRecover entry certificate=%p, mech_type=%ld, source=%p, source_size=%u, target=%p, p_target_size=%p",
-               (void *)certificate,
-               mech_type,
-               source,
-               source_size,
-               target,
-               (void *)p_target_size
-       );
-
-       if (target == NULL) {
-               *p_target_size = 0;
-       }
-
-       if (rv == CKR_OK) {
-               rv = _pkcs11h_certificate_private_op (
-                       certificate,
-                       _pkcs11h_private_op_sign_recover,
-                       mech_type,
-                       source,
-                       source_size,
-                       target,
-                       p_target_size
-               );
-       }
-
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: pkcs11h_certificate_signRecover return rv=%ld-'%s', *p_target_size=%d",
-               rv,
-               pkcs11h_getMessage (rv),
-               *p_target_size
-       );
-
-       return rv;
-}
-
-CK_RV
-pkcs11h_certificate_signAny (
-       IN const pkcs11h_certificate_t certificate,
-       IN const CK_MECHANISM_TYPE mech_type,
-       IN const unsigned char * const source,
-       IN const size_t source_size,
-       OUT unsigned char * const target,
-       IN OUT size_t * const p_target_size
-) {
-       CK_RV rv = CKR_OK;
-       PKCS11H_BOOL fSigned = FALSE;
-
-       PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
-       PKCS11H_ASSERT (s_pkcs11h_data->fInitialized);
-       PKCS11H_ASSERT (certificate!=NULL);
-       PKCS11H_ASSERT (source!=NULL);
-       /*PKCS11H_ASSERT (target); NOT NEEDED*/
-       PKCS11H_ASSERT (p_target_size!=NULL);
-
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: pkcs11h_certificate_signAny entry certificate=%p, mech_type=%ld, source=%p, source_size=%u, target=%p, p_target_size=%p",
-               (void *)certificate,
-               mech_type,
-               source,
-               source_size,
-               target,
-               (void *)p_target_size
-       );
-
-       if (
-               rv == CKR_OK &&
-               certificate->maskSignMode == 0
-       ) {
-               PKCS11H_DEBUG (
-                       PKCS11H_LOG_DEBUG1,
-                       "PKCS#11: Getting key attributes"
-               );
-               rv = _pkcs11h_getCertificateKeyAttributes (certificate);
-       }
-
-       if (
-               rv == CKR_OK &&
-               !fSigned &&
-               (certificate->maskSignMode & PKCS11H_SIGNMODE_MASK_SIGN) != 0
-       ) {
-               rv = pkcs11h_certificate_sign (
-                       certificate,
-                       mech_type,
-                       source,
-                       source_size,
-                       target,
-                       p_target_size
-               );
-
-               if (rv == CKR_OK) {
-                       fSigned = TRUE;
-               }
-               else if (
-                       rv == CKR_FUNCTION_NOT_SUPPORTED ||
-                       rv == CKR_KEY_FUNCTION_NOT_PERMITTED
-               ) {
-                       certificate->maskSignMode &= ~PKCS11H_SIGNMODE_MASK_SIGN;
-                       rv = CKR_OK;
-               }
-       }
-       
-       if (
-               rv == CKR_OK &&
-               !fSigned &&
-               (certificate->maskSignMode & PKCS11H_SIGNMODE_MASK_RECOVER) != 0
-       ) {
-               rv = pkcs11h_certificate_signRecover (
-                       certificate,
-                       mech_type,
-                       source,
-                       source_size,
-                       target,
-                       p_target_size
-               );
-
-               if (rv == CKR_OK) {
-                       fSigned = TRUE;
-               }
-               else if (
-                       rv == CKR_FUNCTION_NOT_SUPPORTED ||
-                       rv == CKR_KEY_FUNCTION_NOT_PERMITTED
-               ) {
-                       certificate->maskSignMode &= ~PKCS11H_SIGNMODE_MASK_RECOVER;
-                       rv = CKR_OK;
-               }
-       }
-
-       if (rv == CKR_OK && !fSigned) {
-               rv = CKR_FUNCTION_FAILED;
-       }
-       
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: pkcs11h_certificate_signAny return rv=%ld-'%s', *p_target_size=%p",
-               rv,
-               pkcs11h_getMessage (rv),
-               (void *)*p_target_size
-       );
-
-       return rv;
-}
-
-CK_RV
-pkcs11h_certificate_decrypt (
-       IN const pkcs11h_certificate_t certificate,
-       IN const CK_MECHANISM_TYPE mech_type,
-       IN const unsigned char * const source,
-       IN const size_t source_size,
-       OUT unsigned char * const target,
-       IN OUT size_t * const p_target_size
-) {
-       CK_RV rv = CKR_OK;
-
-       PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
-       PKCS11H_ASSERT (s_pkcs11h_data->fInitialized);
-       PKCS11H_ASSERT (certificate!=NULL);
-       PKCS11H_ASSERT (source!=NULL);
-       /*PKCS11H_ASSERT (target); NOT NEEDED*/
-       PKCS11H_ASSERT (p_target_size!=NULL);
-
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: pkcs11h_decrypt entry certificate=%p, mech_type=%ld, source=%p, source_size=%u, target=%p, p_target_size=%p",
-               (void *)certificate,
-               mech_type,
-               source,
-               source_size,
-               target,
-               (void *)p_target_size
-       );
-
-       if (target == NULL) {
-               *p_target_size = 0;
-       }
-
-       if (rv == CKR_OK) {
-               rv = _pkcs11h_certificate_private_op (
-                       certificate,
-                       _pkcs11h_private_op_decrypt,
-                       mech_type,
-                       source,
-                       source_size,
-                       target,
-                       p_target_size
-               );
-       }
-
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: pkcs11h_decrypt return rv=%ld-'%s', *p_target_size=%d",
-               rv,
-               pkcs11h_getMessage (rv),
-               *p_target_size
-       );
-
-       return rv;
-}
-
-CK_RV
-pkcs11h_certificate_create (
-       IN const pkcs11h_certificate_id_t certificate_id,
-       IN const int nPINCachePeriod,
-       OUT pkcs11h_certificate_t * const p_certificate
-) {
-       pkcs11h_certificate_t certificate = NULL;
-       CK_RV rv = CKR_OK;
-
-       PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
-       PKCS11H_ASSERT (s_pkcs11h_data->fInitialized);
-       PKCS11H_ASSERT (p_certificate!=NULL);
-
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: pkcs11h_certificate_create entry certificate_id=%p, nPINCachePeriod=%d, p_certificate=%p",
-               (void *)certificate_id,
-               nPINCachePeriod,
-               (void *)p_certificate
-       );
-
-       *p_certificate = NULL;
-
-       if (
-               rv == CKR_OK &&
-               (rv = _pkcs11h_malloc ((void*)&certificate, sizeof (struct pkcs11h_certificate_s))) == CKR_OK
-       ) {
-               certificate->hKey = PKCS11H_INVALID_OBJECT_HANDLE;
-               certificate->nPINCachePeriod = nPINCachePeriod;
-       }
-
-#if defined(ENABLE_PKCS11H_THREADING)
-       if (rv == CKR_OK) {
-               rv = _pkcs11h_mutexInit (&certificate->mutexCertificate);
-       }
-#endif
-
-       if (rv == CKR_OK) {
-               rv = pkcs11h_duplicateCertificateId (&certificate->id, certificate_id);
-       }
-
-       if (rv == CKR_OK) {
-               *p_certificate = certificate;
-               certificate = NULL;
-       }
-
-       if (certificate != NULL) {
-#if defined(ENABLE_PKCS11H_THREADING)
-               _pkcs11h_mutexFree (&certificate->mutexCertificate);
-#endif
-               _pkcs11h_free ((void *)&certificate);
-       }
-
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: pkcs11h_certificate_create return rv=%ld-'%s' *p_certificate=%p",
-               rv,
-               pkcs11h_getMessage (rv),
-               (void *)*p_certificate
-       );
-       
-       return rv;
-}
-
-CK_RV
-pkcs11h_certificate_getCertificateId (
-       IN const pkcs11h_certificate_t certificate,
-       OUT pkcs11h_certificate_id_t * const p_certificate_id
-) {
-       CK_RV rv = CKR_OK;
-
-       PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
-       PKCS11H_ASSERT (s_pkcs11h_data->fInitialized);
-       PKCS11H_ASSERT (certificate!=NULL);
-       PKCS11H_ASSERT (p_certificate_id!=NULL);
-
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: pkcs11h_certificate_getCertificateId entry certificate=%p, certificate_id=%p",
-               (void *)certificate,
-               (void *)p_certificate_id
-       );
-
-       if (rv == CKR_OK) {
-               rv = pkcs11h_duplicateCertificateId (
-                       p_certificate_id,
-                       certificate->id
-               );
-       }
-
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: pkcs11h_certificate_getCertificateId return rv=%ld-'%s'",
-               rv,
-               pkcs11h_getMessage (rv)
-       );
-
-       return rv;
-}
-
-CK_RV
-pkcs11h_certificate_getCertificateBlob (
-       IN const pkcs11h_certificate_t certificate,
-       OUT unsigned char * const certificate_blob,
-       IN OUT size_t * const p_certificate_blob_size
-) {
-       size_t certifiate_blob_size_max = 0;
-
-       CK_RV rv = CKR_OK;
-       
-       PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
-       PKCS11H_ASSERT (s_pkcs11h_data->fInitialized);
-       PKCS11H_ASSERT (certificate!=NULL);
-       /*PKCS11H_ASSERT (certificate_blob!=NULL); NOT NEEDED */
-       PKCS11H_ASSERT (p_certificate_blob_size!=NULL);
-
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: pkcs11h_certificate_getCertificateBlob entry certificate=%p, certificate_blob=%p, p_certificate_blob_size=%p",
-               (void *)certificate,
-               certificate_blob,
-               (void *)p_certificate_blob_size
-       );
-
-       certifiate_blob_size_max = *p_certificate_blob_size;
-       *p_certificate_blob_size = 0;
-
-       if (rv == CKR_OK) {
-               rv = _pkcs11h_ensureCertificateBlob (certificate);
-       }
-
-       if (rv == CKR_OK) {
-               *p_certificate_blob_size = certificate->id->certificate_blob_size;
-       }
-
-       if (certificate_blob != NULL) {
-               if (
-                       rv == CKR_OK &&
-                       certifiate_blob_size_max < certificate->id->certificate_blob_size
-               ) {
-                       rv = CKR_BUFFER_TOO_SMALL;
-               }
-       
-               if (rv == CKR_OK) {
-                       memmove (
-                               certificate_blob,
-                               certificate->id->certificate_blob,
-                               *p_certificate_blob_size
-                       );
-               }
-       }
-
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: pkcs11h_certificate_getCertificateBlob return rv=%ld-'%s'",
-               rv,
-               pkcs11h_getMessage (rv)
-       );
-
-       return rv;
-}
-
-CK_RV
-pkcs11h_certificate_ensureCertificateAccess (
-       IN const pkcs11h_certificate_t certificate,
-       IN const unsigned maskPrompt
-) {
-       PKCS11H_BOOL fValidCert = FALSE;
-       CK_RV rv = CKR_OK;
-
-       PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
-       PKCS11H_ASSERT (s_pkcs11h_data->fInitialized);
-       PKCS11H_ASSERT (certificate!=NULL);
-
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: pkcs11h_certificate_ensureCertificateAccess entry certificate=%p, maskPrompt=%08x",
-               (void *)certificate,
-               maskPrompt
-       );
-
-       if (!fValidCert && rv == CKR_OK) {
-               CK_OBJECT_HANDLE h = PKCS11H_INVALID_OBJECT_HANDLE;
-
-               if (
-                       (rv = _pkcs11h_getObjectById (
-                               certificate->session,
-                               CKO_CERTIFICATE,
-                               certificate->id->attrCKA_ID,
-                               certificate->id->attrCKA_ID_size,
-                               &h
-                       )) == CKR_OK
-               ) {
-                       fValidCert = TRUE;
-               }
-
-               if (rv != CKR_OK) {
-                       PKCS11H_DEBUG (
-                               PKCS11H_LOG_DEBUG1,
-                               "PKCS#11: Cannot access existing object rv=%ld-'%s'",
-                               rv,
-                               pkcs11h_getMessage (rv)
-                       );
-
-                       /*
-                        * Ignore error
-                        */
-                       rv = CKR_OK;
-               }
-       }
-
-       if (!fValidCert && rv == CKR_OK) {
-               if (
-                       (rv = _pkcs11h_resetCertificateSession (
-                               certificate,
-                               TRUE,
-                               maskPrompt
-                       )) == CKR_OK
-               ) {
-                       fValidCert = TRUE;
-               }
-       }
-
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: pkcs11h_certificate_ensureCertificateAccess return rv=%ld-'%s'",
-               rv,
-               pkcs11h_getMessage (rv)
-       );
-       
-       return rv;
-}
-
-CK_RV
-pkcs11h_certificate_ensureKeyAccess (
-       IN const pkcs11h_certificate_t certificate,
-       IN const unsigned maskPrompt
-) {
-       CK_RV rv = CKR_OK;
-       PKCS11H_BOOL fValidKey = FALSE;
-
-       PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
-       PKCS11H_ASSERT (s_pkcs11h_data->fInitialized);
-       PKCS11H_ASSERT (certificate!=NULL);
-
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: pkcs11h_certificate_ensureKeyAccess entry certificate=%p, maskPrompt=%08x",
-               (void *)certificate,
-               maskPrompt
-       );
-
-       if (!fValidKey && rv == CKR_OK) {
-               if (
-                       (rv = _pkcs11h_getObjectById (
-                               certificate->session,
-                               CKO_PRIVATE_KEY,
-                               certificate->id->attrCKA_ID,
-                               certificate->id->attrCKA_ID_size,
-                               &certificate->hKey
-                       )) == CKR_OK
-               ) {
-                       fValidKey = TRUE;
-               }
-
-               if (rv != CKR_OK) {
-                       PKCS11H_DEBUG (
-                               PKCS11H_LOG_DEBUG1,
-                               "PKCS#11: Cannot access existing object rv=%ld-'%s'",
-                               rv,
-                               pkcs11h_getMessage (rv)
-                       );
-
-                       /*
-                        * Ignore error
-                        */
-                       rv = CKR_OK;
-                       certificate->hKey = PKCS11H_INVALID_OBJECT_HANDLE;
-               }
-       }
-
-       if (!fValidKey && rv == CKR_OK) {
-               if (
-                       (rv = _pkcs11h_resetCertificateSession (
-                               certificate,
-                               FALSE,
-                               maskPrompt
-                       )) == CKR_OK
-               ) {
-                       fValidKey = TRUE;
-               }
-       }
-
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: pkcs11h_certificate_ensureKeyAccess return rv=%ld-'%s'",
-               rv,
-               pkcs11h_getMessage (rv)
-       );
-       
-       return rv;
-}
-
-#endif                         /* ENABLE_PKCS11H_CERTIFICATE */
-
-#if defined(ENABLE_PKCS11H_LOCATE)
-/*======================================================================*
- * LOCATE INTERFACE
- *======================================================================*/
-
-#if defined(ENABLE_PKCS11H_TOKEN) || defined(ENABLE_PKCS11H_CERTIFICATE)
-
-static
-CK_RV
-_pkcs11h_locate_getTokenIdBySlotId (
-       IN const char * const szSlot,
-       OUT pkcs11h_token_id_t * const p_token_id
-) {
-       pkcs11h_provider_t current_provider = NULL;
-       char szReferenceName[sizeof (((pkcs11h_provider_t)NULL)->szReferenceName)];
-
-       CK_SLOT_ID selected_slot = PKCS11H_INVALID_SLOT_ID;
-       CK_TOKEN_INFO info;
-       CK_RV rv = CKR_OK;
-
-       PKCS11H_ASSERT (szSlot!=NULL);
-       PKCS11H_ASSERT (p_token_id!=NULL);
-
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: _pkcs11h_locate_getTokenIdBySlotId entry szSlot='%s', p_token_id=%p",
-               szSlot,
-               (void *)p_token_id
-       );
-
-       *p_token_id = NULL;
-
-       if (rv == CKR_OK) {
-               if (strchr (szSlot, ':') == NULL) {
-                       szReferenceName[0] = '\0';
-                       selected_slot = atol (szSlot);
-               }
-               else {
-                       char *p;
-
-                       strncpy (szReferenceName, szSlot, sizeof (szReferenceName));
-                       szReferenceName[sizeof (szReferenceName)-1] = '\0';
-
-                       p = strchr (szReferenceName, ':');
-
-                       *p = '\0';
-                       p++;
-                       selected_slot = atol (p);
-               }
-       }
-       
-       if (rv == CKR_OK) {
-               current_provider=s_pkcs11h_data->providers;
-               while (
-                       current_provider != NULL &&
-                       szReferenceName[0] != '\0' &&           /* So first provider will be selected */
-                       strcmp (current_provider->szReferenceName, szReferenceName)
-               ) {
-                       current_provider = current_provider->next;
-               }
-       
-               if (
-                       current_provider == NULL ||
-                       (
-                               current_provider != NULL &&
-                               !current_provider->fEnabled
-                       )
-               ) {
-                       rv = CKR_SLOT_ID_INVALID;
-               }
-       }
-
-       if (
-               rv == CKR_OK &&
-               (rv = current_provider->f->C_GetTokenInfo (selected_slot, &info)) == CKR_OK
-       ) {
-               rv = _pkcs11h_getTokenId (
-                       &info,
-                       p_token_id
-               );
-       }
-
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: _pkcs11h_locate_getTokenIdBySlotId return rv=%ld-'%s', *p_token_id=%p",
-               rv,
-               pkcs11h_getMessage (rv),
-               (void *)*p_token_id
-       );
-
-       return rv;
-}
-
-static
-CK_RV
-_pkcs11h_locate_getTokenIdBySlotName (
-       IN const char * const szName,
-       OUT pkcs11h_token_id_t * const p_token_id
-) {
-       pkcs11h_provider_t current_provider = NULL;
-
-       CK_SLOT_ID selected_slot = PKCS11H_INVALID_SLOT_ID;
-       CK_TOKEN_INFO info;
-       CK_RV rv = CKR_OK;
-
-       PKCS11H_BOOL fFound = FALSE;
-
-       PKCS11H_ASSERT (szName!=NULL);
-       PKCS11H_ASSERT (p_token_id!=NULL);
-
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: _pkcs11h_locate_getTokenIdBySlotName entry szName='%s', p_token_id=%p",
-               szName,
-               (void *)p_token_id
-       );
-
-       *p_token_id = NULL;
-
-       current_provider = s_pkcs11h_data->providers;
-       while (
-               current_provider != NULL &&
-               rv == CKR_OK &&
-               !fFound
-       ) {
-               CK_SLOT_ID_PTR slots = NULL;
-               CK_ULONG slotnum;
-               CK_SLOT_ID slot_index;
-
-               if (!current_provider->fEnabled) {
-                       rv = CKR_CRYPTOKI_NOT_INITIALIZED;
-               }
-
-               if (rv == CKR_OK) {
-                       rv = _pkcs11h_getSlotList (
-                               current_provider,
-                               CK_TRUE,
-                               &slots,
-                               &slotnum
-                       );
-               }
-
-               for (
-                       slot_index=0;
-                       (
-                               slot_index < slotnum &&
-                               rv == CKR_OK &&
-                               !fFound
-                       );
-                       slot_index++
-               ) {
-                       CK_SLOT_INFO info;
-
-                       if (
-                               (rv = current_provider->f->C_GetSlotInfo (
-                                       slots[slot_index],
-                                       &info
-                               )) == CKR_OK
-                       ) {
-                               char szCurrentName[sizeof (info.slotDescription)+1];
-
-                               _pkcs11h_fixupFixedString (
-                                       szCurrentName,
-                                       (char *)info.slotDescription,
-                                       sizeof (info.slotDescription)
-                               );
-
-                               if (!strcmp (szCurrentName, szName)) {
-                                       fFound = TRUE;
-                                       selected_slot = slots[slot_index];
-                               }
-                       }
-
-                       if (rv != CKR_OK) {
-                               PKCS11H_DEBUG (
-                                       PKCS11H_LOG_DEBUG1,
-                                       "PKCS#11: Cannot get slot information for provider '%s' slot %ld rv=%ld-'%s'",
-                                       current_provider->manufacturerID,
-                                       slots[slot_index],
-                                       rv,
-                                       pkcs11h_getMessage (rv)
-                               );
-
-                               /*
-                                * Ignore error
-                                */
-                               rv = CKR_OK;
-                       }
-               }
-
-               if (rv != CKR_OK) {
-                       PKCS11H_DEBUG (
-                               PKCS11H_LOG_DEBUG1,
-                               "PKCS#11: Cannot get slot list for provider '%s' rv=%ld-'%s'",
-                               current_provider->manufacturerID,
-                               rv,
-                               pkcs11h_getMessage (rv)
-                       );
-
-                       /*
-                        * Ignore error
-                        */
-                       rv = CKR_OK;
-               }
-
-               if (slots != NULL) {
-                       _pkcs11h_free ((void *)&slots);
-                       slots = NULL;
-               }
-
-               if (!fFound) {
-                       current_provider = current_provider->next;
-               }
-       }
-
-       if (rv == CKR_OK && !fFound) {
-               rv = CKR_SLOT_ID_INVALID;
-       }
-
-       if (
-               rv == CKR_OK &&
-               (rv = current_provider->f->C_GetTokenInfo (selected_slot, &info)) == CKR_OK
-       ) {
-               rv = _pkcs11h_getTokenId (
-                       &info,
-                       p_token_id
-               );
-       }
-
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: _pkcs11h_locate_getTokenIdBySlotName return rv=%ld-'%s' *p_token_id=%p",
-               rv,
-               pkcs11h_getMessage (rv),
-               (void *)*p_token_id
-       );
-
-       return rv; 
-}
-
-static
-CK_RV
-_pkcs11h_locate_getTokenIdByLabel (
-       IN const char * const szLabel,
-       OUT pkcs11h_token_id_t * const p_token_id
-) {
-       pkcs11h_provider_t current_provider = NULL;
-
-       CK_SLOT_ID selected_slot = PKCS11H_INVALID_SLOT_ID;
-       CK_TOKEN_INFO info;
-       CK_RV rv = CKR_OK;
-
-       PKCS11H_BOOL fFound = FALSE;
-
-       PKCS11H_ASSERT (szLabel!=NULL);
-       PKCS11H_ASSERT (p_token_id!=NULL);
-
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: _pkcs11h_locate_getTokenIdByLabel entry szLabel='%s', p_token_id=%p",
-               szLabel,
-               (void *)p_token_id
-       );
-
-       *p_token_id = NULL;
-
-       current_provider = s_pkcs11h_data->providers;
-       while (
-               current_provider != NULL &&
-               rv == CKR_OK &&
-               !fFound
-       ) {
-               CK_SLOT_ID_PTR slots = NULL;
-               CK_ULONG slotnum;
-               CK_SLOT_ID slot_index;
-
-               if (!current_provider->fEnabled) {
-                       rv = CKR_CRYPTOKI_NOT_INITIALIZED;
-               }
-
-               if (rv == CKR_OK) {
-                       rv = _pkcs11h_getSlotList (
-                               current_provider,
-                               CK_TRUE,
-                               &slots,
-                               &slotnum
-                       );
-               }
-
-               for (
-                       slot_index=0;
-                       (
-                               slot_index < slotnum &&
-                               rv == CKR_OK &&
-                               !fFound
-                       );
-                       slot_index++
-               ) {
-                       CK_TOKEN_INFO info;
-
-                       if (rv == CKR_OK) {
-                               rv = current_provider->f->C_GetTokenInfo (
-                                       slots[slot_index],
-                                       &info
-                               );
-                       }
-
-                       if (rv == CKR_OK) {
-                               char szCurrentLabel[sizeof (info.label)+1];
-               
-                               _pkcs11h_fixupFixedString (
-                                       szCurrentLabel,
-                                       (char *)info.label,
-                                       sizeof (info.label)
-                               );
-
-                               if (!strcmp (szCurrentLabel, szLabel)) {
-                                       fFound = TRUE;
-                                       selected_slot = slots[slot_index];
-                               }
-                       }
-
-                       if (rv != CKR_OK) {
-                               PKCS11H_DEBUG (
-                                       PKCS11H_LOG_DEBUG1,
-                                       "PKCS#11: Cannot get token information for provider '%s' slot %ld rv=%ld-'%s'",
-                                       current_provider->manufacturerID,
-                                       slots[slot_index],
-                                       rv,
-                                       pkcs11h_getMessage (rv)
-                               );
-
-                               /*
-                                * Ignore error
-                                */
-                               rv = CKR_OK;
-                       }
-               }
-
-               if (rv != CKR_OK) {
-                       PKCS11H_DEBUG (
-                               PKCS11H_LOG_DEBUG1,
-                               "PKCS#11: Cannot get slot list for provider '%s' rv=%ld-'%s'",
-                               current_provider->manufacturerID,
-                               rv,
-                               pkcs11h_getMessage (rv)
-                       );
-
-                       /*
-                        * Ignore error
-                        */
-                       rv = CKR_OK;
-               }
-
-               if (slots != NULL) {
-                       _pkcs11h_free ((void *)&slots);
-                       slots = NULL;
-               }
-
-               if (!fFound) {
-                       current_provider = current_provider->next;
-               }
-       }
-
-       if (rv == CKR_OK && !fFound) {
-               rv = CKR_SLOT_ID_INVALID;
-       }
-
-       if (
-               rv == CKR_OK &&
-               (rv = current_provider->f->C_GetTokenInfo (selected_slot, &info)) == CKR_OK
-       ) {
-               rv = _pkcs11h_getTokenId (
-                       &info,
-                       p_token_id
-               );
-       }
-
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: _pkcs11h_locate_getTokenIdByLabel return rv=%ld-'%s', *p_token_id=%p",
-               rv,
-               pkcs11h_getMessage (rv),
-               (void *)*p_token_id
-       );
-
-       return rv;
-}
-
-CK_RV
-pkcs11h_locate_token (
-       IN const char * const szSlotType,
-       IN const char * const szSlot,
-       OUT pkcs11h_token_id_t * const p_token_id
-) {
-#if defined(ENABLE_PKCS11H_THREADING)
-       PKCS11H_BOOL fMutexLocked = FALSE;
-#endif
-
-       pkcs11h_token_id_t dummy_token_id = NULL;
-       pkcs11h_token_id_t token_id = NULL;
-       PKCS11H_BOOL fFound = FALSE;
-       
-       CK_RV rv = CKR_OK;
-
-       unsigned nRetry = 0;
-
-       PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
-       PKCS11H_ASSERT (s_pkcs11h_data->fInitialized);
-       PKCS11H_ASSERT (szSlotType!=NULL);
-       PKCS11H_ASSERT (szSlot!=NULL);
-       PKCS11H_ASSERT (p_token_id!=NULL);
-
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: pkcs11h_locate_token entry szSlotType='%s', szSlot='%s', p_token_id=%p",
-               szSlotType,
-               szSlot,
-               (void *)p_token_id
-       );
-
-       *p_token_id = NULL;
-
-#if defined(ENABLE_PKCS11H_THREADING)
-       if (
-               rv == CKR_OK &&
-               (rv = _pkcs11h_mutexLock (&s_pkcs11h_data->mutexGlobal)) == CKR_OK
-       ) {
-               fMutexLocked = TRUE;
-       }
-#endif
-
-       if (
-               rv == CKR_OK &&
-               (rv = _pkcs11h_newTokenId (&dummy_token_id)) == CKR_OK
-       ) {
-               /*
-                * Temperary slot id
-                */
-               strcpy (dummy_token_id->label, "SLOT(");
-               strncat (dummy_token_id->label, szSlotType, sizeof (dummy_token_id->label)-1-strlen (dummy_token_id->label));
-               strncat (dummy_token_id->label, "=", sizeof (dummy_token_id->label)-1-strlen (dummy_token_id->label));
-               strncat (dummy_token_id->label, szSlot, sizeof (dummy_token_id->label)-1-strlen (dummy_token_id->label));
-               strncat (dummy_token_id->label, ")", sizeof (dummy_token_id->label)-1-strlen (dummy_token_id->label));
-               dummy_token_id->label[sizeof (dummy_token_id->label)-1] = 0;
-       }
-
-       while (rv == CKR_OK && !fFound) {
-               if (!strcmp (szSlotType, "id")) {
-                       rv = _pkcs11h_locate_getTokenIdBySlotId (
-                               szSlot,
-                               &token_id
-                       );
-               }
-               else if (!strcmp (szSlotType, "name")) {
-                       rv = _pkcs11h_locate_getTokenIdBySlotName (
-                               szSlot,
-                               &token_id
-                       );
-               }
-               else if (!strcmp (szSlotType, "label")) {
-                       rv = _pkcs11h_locate_getTokenIdByLabel (
-                               szSlot,
-                               &token_id
-                       );
-               }
-               else {
-                       rv = CKR_ARGUMENTS_BAD;
-               }
-
-               if (rv == CKR_OK) {
-                       fFound = TRUE;
-               }
-
-               if (!fFound && rv != CKR_ARGUMENTS_BAD) {
-
-                       PKCS11H_DEBUG (
-                               PKCS11H_LOG_DEBUG1,
-                               "PKCS#11: pkcs11h_locate_token failed rv=%ld-'%s'",
-                               rv,
-                               pkcs11h_getMessage (rv)
-                       );
-
-                       /*
-                        * Ignore error
-                        */
-                       rv = CKR_OK;
-
-                       PKCS11H_DEBUG (
-                               PKCS11H_LOG_DEBUG1,
-                               "PKCS#11: Calling token_prompt hook for '%s'",
-                               dummy_token_id->label
-                       );
-       
-                       if (
-                               !s_pkcs11h_data->hooks.token_prompt (
-                                       s_pkcs11h_data->hooks.token_prompt_data,
-                                       dummy_token_id,
-                                       nRetry++
-                               )
-                       ) {
-                               rv = CKR_CANCEL;
-                       }
-
-                       PKCS11H_DEBUG (
-                               PKCS11H_LOG_DEBUG1,
-                               "PKCS#11: token_prompt returned %ld",
-                               rv
-                       );
-               }
-       }
-
-       if (rv == CKR_OK && !fFound) {
-               rv = CKR_SLOT_ID_INVALID;
-       }
-
-       if (rv == CKR_OK) {
-               *p_token_id = token_id;
-               token_id = NULL;
-       }
-
-       if (dummy_token_id != NULL) {
-               pkcs11h_freeTokenId (dummy_token_id);
-               dummy_token_id = NULL;
-       }
-
-#if defined(ENABLE_PKCS11H_THREADING)
-       if (fMutexLocked) {
-               _pkcs11h_mutexRelease (&s_pkcs11h_data->mutexGlobal);
-               fMutexLocked = FALSE;
-       }
-#endif
-
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: pkcs11h_locate_token return rv=%ld-'%s', *p_token_id=%p",
-               rv,
-               pkcs11h_getMessage (rv),
-               (void *)*p_token_id
-       );
-
-       return rv;
-}
-
-#endif                         /* ENABLE_PKCS11H_TOKEN || ENABLE_PKCS11H_CERTIFICATE */
-
-#if defined(ENABLE_PKCS11H_CERTIFICATE)
-
-static
-void
-_pkcs11h_locate_hexToBinary (
-       OUT unsigned char * const target,
-       IN const char * const szSource,
-       IN OUT size_t * const p_target_size
-) {
-       size_t target_max_size;
-       const char *p;
-       char buf[3] = {'\0', '\0', '\0'};
-       int i = 0;
-
-       PKCS11H_ASSERT (szSource!=NULL);
-       PKCS11H_ASSERT (target!=NULL);
-       PKCS11H_ASSERT (p_target_size!=NULL);
-
-       target_max_size = *p_target_size;
-       p = szSource;
-       *p_target_size = 0;
-
-       while (*p != '\0' && *p_target_size < target_max_size) {
-               if (isxdigit ((unsigned char)*p)) {
-                       buf[i%2] = *p;
-
-                       if ((i%2) == 1) {
-                               unsigned v;
-                               if (sscanf (buf, "%x", &v) != 1) {
-                                       v = 0;
-                               }
-                               target[*p_target_size] = v & 0xff;
-                               (*p_target_size)++;
-                       }
-
-                       i++;
-               }
-               p++;
-       }
-}
-
-static
-CK_RV
-_pkcs11h_locate_getCertificateIdByLabel (
-       IN const pkcs11h_session_t session,
-       IN OUT const pkcs11h_certificate_id_t certificate_id,
-       IN const char * const szLabel
-) {
-       CK_OBJECT_CLASS cert_filter_class = CKO_CERTIFICATE;
-       CK_ATTRIBUTE cert_filter[] = {
-               {CKA_CLASS, &cert_filter_class, sizeof (cert_filter_class)},
-               {CKA_LABEL, (CK_BYTE_PTR)szLabel, strlen (szLabel)}
-       };
-
-       CK_OBJECT_HANDLE *objects = NULL;
-       CK_ULONG objects_found = 0;
-       CK_RV rv = CKR_OK;
-
-       CK_ULONG i;
-
-       PKCS11H_ASSERT (session!=NULL);
-       PKCS11H_ASSERT (certificate_id!=NULL);
-       PKCS11H_ASSERT (szLabel!=NULL);
-
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: _pkcs11h_locate_getCertificateIdByLabel entry session=%p, certificate_id=%p, szLabel='%s'",
-               (void *)session,
-               (void *)certificate_id,
-               szLabel
-       );
-
-       if (rv == CKR_OK) {
-               rv = _pkcs11h_validateSession (session);
-       }
-
-       if (rv == CKR_OK) {
-               rv = _pkcs11h_findObjects (
-                       session,
-                       cert_filter,
-                       sizeof (cert_filter) / sizeof (CK_ATTRIBUTE),
-                       &objects,
-                       &objects_found
-               );
-       }
-
-       for (i=0;rv == CKR_OK && i < objects_found;i++) {
-               CK_ATTRIBUTE attrs[] = {
-                       {CKA_ID, NULL, 0},
-                       {CKA_VALUE, NULL, 0}
-               };
-
-               if (rv == CKR_OK) {
-                       rv = _pkcs11h_getObjectAttributes (
-                               session,
-                               objects[i],
-                               attrs,
-                               sizeof (attrs) / sizeof (CK_ATTRIBUTE)
-                       );
-               }
-
-               if (
-                       rv == CKR_OK &&
-                       _pkcs11h_isBetterCertificate (
-                               certificate_id->certificate_blob,
-                               certificate_id->certificate_blob_size,
-                               attrs[1].pValue,
-                               attrs[1].ulValueLen
-                       )
-               ) {
-                       if (certificate_id->attrCKA_ID != NULL) {
-                               _pkcs11h_free ((void *)&certificate_id->attrCKA_ID);
-                       }
-                       if (certificate_id->certificate_blob != NULL) {
-                               _pkcs11h_free ((void *)&certificate_id->certificate_blob);
-                       }
-                       rv = _pkcs11h_dupmem (
-                               (void *)&certificate_id->attrCKA_ID,
-                               &certificate_id->attrCKA_ID_size,
-                               attrs[0].pValue,
-                               attrs[0].ulValueLen
-                       );
-                       rv = _pkcs11h_dupmem (
-                               (void *)&certificate_id->certificate_blob,
-                               &certificate_id->certificate_blob_size,
-                               attrs[1].pValue,
-                               attrs[1].ulValueLen
-                       );
-               }
-
-               if (rv != CKR_OK) {
-                       PKCS11H_DEBUG (
-                               PKCS11H_LOG_DEBUG1,
-                               "PKCS#11: Cannot get object attribute for provider '%s' object %ld rv=%ld-'%s'",
-                               session->provider->manufacturerID,
-                               objects[i],
-                               rv,
-                               pkcs11h_getMessage (rv)
-                       );
-
-                       /*
-                        * Ignore error
-                        */
-                       rv = CKR_OK;
-               }
-
-               _pkcs11h_freeObjectAttributes (
-                       attrs,
-                       sizeof (attrs) / sizeof (CK_ATTRIBUTE)
-               );
-       }
-       
-       if (
-               rv == CKR_OK &&
-               certificate_id->certificate_blob == NULL
-       ) {
-               rv = CKR_ATTRIBUTE_VALUE_INVALID;
-       }
-
-       if (objects != NULL) {
-               _pkcs11h_free ((void *)&objects);
-       }
-
-       /*
-        * No need to free allocated objects
-        * on error, since the certificate_id
-        * should be free by caller.
-        */
-
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: _pkcs11h_locate_getCertificateIdByLabel return rv=%ld-'%s'",
-               rv,
-               pkcs11h_getMessage (rv)
-       );
-
-       return rv;
-}
-
-static
-CK_RV
-_pkcs11h_locate_getCertificateIdBySubject (
-       IN const pkcs11h_session_t session,
-       IN OUT const pkcs11h_certificate_id_t certificate_id,
-       IN const char * const szSubject
-) {
-       CK_OBJECT_CLASS cert_filter_class = CKO_CERTIFICATE;
-       CK_ATTRIBUTE cert_filter[] = {
-               {CKA_CLASS, &cert_filter_class, sizeof (cert_filter_class)}
-       };
-
-       CK_OBJECT_HANDLE *objects = NULL;
-       CK_ULONG objects_found = 0;
-       CK_RV rv = CKR_OK;
-
-       CK_ULONG i;
-
-       PKCS11H_ASSERT (session!=NULL);
-       PKCS11H_ASSERT (certificate_id!=NULL);
-       PKCS11H_ASSERT (szSubject!=NULL);
-
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: _pkcs11h_locate_getCertificateIdBySubject entry session=%p, certificate_id=%p, szSubject=%s",
-               (void *)session,
-               (void *)certificate_id,
-               szSubject
-       );
-
-       if (rv == CKR_OK) {
-               rv = _pkcs11h_validateSession (session);
-       }
-
-       if (rv == CKR_OK) {
-               rv = _pkcs11h_findObjects (
-                       session,
-                       cert_filter,
-                       sizeof (cert_filter) / sizeof (CK_ATTRIBUTE),
-                       &objects,
-                       &objects_found
-               );
-       }
-
-       for (i=0;rv == CKR_OK && i < objects_found;i++) {
-               CK_ATTRIBUTE attrs[] = {
-                       {CKA_ID, NULL, 0},
-                       {CKA_VALUE, NULL, 0}
-               };
-               char szCurrentSubject[1024];
-               szCurrentSubject[0] = '\0';
-
-               if (rv == CKR_OK) {
-                       rv = _pkcs11h_getObjectAttributes (
-                               session,
-                               objects[i],
-                               attrs,
-                               sizeof (attrs) / sizeof (CK_ATTRIBUTE)
-                       );
-               }
-
-               if (rv == CKR_OK) {
-                       X509 *x509 = NULL;
-                       pkcs11_openssl_d2i_t d2i1;
-
-                       x509 = X509_new ();
-
-                       d2i1 = (pkcs11_openssl_d2i_t)attrs[1].pValue;
-                       if (d2i_X509 (&x509, &d2i1, attrs[1].ulValueLen)) {
-                               X509_NAME_oneline (
-                                       X509_get_subject_name (x509),
-                                       szCurrentSubject,
-                                       sizeof (szCurrentSubject)
-                               );
-                               szCurrentSubject[sizeof (szCurrentSubject) - 1] = '\0';
-                       }
-
-                       if (x509 != NULL) {
-                               X509_free (x509);
-                               x509 = NULL;
-                       }
-               }
-
-               if (
-                       rv == CKR_OK &&
-                       !strcmp (szSubject, szCurrentSubject) &&
-                       _pkcs11h_isBetterCertificate (
-                               certificate_id->certificate_blob,
-                               certificate_id->certificate_blob_size,
-                               attrs[1].pValue,
-                               attrs[1].ulValueLen
-                       )
-               ) {
-                       if (certificate_id->attrCKA_ID != NULL) {
-                               _pkcs11h_free ((void *)&certificate_id->attrCKA_ID);
-                       }
-                       if (certificate_id->certificate_blob != NULL) {
-                               _pkcs11h_free ((void *)&certificate_id->certificate_blob);
-                       }
-                       rv = _pkcs11h_dupmem (
-                               (void *)&certificate_id->attrCKA_ID,
-                               &certificate_id->attrCKA_ID_size,
-                               attrs[0].pValue,
-                               attrs[0].ulValueLen
-                       );
-                       rv = _pkcs11h_dupmem (
-                               (void *)&certificate_id->certificate_blob,
-                               &certificate_id->certificate_blob_size,
-                               attrs[1].pValue,
-                               attrs[1].ulValueLen
-                       );
-               }
-
-               if (rv != CKR_OK) {
-                       PKCS11H_DEBUG (
-                               PKCS11H_LOG_DEBUG1,
-                               "PKCS#11: Cannot get object attribute for provider '%s' object %ld rv=%ld-'%s'",
-                               session->provider->manufacturerID,
-                               objects[i],
-                               rv,
-                               pkcs11h_getMessage (rv)
-                       );
-
-                       /*
-                        * Ignore error
-                        */
-                       rv = CKR_OK;
-               }
-
-               _pkcs11h_freeObjectAttributes (
-                       attrs,
-                       sizeof (attrs) / sizeof (CK_ATTRIBUTE)
-               );
-       }
-       
-       if (
-               rv == CKR_OK &&
-               certificate_id->certificate_blob == NULL
-       ) {
-               rv = CKR_ATTRIBUTE_VALUE_INVALID;
-       }
-
-       if (objects != NULL) {
-               _pkcs11h_free ((void *)&objects);
-       }
-
-       /*
-        * No need to free allocated objects
-        * on error, since the certificate_id
-        * should be free by caller.
-        */
-
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: _pkcs11h_locate_getCertificateIdBySubject return rv=%ld-'%s'",
-               rv,
-               pkcs11h_getMessage (rv)
-       );
-
-       return rv;
-}
-
-CK_RV
-pkcs11h_locate_certificate (
-       IN const char * const szSlotType,
-       IN const char * const szSlot,
-       IN const char * const szIdType,
-       IN const char * const szId,
-       OUT pkcs11h_certificate_id_t * const p_certificate_id
-) {
-       pkcs11h_certificate_id_t certificate_id = NULL;
-       pkcs11h_session_t session = NULL;
-       PKCS11H_BOOL fOpSuccess = FALSE;
-       PKCS11H_BOOL fLoginRetry = FALSE;
-       
-       CK_RV rv = CKR_OK;
-
-       PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
-       PKCS11H_ASSERT (s_pkcs11h_data->fInitialized);
-       PKCS11H_ASSERT (szSlotType!=NULL);
-       PKCS11H_ASSERT (szSlot!=NULL);
-       PKCS11H_ASSERT (szIdType!=NULL);
-       PKCS11H_ASSERT (szId!=NULL);
-       PKCS11H_ASSERT (p_certificate_id!=NULL);
-
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: pkcs11h_locateCertificate entry szSlotType='%s', szSlot='%s', szIdType='%s', szId='%s', p_certificate_id=%p",
-               szSlotType,
-               szSlot,
-               szIdType,
-               szId,
-               (void *)p_certificate_id
-       );
-
-       *p_certificate_id = NULL;
-
-       if (rv == CKR_OK) {
-               rv = _pkcs11h_newCertificateId (&certificate_id);
-       }
-
-       if (rv == CKR_OK) {
-               rv = pkcs11h_locate_token (
-                       szSlotType,
-                       szSlot,
-                       &certificate_id->token_id
-               );
-       }
-
-       if (rv == CKR_OK) {
-               rv = _pkcs11h_getSessionByTokenId (
-                       certificate_id->token_id,
-                       &session
-               );
-       }
-
-       while (rv == CKR_OK && !fOpSuccess) {
-#if defined(ENABLE_PKCS11H_THREADING)
-               PKCS11H_BOOL fMutexLocked = FALSE;
-#endif
-
-#if defined(ENABLE_PKCS11H_THREADING)
-               if (
-                       rv == CKR_OK &&
-                       (rv = _pkcs11h_mutexLock (&s_pkcs11h_data->mutexGlobal)) == CKR_OK
-               ) {
-                       fMutexLocked = TRUE;
-               }
-#endif
-
-               if (!strcmp (szIdType, "id")) {
-                       certificate_id->attrCKA_ID_size = strlen (szId)/2;
-
-                       if (certificate_id->attrCKA_ID_size == 0) {
-                               rv = CKR_FUNCTION_FAILED;
-                       }
-
-                       if (
-                               rv == CKR_OK &&
-                               (rv = _pkcs11h_malloc (
-                                       (void*)&certificate_id->attrCKA_ID,
-                                       certificate_id->attrCKA_ID_size
-                               )) == CKR_OK
-                       ) {
-                               _pkcs11h_locate_hexToBinary (
-                                       certificate_id->attrCKA_ID,
-                                       szId,
-                                       &certificate_id->attrCKA_ID_size
-                               );
-                       }
-               }
-               else if (!strcmp (szIdType, "label")) {
-                       rv = _pkcs11h_locate_getCertificateIdByLabel (
-                               session,
-                               certificate_id,
-                               szId
-                       );
-               }
-               else if (!strcmp (szIdType, "subject")) {
-                       rv = _pkcs11h_locate_getCertificateIdBySubject (
-                               session,
-                               certificate_id,
-                               szId
-                       );
-               }
-               else {
-                       rv = CKR_ARGUMENTS_BAD;
-               }
-
-#if defined(ENABLE_PKCS11H_THREADING)
-               if (fMutexLocked) {
-                       _pkcs11h_mutexRelease (&s_pkcs11h_data->mutexGlobal);
-                       fMutexLocked = FALSE;
-               }
-#endif
-
-               if (rv == CKR_OK) {
-                       fOpSuccess = TRUE;
-               }
-               else {
-                       if (!fLoginRetry) {
-                               PKCS11H_DEBUG (
-                                       PKCS11H_LOG_DEBUG1,
-                                       "PKCS#11: Get certificate failed: %ld:'%s'",
-                                       rv,
-                                       pkcs11h_getMessage (rv)
-                               );
-
-                               rv = _pkcs11h_login (
-                                       session,
-                                       TRUE,
-                                       TRUE,
-                                       (
-                                               PKCS11H_PROMPT_MASK_ALLOW_PIN_PROMPT |
-                                               PKCS11H_PROMPT_MAST_ALLOW_CARD_PROMPT 
-                                       )
-                               );
-
-                               fLoginRetry = TRUE;
-                       }
-               }
-       }
-
-       if (rv == CKR_OK) {
-               *p_certificate_id = certificate_id;
-               certificate_id = NULL;
-       }
-
-       if (certificate_id != NULL) {
-               pkcs11h_freeCertificateId (certificate_id);
-               certificate_id = NULL;
-       }
-
-       if (session != NULL) {
-               _pkcs11h_releaseSession (session);
-               session = NULL;
-       }
-
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: pkcs11h_locateCertificate return rv=%ld-'%s' *p_certificate_id=%p",
-               rv,
-               pkcs11h_getMessage (rv),
-               (void *)*p_certificate_id
-       );
-       
-       return rv;
-}
-
-#endif                         /* ENABLE_PKCS11H_CERTIFICATE */
-
-#endif                         /* ENABLE_PKCS11H_LOCATE */
-
-#if defined(ENABLE_PKCS11H_ENUM)
-/*======================================================================*
- * ENUM INTERFACE
- *======================================================================*/
-
-#if defined(ENABLE_PKCS11H_TOKEN)
-
-CK_RV
-pkcs11h_freeTokenIdList (
-       IN const pkcs11h_token_id_list_t token_id_list
-) {
-       pkcs11h_token_id_list_t _id = token_id_list;
-
-       PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
-       PKCS11H_ASSERT (s_pkcs11h_data->fInitialized);
-       /*PKCS11H_ASSERT (token_id_list!=NULL); NOT NEEDED*/
-
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: pkcs11h_freeTokenIdList entry token_id_list=%p",
-               (void *)token_id_list
-       );
-
-       while (_id != NULL) {
-               pkcs11h_token_id_list_t x = _id;
-               _id = _id->next;
-               if (x->token_id != NULL) {
-                       pkcs11h_freeTokenId (x->token_id);
-               }
-               x->next = NULL;
-               _pkcs11h_free ((void *)&x);
-       }
-
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: pkcs11h_freeTokenIdList return"
-       );
-
-       return CKR_OK;
-}
-
-CK_RV
-pkcs11h_enum_getTokenIds (
-       IN const int method,
-       OUT pkcs11h_token_id_list_t * const p_token_id_list
-) {
-#if defined(ENABLE_PKCS11H_THREADING)
-       PKCS11H_BOOL fMutexLocked = FALSE;
-#endif
-
-       pkcs11h_token_id_list_t token_id_list = NULL;
-       pkcs11h_provider_t current_provider;
-       CK_RV rv = CKR_OK;
-
-       PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
-       PKCS11H_ASSERT (s_pkcs11h_data->fInitialized);
-       PKCS11H_ASSERT (p_token_id_list!=NULL);
-
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: pkcs11h_enum_getTokenIds entry p_token_id_list=%p",
-               (void *)p_token_id_list
-       );
-
-       *p_token_id_list = NULL;
-
-#if defined(ENABLE_PKCS11H_THREADING)
-       if (
-               rv == CKR_OK &&
-               (rv = _pkcs11h_mutexLock (&s_pkcs11h_data->mutexGlobal)) == CKR_OK
-       ) {
-               fMutexLocked = TRUE;
-       }
-#endif
-
-       for (
-               current_provider = s_pkcs11h_data->providers;
-               (
-                       current_provider != NULL &&
-                       rv == CKR_OK
-               );
-               current_provider = current_provider->next
-       ) {
-               CK_SLOT_ID_PTR slots = NULL;
-               CK_ULONG slotnum;
-               CK_SLOT_ID slot_index;
-
-               if (!current_provider->fEnabled) {
-                       rv = CKR_CRYPTOKI_NOT_INITIALIZED;
-               }
-
-               if (rv == CKR_OK) {
-                       rv = _pkcs11h_getSlotList (
-                               current_provider,
-                               CK_TRUE,
-                               &slots,
-                               &slotnum
-                       );
-               }
-
-               for (
-                       slot_index=0;
-                       (
-                               slot_index < slotnum &&
-                               rv == CKR_OK
-                       );
-                       slot_index++
-               ) {
-                       pkcs11h_token_id_list_t entry = NULL;
-                       CK_TOKEN_INFO info;
-
-                       if (rv == CKR_OK) {
-                               rv = _pkcs11h_malloc ((void *)&entry, sizeof (struct pkcs11h_token_id_list_s));
-                       }
-
-                       if (rv == CKR_OK) {
-                               rv = current_provider->f->C_GetTokenInfo (
-                                       slots[slot_index],
-                                       &info
-                               );
-                       }
-
-                       if (rv == CKR_OK) {
-                               rv = _pkcs11h_getTokenId (
-                                       &info,
-                                       &entry->token_id
-                               );
-                       }
-
-                       if (rv == CKR_OK) {
-                               entry->next = token_id_list;
-                               token_id_list = entry;
-                               entry = NULL;
-                       }
-
-                       if (entry != NULL) {
-                               pkcs11h_freeTokenIdList (entry);
-                               entry = NULL;
-                       }
-               }
-
-               if (rv != CKR_OK) {
-                       PKCS11H_DEBUG (
-                               PKCS11H_LOG_DEBUG1,
-                               "PKCS#11: Cannot get slot list for provider '%s' rv=%ld-'%s'",
-                               current_provider->manufacturerID,
-                               rv,
-                               pkcs11h_getMessage (rv)
-                       );
-
-                       /*
-                        * Ignore error
-                        */
-                       rv = CKR_OK;
-               }
-
-               if (slots != NULL) {
-                       _pkcs11h_free ((void *)&slots);
-                       slots = NULL;
-               }
-       }
-
-       if (rv == CKR_OK && method == PKCS11H_ENUM_METHOD_CACHE) {
-               pkcs11h_session_t session = NULL;
-
-               for (
-                       session = s_pkcs11h_data->sessions;
-                       session != NULL && rv == CKR_OK;
-                       session = session->next
-               ) {
-                       pkcs11h_token_id_list_t entry = NULL;
-                       PKCS11H_BOOL fFound = FALSE;
-
-                       for (
-                               entry = token_id_list;
-                               entry != NULL && !fFound;
-                               entry = entry->next
-                       ) {
-                               if (
-                                       pkcs11h_sameTokenId (
-                                               session->token_id,
-                                               entry->token_id
-                                       )
-                               ) {
-                                       fFound = TRUE;
-                               }
-                       }
-
-                       if (!fFound) {
-                               entry = NULL;
-
-                               if (rv == CKR_OK) {
-                                       rv = _pkcs11h_malloc (
-                                               (void *)&entry,
-                                               sizeof (struct pkcs11h_token_id_list_s)
-                                       );
-                               }
-
-                               if (rv == CKR_OK) {
-                                       rv = pkcs11h_duplicateTokenId (
-                                               &entry->token_id,
-                                               session->token_id
-                                       );
-                               }
-
-                               if (rv == CKR_OK) {
-                                       entry->next = token_id_list;
-                                       token_id_list = entry;
-                                       entry = NULL;
-                               }
-
-                               if (entry != NULL) {
-                                       if (entry->token_id != NULL) {
-                                               pkcs11h_freeTokenId (entry->token_id);
-                                       }
-                                       _pkcs11h_free ((void *)&entry);
-                               }
-                       }
-               }
-       }
-
-       if (rv == CKR_OK) {
-               *p_token_id_list = token_id_list;
-               token_id_list = NULL;
-       }
-
-       if (token_id_list != NULL) {
-               pkcs11h_freeTokenIdList (token_id_list);
-               token_id_list = NULL;
-       }
-
-#if defined(ENABLE_PKCS11H_THREADING)
-       if (fMutexLocked) {
-               rv = _pkcs11h_mutexRelease (&s_pkcs11h_data->mutexGlobal);
-               fMutexLocked = FALSE;
-       }
-#endif
-
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: pkcs11h_enum_getTokenIds return rv=%ld-'%s', *p_token_id_list=%p",
-               rv,
-               pkcs11h_getMessage (rv),
-               (void *)p_token_id_list
-       );
-       
-       return rv;
-}
-
-#endif
-
-#if defined(ENABLE_PKCS11H_DATA)
-
-CK_RV
-pkcs11h_freeDataIdList (
-       IN const pkcs11h_data_id_list_t data_id_list
-) {
-       pkcs11h_data_id_list_t _id = data_id_list;
-
-       PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
-       PKCS11H_ASSERT (s_pkcs11h_data->fInitialized);
-       /*PKCS11H_ASSERT (data_id_list!=NULL); NOT NEEDED*/
-
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: pkcs11h_freeDataIdList entry token_id_list=%p",
-               (void *)data_id_list
-       );
-
-       while (_id != NULL) {
-               pkcs11h_data_id_list_t x = _id;
-               _id = _id->next;
-
-               if (x->application != NULL) {
-                       _pkcs11h_free ((void *)&x->application);
-               }
-               if (x->label != NULL) {
-                       _pkcs11h_free ((void *)&x->label);
-               }
-               _pkcs11h_free ((void *)&x);
-       }
-
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: pkcs11h_freeDataIdList return"
-       );
-
-       return CKR_OK;
-}
-
-CK_RV
-pkcs11h_enumDataObjects (
-       IN const pkcs11h_token_id_t token_id,
-       IN const PKCS11H_BOOL fPublic,
-       OUT pkcs11h_data_id_list_t * const p_data_id_list
-) {
-       pkcs11h_session_t session = NULL;
-       pkcs11h_data_id_list_t data_id_list = NULL;
-       CK_RV rv = CKR_OK;
-
-       PKCS11H_BOOL fOpSuccess = FALSE;
-       PKCS11H_BOOL fLoginRetry = FALSE;
-
-       PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
-       PKCS11H_ASSERT (s_pkcs11h_data->fInitialized);
-       PKCS11H_ASSERT (p_data_id_list!=NULL);
-
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: pkcs11h_enumDataObjects entry p_data_id_list=%p",
-               (void *)p_data_id_list
-       );
-
-       *p_data_id_list = NULL;
-
-       if (rv == CKR_OK) {
-               rv = _pkcs11h_getSessionByTokenId (
-                       token_id,
-                       &session
-               );
-       }
-
-       while (rv == CKR_OK && !fOpSuccess) {
-#if defined(ENABLE_PKCS11H_THREADING)
-               PKCS11H_BOOL fMutexLocked = FALSE;
-#endif
-
-               CK_OBJECT_CLASS class = CKO_DATA;
-               CK_ATTRIBUTE filter[] = {
-                       {CKA_CLASS, (void *)&class, sizeof (class)}
-               };
-               CK_OBJECT_HANDLE *objects = NULL;
-               CK_ULONG objects_found = 0;
-
-               CK_ULONG i;
-
-               if (rv == CKR_OK) {
-                       rv = _pkcs11h_validateSession (session);
-               }
-
-#if defined(ENABLE_PKCS11H_THREADING)
-               if (
-                       rv == CKR_OK &&
-                       (rv = _pkcs11h_mutexLock (&session->mutexSession)) == CKR_OK
-               ) {
-                       fMutexLocked = TRUE;
-               }
-#endif
-
-               if (rv == CKR_OK) {
-                       rv = _pkcs11h_findObjects (
-                               session,
-                               filter,
-                               sizeof (filter) / sizeof (CK_ATTRIBUTE),
-                               &objects,
-                               &objects_found
-                       );
-               }
-
-               for (i = 0;rv == CKR_OK && i < objects_found;i++) {
-                       pkcs11h_data_id_list_t entry = NULL;
-
-                       CK_ATTRIBUTE attrs[] = {
-                               {CKA_APPLICATION, NULL, 0},
-                               {CKA_LABEL, NULL, 0}
-                       };
-
-                       if (rv == CKR_OK) {
-                               rv = _pkcs11h_getObjectAttributes (
-                                       session,
-                                       objects[i],
-                                       attrs,
-                                       sizeof (attrs) / sizeof (CK_ATTRIBUTE)
-                               );
-                       }
-                       
-                       if (rv == CKR_OK) {
-                               rv = _pkcs11h_malloc (
-                                       (void *)&entry,
-                                       sizeof (struct pkcs11h_data_id_list_s)
-                               );
-                       }
-
-                       if (
-                               rv == CKR_OK &&
-                               (rv = _pkcs11h_malloc (
-                                       (void *)&entry->application,
-                                       attrs[0].ulValueLen+1
-                               )) == CKR_OK
-                       ) {
-                               memmove (entry->application, attrs[0].pValue, attrs[0].ulValueLen);
-                               entry->application[attrs[0].ulValueLen] = '\0';
-                       }
-
-                       if (
-                               rv == CKR_OK &&
-                               (rv = _pkcs11h_malloc (
-                                       (void *)&entry->label,
-                                       attrs[1].ulValueLen+1
-                               )) == CKR_OK
-                       ) {
-                               memmove (entry->label, attrs[1].pValue, attrs[1].ulValueLen);
-                               entry->label[attrs[1].ulValueLen] = '\0';
-                       }
-
-                       if (rv == CKR_OK) {
-                               entry->next = data_id_list;
-                               data_id_list = entry;
-                               entry = NULL;
-                       }
-
-                       _pkcs11h_freeObjectAttributes (
-                               attrs,
-                               sizeof (attrs) / sizeof (CK_ATTRIBUTE)
-                       );
-
-                       if (entry != NULL) {
-                               if (entry->application != NULL) {
-                                       _pkcs11h_free ((void *)&entry->application);
-                               }
-                               if (entry->label != NULL) {
-                                       _pkcs11h_free ((void *)&entry->label);
-                               }
-                               _pkcs11h_free ((void *)&entry);
-                       }
-               }
-
-               if (objects != NULL) {
-                       _pkcs11h_free ((void *)&objects);
-               }
-
-#if defined(ENABLE_PKCS11H_THREADING)
-               if (fMutexLocked) {
-                       _pkcs11h_mutexRelease (&session->mutexSession);
-                       fMutexLocked = FALSE;
-               }
-#endif
-
-               if (rv == CKR_OK) {
-                       fOpSuccess = TRUE;
-               }
-               else {
-                       if (!fLoginRetry) {
-                               PKCS11H_DEBUG (
-                                       PKCS11H_LOG_DEBUG1,
-                                       "PKCS#11: Enumerate data objects failed rv=%ld-'%s'",
-                                       rv,
-                                       pkcs11h_getMessage (rv)
-                               );
-                               fLoginRetry = TRUE;
-                               rv = _pkcs11h_login (
-                                       session,
-                                       fPublic,
-                                       TRUE,
-                                       (
-                                               PKCS11H_PROMPT_MASK_ALLOW_PIN_PROMPT |
-                                               PKCS11H_PROMPT_MAST_ALLOW_CARD_PROMPT 
-                                       )
-                               );
-                       }
-               }
-       }
-
-       if (rv == CKR_OK) {
-               *p_data_id_list = data_id_list;
-               data_id_list = NULL;
-       }
-
-       if (session != NULL) {
-               _pkcs11h_releaseSession (session);
-               session = NULL;
-       }
-
-       if (data_id_list != NULL) {
-               pkcs11h_freeDataIdList (data_id_list);
-               data_id_list = NULL;
-       }
-
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: pkcs11h_data_id_list_t return rv=%ld-'%s', *p_data_id_list=%p",
-               rv,
-               pkcs11h_getMessage (rv),
-               (void *)*p_data_id_list
-       );
-       
-       return rv;
-}
-
-#endif                         /* ENABLE_PKCS11H_DATA */
-
-#if defined(ENABLE_PKCS11H_CERTIFICATE)
-
-static
-CK_RV
-_pkcs11h_enum_getSessionCertificates (
-       IN const pkcs11h_session_t session
-) {
-       PKCS11H_BOOL fOpSuccess = FALSE;
-       PKCS11H_BOOL fLoginRetry = FALSE;
-
-       CK_RV rv = CKR_OK;
-
-       PKCS11H_ASSERT (session!=NULL);
-
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: _pkcs11h_enum_getSessionCertificates entry session=%p",
-               (void *)session
-       );
-       
-       /* THREADS: NO NEED TO LOCK, GLOBAL CACHE IS LOCKED */
-
-       while (rv == CKR_OK && !fOpSuccess) {
-               CK_OBJECT_CLASS cert_filter_class = CKO_CERTIFICATE;
-               CK_ATTRIBUTE cert_filter[] = {
-                       {CKA_CLASS, &cert_filter_class, sizeof (cert_filter_class)}
-               };
-
-               CK_OBJECT_HANDLE *objects = NULL;
-               CK_ULONG objects_found = 0;
-
-               CK_ULONG i;
-
-               if (rv == CKR_OK) {
-                       rv = _pkcs11h_validateSession (session);
-               }
-
-               if (rv == CKR_OK) {
-                       rv = _pkcs11h_findObjects (
-                               session,
-                               cert_filter,
-                               sizeof (cert_filter) / sizeof (CK_ATTRIBUTE),
-                               &objects,
-                               &objects_found
-                       );
-               }
-                       
-               for (i=0;rv == CKR_OK && i < objects_found;i++) {
-                       pkcs11h_certificate_id_t certificate_id = NULL;
-                       pkcs11h_certificate_id_list_t new_element = NULL;
-                       
-                       CK_ATTRIBUTE attrs[] = {
-                               {CKA_ID, NULL, 0},
-                               {CKA_VALUE, NULL, 0}
-                       };
-
-                       if (rv == CKR_OK) {
-                               rv = _pkcs11h_getObjectAttributes (
-                                       session,
-                                       objects[i],
-                                       attrs,
-                                       sizeof (attrs) / sizeof (CK_ATTRIBUTE)
-                               );
-                       }
-
-                       if (
-                               rv == CKR_OK &&
-                               (rv = _pkcs11h_newCertificateId (&certificate_id)) == CKR_OK
-                       ) {
-                               rv = pkcs11h_duplicateTokenId (
-                                       &certificate_id->token_id,
-                                       session->token_id
-                               );
-                       }
-
-                       if (rv == CKR_OK) {
-                               rv = _pkcs11h_dupmem (
-                                       (void*)&certificate_id->attrCKA_ID,
-                                       &certificate_id->attrCKA_ID_size,
-                                       attrs[0].pValue,
-                                       attrs[0].ulValueLen
-                               );
-                       }
-
-                       if (rv == CKR_OK) {
-                               rv = _pkcs11h_dupmem (
-                                       (void*)&certificate_id->certificate_blob,
-                                       &certificate_id->certificate_blob_size,
-                                       attrs[1].pValue,
-                                       attrs[1].ulValueLen
-                               );
-                       }
-
-                       if (rv == CKR_OK) {
-                               rv = _pkcs11h_updateCertificateIdDescription (certificate_id);
-                       }
-
-                       if (
-                               rv == CKR_OK &&
-                               (rv = _pkcs11h_malloc (
-                                       (void *)&new_element,
-                                       sizeof (struct pkcs11h_certificate_id_list_s)
-                               )) == CKR_OK
-                       ) {
-                               new_element->next = session->cached_certs;
-                               new_element->certificate_id = certificate_id;
-                               certificate_id = NULL;
-
-                               session->cached_certs = new_element;
-                               new_element = NULL;
-                       }
-
-                       if (certificate_id != NULL) {
-                               pkcs11h_freeCertificateId (certificate_id);
-                               certificate_id = NULL;
-                       }
-
-                       if (new_element != NULL) {
-                               _pkcs11h_free ((void *)&new_element);
-                               new_element = NULL;
-                       }
-
-                       _pkcs11h_freeObjectAttributes (
-                               attrs,
-                               sizeof (attrs) / sizeof (CK_ATTRIBUTE)
-                       );
-
-                       if (rv != CKR_OK) {
-                               PKCS11H_DEBUG (
-                                       PKCS11H_LOG_DEBUG1,
-                                       "PKCS#11: Cannot get object attribute for provider '%s' object %ld rv=%ld-'%s'",
-                                       session->provider->manufacturerID,
-                                       objects[i],
-                                       rv,
-                                       pkcs11h_getMessage (rv)
-                               );
-
-                               /*
-                                * Ignore error
-                                */
-                               rv = CKR_OK;
-                       }
-               }
-
-               if (objects != NULL) {
-                       _pkcs11h_free ((void *)&objects);
-               }
-
-               if (rv == CKR_OK) {
-                       fOpSuccess = TRUE;
-               }
-               else {
-                       if (!fLoginRetry) {
-                               PKCS11H_DEBUG (
-                                       PKCS11H_LOG_DEBUG1,
-                                       "PKCS#11: Get certificate attributes failed: %ld:'%s'",
-                                       rv,
-                                       pkcs11h_getMessage (rv)
-                               );
-
-                               rv = _pkcs11h_login (
-                                       session,
-                                       TRUE,
-                                       TRUE,
-                                       PKCS11H_PROMPT_MASK_ALLOW_PIN_PROMPT
-                               );
-
-                               fLoginRetry = TRUE;
-                       }
-               }
-       }
-
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: _pkcs11h_enum_getSessionCertificates return rv=%ld-'%s'",
-               rv,
-               pkcs11h_getMessage (rv)
-       );
-
-       return rv;
-}
-
-static
-CK_RV
-_pkcs11h_enum_splitCertificateIdList (
-       IN const pkcs11h_certificate_id_list_t cert_id_all,
-       OUT pkcs11h_certificate_id_list_t * const p_cert_id_issuers_list,
-       OUT pkcs11h_certificate_id_list_t * const p_cert_id_end_list
-) {
-       typedef struct info_s {
-               struct info_s *next;
-               pkcs11h_certificate_id_t e;
-               X509 *x509;
-               PKCS11H_BOOL fIsIssuer;
-       } *info_t;
-
-       pkcs11h_certificate_id_list_t cert_id_issuers_list = NULL;
-       pkcs11h_certificate_id_list_t cert_id_end_list = NULL;
-
-       info_t head = NULL;
-       info_t info = NULL;
-
-       CK_RV rv = CKR_OK;
-
-       /*PKCS11H_ASSERT (cert_id_all!=NULL); NOT NEEDED */
-       /*PKCS11H_ASSERT (p_cert_id_issuers_list!=NULL); NOT NEEDED*/
-       PKCS11H_ASSERT (p_cert_id_end_list!=NULL);
-
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: pkcs11h_splitCertificateIdList entry cert_id_all=%p, p_cert_id_issuers_list=%p, p_cert_id_end_list=%p",
-               (void *)cert_id_all,
-               (void *)p_cert_id_issuers_list,
-               (void *)p_cert_id_end_list
-       );
-
-       if (p_cert_id_issuers_list != NULL) {
-               *p_cert_id_issuers_list = NULL;
-       }
-       *p_cert_id_end_list = NULL;
-
-       OpenSSL_add_all_digests ();
-
-       if (rv == CKR_OK) {
-               pkcs11h_certificate_id_list_t entry = NULL;
-
-               for (
-                       entry = cert_id_all;
-                       entry != NULL && rv == CKR_OK;
-                       entry = entry->next
-               ) {
-                       info_t new_info = NULL;
-
-                       if (
-                               rv == CKR_OK &&
-                               (rv = _pkcs11h_malloc ((void *)&new_info, sizeof (struct info_s))) == CKR_OK &&
-                               entry->certificate_id->certificate_blob != NULL
-                       ) {
-                               pkcs11_openssl_d2i_t d2i = (pkcs11_openssl_d2i_t)entry->certificate_id->certificate_blob;
-                               new_info->next = head;
-                               new_info->e = entry->certificate_id;
-                               new_info->x509 = X509_new ();
-                               if (
-                                       new_info->x509 != NULL &&
-                                       !d2i_X509 (
-                                               &new_info->x509,
-                                               &d2i,
-                                               entry->certificate_id->certificate_blob_size
-                                       )
-                               ) {
-                                       X509_free (new_info->x509);
-                                       new_info->x509 = NULL;
-                               }
-                               head = new_info;
-                               new_info = NULL;
-                       }
-               }
-
-       }
-
-       if (rv == CKR_OK) {
-               for (
-                       info = head;
-                       info != NULL;
-                       info = info->next
-               ) {
-                       info_t info2 = NULL;
-                       for (
-                               info2 = head;
-                               info2 != NULL && !info->fIsIssuer;
-                               info2 = info2->next
-                       ) {
-                               EVP_PKEY *pub = NULL;
-
-                               pub = X509_get_pubkey (info->x509);
-
-                               if (
-                                       info != info2 &&
-                                       info->x509 != NULL &&
-                                       info2->x509 != NULL &&
-/* Some people get this wrong          !X509_NAME_cmp (
-                                               X509_get_subject_name (info->x509),
-                                               X509_get_issuer_name (info2->x509)
-                                       ) && */
-                                       X509_verify (info2->x509, pub) == 1
-                               ) {
-                                       info->fIsIssuer = TRUE;
-                               }
-
-                               if (pub != NULL) {
-                                       EVP_PKEY_free (pub);
-                                       pub = NULL;
-                               }
-                       }
-               }
-       }
-
-       if (rv == CKR_OK) {
-               for (
-                       info = head;
-                       info != NULL && rv == CKR_OK;
-                       info = info->next
-               ) {
-                       pkcs11h_certificate_id_list_t new_entry = NULL;
-
-                       if (rv == CKR_OK) {
-                               rv = _pkcs11h_malloc (
-                                       (void *)&new_entry,
-                                       sizeof (struct pkcs11h_certificate_id_list_s)
-                               );
-                       }
-
-                       if (
-                               rv == CKR_OK &&
-                               (rv = pkcs11h_duplicateCertificateId (
-                                       &new_entry->certificate_id,
-                                       info->e
-                               )) == CKR_OK
-                       ) {
-                               /*
-                                * Should not free base list
-                                */
-                               info->e = NULL;
-                       }
-
-                       if (rv == CKR_OK) {
-                               if (info->fIsIssuer) {
-                                       new_entry->next = cert_id_issuers_list;
-                                       cert_id_issuers_list = new_entry;
-                                       new_entry = NULL;
-                               }
-                               else {
-                                       new_entry->next = cert_id_end_list;
-                                       cert_id_end_list = new_entry;
-                                       new_entry = NULL;
-                               }
-                       }
-
-                       if (new_entry != NULL) {
-                               if (new_entry->certificate_id != NULL) {
-                                       pkcs11h_freeCertificateId (new_entry->certificate_id);
-                               }
-                               _pkcs11h_free ((void *)&new_entry);
-                       }
-               }
-       }
-
-       if (rv == CKR_OK) {
-               while (head != NULL) {
-                       info_t entry = head;
-                       head = head->next;
-
-                       if (entry->x509 != NULL) {
-                               X509_free (entry->x509);
-                               entry->x509 = NULL;
-                       }
-                       _pkcs11h_free ((void *)&entry);
-               }
-       }
-
-       if (rv == CKR_OK && p_cert_id_issuers_list != NULL ) {
-               *p_cert_id_issuers_list = cert_id_issuers_list;
-               cert_id_issuers_list = NULL;
-       }
-
-       if (rv == CKR_OK) {
-               *p_cert_id_end_list = cert_id_end_list;
-               cert_id_end_list = NULL;
-       }
-
-       if (cert_id_issuers_list != NULL) {
-               pkcs11h_freeCertificateIdList (cert_id_issuers_list);
-       }
-
-       if (cert_id_end_list != NULL) {
-               pkcs11h_freeCertificateIdList (cert_id_end_list);
-       }
-
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: pkcs11h_splitCertificateIdList return rv=%ld-'%s'",
-               rv,
-               pkcs11h_getMessage (rv)
-       );
-
-       return rv;
-}
-
-CK_RV
-pkcs11h_freeCertificateIdList (
-       IN const pkcs11h_certificate_id_list_t cert_id_list
-) {
-       pkcs11h_certificate_id_list_t _id = cert_id_list;
-
-       PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
-       PKCS11H_ASSERT (s_pkcs11h_data->fInitialized);
-       /*PKCS11H_ASSERT (cert_id_list!=NULL); NOT NEEDED*/
-
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: pkcs11h_freeCertificateIdList entry cert_id_list=%p",
-               (void *)cert_id_list
-       );
-
-       while (_id != NULL) {
-               pkcs11h_certificate_id_list_t x = _id;
-               _id = _id->next;
-               if (x->certificate_id != NULL) {
-                       pkcs11h_freeCertificateId (x->certificate_id);
-               }
-               x->next = NULL;
-               _pkcs11h_free ((void *)&x);
-       }
-
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: pkcs11h_freeCertificateIdList return"
-       );
-
-       return CKR_OK;
-}
-
-CK_RV
-pkcs11h_enum_getTokenCertificateIds (
-       IN const pkcs11h_token_id_t token_id,
-       IN const int method,
-       OUT pkcs11h_certificate_id_list_t * const p_cert_id_issuers_list,
-       OUT pkcs11h_certificate_id_list_t * const p_cert_id_end_list
-) {
-#if defined(ENABLE_PKCS11H_THREADING)
-       PKCS11H_BOOL fMutexLocked = FALSE;
-#endif
-       pkcs11h_session_t session = NULL;
-       CK_RV rv = CKR_OK;
-
-       PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
-       PKCS11H_ASSERT (s_pkcs11h_data->fInitialized);
-       PKCS11H_ASSERT (token_id!=NULL);
-       /*PKCS11H_ASSERT (p_cert_id_issuers_list!=NULL); NOT NEEDED*/
-       PKCS11H_ASSERT (p_cert_id_end_list!=NULL);
-
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: pkcs11h_enum_getTokenCertificateIds entry token_id=%p, method=%d, p_cert_id_issuers_list=%p, p_cert_id_end_list=%p",
-               (void *)token_id,
-               method,
-               (void *)p_cert_id_issuers_list,
-               (void *)p_cert_id_end_list
-       );
-
-       if (p_cert_id_issuers_list != NULL) {
-               *p_cert_id_issuers_list = NULL;
-       }
-       *p_cert_id_end_list = NULL;
-
-#if defined(ENABLE_PKCS11H_THREADING)
-       if (
-               rv == CKR_OK &&
-               (rv = _pkcs11h_mutexLock (&s_pkcs11h_data->mutexCache)) == CKR_OK
-       ) {
-               fMutexLocked = TRUE;
-       }
-#endif
-
-       if (
-               rv == CKR_OK &&
-               (rv = _pkcs11h_getSessionByTokenId (
-                       token_id,
-                       &session
-               )) == CKR_OK
-       ) {
-               if (method == PKCS11H_ENUM_METHOD_RELOAD) {
-                       pkcs11h_freeCertificateIdList (session->cached_certs);
-                       session->cached_certs = NULL;
-               }
-
-               if (session->cached_certs == NULL) {
-                       rv = _pkcs11h_enum_getSessionCertificates (session);
-               }
-       }
-
-       if (rv == CKR_OK) {
-               rv = _pkcs11h_enum_splitCertificateIdList (
-                       session->cached_certs,
-                       p_cert_id_issuers_list,
-                       p_cert_id_end_list
-               );
-       }
-
-       if (session != NULL) {
-               _pkcs11h_releaseSession (session);
-       }
-
-#if defined(ENABLE_PKCS11H_THREADING)
-       if (fMutexLocked) {
-               _pkcs11h_mutexRelease (&s_pkcs11h_data->mutexCache);
-               fMutexLocked = FALSE;
-       }
-#endif
-
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: pkcs11h_enum_getTokenCertificateIds return rv=%ld-'%s'",
-               rv,
-               pkcs11h_getMessage (rv)
-       );
-       
-       return rv;
-}
-
-CK_RV
-pkcs11h_enum_getCertificateIds (
-       IN const int method,
-       OUT pkcs11h_certificate_id_list_t * const p_cert_id_issuers_list,
-       OUT pkcs11h_certificate_id_list_t * const p_cert_id_end_list
-) {
-#if defined(ENABLE_PKCS11H_THREADING)
-       PKCS11H_BOOL fMutexLocked = FALSE;
-#endif
-       pkcs11h_certificate_id_list_t cert_id_list = NULL;
-       pkcs11h_provider_t current_provider;
-       pkcs11h_session_t current_session;
-       CK_RV rv = CKR_OK;
-
-       PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
-       PKCS11H_ASSERT (s_pkcs11h_data->fInitialized);
-       /*PKCS11H_ASSERT (p_cert_id_issuers_list!=NULL); NOT NEEDED*/
-       PKCS11H_ASSERT (p_cert_id_end_list!=NULL);
-
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: pkcs11h_enum_getCertificateIds entry method=%d, p_cert_id_issuers_list=%p, p_cert_id_end_list=%p",
-               method,
-               (void *)p_cert_id_issuers_list,
-               (void *)p_cert_id_end_list
-       );
-
-       if (p_cert_id_issuers_list != NULL) {
-               *p_cert_id_issuers_list = NULL;
-       }
-       *p_cert_id_end_list = NULL;
-
-#if defined(ENABLE_PKCS11H_THREADING)
-       if (
-               rv == CKR_OK &&
-               (rv = _pkcs11h_mutexLock (&s_pkcs11h_data->mutexCache)) == CKR_OK
-       ) {
-               fMutexLocked = TRUE;
-       }
-#endif
-
-       for (
-               current_session = s_pkcs11h_data->sessions;
-               current_session != NULL;
-               current_session = current_session->next
-       ) {
-               current_session->fTouch = FALSE;
-               if (method == PKCS11H_ENUM_METHOD_RELOAD) {
-                       pkcs11h_freeCertificateIdList (current_session->cached_certs);
-                       current_session->cached_certs = NULL;
-               }
-       }
-
-       for (
-               current_provider = s_pkcs11h_data->providers;
-               (
-                       current_provider != NULL &&
-                       rv == CKR_OK
-               );
-               current_provider = current_provider->next
-       ) {
-               CK_SLOT_ID_PTR slots = NULL;
-               CK_ULONG slotnum;
-               CK_SLOT_ID slot_index;
-
-               if (!current_provider->fEnabled) {
-                       rv = CKR_CRYPTOKI_NOT_INITIALIZED;
-               }
-
-               if (rv == CKR_OK) {
-                       rv = _pkcs11h_getSlotList (
-                               current_provider,
-                               CK_TRUE,
-                               &slots,
-                               &slotnum
-                       );
-               }
-
-               for (
-                       slot_index=0;
-                       (
-                               slot_index < slotnum &&
-                               rv == CKR_OK
-                       );
-                       slot_index++
-               ) {
-                       pkcs11h_session_t session = NULL;
-                       pkcs11h_token_id_t token_id = NULL;
-                       CK_TOKEN_INFO info;
-
-                       if (rv == CKR_OK) {
-                               rv = current_provider->f->C_GetTokenInfo (
-                                       slots[slot_index],
-                                       &info
-                               );
-                       }
-
-                       if (
-                               rv == CKR_OK &&
-                               (rv = _pkcs11h_getTokenId (
-                                       &info,
-                                       &token_id
-                               )) == CKR_OK &&
-                               (rv = _pkcs11h_getSessionByTokenId (
-                                       token_id,
-                                       &session
-                               )) == CKR_OK
-                       ) {
-                               session->fTouch = TRUE;
-
-                               if (session->cached_certs == NULL) {
-                                       rv = _pkcs11h_enum_getSessionCertificates (session);
-                               }
-                       }
-
-                       if (rv != CKR_OK) {
-                               PKCS11H_DEBUG (
-                                       PKCS11H_LOG_DEBUG1,
-                                       "PKCS#11: Cannot get token information for provider '%s' slot %ld rv=%ld-'%s'",
-                                       current_provider->manufacturerID,
-                                       slots[slot_index],
-                                       rv,
-                                       pkcs11h_getMessage (rv)
-                               );
-
-                               /*
-                                * Ignore error
-                                */
-                               rv = CKR_OK;
-                       }
-
-                       if (session != NULL) {
-                               _pkcs11h_releaseSession (session);
-                               session = NULL;
-                       }
-
-                       if (token_id != NULL) {
-                               pkcs11h_freeTokenId (token_id);
-                               token_id = NULL;
-                       }
-               }
-
-               if (rv != CKR_OK) {
-                       PKCS11H_DEBUG (
-                               PKCS11H_LOG_DEBUG1,
-                               "PKCS#11: Cannot get slot list for provider '%s' rv=%ld-'%s'",
-                               current_provider->manufacturerID,
-                               rv,
-                               pkcs11h_getMessage (rv)
-                       );
-
-                       /*
-                        * Ignore error
-                        */
-                       rv = CKR_OK;
-               }
-
-               if (slots != NULL) {
-                       _pkcs11h_free ((void *)&slots);
-                       slots = NULL;
-               }
-       }
-
-       for (
-               current_session = s_pkcs11h_data->sessions;
-               (
-                       current_session != NULL &&
-                       rv == CKR_OK
-               );
-               current_session = current_session->next
-       ) {
-               if (
-                       method == PKCS11H_ENUM_METHOD_CACHE ||
-                       (
-                               (
-                                       method == PKCS11H_ENUM_METHOD_RELOAD ||
-                                       method == PKCS11H_ENUM_METHOD_CACHE_EXIST
-                               ) &&
-                               current_session->fTouch
-                       )
-               ) {
-                       pkcs11h_certificate_id_list_t entry = NULL;
-
-                       for (
-                               entry = current_session->cached_certs;
-                               (
-                                       entry != NULL &&
-                                       rv == CKR_OK
-                               );
-                               entry = entry->next
-                       ) {
-                               pkcs11h_certificate_id_list_t new_entry = NULL;
-
-                               if (
-                                       rv == CKR_OK &&
-                                       (rv = _pkcs11h_malloc (
-                                               (void *)&new_entry,
-                                               sizeof (struct pkcs11h_certificate_id_list_s)
-                                       )) == CKR_OK &&
-                                       (rv = pkcs11h_duplicateCertificateId (
-                                               &new_entry->certificate_id,
-                                               entry->certificate_id
-                                       )) == CKR_OK
-                               ) {
-                                       new_entry->next = cert_id_list;
-                                       cert_id_list = new_entry;
-                                       new_entry = NULL;
-                               }
-
-                               if (new_entry != NULL) {
-                                       new_entry->next = NULL;
-                                       pkcs11h_freeCertificateIdList (new_entry);
-                                       new_entry = NULL;
-                               }
-                       }
-               }
-       }
-
-       if (rv == CKR_OK) {
-               rv = _pkcs11h_enum_splitCertificateIdList (
-                       cert_id_list,
-                       p_cert_id_issuers_list,
-                       p_cert_id_end_list
-               );
-       }
-
-       if (cert_id_list != NULL) {
-               pkcs11h_freeCertificateIdList (cert_id_list);
-               cert_id_list = NULL;
-       }
-
-
-#if defined(ENABLE_PKCS11H_THREADING)
-       if (fMutexLocked) {
-               _pkcs11h_mutexRelease (&s_pkcs11h_data->mutexCache);
-               fMutexLocked = FALSE;
-       }
-#endif
-
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: pkcs11h_enum_getCertificateIds return rv=%ld-'%s'",
-               rv,
-               pkcs11h_getMessage (rv)
-       );
-       
-       return rv;
-}
-
-#endif                         /* ENABLE_PKCS11H_CERTIFICATE */
-
-#endif                         /* ENABLE_PKCS11H_ENUM */
-
-#if defined(ENABLE_PKCS11H_SLOTEVENT)
-/*======================================================================*
- * SLOTEVENT INTERFACE
- *======================================================================*/
-
-static
-unsigned long
-_pkcs11h_slotevent_checksum (
-       IN const unsigned char * const p,
-       IN const size_t s
-) {
-       unsigned long r = 0;
-       size_t i;
-       for (i=0;i<s;i++) {
-               r += p[i];
-       }
-       return r;
-}
-
-static
-void *
-_pkcs11h_slotevent_provider (
-       IN void *p
-) {
-       pkcs11h_provider_t provider = (pkcs11h_provider_t)p;
-       CK_SLOT_ID slot;
-       CK_RV rv = CKR_OK;
-
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: _pkcs11h_slotevent_provider provider='%s' entry",
-               provider->manufacturerID
-       );
-
-       if (rv == CKR_OK && !provider->fEnabled) {
-               rv = CKR_OPERATION_NOT_INITIALIZED;
-       }
-
-       if (rv == CKR_OK) {
-
-               if (provider->nSlotEventPollInterval == 0) {
-                       provider->nSlotEventPollInterval = PKCS11H_DEFAULT_SLOTEVENT_POLL;
-               }
-
-               /*
-                * If we cannot finalize, we cannot cause
-                * WaitForSlotEvent to terminate
-                */
-               if (!provider->fShouldFinalize) {
-                       PKCS11H_DEBUG (
-                               PKCS11H_LOG_DEBUG1,
-                               "PKCS#11: Setup slotevent provider='%s' mode hardset to poll",
-                               provider->manufacturerID
-                       );
-                       provider->nSlotEventMethod = PKCS11H_SLOTEVENT_METHOD_POLL;
-               }
-
-               if (
-                       provider->nSlotEventMethod == PKCS11H_SLOTEVENT_METHOD_AUTO ||
-                       provider->nSlotEventMethod == PKCS11H_SLOTEVENT_METHOD_TRIGGER
-               ) { 
-                       if (
-                               provider->f->C_WaitForSlotEvent (
-                                       CKF_DONT_BLOCK,
-                                       &slot,
-                                       NULL_PTR
-                               ) == CKR_FUNCTION_NOT_SUPPORTED
-                       ) {
-                               PKCS11H_DEBUG (
-                                       PKCS11H_LOG_DEBUG1,
-                                       "PKCS#11: Setup slotevent provider='%s' mode is poll",
-                                       provider->manufacturerID
-                               );
-
-                               provider->nSlotEventMethod = PKCS11H_SLOTEVENT_METHOD_POLL;
-                       }
-                       else {
-                               PKCS11H_DEBUG (
-                                       PKCS11H_LOG_DEBUG1,
-                                       "PKCS#11: Setup slotevent provider='%s' mode is trigger",
-                                       provider->manufacturerID
-                               );
-
-                               provider->nSlotEventMethod = PKCS11H_SLOTEVENT_METHOD_TRIGGER;
-                       }
-               }
-       }
-
-       if (provider->nSlotEventMethod == PKCS11H_SLOTEVENT_METHOD_TRIGGER) {
-               while (
-                       !s_pkcs11h_data->fSlotEventShouldTerminate &&
-                       provider->fEnabled &&
-                       rv == CKR_OK &&
-                       (rv = provider->f->C_WaitForSlotEvent (
-                               0,
-                               &slot,
-                               NULL_PTR
-                       )) == CKR_OK
-               ) {
-                       PKCS11H_DEBUG (
-                               PKCS11H_LOG_DEBUG1,
-                               "PKCS#11: Slotevent provider='%s' event",
-                               provider->manufacturerID
-                       );
-
-                       _pkcs11h_condSignal (&s_pkcs11h_data->condSlotEvent);
-               }
-       }
-       else {
-               unsigned long ulLastChecksum = 0;
-               PKCS11H_BOOL fFirstTime = TRUE;
-
-               while (
-                       !s_pkcs11h_data->fSlotEventShouldTerminate &&
-                       provider->fEnabled &&
-                       rv == CKR_OK
-               ) {
-                       unsigned long ulCurrentChecksum = 0;
-
-                       CK_SLOT_ID_PTR slots = NULL;
-                       CK_ULONG slotnum;
-
-                       PKCS11H_DEBUG (
-                               PKCS11H_LOG_DEBUG1,
-                               "PKCS#11: Slotevent provider='%s' poll",
-                               provider->manufacturerID
-                       );
-
-                       if (
-                               rv == CKR_OK &&
-                               (rv = _pkcs11h_getSlotList (
-                                       provider,
-                                       TRUE,
-                                       &slots,
-                                       &slotnum
-                               )) == CKR_OK
-                       ) {
-                               CK_ULONG i;
-                               
-                               for (i=0;i<slotnum;i++) {
-                                       CK_TOKEN_INFO info;
-
-                                       if (provider->f->C_GetTokenInfo (slots[i], &info) == CKR_OK) {
-                                               ulCurrentChecksum += (
-                                                       _pkcs11h_slotevent_checksum (
-                                                               info.label,
-                                                               sizeof (info.label)
-                                                       ) +
-                                                       _pkcs11h_slotevent_checksum (
-                                                               info.manufacturerID,
-                                                               sizeof (info.manufacturerID)
-                                                       ) +
-                                                       _pkcs11h_slotevent_checksum (
-                                                               info.model,
-                                                               sizeof (info.model)
-                                                       ) +
-                                                       _pkcs11h_slotevent_checksum (
-                                                               info.serialNumber,
-                                                               sizeof (info.serialNumber)
-                                                       )
-                                               );
-                                       }
-                               }
-                       }
-                       
-                       if (rv == CKR_OK) {
-                               if (fFirstTime) {
-                                       fFirstTime = FALSE;
-                               }
-                               else {
-                                       if (ulLastChecksum != ulCurrentChecksum) {
-                                               PKCS11H_DEBUG (
-                                                       PKCS11H_LOG_DEBUG1,
-                                                       "PKCS#11: Slotevent provider='%s' event",
-                                                       provider->manufacturerID
-                                               );
-
-                                               _pkcs11h_condSignal (&s_pkcs11h_data->condSlotEvent);
-                                       }
-                               }
-                               ulLastChecksum = ulCurrentChecksum;
-                       }
-
-                       if (slots != NULL) {
-                               _pkcs11h_free ((void *)&slots);
-                       }
-                       
-                       if (!s_pkcs11h_data->fSlotEventShouldTerminate) {
-                               _pkcs11h_sleep (provider->nSlotEventPollInterval);
-                       }
-               }
-       }
-
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: _pkcs11h_slotevent_provider provider='%s' return",
-               provider->manufacturerID
-       );
-
-       return NULL;
-}
-
-static
-void *
-_pkcs11h_slotevent_manager (
-       IN void *p
-) {
-       PKCS11H_BOOL fFirst = TRUE;
-
-       (void)p;
-
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: _pkcs11h_slotevent_manager entry"
-       );
-
-       /*
-        * Trigger hook, so application may
-        * depend on initial slot change
-        */
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG1,
-               "PKCS#11: Calling slotevent hook"
-       );
-       s_pkcs11h_data->hooks.slotevent (s_pkcs11h_data->hooks.slotevent_data);
-
-       while (
-               fFirst ||       /* Must enter wait or mutex will never be free */
-               !s_pkcs11h_data->fSlotEventShouldTerminate
-       ) {
-               pkcs11h_provider_t current_provider;
-
-               fFirst = FALSE;
-
-               /*
-                * Start each provider thread
-                * if not already started.
-                * This is required in order to allow
-                * adding new providers.
-                */
-               for (
-                       current_provider = s_pkcs11h_data->providers;
-                       current_provider != NULL;
-                       current_provider = current_provider->next
-               ) {
-                       if (!current_provider->fEnabled) {
-                               if (current_provider->threadSlotEvent == PKCS11H_THREAD_NULL) {
-                                       _pkcs11h_threadStart (
-                                               &current_provider->threadSlotEvent,
-                                               _pkcs11h_slotevent_provider,
-                                               current_provider
-                                       );
-                               }
-                       }
-                       else {
-                               if (current_provider->threadSlotEvent != PKCS11H_THREAD_NULL) {
-                                       _pkcs11h_threadJoin (&current_provider->threadSlotEvent);
-                               }
-                       }
-               }
-
-               PKCS11H_DEBUG (
-                       PKCS11H_LOG_DEBUG2,
-                       "PKCS#11: _pkcs11h_slotevent_manager waiting for slotevent"
-               );
-               _pkcs11h_condWait (&s_pkcs11h_data->condSlotEvent, PKCS11H_COND_INFINITE);
-
-               if (s_pkcs11h_data->fSlotEventSkipEvent) {
-                       PKCS11H_DEBUG (
-                               PKCS11H_LOG_DEBUG1,
-                               "PKCS#11: Slotevent skipping event"
-                       );
-                       s_pkcs11h_data->fSlotEventSkipEvent = FALSE;
-               }
-               else {
-                       PKCS11H_DEBUG (
-                               PKCS11H_LOG_DEBUG1,
-                               "PKCS#11: Calling slotevent hook"
-                       );
-                       s_pkcs11h_data->hooks.slotevent (s_pkcs11h_data->hooks.slotevent_data);
-               }
-       }
-
-       {
-               pkcs11h_provider_t current_provider;
-
-               PKCS11H_DEBUG (
-                       PKCS11H_LOG_DEBUG2,
-                       "PKCS#11: _pkcs11h_slotevent_manager joining threads"
-               );
-
-
-               for (
-                       current_provider = s_pkcs11h_data->providers;
-                       current_provider != NULL;
-                       current_provider = current_provider->next
-               ) {
-                       if (current_provider->threadSlotEvent != PKCS11H_THREAD_NULL) {
-                               _pkcs11h_threadJoin (&current_provider->threadSlotEvent);
-                       }
-               }
-       }
-
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: _pkcs11h_slotevent_manager return"
-       );
-
-       return NULL;
-}
-
-static
-CK_RV
-_pkcs11h_slotevent_init () {
-       CK_RV rv = CKR_OK;
-
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: _pkcs11h_slotevent_init entry"
-       );
-
-       if (!s_pkcs11h_data->fSlotEventInitialized) {
-               if (rv == CKR_OK) {
-                       rv = _pkcs11h_condInit (&s_pkcs11h_data->condSlotEvent);
-               }
-               
-               if (rv == CKR_OK) {
-                       rv = _pkcs11h_threadStart (
-                               &s_pkcs11h_data->threadSlotEvent,
-                               _pkcs11h_slotevent_manager,
-                               NULL
-                       );
-               }
-               
-               if (rv == CKR_OK) {
-                       s_pkcs11h_data->fSlotEventInitialized = TRUE;
-               }
-       }
-
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: _pkcs11h_slotevent_init return rv=%ld-'%s'",
-               rv,
-               pkcs11h_getMessage (rv)
-       );
-
-       return rv;
-}
-
-static
-CK_RV
-_pkcs11h_slotevent_notify () {
-       
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: _pkcs11h_slotevent_notify entry"
-       );
-
-       if (s_pkcs11h_data->fSlotEventInitialized) {
-               s_pkcs11h_data->fSlotEventSkipEvent = TRUE;
-               _pkcs11h_condSignal (&s_pkcs11h_data->condSlotEvent);
-       }
-
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: _pkcs11h_slotevent_notify return"
-       );
-
-       return CKR_OK;
-}
-
-static
-CK_RV
-_pkcs11h_slotevent_terminate () {
-       
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: _pkcs11h_slotevent_terminate entry"
-       );
-
-       if (s_pkcs11h_data->fSlotEventInitialized) {
-               s_pkcs11h_data->fSlotEventShouldTerminate = TRUE;
-
-               _pkcs11h_slotevent_notify ();
-
-               if (s_pkcs11h_data->threadSlotEvent != PKCS11H_THREAD_NULL) {
-                       _pkcs11h_threadJoin (&s_pkcs11h_data->threadSlotEvent);
-               }
-
-               _pkcs11h_condFree (&s_pkcs11h_data->condSlotEvent);
-               s_pkcs11h_data->fSlotEventInitialized = FALSE;
-       }
-
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: _pkcs11h_slotevent_terminate return"
-       );
-
-       return CKR_OK;
-}
-
-#endif
-
-#if defined(ENABLE_PKCS11H_OPENSSL)
-/*======================================================================*
- * OPENSSL INTERFACE
- *======================================================================*/
-
-static
-pkcs11h_openssl_session_t
-_pkcs11h_openssl_get_openssl_session (
-       IN OUT const RSA *rsa
-) {
-       pkcs11h_openssl_session_t session;
-               
-       PKCS11H_ASSERT (rsa!=NULL);
-#if OPENSSL_VERSION_NUMBER < 0x00907000L
-       session = (pkcs11h_openssl_session_t)RSA_get_app_data ((RSA *)rsa);
-#else
-       session = (pkcs11h_openssl_session_t)RSA_get_app_data (rsa);
-#endif
-       PKCS11H_ASSERT (session!=NULL);
-
-       return session;
-}
-
-static
-pkcs11h_certificate_t
-_pkcs11h_openssl_get_pkcs11h_certificate (
-       IN OUT const RSA *rsa
-) {
-       pkcs11h_openssl_session_t session = _pkcs11h_openssl_get_openssl_session (rsa);
-       
-       PKCS11H_ASSERT (session!=NULL);
-       PKCS11H_ASSERT (session->certificate!=NULL);
-
-       return session->certificate;
-}
-
-#if OPENSSL_VERSION_NUMBER < 0x00907000L
-static
-int
-_pkcs11h_openssl_dec (
-       IN int flen,
-       IN unsigned char *from,
-       OUT unsigned char *to,
-       IN OUT RSA *rsa,
-       IN int padding
-) {
-#else
-static
-int
-_pkcs11h_openssl_dec (
-       IN int flen,
-       IN const unsigned char *from,
-       OUT unsigned char *to,
-       IN OUT RSA *rsa,
-       IN int padding
-) {
-#endif
-       PKCS11H_ASSERT (from!=NULL);
-       PKCS11H_ASSERT (to!=NULL);
-       PKCS11H_ASSERT (rsa!=NULL);
-
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: _pkcs11h_openssl_dec entered - flen=%d, from=%p, to=%p, rsa=%p, padding=%d",
-               flen,
-               from,
-               to,
-               (void *)rsa,
-               padding
-       );
-
-       PKCS11H_LOG (
-               PKCS11H_LOG_ERROR,
-               "PKCS#11: Private key decryption is not supported"
-       );
-
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: _pkcs11h_openssl_dec return"
-       );
-
-       return -1;
-}
-
-#if OPENSSL_VERSION_NUMBER < 0x00907000L
-static
-int
-_pkcs11h_openssl_sign (
-       IN int type,
-       IN unsigned char *m,
-       IN unsigned int m_len,
-       OUT unsigned char *sigret,
-       OUT unsigned int *siglen,
-       IN OUT RSA *rsa
-) {
-#else
-static
-int
-_pkcs11h_openssl_sign (
-       IN int type,
-       IN const unsigned char *m,
-       IN unsigned int m_len,
-       OUT unsigned char *sigret,
-       OUT unsigned int *siglen,
-       IN OUT const RSA *rsa
-) {
-#endif
-       pkcs11h_certificate_t certificate = _pkcs11h_openssl_get_pkcs11h_certificate (rsa);
-       CK_RV rv = CKR_OK;
-
-       int myrsa_size = 0;
-       
-       unsigned char *enc_alloc = NULL;
-       unsigned char *enc = NULL;
-       int enc_len = 0;
-
-       PKCS11H_ASSERT (m!=NULL);
-       PKCS11H_ASSERT (sigret!=NULL);
-       PKCS11H_ASSERT (siglen!=NULL);
-
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: _pkcs11h_openssl_sign entered - type=%d, m=%p, m_len=%u, signret=%p, signlen=%p, rsa=%p",
-               type,
-               m,
-               m_len,
-               sigret,
-               (void *)siglen,
-               (void *)rsa
-       );
-
-       if (rv == CKR_OK) {
-               myrsa_size=RSA_size(rsa);
-       }
-
-       if (type == NID_md5_sha1) {
-               if (rv == CKR_OK) {
-                       enc = (unsigned char *)m;
-                       enc_len = m_len;
-               }
-       }
-       else {
-               X509_SIG sig;
-               ASN1_TYPE parameter;
-               X509_ALGOR algor;
-               ASN1_OCTET_STRING digest;
-
-               if (
-                       rv == CKR_OK &&
-                       (rv = _pkcs11h_malloc ((void*)&enc, myrsa_size+1)) == CKR_OK
-               ) {
-                       enc_alloc = enc;
-               }
-               
-               if (rv == CKR_OK) {
-                       sig.algor = &algor;
-               }
-
-               if (
-                       rv == CKR_OK &&
-                       (sig.algor->algorithm = OBJ_nid2obj (type)) == NULL
-               ) {
-                       rv = CKR_FUNCTION_FAILED;
-               }
-       
-               if (
-                       rv == CKR_OK &&
-                       sig.algor->algorithm->length == 0
-               ) {
-                       rv = CKR_KEY_SIZE_RANGE;
-               }
-       
-               if (rv == CKR_OK) {
-                       parameter.type = V_ASN1_NULL;
-                       parameter.value.ptr = NULL;
-       
-                       sig.algor->parameter = &parameter;
-
-                       sig.digest = &digest;
-                       sig.digest->data = (unsigned char *)m;
-                       sig.digest->length = m_len;
-               }
-       
-               if (
-                       rv == CKR_OK &&
-                       (enc_len=i2d_X509_SIG (&sig, NULL)) < 0
-               ) {
-                       rv = CKR_FUNCTION_FAILED;
-               }
-       
-               if (rv == CKR_OK) {
-                       unsigned char *p = enc;
-                       i2d_X509_SIG (&sig, &p);
-               }
-       }
-
-       if (
-               rv == CKR_OK &&
-               enc_len > (myrsa_size-RSA_PKCS1_PADDING_SIZE)
-       ) {
-               rv = CKR_KEY_SIZE_RANGE;
-       }
-
-       if (rv == CKR_OK) {
-               PKCS11H_DEBUG (
-                       PKCS11H_LOG_DEBUG1,
-                       "PKCS#11: Performing signature"
-               );
-
-               *siglen = myrsa_size;
-
-               if (
-                       (rv = pkcs11h_certificate_signAny (
-                               certificate,
-                               CKM_RSA_PKCS,
-                               enc,
-                               enc_len,
-                               sigret,
-                               siglen
-                       )) != CKR_OK
-               ) {
-                       PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Cannot perform signature %ld:'%s'", rv, pkcs11h_getMessage (rv));
-               }
-       }
-
-       if (enc_alloc != NULL) {
-               _pkcs11h_free ((void *)&enc_alloc);
-       }
-       
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: _pkcs11h_openssl_sign - return rv=%ld-'%s'",
-               rv,
-               pkcs11h_getMessage (rv)
-       );
-
-       return rv == CKR_OK ? 1 : -1; 
-}
-
-static
-int
-_pkcs11h_openssl_finish (
-       IN OUT RSA *rsa
-) {
-       pkcs11h_openssl_session_t openssl_session = _pkcs11h_openssl_get_openssl_session (rsa);
-
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: _pkcs11h_openssl_finish - entered rsa=%p",
-               (void *)rsa
-       );
-
-       RSA_set_app_data (rsa, NULL);
-       
-       if (openssl_session->orig_finish != NULL) {
-               openssl_session->orig_finish (rsa);
-
-#ifdef BROKEN_OPENSSL_ENGINE
-               {
-                       /* We get called TWICE here, once for
-                        * releasing the key and also for
-                        * releasing the engine.
-                        * To prevent endless recursion, FIRST
-                        * clear rsa->engine, THEN call engine->finish
-                        */
-                       ENGINE *e = rsa->engine;
-                       rsa->engine = NULL;
-                       if (e) {
-                               ENGINE_finish(e);
-                       }
-               }
-#endif
-       }
-
-       pkcs11h_openssl_freeSession (openssl_session);
-
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: _pkcs11h_openssl_finish - return"
-       );
-       
-       return 1;
-}
-
-pkcs11h_openssl_session_t
-pkcs11h_openssl_createSession (
-       IN const pkcs11h_certificate_t certificate
-) {
-       pkcs11h_openssl_session_t openssl_session = NULL;
-       PKCS11H_BOOL fOK = TRUE;
-
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: pkcs11h_openssl_createSession - entry"
-       );
-
-       if (
-               fOK &&
-               _pkcs11h_malloc (
-                       (void*)&openssl_session,
-                       sizeof (struct pkcs11h_openssl_session_s)) != CKR_OK
-       ) {
-               fOK = FALSE;
-               PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Cannot allocate memory");
-       }
-
-       if (fOK) {
-               const RSA_METHOD *def = RSA_get_default_method();
-
-               memmove (&openssl_session->smart_rsa, def, sizeof(RSA_METHOD));
-
-               openssl_session->orig_finish = def->finish;
-
-               openssl_session->smart_rsa.name = "pkcs11";
-               openssl_session->smart_rsa.rsa_priv_dec = _pkcs11h_openssl_dec;
-               openssl_session->smart_rsa.rsa_sign = _pkcs11h_openssl_sign;
-               openssl_session->smart_rsa.finish = _pkcs11h_openssl_finish;
-               openssl_session->smart_rsa.flags  = RSA_METHOD_FLAG_NO_CHECK | RSA_FLAG_EXT_PKEY;
-               openssl_session->certificate = certificate;
-               openssl_session->nReferenceCount = 1;
-       }
-
-       if (!fOK) {
-               _pkcs11h_free ((void *)&openssl_session);
-       }
-       
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: pkcs11h_openssl_createSession - return openssl_session=%p",
-               (void *)openssl_session
-       );
-
-       return openssl_session;
-}
-
-void
-pkcs11h_openssl_freeSession (
-       IN const pkcs11h_openssl_session_t openssl_session
-) {
-       PKCS11H_ASSERT (openssl_session!=NULL);
-       PKCS11H_ASSERT (openssl_session->nReferenceCount>0);
-       
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: pkcs11h_openssl_freeSession - entry openssl_session=%p, count=%d",
-               (void *)openssl_session,
-               openssl_session->nReferenceCount
-       );
-
-       openssl_session->nReferenceCount--;
-       
-       if (openssl_session->nReferenceCount == 0) {
-               if (openssl_session->x509 != NULL) {
-                       X509_free (openssl_session->x509);
-                       openssl_session->x509 = NULL;
-               }
-               if (openssl_session->certificate != NULL) {
-                       pkcs11h_freeCertificate (openssl_session->certificate);
-                       openssl_session->certificate = NULL;
-               }
-               
-               _pkcs11h_free ((void *)&openssl_session);
-       }
-
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: pkcs11h_openssl_freeSession - return"
-       );
-}
-
-RSA *
-pkcs11h_openssl_getRSA (
-       IN const pkcs11h_openssl_session_t openssl_session
-) {
-       X509 *x509 = NULL;
-       RSA *rsa = NULL;
-       EVP_PKEY *pubkey = NULL;
-       CK_RV rv = CKR_OK;
-
-       pkcs11_openssl_d2i_t d2i1 = NULL;
-       PKCS11H_BOOL fOK = TRUE;
-
-       PKCS11H_ASSERT (openssl_session!=NULL);
-       PKCS11H_ASSERT (!openssl_session->fInitialized);
-       PKCS11H_ASSERT (openssl_session!=NULL);
-
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: pkcs11h_openssl_getRSA - entry openssl_session=%p",
-               (void *)openssl_session
-       );
-
-       if (
-               fOK &&
-               (x509 = X509_new ()) == NULL
-       ) {
-               fOK = FALSE;
-               PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Unable to allocate certificate object");
-       }
-
-       if (
-               fOK &&
-               (rv = _pkcs11h_ensureCertificateBlob (openssl_session->certificate)) != CKR_OK
-       ) {
-               fOK = FALSE;
-               PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Cannot read X.509 certificate from token %ld-'%s'", rv, pkcs11h_getMessage (rv));
-       }
-
-       d2i1 = (pkcs11_openssl_d2i_t)openssl_session->certificate->id->certificate_blob;
-       if (
-               fOK &&
-               !d2i_X509 (&x509, &d2i1, openssl_session->certificate->id->certificate_blob_size)
-       ) {
-               fOK = FALSE;
-               PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Unable to parse X.509 certificate");
-       }
-
-       if (
-               fOK &&
-               (pubkey = X509_get_pubkey (x509)) == NULL
-       ) {
-               fOK = FALSE;
-               PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Cannot get public key");
-       }
-       
-       if (
-               fOK &&
-               pubkey->type != EVP_PKEY_RSA
-       ) {
-               fOK = FALSE;
-               PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Invalid public key algorithm");
-       }
-
-       if (
-               fOK &&
-               (rsa = EVP_PKEY_get1_RSA (pubkey)) == NULL
-       ) {
-               fOK = FALSE;
-               PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Cannot get RSA key");
-       }
-
-       if (fOK) {
-
-               RSA_set_method (rsa, &openssl_session->smart_rsa);
-               RSA_set_app_data (rsa, openssl_session);
-               openssl_session->nReferenceCount++;
-       }
-       
-#ifdef BROKEN_OPENSSL_ENGINE
-       if (fOK) {
-               if (!rsa->engine) {
-                       rsa->engine = ENGINE_get_default_RSA();
-               }
-
-               ENGINE_set_RSA(ENGINE_get_default_RSA(), &openssl_session->smart_rsa);
-               PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: OpenSSL engine support is broken! Workaround enabled");
-       }
-#endif
-               
-       if (fOK) {
-               /*
-                * dup x509 so that it won't hold RSA
-                */
-               openssl_session->x509 = X509_dup (x509);
-               rsa->flags |= RSA_FLAG_SIGN_VER;
-               openssl_session->fInitialized = TRUE;
-       }
-       else {
-               if (rsa != NULL) {
-                       RSA_free (rsa);
-                       rsa = NULL;
-               }
-       }
-
-       /*
-        * openssl objects have reference
-        * count, so release them
-        */
-       if (pubkey != NULL) {
-               EVP_PKEY_free (pubkey);
-               pubkey = NULL;
-       }
-
-       if (x509 != NULL) {
-               X509_free (x509);
-               x509 = NULL;
-       }
-       
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: pkcs11h_openssl_getRSA - return rsa=%p",
-               (void *)rsa
-       );
-
-       return rsa;
-}
-
-X509 *
-pkcs11h_openssl_getX509 (
-       IN const pkcs11h_openssl_session_t openssl_session
-) {
-       X509 *x509 = NULL;
-       
-       PKCS11H_ASSERT (openssl_session!=NULL);
-
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: pkcs11h_openssl_getX509 - entry openssl_session=%p",
-               (void *)openssl_session
-       );
-
-       if (openssl_session->x509 != NULL) {
-               x509 = X509_dup (openssl_session->x509);
-       }
-       
-       PKCS11H_DEBUG (
-               PKCS11H_LOG_DEBUG2,
-               "PKCS#11: pkcs11h_openssl_getX509 - return x509=%p",
-               (void *)x509
-       );
-
-       return x509;
-}
-
-#endif                         /* ENABLE_PKCS11H_OPENSSL */
-
-#if defined(ENABLE_PKCS11H_STANDALONE)
-/*======================================================================*
- * STANDALONE INTERFACE
- *======================================================================*/
-
-void
-pkcs11h_standalone_dump_slots (
-       IN const pkcs11h_output_print_t my_output,
-       IN const void *pData,
-       IN const char * const provider
-) {
-       CK_RV rv = CKR_OK;
-
-       pkcs11h_provider_t pkcs11h_provider;
-
-       PKCS11H_ASSERT (my_output!=NULL);
-       /*PKCS11H_ASSERT (pData) NOT NEEDED */
-       PKCS11H_ASSERT (provider!=NULL);
-
-       if (
-               rv == CKR_OK &&
-               (rv = pkcs11h_initialize ()) != CKR_OK
-       ) {
-               my_output (pData, "PKCS#11: Cannot initialize interface %ld-'%s'\n", rv, pkcs11h_getMessage (rv));
-       }
-
-       if (
-               rv == CKR_OK &&
-               (rv = pkcs11h_addProvider (
-                       provider,
-                       provider,
-                       FALSE,
-                       (
-                               PKCS11H_SIGNMODE_MASK_SIGN |
-                               PKCS11H_SIGNMODE_MASK_RECOVER
-                       ),
-                       PKCS11H_SLOTEVENT_METHOD_AUTO,
-                       0,
-                       FALSE
-               )) != CKR_OK
-       ) {
-               my_output (pData, "PKCS#11: Cannot initialize provider %ld-'%s'\n", rv, pkcs11h_getMessage (rv));
-       }
-
-       /*
-        * our provider is head
-        */
-       if (rv == CKR_OK) {
-               pkcs11h_provider = s_pkcs11h_data->providers;
-               if (pkcs11h_provider == NULL || !pkcs11h_provider->fEnabled) {
-                       my_output (pData, "PKCS#11: Cannot get provider %ld-'%s'\n", rv, pkcs11h_getMessage (rv));
-                       rv = CKR_GENERAL_ERROR;
-               }
-       }
-
-       if (rv == CKR_OK) {
-               CK_INFO info;
-               
-               if ((rv = pkcs11h_provider->f->C_GetInfo (&info)) != CKR_OK) {
-                       my_output (pData, "PKCS#11: Cannot get PKCS#11 provider information %ld-'%s'\n", rv, pkcs11h_getMessage (rv));
-                       rv = CKR_OK;
-               }
-               else {
-                       char szManufacturerID[sizeof (info.manufacturerID)+1];
-       
-                       _pkcs11h_fixupFixedString (
-                               szManufacturerID,
-                               (char *)info.manufacturerID,
-                               sizeof (info.manufacturerID)
-                       );
-       
-                       my_output (
-                               pData,
-                               (
-                                       "Provider Information:\n"
-                                       "\tcryptokiVersion:\t%u.%u\n"
-                                       "\tmanufacturerID:\t\t%s\n"
-                                       "\tflags:\t\t\t%d\n"
-                                       "\n"
-                               ),
-                               info.cryptokiVersion.major,
-                               info.cryptokiVersion.minor,
-                               szManufacturerID,
-                               (unsigned)info.flags
-                       );
-               }
-       }
-       
-       if (rv == CKR_OK) {
-               CK_SLOT_ID_PTR slots = NULL;
-               CK_ULONG slotnum;
-               CK_SLOT_ID slot_index;
-               
-               if (
-                        _pkcs11h_getSlotList (
-                               pkcs11h_provider,
-                               CK_FALSE,
-                               &slots,
-                               &slotnum
-                       ) != CKR_OK
-               ) {
-                       my_output (pData, "PKCS#11: Cannot get slot list %ld-'%s'\n", rv, pkcs11h_getMessage (rv));
-               }
-               else {
-                       my_output (
-                               pData,
-                               (
-                                       "The following slots are available for use with this provider.\n"
-                                       "Each slot shown below may be used as a parameter to a\n"
-                                       "%s and %s options.\n"
-                                       "\n"
-                                       "Slots: (id - name)\n"
-                               ),
-                               PKCS11H_PRM_SLOT_TYPE,
-                               PKCS11H_PRM_SLOT_ID
-                       );
-                       for (slot_index=0;slot_index < slotnum;slot_index++) {
-                               CK_SLOT_INFO info;
-       
-                               if (
-                                       (rv = pkcs11h_provider->f->C_GetSlotInfo (
-                                               slots[slot_index],
-                                               &info
-                                       )) == CKR_OK
-                               ) {
-                                       char szCurrentName[sizeof (info.slotDescription)+1];
-                               
-                                       _pkcs11h_fixupFixedString (
-                                               szCurrentName,
-                                               (char *)info.slotDescription,
-                                               sizeof (info.slotDescription)
-                                       );
-       
-                                       my_output (pData, "\t%lu - %s\n", slots[slot_index], szCurrentName);
-                               }
-                       }
-               }
-
-               if (slots != NULL) {
-                       _pkcs11h_free ((void *)&slots);
-               }
-       }
-       
-       pkcs11h_terminate ();
-}
-
-static
-PKCS11H_BOOL
-_pkcs11h_standalone_dump_objects_pin_prompt (
-       IN const void *pData,
-       IN const pkcs11h_token_id_t token,
-       IN const unsigned retry,
-       OUT char * const szPIN,
-       IN const size_t nMaxPIN
-) {
-       /*
-        * Don't lock card
-        */
-       if (retry == 0) {
-               strncpy (szPIN, (char *)pData, nMaxPIN);
-               return TRUE;
-       }
-       else {
-               return FALSE;
-       }
-}
-
-void
-_pkcs11h_standalone_dump_objects_hex (
-       IN const unsigned char * const p,
-       IN const size_t p_size,
-       OUT char * const sz,
-       IN const size_t max,
-       IN const char * const szLinePrefix
-) {
-       size_t j;
-
-       sz[0] = '\0';
-
-       for (j=0;j<p_size;j+=16) {
-               char szLine[3*16+1];
-               size_t k;
-
-               szLine[0] = '\0';
-               for (k=0;k<16 && j+k<p_size;k++) {
-                       sprintf (szLine+strlen (szLine), "%02x ", p[j+k]);
-               }
-
-               strncat (
-                       sz,
-                       szLinePrefix,
-                       max-1-strlen (sz)
-               );
-               strncat (
-                       sz,
-                       szLine,
-                       max-1-strlen (sz)
-               );
-               strncat (
-                       sz,
-                       "\n",
-                       max-1-strlen (sz)
-               );
-       }
-
-       sz[max-1] = '\0';
-}
-       
-void
-pkcs11h_standalone_dump_objects (
-       IN const pkcs11h_output_print_t my_output,
-       IN const void *pData,
-       IN const char * const provider,
-       IN const char * const slot,
-       IN const char * const pin
-) {
-       CK_SLOT_ID s;
-       CK_RV rv = CKR_OK;
-
-       pkcs11h_provider_t pkcs11h_provider = NULL;
-       pkcs11h_token_id_t token_id = NULL;
-       pkcs11h_session_t session = NULL;
-
-       PKCS11H_ASSERT (my_output!=NULL);
-       /*PKCS11H_ASSERT (pData) NOT NEEDED */
-       PKCS11H_ASSERT (provider!=NULL);
-       PKCS11H_ASSERT (slot!=NULL);
-       PKCS11H_ASSERT (pin!=NULL);
-
-       s = atoi (slot);
-
-       if (
-               rv == CKR_OK &&
-               (rv = pkcs11h_initialize ()) != CKR_OK
-       ) {
-               my_output (pData, "PKCS#11: Cannot initialize interface %ld-'%s'\n", rv, pkcs11h_getMessage (rv));
-       }
-
-       if (
-               rv == CKR_OK &&
-               (rv = pkcs11h_setPINPromptHook (_pkcs11h_standalone_dump_objects_pin_prompt, (void *)pin)) != CKR_OK
-       ) {
-               my_output (pData, "PKCS#11: Cannot set hooks %ld-'%s'\n", rv, pkcs11h_getMessage (rv));
-       }
-
-       if (
-               rv == CKR_OK &&
-               (rv = pkcs11h_addProvider (
-                       provider,
-                       provider,
-                       FALSE,
-                       (
-                               PKCS11H_SIGNMODE_MASK_SIGN |
-                               PKCS11H_SIGNMODE_MASK_RECOVER
-                       ),
-                       PKCS11H_SLOTEVENT_METHOD_AUTO,
-                       0,
-                       FALSE
-               )) != CKR_OK
-       ) {
-               my_output (pData, "PKCS#11: Cannot initialize provider %ld-'%s'\n", rv, pkcs11h_getMessage (rv));
-       }
-
-       /*
-        * our provider is head
-        */
-       if (rv == CKR_OK) {
-               pkcs11h_provider = s_pkcs11h_data->providers;
-               if (pkcs11h_provider == NULL || !pkcs11h_provider->fEnabled) {
-                       my_output (pData, "PKCS#11: Cannot get provider %ld-'%s'\n", rv, pkcs11h_getMessage (rv));
-                       rv = CKR_GENERAL_ERROR;
-               }
-       }
-
-       if (rv == CKR_OK) {
-               CK_TOKEN_INFO info;
-               
-               if (
-                       (rv = pkcs11h_provider->f->C_GetTokenInfo (
-                               s,
-                               &info
-                       )) != CKR_OK
-               ) {
-                       my_output (pData, "PKCS#11: Cannot get token information for slot %ld %ld-'%s'\n", s, rv, pkcs11h_getMessage (rv));
-                       /* Ignore this error */
-                       rv = CKR_OK;
-               }
-               else {
-                       char szLabel[sizeof (info.label)+1];
-                       char szManufacturerID[sizeof (info.manufacturerID)+1];
-                       char szModel[sizeof (info.model)+1];
-                       char szSerialNumber[sizeof (info.serialNumber)+1];
-                       
-                       _pkcs11h_fixupFixedString (
-                               szLabel,
-                               (char *)info.label,
-                               sizeof (info.label)
-                       );
-                       _pkcs11h_fixupFixedString (
-                               szManufacturerID,
-                               (char *)info.manufacturerID,
-                               sizeof (info.manufacturerID)
-                       );
-                       _pkcs11h_fixupFixedString (
-                               szModel,
-                               (char *)info.model,
-                               sizeof (info.model)
-                       );
-                       _pkcs11h_fixupFixedString (
-                               szSerialNumber,
-                               (char *)info.serialNumber,
-                               sizeof (info.serialNumber)
-                       );
-       
-                       my_output (
-                               pData,
-                               (
-                                       "Token Information:\n"
-                                       "\tlabel:\t\t%s\n"
-                                       "\tmanufacturerID:\t%s\n"
-                                       "\tmodel:\t\t%s\n"
-                                       "\tserialNumber:\t%s\n"
-                                       "\tflags:\t\t%08x\n"
-                                       "\n"
-                                       "You can access this token using\n"
-                                       "%s \"label\" %s \"%s\" options.\n"
-                                       "\n"
-                               ),
-                               szLabel,
-                               szManufacturerID,
-                               szModel,
-                               szSerialNumber,
-                               (unsigned)info.flags,
-                               PKCS11H_PRM_SLOT_TYPE,
-                               PKCS11H_PRM_SLOT_ID,
-                               szLabel
-                       );
-
-                       if (
-                               rv == CKR_OK &&
-                               (rv = _pkcs11h_getTokenId (
-                                       &info,
-                                       &token_id
-                               )) != CKR_OK
-                       ) {
-                               my_output (pData, "PKCS#11: Cannot get token id for slot %ld %ld-'%s'\n", s, rv, pkcs11h_getMessage (rv));              
-                               rv = CKR_OK;
-                       }
-               }
-       }
-
-       if (token_id != NULL) {
-               if (
-                       (rv = _pkcs11h_getSessionByTokenId (
-                               token_id,
-                               &session
-                       )) != CKR_OK
-               ) {
-                       my_output (pData, "PKCS#11: Cannot session for token '%s' %ld-'%s'\n", token_id->label, rv, pkcs11h_getMessage (rv));           
-                       rv = CKR_OK;
-               }
-       }
-
-       if (session != NULL) {
-               CK_OBJECT_HANDLE *objects = NULL;
-               CK_ULONG objects_found = 0;
-               CK_ULONG i;
-
-               if (
-                       (rv = _pkcs11h_login (
-                               session,
-                               FALSE,
-                               TRUE,
-                               PKCS11H_PROMPT_MASK_ALLOW_PIN_PROMPT
-                       )) != CKR_OK
-               ) {
-                       my_output (pData, "PKCS#11: Cannot open session to token '%s' %ld-'%s'\n", session->token_id->label, rv, pkcs11h_getMessage (rv));
-               }
-       
-               my_output (
-                       pData,
-                       (
-                               "The following objects are available for use with this token.\n"
-                               "Each object shown below may be used as a parameter to\n"
-                               "%s and %s options.\n"
-                               "\n"
-                       ),
-                       PKCS11H_PRM_OBJ_TYPE,
-                       PKCS11H_PRM_OBJ_ID
-               );
-
-               if (
-                       rv == CKR_OK &&
-                       (rv = _pkcs11h_findObjects (
-                               session,
-                               NULL,
-                               0,
-                               &objects,
-                               &objects_found
-                       )) != CKR_OK
-               ) {
-                       my_output (pData, "PKCS#11: Cannot query objects for token '%s' %ld-'%s'\n", session->token_id->label, rv, pkcs11h_getMessage (rv));
-               }
-       
-               for (i=0;rv == CKR_OK && i < objects_found;i++) {
-                       CK_OBJECT_CLASS attrs_class = 0;
-                       CK_ATTRIBUTE attrs[] = {
-                               {CKA_CLASS, &attrs_class, sizeof (attrs_class)}
-                       };
-
-                       if (
-                               _pkcs11h_getObjectAttributes (
-                                       session,
-                                       objects[i],
-                                       attrs,
-                                       sizeof (attrs) / sizeof (CK_ATTRIBUTE)
-                               ) == CKR_OK
-                       ) {
-                               if (attrs_class == CKO_CERTIFICATE) {
-                                       CK_ATTRIBUTE attrs_cert[] = {
-                                               {CKA_ID, NULL, 0},
-                                               {CKA_LABEL, NULL, 0},
-                                               {CKA_VALUE, NULL, 0}
-                                       };
-                                       unsigned char *attrs_id = NULL;
-                                       int attrs_id_size = 0;
-                                       unsigned char *attrs_value = NULL;
-                                       int attrs_value_size = 0;
-                                       char *attrs_label = NULL;
-                                       char szHexId[1024];
-                                       char szSubject[1024];
-                                       char szSerial[1024];
-                                       char szNotBefore[1024];
-
-                                       szSubject[0] = '\0';
-                                       szSerial[0] = '\0';
-                                       szNotBefore[0] = '\0';
-
-
-                                       if (
-                                               _pkcs11h_getObjectAttributes (
-                                                       session,
-                                                       objects[i],
-                                                       attrs_cert,
-                                                       sizeof (attrs_cert) / sizeof (CK_ATTRIBUTE)
-                                               ) == CKR_OK &&
-                                               _pkcs11h_malloc (
-                                                       (void *)&attrs_label,
-                                                       attrs_cert[1].ulValueLen+1
-                                               ) == CKR_OK
-                                       ) {
-                                               attrs_id = (unsigned char *)attrs_cert[0].pValue;
-                                               attrs_id_size = attrs_cert[0].ulValueLen;
-                                               attrs_value = (unsigned char *)attrs_cert[2].pValue;
-                                               attrs_value_size = attrs_cert[2].ulValueLen;
-
-                                               memset (attrs_label, 0, attrs_cert[1].ulValueLen+1);
-                                               memmove (attrs_label, attrs_cert[1].pValue, attrs_cert[1].ulValueLen);
-                                               _pkcs11h_standalone_dump_objects_hex (
-                                                       attrs_id,
-                                                       attrs_id_size,
-                                                       szHexId,
-                                                       sizeof (szHexId),
-                                                       "\t\t"
-                                               );
-                                       }
-
-                                       if (attrs_value != NULL) {
-                                               X509 *x509 = NULL;
-                                               BIO *bioSerial = NULL;
-
-                                               if ((x509 = X509_new ()) == NULL) {
-                                                       my_output (pData, "Cannot create x509 context\n");
-                                               }
-                                               else {
-                                                       pkcs11_openssl_d2i_t d2i1 = (pkcs11_openssl_d2i_t)attrs_value;
-                                                       if (d2i_X509 (&x509, &d2i1, attrs_value_size)) {
-
-                                                               ASN1_TIME *notBefore = X509_get_notBefore (x509);
-                                                               if (notBefore != NULL && notBefore->length < (int) sizeof (szNotBefore) - 1) {
-                                                                       memmove (szNotBefore, notBefore->data, notBefore->length);
-                                                                       szNotBefore[notBefore->length] = '\0';
-                                                               }
-
-                                                               X509_NAME_oneline (
-                                                                       X509_get_subject_name (x509),
-                                                                       szSubject,
-                                                                       sizeof (szSubject)
-                                                               );
-                                                               szSubject[sizeof (szSubject) - 1] = '\0';
-                                                       }
-                                               }
-
-                                               if ((bioSerial = BIO_new (BIO_s_mem ())) == NULL) {
-                                                       my_output (pData, "Cannot create BIO context\n");
-                                               }
-                                               else {
-                                                       int n;
-
-                                                       i2a_ASN1_INTEGER(bioSerial, X509_get_serialNumber (x509));
-                                                       n = BIO_read (bioSerial, szSerial, sizeof (szSerial)-1);
-                                                       if (n<0) {
-                                                               szSerial[0] = '\0';
-                                                       }
-                                                       else {
-                                                               szSerial[n] = '\0';
-                                                       }
-                                               }
-
-                                               if (x509 != NULL) {
-                                                       X509_free (x509);
-                                                       x509 = NULL;
-                                               }
-                                               if (bioSerial != NULL) {
-                                                       BIO_free_all (bioSerial);
-                                                       bioSerial = NULL;
-                                               }
-                                       }
-
-                                       my_output (
-                                               pData,
-                                               (
-                                                       "Object\n"
-                                                       "\tType:\t\t\tCertificate\n"
-                                                       "\tCKA_ID:\n"
-                                                       "%s"
-                                                       "\tCKA_LABEL:\t\t%s\n"
-                                                       "\tsubject:\t\t%s\n"
-                                                       "\tserialNumber:\t\t%s\n"
-                                                       "\tnotBefore:\t\t%s\n"
-                                               ),
-                                               szHexId,
-                                               attrs_label,
-                                               szSubject,
-                                               szSerial,
-                                               szNotBefore
-                                       );
-
-                                       _pkcs11h_free ((void *)&attrs_label);
-
-                                       _pkcs11h_freeObjectAttributes (
-                                               attrs_cert,
-                                               sizeof (attrs_cert) / sizeof (CK_ATTRIBUTE)
-                                       );
-                               }
-                               else if (attrs_class == CKO_PRIVATE_KEY) {
-                                       CK_BBOOL sign_recover = CK_FALSE;
-                                       CK_BBOOL sign = CK_FALSE;
-                                       CK_ATTRIBUTE attrs_key[] = {
-                                               {CKA_SIGN, &sign, sizeof (sign)},
-                                               {CKA_SIGN_RECOVER, &sign_recover, sizeof (sign_recover)}
-                                       };
-                                       CK_ATTRIBUTE attrs_key_common[] = {
-                                               {CKA_ID, NULL, 0},
-                                               {CKA_LABEL, NULL, 0}
-                                       };
-                                       unsigned char *attrs_id = NULL;
-                                       int attrs_id_size = 0;
-                                       char *attrs_label = NULL;
-                                       char szHexId[1024];
-
-                                       pkcs11h_provider->f->C_GetAttributeValue (
-                                               session->hSession,
-                                               objects[i],
-                                               attrs_key,
-                                               sizeof (attrs_key) / sizeof (CK_ATTRIBUTE)
-                                       );
-
-                                       if (
-                                               _pkcs11h_getObjectAttributes (
-                                                       session,
-                                                       objects[i],
-                                                       attrs_key_common,
-                                                       sizeof (attrs_key_common) / sizeof (CK_ATTRIBUTE)
-                                               ) == CKR_OK &&
-                                               _pkcs11h_malloc (
-                                                       (void *)&attrs_label,
-                                                       attrs_key_common[1].ulValueLen+1
-                                               ) == CKR_OK
-                                       ) {
-                                               attrs_id = (unsigned char *)attrs_key_common[0].pValue;
-                                               attrs_id_size = attrs_key_common[0].ulValueLen;
-
-                                               memset (attrs_label, 0, attrs_key_common[1].ulValueLen+1);
-                                               memmove (attrs_label, attrs_key_common[1].pValue, attrs_key_common[1].ulValueLen);
-
-                                               _pkcs11h_standalone_dump_objects_hex (
-                                                       attrs_id,
-                                                       attrs_id_size,
-                                                       szHexId,
-                                                       sizeof (szHexId),
-                                                       "\t\t"
-                                               );
-                                                       
-                                       }
-
-                                       my_output (
-                                               pData,
-                                               (
-                                                       "Object\n"
-                                                       "\tType:\t\t\tPrivate Key\n"
-                                                       "\tCKA_ID:\n"
-                                                       "%s"
-                                                       "\tCKA_LABEL:\t\t%s\n"
-                                                       "\tCKA_SIGN:\t\t%s\n"
-                                                       "\tCKA_SIGN_RECOVER:\t%s\n"
-                                               ),
-                                               szHexId,
-                                               attrs_label,
-                                               sign ? "TRUE" : "FALSE",
-                                               sign_recover ? "TRUE" : "FALSE"
-                                       );
-
-                                       _pkcs11h_free ((void *)&attrs_label);
-
-                                       _pkcs11h_freeObjectAttributes (
-                                               attrs_key_common,
-                                               sizeof (attrs_key_common) / sizeof (CK_ATTRIBUTE)
-                                       );
-                               }
-                               else if (attrs_class == CKO_PUBLIC_KEY) {
-                                       CK_ATTRIBUTE attrs_key_common[] = {
-                                               {CKA_ID, NULL, 0},
-                                               {CKA_LABEL, NULL, 0}
-                                       };
-                                       unsigned char *attrs_id = NULL;
-                                       int attrs_id_size = 0;
-                                       char *attrs_label = NULL;
-                                       char szHexId[1024];
-
-                                       if (
-                                               _pkcs11h_getObjectAttributes (
-                                                       session,
-                                                       objects[i],
-                                                       attrs_key_common,
-                                                       sizeof (attrs_key_common) / sizeof (CK_ATTRIBUTE)
-                                               ) == CKR_OK &&
-                                               _pkcs11h_malloc (
-                                                       (void *)&attrs_label,
-                                                       attrs_key_common[1].ulValueLen+1
-                                               ) == CKR_OK
-                                       ) {
-                                               attrs_id = (unsigned char *)attrs_key_common[0].pValue;
-                                               attrs_id_size = attrs_key_common[0].ulValueLen;
-
-                                               memset (attrs_label, 0, attrs_key_common[1].ulValueLen+1);
-                                               memmove (attrs_label, attrs_key_common[1].pValue, attrs_key_common[1].ulValueLen);
-
-                                               _pkcs11h_standalone_dump_objects_hex (
-                                                       attrs_id,
-                                                       attrs_id_size,
-                                                       szHexId,
-                                                       sizeof (szHexId),
-                                                       "\t\t"
-                                               );
-                                                       
-                                       }
-
-                                       my_output (
-                                               pData,
-                                               (
-                                                       "Object\n"
-                                                       "\tType:\t\t\tPublic Key\n"
-                                                       "\tCKA_ID:\n"
-                                                       "%s"
-                                                       "\tCKA_LABEL:\t\t%s\n"
-                                               ),
-                                               szHexId,
-                                               attrs_label
-                                       );
-
-                                       _pkcs11h_free ((void *)&attrs_label);
-
-                                       _pkcs11h_freeObjectAttributes (
-                                               attrs_key_common,
-                                               sizeof (attrs_key_common) / sizeof (CK_ATTRIBUTE)
-                                       );
-                               }
-                               else if (attrs_class == CKO_DATA) {
-                                       CK_ATTRIBUTE attrs_key_common[] = {
-                                               {CKA_APPLICATION, NULL, 0},
-                                               {CKA_LABEL, NULL, 0}
-                                       };
-                                       char *attrs_application = NULL;
-                                       char *attrs_label = NULL;
-
-                                       if (
-                                               _pkcs11h_getObjectAttributes (
-                                                       session,
-                                                       objects[i],
-                                                       attrs_key_common,
-                                                       sizeof (attrs_key_common) / sizeof (CK_ATTRIBUTE)
-                                               ) == CKR_OK &&
-                                               _pkcs11h_malloc (
-                                                       (void *)&attrs_application,
-                                                       attrs_key_common[0].ulValueLen+1
-                                               ) == CKR_OK &&
-                                               _pkcs11h_malloc (
-                                                       (void *)&attrs_label,
-                                                       attrs_key_common[1].ulValueLen+1
-                                               ) == CKR_OK
-                                       ) {
-                                               memset (attrs_application, 0, attrs_key_common[0].ulValueLen+1);
-                                               memmove (attrs_application, attrs_key_common[0].pValue, attrs_key_common[0].ulValueLen);
-                                               memset (attrs_label, 0, attrs_key_common[1].ulValueLen+1);
-                                               memmove (attrs_label, attrs_key_common[1].pValue, attrs_key_common[1].ulValueLen);
-                                       }
-
-                                       my_output (
-                                               pData,
-                                               (
-                                                       "Object\n"
-                                                       "\tType:\t\t\tData\n"
-                                                       "\tCKA_APPLICATION\t\t%s\n"
-                                                       "\tCKA_LABEL:\t\t%s\n"
-                                               ),
-                                               attrs_application,
-                                               attrs_label
-                                       );
-
-                                       _pkcs11h_free ((void *)&attrs_application);
-                                       _pkcs11h_free ((void *)&attrs_label);
-
-                                       _pkcs11h_freeObjectAttributes (
-                                               attrs_key_common,
-                                               sizeof (attrs_key_common) / sizeof (CK_ATTRIBUTE)
-                                       );
-                               }
-                               else {
-                                       my_output (
-                                               pData,
-                                               (
-                                                       "Object\n"
-                                                       "\tType:\t\t\tUnsupported\n"
-                                               )
-                                       );
-                               }
-                       }
-
-                       _pkcs11h_freeObjectAttributes (
-                               attrs,
-                               sizeof (attrs) / sizeof (CK_ATTRIBUTE)
-                       );
-
-                       /*
-                        * Ignore any error and
-                        * perform next iteration
-                        */
-                       rv = CKR_OK;
-               }
-       
-               if (objects != NULL) {
-                       _pkcs11h_free ((void *)&objects);
-               }
-
-               /*
-                * Ignore this error
-                */
-               rv = CKR_OK;
-       }
-
-       if (session != NULL) {
-               _pkcs11h_releaseSession (session);
-               session = NULL;
-       }
-
-       if (token_id != NULL) {
-               pkcs11h_freeTokenId (token_id);
-               token_id = NULL;
-       }
-       
-       pkcs11h_terminate ();
-}
-
-#endif                         /* ENABLE_PKCS11H_STANDALONE */
-
-#ifdef BROKEN_OPENSSL_ENGINE
-static void broken_openssl_init() __attribute__ ((constructor));
-static void  broken_openssl_init()
-{
-       SSL_library_init();
-       ENGINE_load_openssl();
-       ENGINE_register_all_RSA();
-}
-#endif
-
-#else
-static void dummy (void) {}
-#endif                         /* PKCS11H_HELPER_ENABLE */
-
diff --git a/pkcs11-helper.h b/pkcs11-helper.h
deleted file mode 100644 (file)
index f6eb967..0000000
+++ /dev/null
@@ -1,972 +0,0 @@
-/*
- * Copyright (c) 2005-2006 Alon Bar-Lev <alon.barlev@gmail.com>
- * All rights reserved.
- *
- * This software is available to you under a choice of one of two
- * licenses.  You may choose to be licensed under the terms of the GNU
- * General Public License (GPL) Version 2, or the OpenIB.org BSD license.
- *
- * GNU General Public License (GPL) Version 2
- * ===========================================
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License version 2
- *  as published by the Free Software Foundation.
- *
- *  This program 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 General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program (see the file COPYING[.GPL2] included with this
- *  distribution); if not, write to the Free Software Foundation, Inc.,
- *  59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- *
- * OpenIB.org BSD license
- * =======================
- * Redistribution and use in source and binary forms, with or without modifi-
- * cation, are permitted provided that the following conditions are met:
- *
- *   o  Redistributions of source code must retain the above copyright notice,
- *      this list of conditions and the following disclaimer.
- *
- *   o  Redistributions in binary form must reproduce the above copyright no-
- *      tice, this list of conditions and the following disclaimer in the do-
- *      cumentation and/or other materials provided with the distribution.
- *
- *   o  The names of the contributors 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 REGENTS OR CONTRIBUTORS BE LI-
- * ABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUEN-
- * TIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEV-
- * ER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABI-
- * LITY, 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.
- */
-
-/*
- * The routines in this file deal with providing private key cryptography
- * using RSA Security Inc. PKCS #11 Cryptographic Token Interface (Cryptoki).
- *
- */
-
-#ifndef __PKCS11H_HELPER_H
-#define __PKCS11H_HELPER_H
-
-#if defined(__cplusplus)
-extern "C" {
-#endif
-
-#include "pkcs11-helper-config.h"
-
-#if defined(ENABLE_PKCS11H_SLOTEVENT) && !defined(ENABLE_PKCS11H_THREADING)
-#error PKCS#11: ENABLE_PKCS11H_SLOTEVENT requires ENABLE_PKCS11H_THREADING
-#endif
-#if defined(ENABLE_PKCS11H_OPENSSL) && !defined(ENABLE_PKCS11H_CERTIFICATE)
-#error PKCS#11: ENABLE_PKCS11H_OPENSSL requires ENABLE_PKCS11H_CERTIFICATE
-#endif
-
-#define PKCS11H_LOG_DEBUG2     5
-#define PKCS11H_LOG_DEBUG1     4
-#define PKCS11H_LOG_INFO       3
-#define PKCS11H_LOG_WARN       2
-#define PKCS11H_LOG_ERROR      1
-#define PKCS11H_LOG_QUITE      0
-
-#define PKCS11H_PIN_CACHE_INFINITE     -1
-
-#define PKCS11H_SIGNMODE_MASK_SIGN     (1<<0)
-#define PKCS11H_SIGNMODE_MASK_RECOVER  (1<<1)
-
-#define PKCS11H_PROMPT_MASK_ALLOW_PIN_PROMPT   (1<<0)
-#define PKCS11H_PROMPT_MAST_ALLOW_CARD_PROMPT  (1<<1)
-
-#define PKCS11H_SLOTEVENT_METHOD_AUTO          0
-#define PKCS11H_SLOTEVENT_METHOD_TRIGGER       1
-#define PKCS11H_SLOTEVENT_METHOD_POLL          2
-
-#define PKCS11H_ENUM_METHOD_CACHE              0
-#define PKCS11H_ENUM_METHOD_CACHE_EXIST        1
-#define PKCS11H_ENUM_METHOD_RELOAD             2
-
-typedef void (*pkcs11h_output_print_t)(
-       IN const void *pData,
-       IN const char * const szFormat,
-       IN ...
-)
-#if __GNUC__ > 2
-    __attribute__ ((format (printf, 2, 3)))
-#endif
- ;
-
-struct pkcs11h_token_id_s;
-typedef struct pkcs11h_token_id_s *pkcs11h_token_id_t;
-
-#if defined(ENABLE_PKCS11H_CERTIFICATE)
-
-struct pkcs11h_certificate_id_s;
-struct pkcs11h_certificate_s;
-typedef struct pkcs11h_certificate_id_s *pkcs11h_certificate_id_t;
-typedef struct pkcs11h_certificate_s *pkcs11h_certificate_t;
-
-#endif                         /* ENABLE_PKCS11H_CERTIFICATE */
-
-#if defined(ENABLE_PKCS11H_ENUM)
-
-struct pkcs11h_token_id_list_s;
-typedef struct pkcs11h_token_id_list_s *pkcs11h_token_id_list_t;
-
-#if defined(ENABLE_PKCS11H_DATA)
-
-struct pkcs11h_data_id_list_s;
-typedef struct pkcs11h_data_id_list_s *pkcs11h_data_id_list_t;
-
-#endif                         /* ENABLE_PKCS11H_DATA */
-
-#if defined(ENABLE_PKCS11H_CERTIFICATE)
-
-struct pkcs11h_certificate_id_list_s;
-typedef struct pkcs11h_certificate_id_list_s *pkcs11h_certificate_id_list_t;
-
-#endif                         /* ENABLE_PKCS11H_CERTIFICATE */
-
-#endif                         /* ENABLE_PKCS11H_ENUM */
-
-typedef void (*pkcs11h_hook_log_t)(
-       IN const void *pData,
-       IN const unsigned flags,
-       IN const char * const szFormat,
-       IN va_list args
-);
-
-typedef void (*pkcs11h_hook_slotevent_t)(
-       IN const void *pData
-);
-
-typedef PKCS11H_BOOL (*pkcs11h_hook_token_prompt_t)(
-       IN const void *pData,
-       IN const pkcs11h_token_id_t token,
-       IN const unsigned retry
-);
-
-typedef PKCS11H_BOOL (*pkcs11h_hook_pin_prompt_t)(
-       IN const void *pData,
-       IN const pkcs11h_token_id_t token,
-       IN const unsigned retry,
-       OUT char * const szPIN,
-       IN const size_t nMaxPIN
-);
-
-struct pkcs11h_token_id_s {
-       char label[1024];
-       char manufacturerID[sizeof (((CK_TOKEN_INFO *)NULL)->manufacturerID)+1];
-       char model[sizeof (((CK_TOKEN_INFO *)NULL)->model)+1];
-       char serialNumber[sizeof (((CK_TOKEN_INFO *)NULL)->serialNumber)+1];
-};
-
-#if defined(ENABLE_PKCS11H_CERTIFICATE)
-
-struct pkcs11h_certificate_id_s {
-       pkcs11h_token_id_t token_id;
-
-       char displayName[1024];
-       CK_BYTE_PTR attrCKA_ID;
-       size_t attrCKA_ID_size;
-
-       unsigned char *certificate_blob;
-       size_t certificate_blob_size;
-};
-
-#endif
-
-#if defined(ENABLE_PKCS11H_ENUM)
-
-struct pkcs11h_token_id_list_s {
-       pkcs11h_token_id_list_t next;
-       pkcs11h_token_id_t token_id;
-};
-
-#if defined(ENABLE_PKCS11H_DATA)
-
-struct pkcs11h_data_id_list_s {
-       pkcs11h_data_id_list_t next;
-
-       char *application;
-       char *label;
-};
-
-#endif                         /* ENABLE_PKCS11H_DATA */
-
-#if defined(ENABLE_PKCS11H_CERTIFICATE)
-
-struct pkcs11h_certificate_id_list_s {
-       pkcs11h_certificate_id_list_t next;
-       pkcs11h_certificate_id_t certificate_id;
-};
-
-#endif                         /* ENABLE_PKCS11H_CERTIFICATE */
-
-#endif                         /* ENABLE_PKCS11H_CERTIFICATE */
-
-#if defined(ENABLE_PKCS11H_OPENSSL)
-
-struct pkcs11h_openssl_session_s;
-typedef struct pkcs11h_openssl_session_s *pkcs11h_openssl_session_t;
-
-#endif                         /* ENABLE_PKCS11H_OPENSSL */
-
-/*
- * pkcs11h_getMessage - Get message by return value.
- *
- * Parameters:
- *     rv      - Return value.
- */
-char *
-pkcs11h_getMessage (
-       IN const int rv
-);
-
-/*
- * pkcs11h_initialize - Inititalize helper interface.
- *
- * Must be called once, from main thread.
- * Defaults:
- *     Protected authentication enabled.
- *     PIN cached is infinite.
- */
-CK_RV
-pkcs11h_initialize ();
-
-/*
- * pkcs11h_terminate - Terminate helper interface.
- *
- * Must be called once, from main thread, after all
- * related resources freed.
- */
-CK_RV
-pkcs11h_terminate ();
-
-/*
- * pkcs11h_setLogLevel - Set current log level of the helper.
- *
- * Parameters:
- *     flags   - current log level.
- *
- * The log level can be set to maximum, but setting it to lower
- * level will improve performance.
- */
-void
-pkcs11h_setLogLevel (
-       IN const unsigned flags
-);
-
-/*
- * pkcs11h_getLogLevel - Get current log level.
- */
-unsigned
-pkcs11h_getLogLevel ();
-
-/*
- * pkcs11h_setLogHook - Set a log callback.
- *
- * Parameters:
- *     hook    - Callback.
- *     pData   - Data to send to callback.
- */
-CK_RV
-pkcs11h_setLogHook (
-       IN const pkcs11h_hook_log_t hook,
-       IN void * const pData
-);
-
-/*
- * pkcs11h_setSlotEventHook - Set a slot event callback.
- *
- * Parameters:
- *     hook    - Callback.
- *     pData   - Data to send to callback.
- *
- * Calling this function initialize slot event notifications, these
- * notifications can be started, but never terminate due to PKCS#11 limitation.
- *
- * In order to use slot events you must have threading enabled.
- */
-CK_RV
-pkcs11h_setSlotEventHook (
-       IN const pkcs11h_hook_slotevent_t hook,
-       IN void * const pData
-);
-
-/*
- * pkcs11h_setTokenPromptHook - Set a token prompt callback.
- *
- * Parameters:
- *     hook    - Callback.
- *     pData   - Data to send to callback.
- */
-CK_RV
-pkcs11h_setTokenPromptHook (
-       IN const pkcs11h_hook_token_prompt_t hook,
-       IN void * const pData
-);
-
-/*
- * pkcs11h_setPINPromptHook - Set a pin prompt callback.
- *
- * Parameters:
- *     hook    - Callback.
- *     pData   - Data to send to callback.
- */
-CK_RV
-pkcs11h_setPINPromptHook (
-       IN const pkcs11h_hook_pin_prompt_t hook,
-       IN void * const pData
-);
-
-/*
- * pkcs11h_setProtectedAuthentication - Set global protected authentication mode.
- *
- * Parameters:
- *     fProtectedAuthentication        - Allow protected authentication if enabled by token.
- */
-CK_RV
-pkcs11h_setProtectedAuthentication (
-       IN const PKCS11H_BOOL fProtectedAuthentication
-);
-
-/*
- * pkcs11h_setPINCachePeriod - Set global PIN cache timeout.
- *
- * Parameters:
- *     nPINCachePeriod - Cache period in seconds, or PKCS11H_PIN_CACHE_INFINITE.
- */
-CK_RV
-pkcs11h_setPINCachePeriod (
-       IN const int nPINCachePeriod
-);
-
-/*
- * pkcs11h_setMaxLoginRetries - Set global login retries attempts.
- *
- * Parameters:
- *     nMaxLoginRetries        - Login retries handled by the helper.
- */
-CK_RV
-pkcs11h_setMaxLoginRetries (
-       IN const unsigned nMaxLoginRetries
-);
-
-/*
- * pkcs11h_addProvider - Add a PKCS#11 provider.
- *
- * Parameters:
- *     szReferenceName         - Reference name for this provider.
- *     szProvider              - Provider library location.
- *     fProtectedAuthentication        - Allow this provider to use protected authentication.
- *     maskSignMode            - Provider signmode override.
- *     nSlotEventMethod        - Provider slot event method.
- *     nSlotEventPollInterval  - Slot event poll interval (If in polling mode).
- *     fCertIsPrivate          - Provider's certificate access should be done after login.
- *
- * This function must be called from the main thread.
- *
- * The global fProtectedAuthentication must be enabled in order to allow provider specific.
- * The maskSignMode can be 0 in order to automatically detect key sign mode.
- */
-CK_RV
-pkcs11h_addProvider (
-       IN const char * const szReferenceName,
-       IN const char * const szProvider,
-       IN const PKCS11H_BOOL fProtectedAuthentication,
-       IN const unsigned maskSignMode,
-       IN const int nSlotEventMethod,
-       IN const int nSlotEventPollInterval,
-       IN const PKCS11H_BOOL fCertIsPrivate
-);
-
-/*
- * pkcs11h_delProvider - Delete a PKCS#11 provider.
- *
- * Parameters:
- *     szReferenceName         - Reference name for this provider.
- *
- * This function must be called from the main thread.
- */
-CK_RV
-pkcs11h_removeProvider (
-       IN const char * const szReferenceName
-);
-
-/*
- * pkcs11h_forkFixup - Handle special case of Unix fork()
- *
- * This function should be called after fork is called. This is required
- * due to a limitation of the PKCS#11 standard.
- *
- * This function must be called from the main thread.
- *
- * The helper library handles fork automatically if ENABLE_PKCS11H_THREADING
- * is set on configuration file, by use of pthread_atfork.
- */
-CK_RV
-pkcs11h_forkFixup ();
-
-/*
- * pkcs11h_plugAndPlay - Handle slot rescan.
- *
- * This function must be called from the main thread.
- *
- * PKCS#11 providers do not allow plug&play, plug&play can be established by
- * finalizing all providers and initializing them again.
- *
- * The cost of this process is invalidating all sessions, and require user
- * login at the next access.
- */
-CK_RV
-pkcs11h_plugAndPlay ();
-
-/*
- * pkcs11h_freeTokenId - Free token_id object.
- */
-CK_RV
-pkcs11h_freeTokenId (
-       IN pkcs11h_token_id_t certificate_id
-);
-
-/*
- * pkcs11h_duplicateTokenId - Duplicate token_id object.
- */
-CK_RV
-pkcs11h_duplicateTokenId (
-       OUT pkcs11h_token_id_t * const to,
-       IN const pkcs11h_token_id_t from
-);
-
-/*
- * pkcs11h_sameTokenId - Returns TRUE if same token id
- */
-PKCS11H_BOOL
-pkcs11h_sameTokenId (
-       IN const pkcs11h_token_id_t a,
-       IN const pkcs11h_token_id_t b
-);
-
-#if defined(ENABLE_PKCS11H_TOKEN)
-
-/*
- * pkcs11h_token_ensureAccess - Ensure token is accessible.
- *
- * Parameters:
- *     token_id        - Token id object.
- *     maskPrompt      - Allow prompt.
- */
-CK_RV
-pkcs11h_token_ensureAccess (
-       IN const pkcs11h_token_id_t token_id,
-       IN const unsigned maskPrompt
-);
-
-#endif                         /* ENABLE_PKCS11H_TOKEN */
-
-#if defined(ENABLE_PKCS11H_DATA)
-
-CK_RV
-pkcs11h_data_get (
-       IN const pkcs11h_token_id_t token_id,
-       IN const PKCS11H_BOOL fPublic,
-       IN const char * const szApplication,
-       IN const char * const szLabel,
-       OUT char * const blob,
-       IN OUT size_t * const p_blob_size
-);
-
-CK_RV
-pkcs11h_data_put (
-       IN const pkcs11h_token_id_t token_id,
-       IN const PKCS11H_BOOL fPublic,
-       IN const char * const szApplication,
-       IN const char * const szLabel,
-       OUT char * const blob,
-       IN const size_t blob_size
-);
-
-CK_RV
-pkcs11h_data_del (
-       IN const pkcs11h_token_id_t token_id,
-       IN const PKCS11H_BOOL fPublic,
-       IN const char * const szApplication,
-       IN const char * const szLabel
-);
-
-#endif                         /* ENABLE_PKCS11H_DATA */
-
-#if defined(ENABLE_PKCS11H_CERTIFICATE)
-/*======================================================================*
- * CERTIFICATE INTERFACE
- *======================================================================*/
-
-/*
- * pkcs11h_freeCertificateId - Free certificate_id object.
- */
-CK_RV
-pkcs11h_freeCertificateId (
-       IN pkcs11h_certificate_id_t certificate_id
-);
-
-/*
- * pkcs11h_duplicateCertificateId - Duplicate certificate_id object.
- */
-CK_RV
-pkcs11h_duplicateCertificateId (
-       OUT pkcs11h_certificate_id_t * const to,
-       IN const pkcs11h_certificate_id_t from
-);
-
-/*
- * pkcs11h_freeCertificate - Free certificate object.
- */
-CK_RV
-pkcs11h_freeCertificate (
-       IN pkcs11h_certificate_t certificate
-);
-
-/*
- * pkcs11h_certificate_create - Create a certificate object out of certificate_id.
- *
- * Parameters:
- *     certificate_id  - Certificate id object to be based on.
- *     nPINCachePeriod - Session specific cache period.
- *     p_certificate   - Receives certificate object.
- *
- * The certificate id object may not specify the full certificate.
- * The certificate object must be freed by caller.
- */    
-CK_RV
-pkcs11h_certificate_create (
-       IN const pkcs11h_certificate_id_t certificate_id,
-       IN const int nPINCachePeriod,
-       OUT pkcs11h_certificate_t * const p_certificate
-);
-
-/*
- * pkcs11h_certificate_getCertificateId - Get certifiate id object out of a certifiate
- *
- * Parameters:
- *     certificate             - Certificate object.
- *     p_certificate_id        - Certificate id object pointer.
- *
- * The certificate id must be freed by caller.
- */
-CK_RV
-pkcs11h_certificate_getCertificateId (
-       IN const pkcs11h_certificate_t certificate,
-       OUT pkcs11h_certificate_id_t * const p_certificate_id
-);
-
-/*
- * pkcs11h_certificate_getCertificateBlob - Get the certificate blob out of the certificate object.
- *
- * ParametersL
- *     certificate             - Certificate object.
- *     certificate_blob        - Buffer.
- *     certificate_blob_size   - Buffer size.
- *
- * Buffer may be NULL in order to get size.
- */
-CK_RV
-pkcs11h_certificate_getCertificateBlob (
-       IN const pkcs11h_certificate_t certificate,
-       OUT unsigned char * const certificate_blob,
-       IN OUT size_t * const p_certificate_blob_size
-);
-
-/*
- * pkcs11h_certificate_ensureCertificateAccess - Ensure certificate is accessible.
- *
- * Parameters:
- *     certificate     - Certificate object.
- *     maskPrompt      - Allow prompt.
- */
-CK_RV
-pkcs11h_certificate_ensureCertificateAccess (
-       IN const pkcs11h_certificate_t certificate,
-       IN const unsigned maskPrompt
-);
-
-/*
- * pkcs11h_certificate_ensureKeyAccess - Ensure key is accessible.
- *
- * Parameters:
- *     certificate     - Certificate object.
- *     maskPrompt      - Allow prompt.
- */
-CK_RV
-pkcs11h_certificate_ensureKeyAccess (
-       IN const pkcs11h_certificate_t certificate,
-       IN const unsigned maskPrompt
-);
-
-/*
- * pkcs11h_certificate_sign - Sign data.
- *
- * Parameters:
- *     certificate     - Certificate object.
- *     mech_type       - PKCS#11 mechanism.
- *     source          - Buffer to sign.
- *     source_size     - Buffer size.
- *     target          - Target buffer, can be NULL to get size.
- *     target_size     - Target buffer size.
- */
-CK_RV
-pkcs11h_certificate_sign (
-       IN const pkcs11h_certificate_t certificate,
-       IN const CK_MECHANISM_TYPE mech_type,
-       IN const unsigned char * const source,
-       IN const size_t source_size,
-       OUT unsigned char * const target,
-       IN OUT size_t * const p_target_size
-);
-
-/*
- * pkcs11h_certificate_signRecover - Sign data.
- *
- * Parameters:
- *     certificate     - Certificate object.
- *     mech_type       - PKCS#11 mechanism.
- *     source          - Buffer to sign.
- *     source_size     - Buffer size.
- *     target          - Target buffer, can be NULL to get size.
- *     target_size     - Target buffer size.
- */
-CK_RV
-pkcs11h_certificate_signRecover (
-       IN const pkcs11h_certificate_t certificate,
-       IN const CK_MECHANISM_TYPE mech_type,
-       IN const unsigned char * const source,
-       IN const size_t source_size,
-       OUT unsigned char * const target,
-       IN OUT size_t * const p_target_size
-);
-
-/*
- * pkcs11h_certificate_signAny - Sign data mechanism determined by key attributes.
- *
- * Parameters:
- *     certificate     - Certificate object.
- *     mech_type       - PKCS#11 mechanism.
- *     source          - Buffer to sign.
- *     source_size     - Buffer size.
- *     target          - Target buffer, can be NULL to get size.
- *     target_size     - Target buffer size.
- */
-CK_RV
-pkcs11h_certificate_signAny (
-       IN const pkcs11h_certificate_t certificate,
-       IN const CK_MECHANISM_TYPE mech_type,
-       IN const unsigned char * const source,
-       IN const size_t source_size,
-       OUT unsigned char * const target,
-       IN OUT size_t * const p_target_size
-);
-
-/*
- * pkcs11h_certificate_decrypt - Decrypt data.
- *
- * Parameters:
- *     certificate     - Certificate object.
- *     mech_type       - PKCS#11 mechanism.
- *     source          - Buffer to sign.
- *     source_size     - Buffer size.
- *     target          - Target buffer, can be NULL to get size.
- *     target_size     - Target buffer size.
- */
-CK_RV
-pkcs11h_certificate_decrypt (
-       IN const pkcs11h_certificate_t certificate,
-       IN const CK_MECHANISM_TYPE mech_type,
-       IN const unsigned char * const source,
-       IN const size_t source_size,
-       OUT unsigned char * const target,
-       IN OUT size_t * const p_target_size
-);
-
-#endif                         /* ENABLE_PKCS11H_CERTIFICATE */
-
-#if defined(ENABLE_PKCS11H_LOCATE)
-/*======================================================================*
- * LOCATE INTERFACE
- *======================================================================*/
-
-#if defined(ENABLE_PKCS11H_TOKEN) || defined(ENABLE_PKCS11H_CERTIFICATE)
-
-/*
- * pkcs11h_locate_token - Locate token based on atributes.
- *
- * Parameters:
- *     szSlotType      - How to locate slot.
- *     szSlot          - Slot name.
- *     p_token_id      - Token object.
- *
- * Slot:
- *     id      - Slot number.
- *     name    - Slot name.
- *     label   - Available token label.
- *
- * Caller must free token id.
- */
-CK_RV
-pkcs11h_locate_token (
-       IN const char * const szSlotType,
-       IN const char * const szSlot,
-       OUT pkcs11h_token_id_t * const p_token_id
-);
-
-#endif                         /* ENABLE_PKCS11H_TOKEN || ENABLE_PKCS11H_CERTIFICATE */
-
-#if defined(ENABLE_PKCS11H_CERTIFICATE)
-
-/*
- * pkcs11h_locate_certificate - Locate certificate based on atributes.
- *
- * Parameters:
- *     szSlotType      - How to locate slot.
- *     szSlot          - Slot name.
- *     szIdType        - How to locate object.
- *     szId            - Object name.
- *     p_certificate_id        - Certificate object.
- *
- * Slot:
- * Same as pkcs11h_locate_token.
- *
- * Object:
- *     id      - Certificate CKA_ID (hex string) (Fastest).
- *     label   - Certificate CKA_LABEL (string).
- *     subject - Certificate subject (OpenSSL DN).
- *
- * Caller must free certificate id.
- */
-CK_RV
-pkcs11h_locate_certificate (
-       IN const char * const szSlotType,
-       IN const char * const szSlot,
-       IN const char * const szIdType,
-       IN const char * const szId,
-       OUT pkcs11h_certificate_id_t * const p_certificate_id
-);
-
-#endif                         /* ENABLE_PKCS11H_CERTIFICATE */
-
-#endif                         /* ENABLE_PKCS11H_LOCATE */
-
-#if defined(ENABLE_PKCS11H_ENUM)
-/*======================================================================*
- * ENUM INTERFACE
- *======================================================================*/
-
-#if defined(ENABLE_PKCS11H_TOKEN)
-
-/*
- * pkcs11h_freeCertificateIdList - Free certificate_id list.
- */
-CK_RV
-pkcs11h_freeTokenIdList (
-       IN const pkcs11h_token_id_list_t token_id_list
-);
-
-/*
- * pkcs11h_enum_getTokenIds - Enumerate available tokens
- *
- * Parameters:
- *     p_token_id_list         - A list of token ids.
- *     
- * Caller must free the list.
- */
-CK_RV
-pkcs11h_enum_getTokenIds (
-       IN const int method,
-       OUT pkcs11h_token_id_list_t * const p_token_id_list
-);
-
-#endif                         /* ENABLE_PKCS11H_TOKEN */
-
-#if defined(ENABLE_PKCS11H_DATA)
-
-CK_RV
-pkcs11h_freeDataIdList (
-       IN const pkcs11h_data_id_list_t data_id_list
-);
-
-CK_RV
-pkcs11h_enumDataObjects (
-       IN const pkcs11h_token_id_t token_id,
-       IN const PKCS11H_BOOL fPublic,
-       OUT pkcs11h_data_id_list_t * const p_data_id_list
-);
-
-#endif                         /* ENABLE_PKCS11H_DATA */
-
-#if defined(ENABLE_PKCS11H_CERTIFICATE)
-
-/*
- * pkcs11h_freeCertificateIdList - Free certificate_id list.
- */
-CK_RV
-pkcs11h_freeCertificateIdList (
-       IN const pkcs11h_certificate_id_list_t cert_id_list
-);
-
-/*
- * pkcs11h_enum_getTokenCertificateIds - Enumerate available certificates on specific token
- *
- * Parameters:
- *     token_id                - Token id to enum.
- *     method                  - How to fetch certificates.
- *     p_cert_id_issuers_list  - Receives issues list, can be NULL.
- *     p_cert_id_end_list      - Receives end certificates list.
- *
- * This function will likely take long time.
- *
- * Method can be one of the following:
- *     PKCS11H_ENUM_METHOD_CACHE
- *             Return available certificates, even if token was once detected and
- *             was removed.
- *     PKCS11H_ENUM_METHOD_CACHE_EXIST
- *             Return available certificates for available tokens only, don't
- *             read the contents of the token if already read, even if this token
- *             removed and inserted.
- *     PKCS11H_ENUM_METHOD_RELOAD
- *             Clear all caches and then enum.
- *
- * Caller must free the lists.
- */
-CK_RV
-pkcs11h_enum_getTokenCertificateIds (
-       IN const pkcs11h_token_id_t token_id,
-       IN const int method,
-       OUT pkcs11h_certificate_id_list_t * const p_cert_id_issuers_list,
-       OUT pkcs11h_certificate_id_list_t * const p_cert_id_end_list
-);
-
-/*
- * pkcs11h_enum_getCertificateIds - Enumerate available certificates.
- *
- * Parameters:
- *     method                  - How to fetch certificates.
- *     p_cert_id_issuers_list  - Receives issues list, can be NULL.
- *     p_cert_id_end_list      - Receives end certificates list.
- *
- * This function will likely take long time.
- *
- * Method can be one of the following:
- *     PKCS11H_ENUM_METHOD_CACHE
- *             Return available certificates, even if token was once detected and
- *             was removed.
- *     PKCS11H_ENUM_METHOD_CACHE_EXIST
- *             Return available certificates for available tokens only, don't
- *             read the contents of the token if already read, even if this token
- *             removed and inserted.
- *     PKCS11H_ENUM_METHOD_RELOAD
- *             Clear all caches and then enum.
- *
- * Caller must free lists.
- */
-CK_RV
-pkcs11h_enum_getCertificateIds (
-       IN const int method,
-       OUT pkcs11h_certificate_id_list_t * const p_cert_id_issuers_list,
-       OUT pkcs11h_certificate_id_list_t * const p_cert_id_end_list
-);
-
-#endif                         /* ENABLE_PKCS11H_CERTIFICATE */
-
-#endif                         /* ENABLE_PKCS11H_ENUM */
-
-#if defined(ENABLE_PKCS11H_OPENSSL)
-/*======================================================================*
- * OPENSSL INTERFACE
- *======================================================================*/
-
-/*
- * pkcs11h_openssl_createSession - Create OpenSSL session based on a certificate object.
- *
- * Parameters:
- *     certificate     - Certificate object.
- *
- * The certificate object will be freed by the OpenSSL interface on session end.
- */
-pkcs11h_openssl_session_t
-pkcs11h_openssl_createSession (
-       IN const pkcs11h_certificate_t certificate
-);
-
-/*
- * pkcs11h_openssl_freeSession - Free OpenSSL session.
- *
- * Parameters:
- *     openssl_session - Session to free.
- *
- * The openssl_session object has a reference count just like other OpenSSL objects.
- */
-void
-pkcs11h_openssl_freeSession (
-       IN const pkcs11h_openssl_session_t openssl_session
-);
-
-/*
- * pkcs11h_openssl_getRSA - Returns an RSA object out of the openssl_session object.
- *
- * Parameters:
- *     openssl_session - Session.
- */
-RSA *
-pkcs11h_openssl_getRSA (
-       IN const pkcs11h_openssl_session_t openssl_session
-);
-
-/*
- * pkcs11h_openssl_getX509 - Returns an X509 object out of the openssl_session object.
- *
- * Parameters:
- *     openssl_session - Session.
- */
-X509 *
-pkcs11h_openssl_getX509 (
-       IN const pkcs11h_openssl_session_t openssl_session
-);
-
-#endif                         /* ENABLE_PKCS11H_OPENSSL */
-
-#if defined(ENABLE_PKCS11H_STANDALONE)
-/*======================================================================*
- * STANDALONE INTERFACE
- *======================================================================*/
-
-void
-pkcs11h_standalone_dump_slots (
-       IN const pkcs11h_output_print_t my_output,
-       IN const void *pData,
-       IN const char * const provider
-);
-
-void
-pkcs11h_standalone_dump_objects (
-       IN const pkcs11h_output_print_t my_output,
-       IN const void *pData,
-       IN const char * const provider,
-       IN const char * const slot,
-       IN const char * const pin
-);
-
-#endif                         /* ENABLE_PKCS11H_STANDALONE */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif                         /* __PKCS11H_HELPER_H */
index bdd2690380bfc6fc688586ccad631b2b981f53ab..bd75d58d30aaa42ff10b5dccf88baa56c0fec38d 100644 (file)
--- a/pkcs11.c
+++ b/pkcs11.c
  *  59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
-/*
- * The routines in this file deal with providing private key cryptography
- * using RSA Security Inc. PKCS #11 Cryptographic Token Interface (Cryptoki).
- *
- */
-
 #if defined(WIN32)
 #include "config-win32.h"
 #else
 
 #if defined(ENABLE_PKCS11)
 
-#define PKCS11H_NO_NEED_INCLUDE_CONFIG
-
-#include "pkcs11-helper.h"
+#include <pkcs11-helper-1.0/pkcs11h-certificate.h>
+#include <pkcs11-helper-1.0/pkcs11h-openssl.h>
+#include "basic.h"
+#include "error.h"
+#include "manage.h"
 #include "pkcs11.h"
 
+static
+time_t
+__mytime (void) {
+       return openvpn_time (NULL);
+}
+
+#if !defined(_WIN32)
+static
+int
+__mygettimeofday (struct timeval *tv) {
+       return gettimeofday (tv, NULL);
+}
+#endif
+
+static
+void
+__mysleep (const unsigned long usec) {
+#if defined(_WIN32)
+       Sleep (usec/1000);
+#else
+       usleep (usec);
+#endif
+}
+
+
+static pkcs11h_engine_system_t s_pkcs11h_sys_engine = {
+       malloc,
+       free,
+       __mytime,
+       __mysleep,
+#if defined(_WIN32)
+       NULL
+#else
+       __mygettimeofday
+#endif
+};
+
 static
 unsigned
 _pkcs11_msg_pkcs112openvpn (
-       IN const unsigned flags
+       const unsigned flags
 ) {
        unsigned openvpn_flags;
 
@@ -81,7 +114,7 @@ _pkcs11_msg_pkcs112openvpn (
 static
 unsigned
 _pkcs11_msg_openvpn2pkcs11 (
-       IN const unsigned flags
+       const unsigned flags
 ) {
        unsigned pkcs11_flags;
 
@@ -111,31 +144,13 @@ _pkcs11_msg_openvpn2pkcs11 (
        return pkcs11_flags;
 }
 
-static
-void
-_pkcs11_openvpn_print (
-       IN const void *pData,
-       IN const char * const szFormat,
-       IN ...
-) {
-       char Buffer[10*1024];
-       va_list args;
-       
-       va_start (args, szFormat);
-       vsnprintf (Buffer, sizeof (Buffer), szFormat, args);
-       va_end (args);
-       Buffer[sizeof (Buffer)-1] = 0;
-       
-       msg (M_INFO|M_NOPREFIX|M_NOLF, "%s", Buffer);
-}
-
 static
 void
 _pkcs11_openvpn_log (
-       IN const void *pData,
-       IN unsigned flags,
-       IN const char * const szFormat,
-       IN va_list args
+       void * const global_data,
+       unsigned flags,
+       const char * const szFormat,
+       va_list args
 ) {
        char Buffer[10*1024];
        
@@ -146,15 +161,19 @@ _pkcs11_openvpn_log (
 }
 
 static
-bool
+PKCS11H_BOOL
 _pkcs11_openvpn_token_prompt (
-       IN const void *pData,
-       IN const pkcs11h_token_id_t token,
-       IN const unsigned retry
+       void * const global_data,
+       void * const user_data,
+       const pkcs11h_token_id_t token,
+       const unsigned retry
 ) {
        static struct user_pass token_resp;
 
+       (void)global_data;
+       (void)user_data;
        (void)retry;
+
        ASSERT (token!=NULL);
 
        CLEAR (token_resp);
@@ -185,38 +204,42 @@ _pkcs11_openvpn_token_prompt (
 static
 bool
 _pkcs11_openvpn_pin_prompt (
-       IN const void *pData,
-       IN const pkcs11h_token_id_t token,
-       IN const unsigned retry,
-       OUT char * const szPIN,
-       IN const size_t nMaxPIN
+       void * const global_data,
+       void * const user_data,
+       const pkcs11h_token_id_t token,
+       const unsigned retry,
+       char * const pin,
+       const size_t pin_max
 ) {
        static struct user_pass token_pass;
-       char szPrompt[1024];
+       char prompt[1024];
 
+       (void)global_data;
+       (void)user_data;
        (void)retry;
+
        ASSERT (token!=NULL);
 
-       openvpn_snprintf (szPrompt, sizeof (szPrompt), "%s token", token->label);
+       openvpn_snprintf (prompt, sizeof (prompt), "%s token", token->label);
 
        token_pass.defined = false;
        token_pass.nocache = true;
-
+       
        if (
                !get_user_pass (
                        &token_pass,
                        NULL,
-                       szPrompt,
+                       prompt,
                        GET_USER_PASS_MANAGEMENT|GET_USER_PASS_PASSWORD_ONLY|GET_USER_PASS_NOFATAL
                )
        ) {
                return false;
        }
        else {
-               strncpynt (szPIN, token_pass.password, nMaxPIN);
+               strncpynt (pin, token_pass.password, pin_max);
                purge_user_pass (&token_pass, true);
 
-               if (strlen (szPIN) == 0) {
+               if (strlen (pin) == 0) {
                        return false;
                }
                else {
@@ -227,62 +250,61 @@ _pkcs11_openvpn_pin_prompt (
 
 bool
 pkcs11_initialize (
-       IN const bool fProtectedAuthentication,
-       IN const int nPINCachePeriod
+       const bool protected_auth,
+       const int nPINCachePeriod
 ) {
-       CK_RV rv = CKR_OK;
+       CK_RV rv = CKR_FUNCTION_FAILED;
 
        dmsg (
                D_PKCS11_DEBUG,
                "PKCS#11: pkcs11_initialize - entered"
        );
 
-       if (
-               rv == CKR_OK &&
-               (rv = pkcs11h_initialize ()) != CKR_OK
-       ) {
+       if ((rv = pkcs11h_engine_setSystem (&s_pkcs11h_sys_engine)) != CKR_OK) {
+               msg (M_FATAL, "PKCS#11: Cannot initialize system engine %ld-'%s'", rv, pkcs11h_getMessage (rv));
+               goto cleanup;
+       }
+
+       if ((rv = pkcs11h_initialize ()) != CKR_OK) {
                msg (M_FATAL, "PKCS#11: Cannot initialize %ld-'%s'", rv, pkcs11h_getMessage (rv));
+               goto cleanup;
        }
 
-       if (
-               rv == CKR_OK &&
-               (rv = pkcs11h_setLogHook (_pkcs11_openvpn_log, NULL)) != CKR_OK
-       ) {
+       if ((rv = pkcs11h_setLogHook (_pkcs11_openvpn_log, NULL)) != CKR_OK) {
                msg (M_FATAL, "PKCS#11: Cannot set hooks %ld-'%s'", rv, pkcs11h_getMessage (rv));
+               goto cleanup;
        }
 
-       if (rv == CKR_OK) {
-               pkcs11h_setLogLevel (_pkcs11_msg_openvpn2pkcs11 (get_debug_level ()));
+       pkcs11h_setLogLevel (_pkcs11_msg_openvpn2pkcs11 (get_debug_level ()));
+
+       if ((rv = pkcs11h_setForkMode (TRUE)) != CKR_OK) {
+               msg (M_FATAL, "PKCS#11: Cannot set fork mode %ld-'%s'", rv, pkcs11h_getMessage (rv));
+               goto cleanup;
        }
 
-       if (
-               rv == CKR_OK &&
-               (rv = pkcs11h_setTokenPromptHook (_pkcs11_openvpn_token_prompt, NULL)) != CKR_OK
-       ) {
+       if ((rv = pkcs11h_setTokenPromptHook (_pkcs11_openvpn_token_prompt, NULL)) != CKR_OK) {
                msg (M_FATAL, "PKCS#11: Cannot set hooks %ld-'%s'", rv, pkcs11h_getMessage (rv));
+               goto cleanup;
        }
 
-       if (
-               rv == CKR_OK &&
-               (rv = pkcs11h_setPINPromptHook (_pkcs11_openvpn_pin_prompt, NULL)) != CKR_OK
-       ) {
+       if ((rv = pkcs11h_setPINPromptHook (_pkcs11_openvpn_pin_prompt, NULL)) != CKR_OK) {
                msg (M_FATAL, "PKCS#11: Cannot set hooks %ld-'%s'", rv, pkcs11h_getMessage (rv));
+               goto cleanup;
        }
 
-       if (
-               rv == CKR_OK &&
-               (rv = pkcs11h_setProtectedAuthentication (fProtectedAuthentication)) != CKR_OK
-       ) {
+       if ((rv = pkcs11h_setProtectedAuthentication (protected_auth)) != CKR_OK) {
                msg (M_FATAL, "PKCS#11: Cannot set protected authentication mode %ld-'%s'", rv, pkcs11h_getMessage (rv));
+               goto cleanup;
        }
 
-       if (
-               rv == CKR_OK &&
-               (rv = pkcs11h_setPINCachePeriod (nPINCachePeriod)) != CKR_OK
-       ) {
-               msg (M_FATAL, "PKCS#11: Cannot set PIN cache period %ld-'%s'", rv, pkcs11h_getMessage (rv));
+       if ((rv = pkcs11h_setPINCachePeriod (nPINCachePeriod)) != CKR_OK) {
+               msg (M_FATAL, "PKCS#11: Cannot set Pcache period %ld-'%s'", rv, pkcs11h_getMessage (rv));
+               goto cleanup;
        }
 
+       rv = CKR_OK;
+
+cleanup:
        dmsg (
                D_PKCS11_DEBUG,
                "PKCS#11: pkcs11_initialize - return %ld-'%s'",
@@ -315,23 +337,20 @@ pkcs11_forkFixup () {
 
 bool
 pkcs11_addProvider (
-       IN const char * const provider,
-       IN const bool fProtectedAuthentication,
-       IN const char * const sign_mode,
-       IN const bool fCertIsPrivate
+       const char * const provider,
+       const bool protected_auth,
+       const unsigned private_mode,
+       const bool cert_private
 ) {
-       unsigned maskSignMode = 0;
-
        CK_RV rv = CKR_OK;
 
        ASSERT (provider!=NULL);
-       /*ASSERT (sign_mode!=NULL); NULL is default */
 
        dmsg (
                D_PKCS11_DEBUG,
-               "PKCS#11: pkcs11_addProvider - entered - provider='%s', sign_mode='%s'",
+               "PKCS#11: pkcs11_addProvider - entered - provider='%s', private_mode=%08x",
                provider,
-               sign_mode == NULL ? "default" : sign_mode
+               private_mode
        );
 
        msg (
@@ -340,38 +359,15 @@ pkcs11_addProvider (
                provider
        );
 
-       if (rv == CKR_OK) {
-               if (sign_mode == NULL || !strcmp (sign_mode, "auto")) {
-                       maskSignMode = 0;
-               }
-               else if (!strcmp (sign_mode, "sign")) {
-                       maskSignMode = PKCS11H_SIGNMODE_MASK_SIGN;
-               }
-               else if (!strcmp (sign_mode, "recover")) {
-                       maskSignMode = PKCS11H_SIGNMODE_MASK_RECOVER;
-               }
-               else if (!strcmp (sign_mode, "any")) {
-                       maskSignMode = (
-                               PKCS11H_SIGNMODE_MASK_SIGN |
-                               PKCS11H_SIGNMODE_MASK_RECOVER
-                       );
-               }
-               else {
-                       msg (M_FATAL, "PKCS#11: Invalid sign mode '%s'", sign_mode);
-                       rv = CKR_ARGUMENTS_BAD;
-               }
-       }
-
        if (
-               rv == CKR_OK &&
                (rv = pkcs11h_addProvider (
                        provider,
                        provider,
-                       fProtectedAuthentication,
-                       maskSignMode,
+                       protected_auth,
+                       private_mode,
                        PKCS11H_SLOTEVENT_METHOD_AUTO,
                        0,
-                       fCertIsPrivate
+                       cert_private
                )) != CKR_OK
        ) {
                msg (M_WARN, "PKCS#11: Cannot initialize provider '%s' %ld-'%s'", provider, rv, pkcs11h_getMessage (rv));
@@ -387,13 +383,15 @@ pkcs11_addProvider (
        return rv == CKR_OK;
 }
 
+int
+pkcs11_logout() {
+       return pkcs11h_logout () == CKR_OK;
+}
+
 int
 SSL_CTX_use_pkcs11 (
-       IN OUT SSL_CTX * const ssl_ctx,
-       IN const char * const pkcs11_slot_type,
-       IN const char * const pkcs11_slot,
-       IN const char * const pkcs11_id_type,
-       IN const char * const pkcs11_id
+       SSL_CTX * const ssl_ctx,
+       const char * const pkcs11_id
 ) {
        X509 *x509 = NULL;
        RSA *rsa = NULL;
@@ -402,103 +400,74 @@ SSL_CTX_use_pkcs11 (
        pkcs11h_openssl_session_t openssl_session = NULL;
        CK_RV rv = CKR_OK;
 
-       bool fOK = true;
+       bool ok = false;
 
        ASSERT (ssl_ctx!=NULL);
-       ASSERT (pkcs11_slot_type!=NULL);
-       ASSERT (pkcs11_slot!=NULL);
-       ASSERT (pkcs11_id_type!=NULL);
        ASSERT (pkcs11_id!=NULL);
 
        dmsg (
                D_PKCS11_DEBUG,
-               "PKCS#11: SSL_CTX_use_pkcs11 - entered - ssl_ctx=%p, pkcs11_slot_type='%s', pkcs11_slot='%s', pkcs11_id_type='%s', pkcs11_id='%s'",
+               "PKCS#11: SSL_CTX_use_pkcs11 - entered - ssl_ctx=%p, pkcs11_id='%s'",
                (void *)ssl_ctx,
-               pkcs11_slot_type,
-               pkcs11_slot,
-               pkcs11_id_type,
                pkcs11_id
        );
 
-       ASSERT (ssl_ctx!=NULL);
-       ASSERT (pkcs11_slot_type!=NULL);
-       ASSERT (pkcs11_slot!=NULL);
-       ASSERT (pkcs11_id_type!=NULL);
-       ASSERT (pkcs11_id!=NULL);
-
        if (
-               fOK &&
-               (rv = pkcs11h_locate_certificate (
-                       pkcs11_slot_type,
-                       pkcs11_slot,
-                       pkcs11_id_type,
-                       pkcs11_id,
-                       &certificate_id
+               (rv = pkcs11h_certificate_deserializeCertificateId (
+                       &certificate_id,
+                       pkcs11_id
                )) != CKR_OK
        ) {
-               fOK = false;
-               msg (M_WARN, "PKCS#11: Cannot set parameters %ld-'%s'", rv, pkcs11h_getMessage (rv));
+               msg (M_WARN, "PKCS#11: Cannot deserialize id %ld-'%s'", rv, pkcs11h_getMessage (rv));
+               goto cleanup;
        }
 
        if (
-               fOK &&
                (rv = pkcs11h_certificate_create (
                        certificate_id,
+                       NULL,
+                       PKCS11H_PROMPT_MASK_ALLOW_ALL,
                        PKCS11H_PIN_CACHE_INFINITE,
                        &certificate
                )) != CKR_OK
        ) {
-               fOK = false;
                msg (M_WARN, "PKCS#11: Cannot get certificate %ld-'%s'", rv, pkcs11h_getMessage (rv));
+               goto cleanup;
        }
 
-       if (
-               fOK &&
-               (openssl_session = pkcs11h_openssl_createSession (certificate)) == NULL
-       ) {
-               fOK = false;
+       if ((openssl_session = pkcs11h_openssl_createSession (certificate)) == NULL     ) {
                msg (M_WARN, "PKCS#11: Cannot initialize openssl session");
+               goto cleanup;
        }
 
-       if (fOK) {
-               /*
-                * Will be released by openssl_session
-                */
-               certificate = NULL;
-       }
+       /*
+        * Will be released by openssl_session
+        */
+       certificate = NULL;
 
-       if (
-               fOK &&
-               (rsa = pkcs11h_openssl_getRSA (openssl_session)) == NULL
-       ) {
-               fOK = false;
+       if ((rsa = pkcs11h_openssl_session_getRSA (openssl_session)) == NULL) {
                msg (M_WARN, "PKCS#11: Unable get rsa object");
+               goto cleanup;
        }
 
-       if (
-               fOK &&
-               (x509 = pkcs11h_openssl_getX509 (openssl_session)) == NULL
-       ) {
-               fOK = false;
+       if ((x509 = pkcs11h_openssl_session_getX509 (openssl_session)) == NULL) {
                msg (M_WARN, "PKCS#11: Unable get certificate object");
+               goto cleanup;
        }
 
-       if (
-               fOK &&
-               !SSL_CTX_use_RSAPrivateKey (ssl_ctx, rsa)
-       ) {
-               fOK = false;
+       if (!SSL_CTX_use_RSAPrivateKey (ssl_ctx, rsa)) {
                msg (M_WARN, "PKCS#11: Cannot set private key for openssl");
+               goto cleanup;
        }
 
-       if (
-               fOK &&
-               !SSL_CTX_use_certificate (ssl_ctx, x509)
-       ) {
-               fOK = false;
+       if (!SSL_CTX_use_certificate (ssl_ctx, x509)) {
                msg (M_WARN, "PKCS#11: Cannot set certificate for openssl");
+               goto cleanup;
        }
 
+       ok = true;
+
+cleanup:
        /*
         * openssl objects have reference
         * count, so release them
@@ -515,12 +484,12 @@ SSL_CTX_use_pkcs11 (
        }
 
        if (certificate != NULL) {
-               pkcs11h_freeCertificate (certificate);
+               pkcs11h_certificate_freeCertificate (certificate);
                certificate = NULL;
        }
 
        if (certificate_id != NULL) {
-               pkcs11h_freeCertificateId (certificate_id);
+               pkcs11h_certificate_freeCertificateId (certificate_id);
                certificate_id = NULL;
        }
        
@@ -531,38 +500,233 @@ SSL_CTX_use_pkcs11 (
 
        dmsg (
                D_PKCS11_DEBUG,
-               "PKCS#11: SSL_CTX_use_pkcs11 - return fOK=%d, rv=%ld",
-               fOK ? 1 : 0,
+               "PKCS#11: SSL_CTX_use_pkcs11 - return ok=%d, rv=%ld",
+               ok ? 1 : 0,
                rv
        );
 
-       return fOK ? 1 : 0;
+       return ok ? 1 : 0;
 }
 
-void
-show_pkcs11_slots (
-       const char * const provider
+static
+bool
+_pkcs11_openvpn_show_pkcs11_ids_pin_prompt (
+       void * const global_data,
+       void * const user_data,
+       const pkcs11h_token_id_t token,
+       const unsigned retry,
+       char * const pin,
+       const size_t pin_max
 ) {
-       pkcs11h_standalone_dump_slots (
-               _pkcs11_openvpn_print,
-               NULL,
-               provider
-       );
+       struct gc_arena gc = gc_new ();
+       struct buffer pass_prompt = alloc_buf_gc (128, &gc);
+
+       (void)global_data;
+       (void)user_data;
+       (void)retry;
+
+       ASSERT (token!=NULL);
+
+       buf_printf (&pass_prompt, "Please enter '%s' token PIN or 'cancel': ", token->display);
+
+       if (!get_console_input (BSTR (&pass_prompt), false, pin, pin_max)) {
+               msg (M_FATAL, "Cannot read password from stdin");
+       }
+
+       gc_free (&gc);
+
+       if (!strcmp (pin, "cancel")) {
+               return FALSE;
+       }
+       else {
+               return TRUE;
+       }
 }
 
 void
-show_pkcs11_objects (
+show_pkcs11_ids (
        const char * const provider,
-       const char * const slot,
-       const char * const pin
+       bool cert_private
 ) {
-       pkcs11h_standalone_dump_objects (
-               _pkcs11_openvpn_print,
-               NULL,
-               provider,
-               slot,
-               pin
+       pkcs11h_certificate_id_list_t user_certificates = NULL;
+       pkcs11h_certificate_id_list_t current = NULL;
+       CK_RV rv = CKR_FUNCTION_FAILED;
+
+       if ((rv = pkcs11h_initialize ()) != CKR_OK) {
+               msg (M_FATAL, "PKCS#11: Cannot initialize %ld-'%s'", rv, pkcs11h_getMessage (rv));
+               goto cleanup;
+       }
+
+       if ((rv = pkcs11h_setLogHook (_pkcs11_openvpn_log, NULL)) != CKR_OK) {
+               msg (M_FATAL, "PKCS#11: Cannot set hooks %ld-'%s'", rv, pkcs11h_getMessage (rv));
+               goto cleanup;
+       }
+
+       pkcs11h_setLogLevel (_pkcs11_msg_openvpn2pkcs11 (get_debug_level ()));
+
+       if ((rv = pkcs11h_setProtectedAuthentication (TRUE)) != CKR_OK) {
+               msg (M_FATAL, "PKCS#11: Cannot set protected authentication %ld-'%s'", rv, pkcs11h_getMessage (rv));
+               goto cleanup;
+       }
+
+       if ((rv = pkcs11h_setPINPromptHook (_pkcs11_openvpn_show_pkcs11_ids_pin_prompt, NULL)) != CKR_OK) {
+               msg (M_FATAL, "PKCS#11: Cannot set PIN hook %ld-'%s'", rv, pkcs11h_getMessage (rv));
+               goto cleanup;
+       }
+
+       if (
+               (rv = pkcs11h_addProvider (
+                       provider,
+                       provider,
+                       TRUE,
+                       0,
+                       FALSE,
+                       0,
+                       cert_private ? TRUE : FALSE
+               )) != CKR_OK
+       ) {
+               msg (M_FATAL, "PKCS#11: Cannot add provider '%s' %ld-'%s'", provider, rv, pkcs11h_getMessage (rv));
+               goto cleanup;
+       }
+
+       if (
+               (rv = pkcs11h_certificate_enumCertificateIds (
+                       PKCS11H_ENUM_METHOD_CACHE_EXIST,
+                       NULL,
+                       PKCS11H_PROMPT_MASK_ALLOW_ALL,
+                       NULL,
+                       &user_certificates
+               )) != CKR_OK
+       ) {
+               msg (M_FATAL, "PKCS#11: Cannot enumerate certificates %ld-'%s'", rv, pkcs11h_getMessage (rv));
+               goto cleanup;
+       }
+
+       msg (
+               M_INFO|M_NOPREFIX|M_NOLF,
+               (
+                       "\n"
+                       "The following objects are available for use.\n"
+                       "Each object shown below may be used as parameter to\n"
+                       "--pkcs11-id option please remember to use single quote mark.\n"
+               )
        );
+       for (current = user_certificates;current != NULL; current = current->next) {
+               pkcs11h_certificate_t certificate = NULL;
+               X509 *x509 = NULL;
+               BIO *bio = NULL;
+               char dn[1024] = {0};
+               char serial[1024] = {0};
+               char *ser = NULL;
+               size_t ser_len = 0;
+               int n;
+
+               if (
+                       (rv = pkcs11h_certificate_serializeCertificateId (
+                               NULL,
+                               &ser_len,
+                               current->certificate_id
+                       )) != CKR_OK
+               ) {
+                       msg (M_FATAL, "PKCS#11: Cannot serialize certificate %ld-'%s'", rv, pkcs11h_getMessage (rv));
+                       goto cleanup1;
+               }
+
+               if (
+                       rv == CKR_OK &&
+                       (ser = (char *)malloc (ser_len)) == NULL
+               ) {
+                       msg (M_FATAL, "PKCS#11: Cannot allocate memory");
+                       goto cleanup1;
+               }
+
+               if (
+                       (rv = pkcs11h_certificate_serializeCertificateId (
+                               ser,
+                               &ser_len,
+                               current->certificate_id
+                       )) != CKR_OK
+               ) {
+                       msg (M_FATAL, "PKCS#11: Cannot serialize certificate %ld-'%s'", rv, pkcs11h_getMessage (rv));
+                       goto cleanup1;
+               }
+
+               if (
+                       (rv = pkcs11h_certificate_create (
+                               current->certificate_id,
+                               NULL,
+                               PKCS11H_PROMPT_MASK_ALLOW_ALL,
+                               PKCS11H_PIN_CACHE_INFINITE,
+                               &certificate
+                       ))
+               ) {
+                       msg (M_FATAL, "PKCS#11: Cannot create certificate %ld-'%s'", rv, pkcs11h_getMessage (rv));
+                       goto cleanup1;
+               }
+
+               if ((x509 = pkcs11h_openssl_getX509 (certificate)) == NULL) {
+                       msg (M_FATAL, "PKCS#11: Cannot get X509");
+                       goto cleanup1;
+               }
+
+               X509_NAME_oneline (
+                       X509_get_subject_name (x509),
+                       dn,
+                       sizeof (dn)
+               );
+
+               if ((bio = BIO_new (BIO_s_mem ())) == NULL) {
+                       msg (M_FATAL, "PKCS#11: Cannot create BIO");
+                       goto cleanup1;
+               }
+
+               i2a_ASN1_INTEGER(bio, X509_get_serialNumber (x509));
+               n = BIO_read (bio, serial, sizeof (serial)-1);
+               if (n<0) {
+                       serial[0] = '\x0';
+               }
+               else {
+                       serial[n] = 0;
+               }
+
+               msg (
+                       M_INFO|M_NOPREFIX|M_NOLF,
+                       (
+                               "\n"
+                               "Certificate\n"
+                               "       DN:             %s\n"
+                               "       Serial:         %s\n"
+                               "       Serialized id:  %s\n"
+                       ),
+                       dn,
+                       serial,
+                       ser
+               );
+
+       cleanup1:
+               if (x509 != NULL) {
+                       X509_free (x509);
+                       x509 = NULL;
+               }
+
+               if (certificate != NULL) {
+                       pkcs11h_certificate_freeCertificate (certificate);
+                       certificate = NULL;
+               }
+
+               if (ser != NULL) {
+                       free (ser);
+                       ser = NULL;
+               }
+       }
+
+cleanup:
+       if (user_certificates != NULL) {
+               pkcs11h_certificate_freeCertificateIdList (user_certificates);
+               user_certificates = NULL;
+       }
+
+       pkcs11h_terminate ();
 }
 
 #else
index 0e69d11edf810adc5b36bdf527df1e1bfca4ef3a..4b207e73b6478c3d6fd04fc42938b7e1aad6456a 100644 (file)
--- a/pkcs11.h
+++ b/pkcs11.h
@@ -45,29 +45,23 @@ bool
 pkcs11_addProvider (
        const char * const provider,
        const bool fProtectedAuthentication,
-       const char * const sign_mode,
+       const unsigned private_mode,
        const bool fCertIsPrivate
 );
 
+int
+pkcs11_logout();
+
 int
 SSL_CTX_use_pkcs11 (
        SSL_CTX * const ssl_ctx,
-       const char * const pkcs11_slot_type,
-       const char * const pkcs11_slot,
-       const char * const pkcs11_id_type,
        const char * const pkcs11_id
 );
 
 void
-show_pkcs11_slots (
-       const char * const provider
-);
-
-void
-show_pkcs11_objects (
+show_pkcs11_ids (
        const char * const provider,
-       const char * const slot,
-       const char * const pin
+       bool cert_private
 );
 
 #endif                 /* ENABLE_PKCS11 */
diff --git a/ssl.c b/ssl.c
index 85e9c6fc33717bce7dbaf771899fd465860ec034..712489aefad68a9d36d6445ac36a12d1c084e190 100644 (file)
--- a/ssl.c
+++ b/ssl.c
@@ -321,6 +321,9 @@ ssl_set_auth_nocache (void)
 void
 ssl_purge_auth (void)
 {
+#ifdef USE_PKCS11
+  pkcs11_logout ();
+#endif
   purge_user_pass (&passbuf, true);
   purge_user_pass (&auth_user_pass, true);
 }
@@ -1151,10 +1154,9 @@ init_ssl (const struct options *options)
       if (options->pkcs11_providers[0])
         {
          /* Load Certificate and Private Key */
-        if (!SSL_CTX_use_pkcs11 (ctx, options->pkcs11_slot_type, options->pkcs11_slot, options->pkcs11_id_type, options->pkcs11_id))
+        if (!SSL_CTX_use_pkcs11 (ctx, options->pkcs11_id))
           {
-            msg (M_WARN, "Cannot load certificate \"%s:%s\" from slot \"%s:%s\" using PKCS#11 interface",
-               options->pkcs11_id_type, options->pkcs11_id, options->pkcs11_slot_type, options->pkcs11_slot);
+            msg (M_WARN, "Cannot load certificate \"%s\" using PKCS#11 interface", options->pkcs11_id);
             goto err;
           }
         }