aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjames <james@e7ae566f-a301-0410-adde-c780ea21d3b5>2005-10-17 07:39:41 +0000
committerjames <james@e7ae566f-a301-0410-adde-c780ea21d3b5>2005-10-17 07:39:41 +0000
commit6835555ef8ede3ac0997a0fe8365aa95391b32a3 (patch)
treec89421dd8a4f17615ad5936a11ae6e9903bc0d55
parentVERSION 2.1_beta4 (re-released) (diff)
downloadopenvpn-6835555ef8ede3ac0997a0fe8365aa95391b32a3.tar.xz
Brought up-to-date with Alon's PKCS11 patch at
https://svn.openvpn.net/projects/openvpn/contrib/alon/BETA21/openvpn@645 Pre-2.1_beta5 git-svn-id: http://svn.openvpn.net/projects/openvpn/branches/BETA21/openvpn@648 e7ae566f-a301-0410-adde-c780ea21d3b5
-rw-r--r--ChangeLog4
-rw-r--r--configure.ac2
-rw-r--r--init.c12
-rw-r--r--options.c254
-rw-r--r--options.h1
-rw-r--r--pkcs11.c1402
-rw-r--r--pkcs11.h31
-rw-r--r--ssl.c11
8 files changed, 1147 insertions, 570 deletions
diff --git a/ChangeLog b/ChangeLog
index 87d2f5b..cc763c9 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -3,6 +3,10 @@ Copyright (C) 2002-2005 OpenVPN Solutions LLC <info@openvpn.net>
$Id$
+2005.10.xx -- Version 2.1-beta5
+
+* More PKCS#11 additions/changes (Alon Bar-Lev).
+
2005.10.17 -- Version 2.1-beta4
* Fixed bug introduced in 2.1-beta3 where management
diff --git a/configure.ac b/configure.ac
index 9befab2..2fed39b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -25,7 +25,7 @@ dnl Process this file with autoconf to produce a configure script.
AC_PREREQ(2.50)
-AC_INIT([OpenVPN], [2.1_beta4], [openvpn-users@lists.sourceforge.net], [openvpn])
+AC_INIT([OpenVPN], [2.1_beta5], [openvpn-users@lists.sourceforge.net], [openvpn])
AM_CONFIG_HEADER(config.h)
AC_CONFIG_SRCDIR(syshead.h)
diff --git a/init.c b/init.c
index 710a347..879c777 100644
--- a/init.c
+++ b/init.c
@@ -111,15 +111,16 @@ context_init_1 (struct context *c)
/* Certificate password input */
if (c->options.key_pass_file)
pem_password_setup (c->options.key_pass_file);
+#endif
#if defined(ENABLE_PKCS11)
{
int i;
+ init_pkcs11 (c->options.pkcs11_pin_cache_period);
for (i=0;i<MAX_PARMS && c->options.pkcs11_providers[i] != NULL;i++)
add_pkcs11 (c->options.pkcs11_providers[i], c->options.pkcs11_sign_mode[i]);
}
#endif
-#endif
#if P2MP
/* Auth user/pass input */
@@ -232,13 +233,11 @@ uninit_static (void)
#ifdef USE_CRYPTO
free_ssl_lib ();
+#endif
-#ifdef USE_SSL
#ifdef ENABLE_PKCS11
free_pkcs11 ();
#endif
-#endif
-#endif
#if defined(MEASURE_TLS_HANDSHAKE_STATS) && defined(USE_CRYPTO) && defined(USE_SSL)
show_tls_performance_stats ();
@@ -375,6 +374,11 @@ possibly_become_daemon (const struct options *options, const bool first_time)
msg (M_ERR, "daemon() failed");
if (options->log)
set_std_files_to_null (true);
+
+#if defined(ENABLE_PKCS11)
+ fork_fix_pkcs11 ();
+#endif
+
ret = true;
}
return ret;
diff --git a/options.c b/options.c
index 99e5cc0..0a4a113 100644
--- a/options.c
+++ b/options.c
@@ -425,24 +425,6 @@ static const char usage_message[] =
"--key file : Local private key in .pem format.\n"
"--pkcs12 file : PKCS#12 file containing local private key, local certificate\n"
" and optionally the root CA certificate.\n"
-#ifdef ENABLE_PKCS11
- "--pkcs11-providers provider ... : PKCS#11 provider to load.\n"
- "--pkcs11-sign-mode mode ... : PKCS#11 signature method.\n"
- " auto : Try to determind automatically (default).\n"
- " recover : Use SignRecover.\n"
- " sign : Use Sign.\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-protected-authentication : Use PKCS#11 protected authentication path.\n"
-#endif
#ifdef WIN32
"--cryptoapicert select-string : Load the certificate and private key from the\n"
" Windows Certificate System Store.\n"
@@ -479,7 +461,29 @@ static const char usage_message[] =
"--ns-cert-type t: Require that peer certificate was signed with an explicit\n"
" nsCertType designation t = 'client' | 'server'.\n"
#endif /* USE_SSL */
+#ifdef ENABLE_PKCS11
"\n"
+ "PKCS#11 Options:\n"
+ "--pkcs11-providers provider ... : PKCS#11 provider to load.\n"
+ "--pkcs11-sign-mode mode ... : PKCS#11 signature method.\n"
+ " auto : Try to determind automatically (default).\n"
+ " recover : Use SignRecover.\n"
+ " sign : Use Sign.\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-pin-cache seconds : Number of seconds to cache PIN. The default is -1\n"
+ " cache until token removed.\n"
+ "--pkcs11-protected-authentication : Use PKCS#11 protected authentication path.\n"
+#endif /* ENABLE_PKCS11 */
+ "\n"
"SSL Library information:\n"
"--show-ciphers : Show cipher algorithms to use with --cipher option.\n"
"--show-digests : Show message digest algorithms to use with --auth option.\n"
@@ -554,14 +558,12 @@ static const char usage_message[] =
"--dev tunX|tapX : tun/tap device\n"
"--dev-type dt : Device type. See tunnel options above for details.\n"
#endif
-#ifdef USE_SSL
#ifdef ENABLE_PKCS11
"\n"
- "PKCS#11 specific:\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"
-#endif
-#endif
+#endif /* ENABLE_PKCS11 */
;
#endif /* !ENABLE_SMALL */
@@ -646,11 +648,12 @@ init_options (struct options *o)
o->renegotiate_seconds = 3600;
o->handshake_window = 60;
o->transition_window = 3600;
-#ifdef ENABLE_PKCS11
- o->pkcs11_protected_authentication = false;
-#endif
#endif
#endif
+#ifdef ENABLE_PKCS11
+ o->pkcs11_pin_cache_period = -1;
+ o->pkcs11_protected_authentication = false;
+#endif /* ENABLE_PKCS11 */
}
void
@@ -1178,23 +1181,6 @@ show_settings (const struct options *o)
SHOW_STR (cert_file);
SHOW_STR (priv_key_file);
SHOW_STR (pkcs12_file);
-#ifdef ENABLE_PKCS11
- {
- int i;
- for (i=0;i<MAX_PARMS && o->pkcs11_providers[i] != NULL;i++)
- SHOW_PARM (pkcs11_providers, o->pkcs11_providers[i], "%s");
- }
- {
- 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");
- }
- SHOW_STR (pkcs11_slot_type);
- SHOW_STR (pkcs11_slot);
- SHOW_STR (pkcs11_id_type);
- SHOW_STR (pkcs11_id);
- SHOW_BOOL (pkcs11_protected_authentication);
-#endif
#ifdef WIN32
SHOW_STR (cryptoapi_cert);
#endif
@@ -1220,6 +1206,25 @@ show_settings (const struct options *o)
#endif
#endif
+#ifdef ENABLE_PKCS11
+ {
+ int i;
+ for (i=0;i<MAX_PARMS && o->pkcs11_providers[i] != NULL;i++)
+ SHOW_PARM (pkcs11_providers, o->pkcs11_providers[i], "%s");
+ }
+ {
+ 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");
+ }
+ SHOW_STR (pkcs11_slot_type);
+ SHOW_STR (pkcs11_slot);
+ SHOW_STR (pkcs11_id_type);
+ SHOW_STR (pkcs11_id);
+ SHOW_INT (pkcs11_pin_cache_period);
+ SHOW_BOOL (pkcs11_protected_authentication);
+#endif /* ENABLE_PKCS11 */
+
#if P2MP
show_p2mp_parms (o);
#endif
@@ -1702,11 +1707,6 @@ options_postprocess (struct options *options, bool first_time)
notnull (options->pkcs11_id, "PKCS#11 id (--pkcs11-id)");
- if (options->pkcs11_protected_authentication && options->key_pass_file != NULL)
- msg(M_USAGE, "Parameter --askpass cannot be used when --pkcs11-protected-authentication is also specified.");
- if (!options->pkcs11_protected_authentication && options->key_pass_file == NULL)
- msg (M_USAGE, "Please specify one of --askpass or --pkcs11-protected-autentication options.");
-
if (options->cert_file)
msg(M_USAGE, "Parameter --cert cannot be used when --pkcs11-provider is also specified.");
if (options->priv_key_file)
@@ -4733,83 +4733,6 @@ add_option (struct options *options,
VERIFY_PERMISSION (OPT_P_GENERAL);
options->cert_file = p[1];
}
-#ifdef ENABLE_PKCS11
- else if (streq (p[0], "show-pkcs11-slots") && p[1])
- {
- char *module = p[i++];
- VERIFY_PERMISSION (OPT_P_GENERAL);
- show_pkcs11_slots (M_INFO|M_NOPREFIX, M_WARN|M_NOPREFIX, module);
- openvpn_exit (OPENVPN_EXIT_STATUS_GOOD); /* exit point */
- }
- else if (streq (p[0], "show-pkcs11-objects") && p[1] && p[2])
- {
- char *provider = p[i++];
- char *slot = p[i++];
- struct gc_arena gc = gc_new ();
- struct buffer pass_prompt = alloc_buf_gc (128, &gc);
- char pin[256];
-
- 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 (M_INFO|M_NOPREFIX, M_WARN|M_NOPREFIX, provider, slot, pin);
- openvpn_exit (OPENVPN_EXIT_STATUS_GOOD); /* exit point */
- }
- else if (streq (p[0], "pkcs11-providers") && p[1])
- {
- int j;
-
- VERIFY_PERMISSION (OPT_P_GENERAL);
-
- for (j = 1; j < MAX_PARMS && p[j] != NULL; ++j, ++i)
- options->pkcs11_providers[j-1] = p[j];
- }
- else if (streq (p[0], "pkcs11-sign-mode") && p[1])
- {
- int j;
-
- VERIFY_PERMISSION (OPT_P_GENERAL);
-
- for (j = 1; j < MAX_PARMS && p[j] != NULL; ++j, ++i)
- options->pkcs11_sign_mode[j-1] = p[j];
- }
- else if (streq (p[0], "pkcs11-slot-type") && p[1])
- {
- ++i;
- VERIFY_PERMISSION (OPT_P_GENERAL);
- options->pkcs11_slot_type = p[1];
- }
- else if (streq (p[0], "pkcs11-slot") && p[1])
- {
- ++i;
- VERIFY_PERMISSION (OPT_P_GENERAL);
- options->pkcs11_slot = p[1];
- }
- else if (streq (p[0], "pkcs11-id-type") && p[1])
- {
- ++i;
- VERIFY_PERMISSION (OPT_P_GENERAL);
- options->pkcs11_id_type = p[1];
- }
- else if (streq (p[0], "pkcs11-id") && p[1])
- {
- ++i;
- VERIFY_PERMISSION (OPT_P_GENERAL);
- options->pkcs11_id = p[1];
- }
- else if (streq (p[0], "pkcs11-protected-authentication"))
- {
- ++i;
- VERIFY_PERMISSION (OPT_P_GENERAL);
- options->pkcs11_protected_authentication = true;
- }
-#endif
#ifdef WIN32
else if (streq (p[0], "cryptoapicert") && p[1])
{
@@ -4968,6 +4891,89 @@ 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[i++];
+ VERIFY_PERMISSION (OPT_P_GENERAL);
+ show_pkcs11_slots (M_INFO|M_NOPREFIX, M_WARN|M_NOPREFIX, module);
+ openvpn_exit (OPENVPN_EXIT_STATUS_GOOD); /* exit point */
+ }
+ else if (streq (p[0], "show-pkcs11-objects") && p[1] && p[2])
+ {
+ char *provider = p[i++];
+ char *slot = p[i++];
+ struct gc_arena gc = gc_new ();
+ struct buffer pass_prompt = alloc_buf_gc (128, &gc);
+ char pin[256];
+
+ 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 (M_INFO|M_NOPREFIX, M_WARN|M_NOPREFIX, provider, slot, pin);
+ openvpn_exit (OPENVPN_EXIT_STATUS_GOOD); /* exit point */
+ }
+ else if (streq (p[0], "pkcs11-providers") && p[1])
+ {
+ int j;
+
+ VERIFY_PERMISSION (OPT_P_GENERAL);
+
+ for (j = 1; j < MAX_PARMS && p[j] != NULL; ++j, ++i)
+ options->pkcs11_providers[j-1] = p[j];
+ }
+ else if (streq (p[0], "pkcs11-sign-mode") && p[1])
+ {
+ int j;
+
+ VERIFY_PERMISSION (OPT_P_GENERAL);
+
+ for (j = 1; j < MAX_PARMS && p[j] != NULL; ++j, ++i)
+ options->pkcs11_sign_mode[j-1] = p[j];
+ }
+ else if (streq (p[0], "pkcs11-slot-type") && p[1])
+ {
+ ++i;
+ VERIFY_PERMISSION (OPT_P_GENERAL);
+ options->pkcs11_slot_type = p[1];
+ }
+ else if (streq (p[0], "pkcs11-slot") && p[1])
+ {
+ ++i;
+ VERIFY_PERMISSION (OPT_P_GENERAL);
+ options->pkcs11_slot = p[1];
+ }
+ else if (streq (p[0], "pkcs11-id-type") && p[1])
+ {
+ ++i;
+ VERIFY_PERMISSION (OPT_P_GENERAL);
+ options->pkcs11_id_type = p[1];
+ }
+ else if (streq (p[0], "pkcs11-id") && p[1])
+ {
+ ++i;
+ VERIFY_PERMISSION (OPT_P_GENERAL);
+ options->pkcs11_id = p[1];
+ }
+ else if (streq (p[0], "pkcs11-pin-cache") && p[1])
+ {
+ ++i;
+ VERIFY_PERMISSION (OPT_P_GENERAL);
+ options->pkcs11_pin_cache_period = atoi (p[1]);
+ }
+ else if (streq (p[0], "pkcs11-protected-authentication"))
+ {
+ ++i;
+ VERIFY_PERMISSION (OPT_P_GENERAL);
+ options->pkcs11_protected_authentication = true;
+ }
+#endif
#ifdef TUNSETPERSIST
else if (streq (p[0], "rmtun"))
{
diff --git a/options.h b/options.h
index 69a2f04..b9f3f12 100644
--- a/options.h
+++ b/options.h
@@ -385,6 +385,7 @@ struct options
const char *pkcs11_slot;
const char *pkcs11_id_type;
const char *pkcs11_id;
+ int pkcs11_pin_cache_period;
bool pkcs11_protected_authentication;
#ifdef WIN32
const char *cryptoapi_cert;
diff --git a/pkcs11.c b/pkcs11.c
index cee178e..54dc532 100644
--- a/pkcs11.c
+++ b/pkcs11.c
@@ -58,6 +58,12 @@
#include "pkcs11.h"
/*===========================================
+ * MACROS
+ */
+
+#define snprintf openvpn_snprintf
+
+/*===========================================
* Constants
*/
@@ -78,6 +84,25 @@
* Types
*/
+typedef bool (*pkcs11_hook_card_prompt_t)(
+ IN const void *pData,
+ IN const char * const szLabel
+);
+
+typedef bool (*pkcs11_hook_pin_prompt_t)(
+ IN const void *pData,
+ IN const char * const szLabel,
+ OUT char * const szPIN,
+ IN const size_t nMaxPIN
+);
+
+typedef struct pkcs11_hooks_s {
+ void *card_prompt_data;
+ void *pin_prompt_data;
+ pkcs11_hook_card_prompt_t card_prompt;
+ pkcs11_hook_pin_prompt_t pin_prompt;
+} *pkcs11_hooks_t;
+
typedef struct pkcs11_provider_s {
struct pkcs11_provider_s *next;
@@ -91,27 +116,39 @@ typedef struct pkcs11_provider_s {
CK_FUNCTION_LIST_PTR f;
bool fShouldFinalize;
char *szSignMode;
+
} *pkcs11_provider_t;
typedef struct pkcs11_session_s {
pkcs11_provider_t provider;
+ bool fProtectedAuthentication;
+
+ char szLabel[sizeof (((CK_TOKEN_INFO *)NULL)->label)+1];
+ CK_CHAR serialNumber[sizeof (((CK_TOKEN_INFO *)NULL)->serialNumber)];
+
unsigned char *certificate;
- int certificate_size;
+ size_t certificate_size;
unsigned char *certificate_id;
- int certificate_id_size;
-
- char *szPIN;
- bool fLoginFailed;
+ size_t certificate_id_size;
CK_SLOT_ID slot;
bool fKeySignRecover;
CK_SESSION_HANDLE session;
CK_OBJECT_HANDLE key;
+
+ time_t timePINExpire;
} *pkcs11_session_t;
+typedef struct pkcs11_data_s {
+ bool fInitialized;
+ int nPINCachePeriod;
+ pkcs11_provider_t providers;
+ pkcs11_hooks_t hooks;
+} *pkcs11_data_t;
+
/*===========================================
* Low level prototypes
*/
@@ -121,14 +158,14 @@ void
_fixupFixedString (
IN const char * const szSource,
OUT char * const szTarget, /* MUST BE >= nLength+1 */
- IN const int nLength /* FIXED STRING LENGTH */
+ IN const size_t nLength /* FIXED STRING LENGTH */
);
static
void
_hexToBinary (
IN const char * const szSource,
OUT unsigned char * const target,
- IN OUT int * const target_size
+ IN OUT size_t * const target_size
);
static
CK_RV
@@ -154,11 +191,21 @@ _pkcs11_getObjectById (
IN const pkcs11_session_t pkcs11_session,
IN const CK_OBJECT_CLASS class,
IN const unsigned char * const id,
- IN const int id_size,
+ IN const size_t id_size,
OUT CK_OBJECT_HANDLE * const handle
);
static
CK_RV
+_pkcs11_setSessionTokenInfo (
+ IN const pkcs11_session_t pkcs11_session
+);
+static
+CK_RV
+_pkcs11_resetSlot (
+ IN const pkcs11_session_t pkcs11_session
+);
+static
+CK_RV
_pkcs11_loadCertificate (
IN const pkcs11_session_t pkcs11_session,
IN const char * const szIdType,
@@ -173,15 +220,66 @@ static
bool
_isBetterCertificate (
IN const unsigned char * const pCurrent,
- IN const int nCurrentSize,
+ IN const size_t nCurrentSize,
IN const unsigned char * const pNew,
- IN const int nNewSize
+ IN const size_t nNewSize
+);
+static
+CK_RV
+_pkcs11_validateSession (
+ IN const pkcs11_session_t pkcs11_session
+);
+static
+CK_RV
+_pkcs11_login (
+ IN const pkcs11_session_t pkcs11_session
+);
+static
+CK_RV
+_pkcs11_logout (
+ IN const pkcs11_session_t pkcs11_session
);
/*=========================================
* Simplified functions prototypes
*/
-
+static
+bool
+_pkcs11_hooks_card_prompt_default (
+ IN const void *pData,
+ IN const char * const szLabel
+);
+static
+bool
+_pkcs11_hooks_pin_prompt_default (
+ IN const void *pData,
+ IN const char * const szLabel,
+ OUT char * const szPIN,
+ IN const size_t nMaxPIN
+);
+static
+CK_RV
+pkcs11_initialize ();
+static
+CK_RV
+pkcs11_terminate ();
+static
+CK_RV
+pkcs11_setCardPromptHook (
+ IN const pkcs11_hook_card_prompt_t hook,
+ IN void * const pData
+);
+static
+CK_RV
+pkcs11_setPINPromptHook (
+ IN const pkcs11_hook_pin_prompt_t hook,
+ IN void * const pData
+);
+static
+CK_RV
+pkcs11_setPINCachePeriod (
+ IN const int nPINCachePeriod
+);
static
CK_RV
pkcs11_addProvider (
@@ -190,7 +288,7 @@ pkcs11_addProvider (
);
static
CK_RV
-pkcs11_finalize ();
+pkcs11_forkFixup ();
static
CK_RV
pkcs11_createSession (
@@ -198,7 +296,6 @@ pkcs11_createSession (
IN const char * const szSlot,
IN const char * const szIdType,
IN const char * const szId,
- IN const char * const szPIN,
IN const bool fProtectedAuthentication,
OUT pkcs11_session_t * const pkcs11_session
);
@@ -209,23 +306,13 @@ pkcs11_freeSession (
);
static
CK_RV
-pkcs11_login (
- IN const pkcs11_session_t pkcs11_session
-);
-static
-CK_RV
-pkcs11_logout (
- IN const pkcs11_session_t pkcs11_session
-);
-static
-CK_RV
pkcs11_sign (
IN const pkcs11_session_t pkcs11_session,
IN const CK_MECHANISM_TYPE mech_type,
IN const unsigned char * const source,
- IN const int source_size,
+ IN const size_t source_size,
OUT unsigned char * const target,
- IN OUT int * const target_size
+ IN OUT size_t * const target_size
);
static
CK_RV
@@ -233,9 +320,9 @@ pkcs11_signRecover (
IN const pkcs11_session_t pkcs11_session,
IN const CK_MECHANISM_TYPE mech_type,
IN const unsigned char * const source,
- IN const int source_size,
+ IN const size_t source_size,
OUT unsigned char * const target,
- IN OUT int * const target_size
+ IN OUT size_t * const target_size
);
static
CK_RV
@@ -243,16 +330,16 @@ pkcs11_decrypt (
IN const pkcs11_session_t pkcs11_session,
IN const CK_MECHANISM_TYPE mech_type,
IN const unsigned char * const source,
- IN const int source_size,
+ IN const size_t source_size,
OUT unsigned char * const target,
- IN OUT int * const target_size
+ IN OUT size_t * const target_size
);
static
CK_RV
pkcs11_getCertificate (
IN const pkcs11_session_t pkcs11_session,
- OUT char * const certificate,
- IN OUT int * const certificate_size
+ OUT unsigned char * const certificate,
+ IN OUT size_t * const certificate_size
);
static
char *
@@ -264,7 +351,7 @@ pkcs11_getMessage (
* Static data
*/
-static pkcs11_provider_t pkcs11_provider = NULL;
+static pkcs11_data_t pkcs11_data = NULL;
/*==========================================
* Internal utility functions
@@ -275,7 +362,7 @@ void
_fixupFixedString (
IN const char * const szSource,
OUT char * const szTarget, /* MUST BE >= nLength+1 */
- IN const int nLength /* FIXED STRING LENGTH */
+ IN const size_t nLength /* FIXED STRING LENGTH */
) {
char *p;
@@ -297,9 +384,9 @@ void
_hexToBinary (
IN const char * const szSource,
OUT unsigned char * const target,
- IN OUT int * const target_size
+ IN OUT size_t * const target_size
) {
- int target_max_size;
+ size_t target_max_size;
const char *p;
char buf[3] = {'\0', '\0', '\0'};
int i = 0;
@@ -317,7 +404,7 @@ _hexToBinary (
buf[i%2] = *p;
if ((i%2) == 1) {
- int v;
+ unsigned v;
sscanf (buf, "%x", &v);
target[*target_size] = v & 0xff;
(*target_size)++;
@@ -333,9 +420,9 @@ static
bool
_isBetterCertificate (
IN const unsigned char * const pCurrent,
- IN const int nCurrentSize,
+ IN const size_t nCurrentSize,
IN const unsigned char * const pNew,
- IN const int nNewSize
+ IN const size_t nNewSize
) {
/*
* This function compare the notBefore
@@ -427,7 +514,7 @@ _pkcs11_getSlotById (
}
for (
- i=0, provider=pkcs11_provider;
+ i=0, provider=pkcs11_data->providers;
i < provider_number && provider != NULL;
i++, provider = provider->next
);
@@ -453,9 +540,6 @@ _pkcs11_getSlotByName (
IN const pkcs11_session_t pkcs11_session,
IN const char * const szName
) {
- CK_SLOT_ID slots[1024];
- CK_ULONG slotnum;
- CK_SLOT_ID s;
CK_RV rv;
pkcs11_provider_t provider;
@@ -465,13 +549,16 @@ _pkcs11_getSlotByName (
ASSERT (szName!=NULL);
for (
- provider = pkcs11_provider;
+ provider = pkcs11_data->providers;
(
provider != NULL &&
!fFound
);
provider = provider->next
) {
+ CK_SLOT_ID slots[1024];
+ CK_ULONG slotnum;
+
if (!provider->fEnabled) {
continue;
}
@@ -484,6 +571,8 @@ _pkcs11_getSlotByName (
&slotnum
)) == CKR_OK
) {
+ CK_SLOT_ID s;
+
for (s=0;!fFound && s<slotnum;s++) {
CK_SLOT_INFO info;
@@ -496,7 +585,7 @@ _pkcs11_getSlotByName (
char szCurrentName[sizeof (info.slotDescription)+1];
_fixupFixedString (
- info.slotDescription,
+ (char *)info.slotDescription,
szCurrentName,
sizeof (info.slotDescription)
);
@@ -520,9 +609,6 @@ _pkcs11_getSlotByLabel (
IN const pkcs11_session_t pkcs11_session,
IN const char * const szLabel
) {
- CK_SLOT_ID slots[1024];
- CK_ULONG slotnum;
- CK_SLOT_ID s;
CK_RV rv;
pkcs11_provider_t provider;
@@ -532,13 +618,16 @@ _pkcs11_getSlotByLabel (
ASSERT (szLabel!=NULL);
for (
- provider = pkcs11_provider;
+ provider = pkcs11_data->providers;
(
provider != NULL &&
!fFound
);
provider = provider->next
) {
+ CK_SLOT_ID slots[1024];
+ CK_ULONG slotnum;
+
if (!provider->fEnabled) {
continue;
}
@@ -551,6 +640,8 @@ _pkcs11_getSlotByLabel (
&slotnum
)) == CKR_OK
) {
+ CK_SLOT_ID s;
+
for (s=0;!fFound && s<slotnum;s++) {
CK_TOKEN_INFO info;
@@ -563,7 +654,7 @@ _pkcs11_getSlotByLabel (
char szCurrentLabel[sizeof (info.label)+1];
_fixupFixedString (
- info.label,
+ (char *)info.label,
szCurrentLabel,
sizeof (info.label)
);
@@ -583,16 +674,105 @@ _pkcs11_getSlotByLabel (
static
CK_RV
+_pkcs11_setSessionTokenInfo (
+ IN const pkcs11_session_t pkcs11_session
+) {
+ CK_TOKEN_INFO info;
+ CK_RV rv;
+
+ ASSERT (pkcs11_session!=NULL);
+
+ if (
+ (rv = pkcs11_session->provider->f->C_GetTokenInfo (
+ pkcs11_session->slot,
+ &info
+ )) == CKR_OK
+ ) {
+ _fixupFixedString (
+ (char *)info.label,
+ pkcs11_session->szLabel,
+ sizeof (info.label)
+ );
+
+ memmove (
+ pkcs11_session->serialNumber,
+ info.serialNumber,
+ sizeof (pkcs11_session->serialNumber)
+ );
+ }
+
+ return rv;
+}
+
+static
+CK_RV
+_pkcs11_resetSlot (
+ IN const pkcs11_session_t pkcs11_session
+) {
+ CK_SLOT_ID slots[1024];
+ CK_ULONG slotnum;
+ CK_RV rv;
+ bool fFound = false;
+ bool fCancel = false;
+
+ ASSERT (pkcs11_session!=NULL);
+
+ do {
+ slotnum = sizeof (slots) / sizeof (CK_SLOT_ID);
+ if (
+ (rv = pkcs11_session->provider->f->C_GetSlotList (
+ TRUE,
+ slots,
+ &slotnum
+ )) == CKR_OK
+ ) {
+ CK_SLOT_ID s;
+
+ for (s=0;!fFound && s<slotnum;s++) {
+ CK_TOKEN_INFO info;
+
+ if (
+ (rv = pkcs11_session->provider->f->C_GetTokenInfo (
+ slots[s],
+ &info
+ )) == CKR_OK
+ ) {
+ if (
+ !memcmp (
+ pkcs11_session->serialNumber,
+ info.serialNumber,
+ sizeof (pkcs11_session->serialNumber)
+ )
+ ) {
+ pkcs11_session->slot = slots[s];
+ fFound = true;
+ }
+ }
+ }
+ }
+
+ if (!fFound) {
+ fCancel = !pkcs11_data->hooks->card_prompt (
+ pkcs11_data->hooks->card_prompt_data,
+ pkcs11_session->szLabel
+ );
+ }
+ } while (!fFound && !fCancel);
+
+ return fFound ? CKR_OK : CKR_SLOT_ID_INVALID;
+}
+
+static
+CK_RV
_pkcs11_getObjectById (
IN const pkcs11_session_t pkcs11_session,
IN const CK_OBJECT_CLASS class,
IN const unsigned char * const id,
- IN const int id_size,
+ IN const size_t id_size,
OUT CK_OBJECT_HANDLE * const handle
) {
CK_ULONG count;
- bool fFound = false;
- CK_RV rv;
+ CK_RV rv = CKR_OK;
CK_ATTRIBUTE filter[] = {
{CKA_CLASS, (void *)&class, sizeof (class)},
@@ -603,34 +783,35 @@ _pkcs11_getObjectById (
ASSERT (id!=NULL);
ASSERT (handle!=NULL);
- if (
- (rv = pkcs11_session->provider->f->C_FindObjectsInit (
+ if (rv == CKR_OK) {
+ rv = pkcs11_session->provider->f->C_FindObjectsInit (
pkcs11_session->session,
filter,
sizeof (filter) / sizeof (CK_ATTRIBUTE)
- )) != CKR_OK
- ) {
- return rv;
+ );
}
- if (
- (rv = pkcs11_session->provider->f->C_FindObjects (
+ if (rv == CKR_OK) {
+ rv = pkcs11_session->provider->f->C_FindObjects (
pkcs11_session->session,
handle,
1,
&count
- )) == CKR_OK
+ );
+ }
+
+ if (
+ rv == CKR_OK &&
+ count == 0
) {
- if (count > 0) {
- fFound = true;
- }
+ rv = CKR_FUNCTION_REJECTED;
}
pkcs11_session->provider->f->C_FindObjectsFinal (
pkcs11_session->session
);
- return fFound ? CKR_OK : CKR_FUNCTION_REJECTED;
+ return rv;
}
static
@@ -674,7 +855,7 @@ _pkcs11_loadCertificate (
);
}
else if (!strcmp (szIdType, "id")) {
- int s = sizeof (cert_filter_by);
+ size_t s = sizeof (cert_filter_by);
cert_filter[1].type = CKA_ID;
_hexToBinary (
@@ -876,11 +1057,303 @@ _pkcs11_loadKeyProperties (
return CKR_OK;
}
+static
+CK_RV
+_pkcs11_validateSession (
+ IN const pkcs11_session_t pkcs11_session
+) {
+ if (
+ pkcs11_session->timePINExpire != (time_t)0 &&
+ pkcs11_session->timePINExpire < time (NULL)
+ ) {
+ _pkcs11_logout (pkcs11_session);
+ }
+ return CKR_OK;
+}
+
+static
+CK_RV
+_pkcs11_login (
+ IN const pkcs11_session_t pkcs11_session
+) {
+ CK_RV rv = CKR_OK;
+
+
+ ASSERT (pkcs11_session!=NULL);
+
+ _pkcs11_logout (pkcs11_session);
+
+ if (rv == CKR_OK) {
+ rv = _pkcs11_resetSlot (pkcs11_session);
+ }
+
+ if (rv == CKR_OK) {
+ rv = pkcs11_session->provider->f->C_OpenSession (
+ pkcs11_session->slot,
+ CKF_SERIAL_SESSION,
+ NULL_PTR,
+ NULL_PTR,
+ &pkcs11_session->session
+ );
+ }
+
+ if (rv == CKR_OK) {
+ int nRetryCount = 0;
+ do {
+ CK_UTF8CHAR_PTR utfPIN = NULL;
+ CK_ULONG lPINLength = 0;
+ char szPIN[1024];
+
+ /*
+ * Assume OK for next iteration
+ */
+ rv = CKR_OK;
+
+ if (
+ rv == CKR_OK &&
+ !pkcs11_session->fProtectedAuthentication
+ ) {
+ if (
+ !pkcs11_data->hooks->pin_prompt (
+ pkcs11_data->hooks->pin_prompt_data,
+ pkcs11_session->szLabel,
+ szPIN,
+ sizeof (szPIN)
+ )
+ ) {
+ rv = CKR_FUNCTION_FAILED;
+ }
+ else {
+ utfPIN = (CK_UTF8CHAR_PTR)szPIN;
+ lPINLength = strlen (szPIN);
+ }
+ }
+
+ if (pkcs11_data->nPINCachePeriod == -1) {
+ pkcs11_session->timePINExpire = 0;
+ }
+ else {
+ pkcs11_session->timePINExpire = (
+ time (NULL) +
+ (time_t)pkcs11_data->nPINCachePeriod
+ );
+ }
+ if (
+ rv == CKR_OK &&
+ (rv = pkcs11_session->provider->f->C_Login (
+ pkcs11_session->session,
+ CKU_USER,
+ utfPIN,
+ lPINLength
+ )) != CKR_OK
+ ) {
+ if (rv == CKR_USER_ALREADY_LOGGED_IN) {
+ rv = CKR_OK;
+ }
+ }
+
+ /*
+ * Clean PIN buffer
+ */
+ memset (szPIN, 0, sizeof (szPIN));
+ } while (
+ ++nRetryCount < 3 &&
+ (
+ rv == CKR_PIN_INCORRECT ||
+ rv == CKR_PIN_INVALID
+ )
+ );
+ }
+
+ if (
+ rv == CKR_OK &&
+ pkcs11_session->certificate_id != NULL
+ ) {
+ rv = _pkcs11_getObjectById (
+ pkcs11_session,
+ CKO_PRIVATE_KEY,
+ pkcs11_session->certificate_id,
+ pkcs11_session->certificate_id_size,
+ &pkcs11_session->key
+ );
+ }
+
+ return rv;
+}
+
+static
+CK_RV
+_pkcs11_logout (
+ IN const pkcs11_session_t pkcs11_session
+) {
+ ASSERT (pkcs11_session!=NULL);
+
+ if (pkcs11_session->session != (CK_SESSION_HANDLE)-1) {
+ pkcs11_session->provider->f->C_Logout (pkcs11_session->session);
+ pkcs11_session->provider->f->C_CloseSession (pkcs11_session->session);
+ pkcs11_session->key = (CK_OBJECT_HANDLE)-1;
+ pkcs11_session->session = (CK_SESSION_HANDLE)-1;
+ }
+
+ return CKR_OK;
+}
+
+
/*=======================================
* Simplified PKCS#11 functions
*/
static
+bool
+_pkcs11_hooks_card_prompt_default (
+ IN const void * pData,
+ IN const char * const szLabel
+) {
+ return false;
+}
+
+static
+bool
+_pkcs11_hooks_pin_prompt_default (
+ IN const void * pData,
+ IN const char * const szLabel,
+ OUT char * const szPIN,
+ IN const size_t nMaxPIN
+) {
+ return false;
+}
+
+static
+CK_RV
+pkcs11_initialize () {
+
+ pkcs11_terminate ();
+
+ pkcs11_data = (pkcs11_data_t)malloc (sizeof (struct pkcs11_data_s));
+ if (pkcs11_data == NULL) {
+ return CKR_HOST_MEMORY;
+ }
+
+ memset (pkcs11_data, 0, sizeof (struct pkcs11_data_s));
+
+ pkcs11_data->nPINCachePeriod = -1;
+
+ pkcs11_data->hooks = (pkcs11_hooks_t)malloc (sizeof (struct pkcs11_hooks_s));
+ if (pkcs11_data->hooks == NULL) {
+ return CKR_HOST_MEMORY;
+ }
+
+ memset (pkcs11_data->hooks, 0, sizeof (struct pkcs11_hooks_s));
+
+ pkcs11_data->fInitialized = true;
+
+ pkcs11_setCardPromptHook (_pkcs11_hooks_card_prompt_default, NULL);
+ pkcs11_setPINPromptHook (_pkcs11_hooks_pin_prompt_default, NULL);
+
+ return CKR_OK;
+}
+
+static
+CK_RV
+pkcs11_terminate () {
+
+ if (pkcs11_data != NULL) {
+ pkcs11_provider_t last = NULL;
+
+ for (
+ ;
+ pkcs11_data->providers != NULL;
+ pkcs11_data->providers = pkcs11_data->providers->next
+ ) {
+ if (last != NULL) {
+ free (last);
+ }
+ last = pkcs11_data->providers;
+
+ if (pkcs11_data->providers->szSignMode != NULL) {
+ free (pkcs11_data->providers->szSignMode);
+ pkcs11_data->providers->szSignMode = NULL;
+ }
+
+ if (pkcs11_data->providers->fShouldFinalize) {
+ pkcs11_data->providers->f->C_Finalize (NULL);
+ pkcs11_data->providers->fShouldFinalize = false;
+ }
+
+ if (pkcs11_data->providers->f != NULL) {
+ pkcs11_data->providers->f = NULL;
+ }
+
+ if (pkcs11_data->providers->hLibrary != NULL) {
+#if defined(WIN32)
+ FreeLibrary (pkcs11_data->providers->hLibrary);
+#else
+ dlclose (pkcs11_data->providers->hLibrary);
+#endif
+ pkcs11_data->providers->hLibrary = NULL;
+ }
+ }
+
+ if (last != NULL) {
+ free (last);
+ }
+
+ if (pkcs11_data->hooks != NULL) {
+ free (pkcs11_data->hooks);
+ pkcs11_data->hooks = NULL;
+ }
+
+ free (pkcs11_data);
+ pkcs11_data = NULL;
+ }
+
+ return CKR_OK;
+}
+
+static
+CK_RV
+pkcs11_setPINPromptHook (
+ IN const pkcs11_hook_pin_prompt_t hook,
+ IN void * const pData
+) {
+ ASSERT (pkcs11_data!=NULL);
+ ASSERT (pkcs11_data->fInitialized);
+
+ pkcs11_data->hooks->pin_prompt = hook;
+ pkcs11_data->hooks->pin_prompt_data = pData;
+
+ return CKR_OK;
+}
+
+static
+CK_RV
+pkcs11_setCardPromptHook (
+ IN const pkcs11_hook_card_prompt_t hook,
+ IN void * const pData
+) {
+ ASSERT (pkcs11_data!=NULL);
+ ASSERT (pkcs11_data->fInitialized);
+
+ pkcs11_data->hooks->card_prompt = hook;
+ pkcs11_data->hooks->card_prompt_data = pData;
+
+ return CKR_OK;
+}
+
+static
+CK_RV
+pkcs11_setPINCachePeriod (
+ IN const int nPINCachePeriod
+) {
+ ASSERT (pkcs11_data!=NULL);
+ ASSERT (pkcs11_data->fInitialized);
+
+ pkcs11_data->nPINCachePeriod = nPINCachePeriod;
+
+ return CKR_OK;
+}
+
+static
CK_RV
pkcs11_addProvider (
IN const char * const szProvider,
@@ -890,6 +1363,8 @@ pkcs11_addProvider (
CK_C_GetFunctionList gfl = NULL;
CK_RV rv = CKR_OK;
+ ASSERT (pkcs11_data!=NULL);
+ ASSERT (pkcs11_data->fInitialized);
ASSERT (szProvider!=NULL);
if (
@@ -930,10 +1405,18 @@ pkcs11_addProvider (
"C_GetFunctionList"
);
#else
- gfl = (CK_C_GetFunctionList)dlsym (
+ /*
+ * Make compiler happy!
+ */
+ void *p = dlsym (
provider->hLibrary,
"C_GetFunctionList"
);
+ memmove (
+ &gfl,
+ &p,
+ sizeof (void *)
+ );
#endif
if (gfl == NULL) {
rv = CKR_FUNCTION_FAILED;
@@ -960,14 +1443,14 @@ pkcs11_addProvider (
}
if (provider != NULL) {
- if (pkcs11_provider == NULL) {
- pkcs11_provider = provider;
+ if (pkcs11_data->providers == NULL) {
+ pkcs11_data->providers = provider;
}
else {
pkcs11_provider_t last = NULL;
for (
- last = pkcs11_provider;
+ last = pkcs11_data->providers;
last->next != NULL;
last = last->next
);
@@ -977,54 +1460,29 @@ pkcs11_addProvider (
return rv;
}
-
+
static
CK_RV
-pkcs11_finalize () {
-
- pkcs11_provider_t last = NULL;
+pkcs11_forkFixup () {
+
+ pkcs11_provider_t current;
+
+ ASSERT (pkcs11_data!=NULL);
+ ASSERT (pkcs11_data->fInitialized);
for (
- ;
- pkcs11_provider != NULL;
- pkcs11_provider = pkcs11_provider->next
+ current = pkcs11_data->providers;
+ current != NULL;
+ current = current->next
) {
- if (last != NULL) {
- free (last);
- }
- last = pkcs11_provider;
-
- if (pkcs11_provider->szSignMode != NULL) {
- free (pkcs11_provider->szSignMode);
- pkcs11_provider->szSignMode = NULL;
- }
-
- if (pkcs11_provider->fShouldFinalize) {
- pkcs11_provider->f->C_Finalize (NULL);
- pkcs11_provider->fShouldFinalize = false;
- }
-
- if (pkcs11_provider->f != NULL) {
- pkcs11_provider->f = NULL;
+ if (current->fEnabled) {
+ current->f->C_Initialize (NULL);
}
-
- if (pkcs11_provider->hLibrary != NULL) {
-#if defined(WIN32)
- FreeLibrary (pkcs11_provider->hLibrary);
-#else
- dlclose (pkcs11_provider->hLibrary);
-#endif
- pkcs11_provider->hLibrary = NULL;
- }
- }
-
- if (last != NULL) {
- free (last);
}
return CKR_OK;
}
-
+
static
CK_RV
pkcs11_createSession (
@@ -1032,18 +1490,18 @@ pkcs11_createSession (
IN const char * const szSlot,
IN const char * const szIdType,
IN const char * const szId,
- IN const char * const szPIN,
IN const bool fProtectedAuthentication,
OUT pkcs11_session_t * const p_pkcs11_session
) {
pkcs11_session_t pkcs11_session;
CK_RV rv = CKR_OK;
+ ASSERT (pkcs11_data!=NULL);
+ ASSERT (pkcs11_data->fInitialized);
ASSERT (szSlotType!=NULL);
ASSERT (szSlot!=NULL);
ASSERT (szIdType!=NULL);
ASSERT (szId!=NULL);
- ASSERT (szPIN!=NULL);
ASSERT (p_pkcs11_session!=NULL);
if (
@@ -1058,36 +1516,46 @@ pkcs11_createSession (
memset (pkcs11_session, 0, sizeof (struct pkcs11_session_s));
}
- if (
- rv == CKR_OK &&
- !fProtectedAuthentication
- ) {
- if ((pkcs11_session->szPIN = strdup (szPIN)) == NULL) {
- rv = CKR_HOST_MEMORY;
- }
- }
-
if (rv == CKR_OK) {
- pkcs11_session->fLoginFailed = false;
pkcs11_session->key = (CK_OBJECT_HANDLE)-1;
pkcs11_session->session = (CK_SESSION_HANDLE)-1;
+ pkcs11_session->fProtectedAuthentication = fProtectedAuthentication;
+ }
- if (!strcmp (szSlotType, "id")) {
- rv = _pkcs11_getSlotById (pkcs11_session, szSlot);
- }
- else if (!strcmp (szSlotType, "name")) {
- rv = _pkcs11_getSlotByName (pkcs11_session, szSlot);
- }
- else if (!strcmp (szSlotType, "label")) {
- rv = _pkcs11_getSlotByLabel (pkcs11_session, szSlot);
- }
- else {
- rv = CKR_ARGUMENTS_BAD;
- }
+ if (rv == CKR_OK) {
+ bool fCancel = false;
+
+ do {
+ if (!strcmp (szSlotType, "id")) {
+ rv = _pkcs11_getSlotById (pkcs11_session, szSlot);
+ }
+ else if (!strcmp (szSlotType, "name")) {
+ rv = _pkcs11_getSlotByName (pkcs11_session, szSlot);
+ }
+ else if (!strcmp (szSlotType, "label")) {
+ rv = _pkcs11_getSlotByLabel (pkcs11_session, szSlot);
+ }
+ else {
+ rv = CKR_ARGUMENTS_BAD;
+ }
+
+ if (rv == CKR_SLOT_ID_INVALID) {
+ char szLabel[1024];
+ snprintf (szLabel, sizeof (szLabel), "SLOT(%s=%s)", szSlotType, szSlot);
+ fCancel = !pkcs11_data->hooks->card_prompt (
+ pkcs11_data->hooks->card_prompt_data,
+ szLabel
+ );
+ }
+ } while (rv == CKR_SLOT_ID_INVALID && !fCancel);
+ }
+
+ if (rv == CKR_OK) {
+ rv = _pkcs11_setSessionTokenInfo (pkcs11_session);
}
if (rv == CKR_OK) {
- rv = pkcs11_login (
+ rv = _pkcs11_login (
pkcs11_session
);
}
@@ -1106,88 +1574,10 @@ pkcs11_createSession (
);
}
- pkcs11_logout (
- pkcs11_session
- );
-
- return rv;
-}
-
-CK_RV
-pkcs11_freeSession (
- IN const pkcs11_session_t pkcs11_session
-) {
- if (pkcs11_session != NULL) {
- pkcs11_logout (pkcs11_session);
-
- if (pkcs11_session->szPIN != NULL) {
- free (pkcs11_session->szPIN);
- }
- if (pkcs11_session->certificate != NULL) {
- free (pkcs11_session->certificate);
- }
- if (pkcs11_session->certificate_id != NULL) {
- free (pkcs11_session->certificate_id);
- }
-
- free (pkcs11_session);
- }
-
- return CKR_OK;
-}
-
-static
-CK_RV
-pkcs11_login (
- IN const pkcs11_session_t pkcs11_session
-) {
- CK_RV rv = CKR_OK;
-
- ASSERT (pkcs11_session!=NULL);
-
- pkcs11_logout (pkcs11_session);
-
- if (rv == CKR_OK) {
- rv = pkcs11_session->provider->f->C_OpenSession (
- pkcs11_session->slot,
- CKF_SERIAL_SESSION,
- NULL_PTR,
- NULL_PTR,
- &pkcs11_session->session
- );
- }
-
/*
- * Do not lock the token
+ * Complete missing login process
*/
- if (
- rv == CKR_OK &&
- pkcs11_session->fLoginFailed
- ) {
- rv = CKR_PIN_INVALID;
- }
-
- if (
- rv == CKR_OK &&
- (rv = pkcs11_session->provider->f->C_Login (
- pkcs11_session->session,
- CKU_USER,
- pkcs11_session->szPIN,
- pkcs11_session->szPIN == NULL ? 0 : (CK_ULONG)strlen (pkcs11_session->szPIN)
- )) != CKR_OK
- ) {
- if (rv == CKR_USER_ALREADY_LOGGED_IN) {
- rv = CKR_OK;
- }
- else {
- pkcs11_session->fLoginFailed = true;
- }
- }
-
- if (
- rv == CKR_OK &&
- pkcs11_session->certificate_id != NULL
- ) {
+ if (rv == CKR_OK) {
rv = _pkcs11_getObjectById (
pkcs11_session,
CKO_PRIVATE_KEY,
@@ -1197,25 +1587,27 @@ pkcs11_login (
);
}
- if (rv != CKR_OK) {
- pkcs11_logout (pkcs11_session);
- }
-
return rv;
}
-static
CK_RV
-pkcs11_logout (
+pkcs11_freeSession (
IN const pkcs11_session_t pkcs11_session
) {
- ASSERT (pkcs11_session!=NULL);
+ ASSERT (pkcs11_data!=NULL);
+ ASSERT (pkcs11_data->fInitialized);
- if (pkcs11_session->session != (CK_SESSION_HANDLE)-1) {
- pkcs11_session->provider->f->C_Logout (pkcs11_session->session);
- pkcs11_session->provider->f->C_CloseSession (pkcs11_session->session);
- pkcs11_session->key = (CK_OBJECT_HANDLE)-1;
- pkcs11_session->session = (CK_SESSION_HANDLE)-1;
+ if (pkcs11_session != NULL) {
+ _pkcs11_logout (pkcs11_session);
+
+ if (pkcs11_session->certificate != NULL) {
+ free (pkcs11_session->certificate);
+ }
+ if (pkcs11_session->certificate_id != NULL) {
+ free (pkcs11_session->certificate_id);
+ }
+
+ free (pkcs11_session);
}
return CKR_OK;
@@ -1227,40 +1619,55 @@ pkcs11_sign (
IN const pkcs11_session_t pkcs11_session,
IN const CK_MECHANISM_TYPE mech_type,
IN const unsigned char * const source,
- IN const int source_size,
+ IN const size_t source_size,
OUT unsigned char * const target,
- IN OUT int * const target_size
+ IN OUT size_t * const target_size
) {
CK_MECHANISM mech = {
mech_type, NULL, 0
};
- CK_ULONG size;
- CK_RV rv;
+ CK_RV rv = CKR_OK;
+ bool fLogonRetry = false;
+ bool fOpSuccess = false;
+ ASSERT (pkcs11_data!=NULL);
+ ASSERT (pkcs11_data->fInitialized);
ASSERT (pkcs11_session!=NULL);
ASSERT (source!=NULL);
ASSERT (target_size!=NULL);
- if (
- (rv = pkcs11_session->provider->f->C_SignInit (
+ rv = _pkcs11_validateSession (pkcs11_session);
+
+ while (rv == CKR_OK && !fOpSuccess) {
+ rv = pkcs11_session->provider->f->C_SignInit (
pkcs11_session->session,
&mech,
pkcs11_session->key
- )) != CKR_OK
- ) {
- return rv;
+ );
+
+ if (rv == CKR_OK) {
+ fOpSuccess = true;
+ }
+ else {
+ if (!fLogonRetry) {
+ fLogonRetry = true;
+ rv = _pkcs11_login (pkcs11_session);
+ }
+ }
}
- size = *target_size;
- rv = pkcs11_session->provider->f->C_Sign (
- pkcs11_session->session,
- (CK_BYTE_PTR)source,
- source_size,
- (CK_BYTE_PTR)target,
- &size
- );
+ if (rv == CKR_OK) {
+ CK_ULONG size = *target_size;
+ rv = pkcs11_session->provider->f->C_Sign (
+ pkcs11_session->session,
+ (CK_BYTE_PTR)source,
+ source_size,
+ (CK_BYTE_PTR)target,
+ &size
+ );
- *target_size = (int)size;
+ *target_size = (int)size;
+ }
return rv;
}
@@ -1271,40 +1678,55 @@ pkcs11_signRecover (
IN const pkcs11_session_t pkcs11_session,
IN const CK_MECHANISM_TYPE mech_type,
IN const unsigned char * const source,
- IN const int source_size,
+ IN const size_t source_size,
OUT unsigned char * const target,
- IN OUT int * const target_size
+ IN OUT size_t * const target_size
) {
CK_MECHANISM mech = {
mech_type, NULL, 0
};
- CK_ULONG size;
- CK_RV rv;
+ CK_RV rv = CKR_OK;
+ bool fLogonRetry = false;
+ bool fOpSuccess = false;
+ ASSERT (pkcs11_data!=NULL);
+ ASSERT (pkcs11_data->fInitialized);
ASSERT (pkcs11_session!=NULL);
ASSERT (source!=NULL);
ASSERT (target_size!=NULL);
- if (
- (rv = pkcs11_session->provider->f->C_SignRecoverInit (
+ rv = _pkcs11_validateSession (pkcs11_session);
+
+ while (rv == CKR_OK && !fOpSuccess) {
+ rv = pkcs11_session->provider->f->C_SignRecoverInit (
pkcs11_session->session,
&mech,
pkcs11_session->key
- )) != CKR_OK
- ) {
- return rv;
+ );
+
+ if (rv == CKR_OK) {
+ fOpSuccess = true;
+ }
+ else {
+ if (!fLogonRetry) {
+ fLogonRetry = true;
+ rv = _pkcs11_login (pkcs11_session);
+ }
+ }
}
- size = *target_size;
- rv = pkcs11_session->provider->f->C_SignRecover (
- pkcs11_session->session,
- (CK_BYTE_PTR)source,
- source_size,
- (CK_BYTE_PTR)target,
- &size
- );
+ if (rv == CKR_OK) {
+ CK_ULONG size = *target_size;
+ rv = pkcs11_session->provider->f->C_SignRecover (
+ pkcs11_session->session,
+ (CK_BYTE_PTR)source,
+ source_size,
+ (CK_BYTE_PTR)target,
+ &size
+ );
- *target_size = (int)size;
+ *target_size = (int)size;
+ }
return rv;
}
@@ -1315,40 +1737,56 @@ pkcs11_decrypt (
IN const pkcs11_session_t pkcs11_session,
IN const CK_MECHANISM_TYPE mech_type,
IN const unsigned char * const source,
- IN const int source_size,
+ IN const size_t source_size,
OUT unsigned char * const target,
- IN OUT int * const target_size
+ IN OUT size_t * const target_size
) {
CK_MECHANISM mech = {
mech_type, NULL, 0
};
CK_ULONG size;
- CK_RV rv;
+ CK_RV rv = CKR_OK;
+ bool fLogonRetry = false;
+ bool fOpSuccess = false;
+ ASSERT (pkcs11_data!=NULL);
+ ASSERT (pkcs11_data->fInitialized);
ASSERT (pkcs11_session!=NULL);
ASSERT (source!=NULL);
ASSERT (target_size!=NULL);
- if (
- (rv = pkcs11_session->provider->f->C_DecryptInit (
+ rv = _pkcs11_validateSession (pkcs11_session);
+
+ while (rv == CKR_OK && !fOpSuccess) {
+ rv = pkcs11_session->provider->f->C_DecryptInit (
pkcs11_session->session,
&mech,
pkcs11_session->key
- )) != CKR_OK
- ) {
- return rv;
+ );
+
+ if (rv == CKR_OK) {
+ fOpSuccess = true;
+ }
+ else {
+ if (!fLogonRetry) {
+ fLogonRetry = true;
+ rv = _pkcs11_login (pkcs11_session);
+ }
+ }
}
- size = *target_size;
- rv = pkcs11_session->provider->f->C_Decrypt (
- pkcs11_session->session,
- (CK_BYTE_PTR)source,
- source_size,
- (CK_BYTE_PTR)target,
- &size
- );
+ if (rv == CKR_OK) {
+ size = *target_size;
+ rv = pkcs11_session->provider->f->C_Decrypt (
+ pkcs11_session->session,
+ (CK_BYTE_PTR)source,
+ source_size,
+ (CK_BYTE_PTR)target,
+ &size
+ );
- *target_size = (int)size;
+ *target_size = (int)size;
+ }
return rv;
}
@@ -1357,9 +1795,11 @@ static
CK_RV
pkcs11_getCertificate (
IN const pkcs11_session_t pkcs11_session,
- OUT char * const certificate,
- IN OUT int * const certificate_size
+ OUT unsigned char * const certificate,
+ IN OUT size_t * const certificate_size
) {
+ ASSERT (pkcs11_data!=NULL);
+ ASSERT (pkcs11_data->fInitialized);
ASSERT (certificate_size!=NULL);
*certificate_size = pkcs11_session->certificate_size;
@@ -1474,10 +1914,11 @@ pkcs11_getMessage (
}
/*==========================================
- * openvpn interface
+ * openssl interface
*/
typedef struct openssl_session_s {
+ RSA_METHOD smart_rsa;
int (*orig_finish)(RSA *rsa);
pkcs11_session_t pkcs11_session;
} *openssl_session_t;
@@ -1525,7 +1966,7 @@ openssl_pkcs11_priv_dec (
flen,
from,
to,
- rsa,
+ (void *)rsa,
padding
);
@@ -1543,27 +1984,18 @@ openssl_pkcs11_priv_dec (
if (
rv == CKR_OK &&
- (rv = pkcs11_login (pkcs11_session)) != CKR_OK
- ) {
- msg (M_WARN, "PKCS#11: Cannot login to token %ld:'%s'", rv, pkcs11_getMessage (rv));
- }
-
- if (
- rv == CKR_OK &&
(rv = pkcs11_decrypt (
pkcs11_session,
CKM_RSA_PKCS,
from,
flen,
to,
- &flen
+ (size_t *)&flen
)) != CKR_OK
) {
msg (M_WARN, "PKCS#11: Cannot decrypt using private key %ld:'%s'", rv, pkcs11_getMessage (rv));
}
- pkcs11_logout (pkcs11_session);
-
msg (
D_PKCS11_DEBUG,
"PKCS#11: openssl_pkcs11_priv_dec - return rv=%ld",
@@ -1593,8 +2025,8 @@ openssl_pkcs11_sign (
m,
m_len,
sigret,
- siglen,
- rsa
+ (void *)siglen,
+ (void *)rsa
);
ASSERT (m!=NULL);
@@ -1607,46 +2039,35 @@ openssl_pkcs11_sign (
*siglen = RSA_size(rsa);
- if (
- rv == CKR_OK &&
- (rv = pkcs11_login (pkcs11_session)) != CKR_OK
- ) {
- msg (M_WARN, "PKCS#11: Cannot login to token %ld:'%s'", rv, pkcs11_getMessage (rv));
- }
-
- if (rv == CKR_OK) {
- if (pkcs11_session->fKeySignRecover) {
- if (
- (rv = pkcs11_signRecover (
- pkcs11_session,
- CKM_RSA_PKCS,
- m,
- m_len,
- sigret,
- siglen
- )) != CKR_OK
- ) {
- msg (M_WARN, "PKCS#11: Cannot perform signature-recover %ld:'%s'", rv, pkcs11_getMessage (rv));
- }
+ if (pkcs11_session->fKeySignRecover) {
+ if (
+ (rv = pkcs11_signRecover (
+ pkcs11_session,
+ CKM_RSA_PKCS,
+ m,
+ m_len,
+ sigret,
+ siglen
+ )) != CKR_OK
+ ) {
+ msg (M_WARN, "PKCS#11: Cannot perform signature-recover %ld:'%s'", rv, pkcs11_getMessage (rv));
}
- else {
- if (
- (rv = pkcs11_sign (
- pkcs11_session,
- CKM_RSA_PKCS,
- m,
- m_len,
- sigret,
- siglen
- )) != CKR_OK
- ) {
- msg (M_WARN, "PKCS#11: Cannot perform signature %ld:'%s'", rv, pkcs11_getMessage (rv));
- }
+ }
+ else {
+ if (
+ (rv = pkcs11_sign (
+ pkcs11_session,
+ CKM_RSA_PKCS,
+ m,
+ m_len,
+ sigret,
+ siglen
+ )) != CKR_OK
+ ) {
+ msg (M_WARN, "PKCS#11: Cannot perform signature %ld:'%s'", rv, pkcs11_getMessage (rv));
}
}
- pkcs11_logout (pkcs11_session);
-
msg (
D_PKCS11_DEBUG,
"PKCS#11: openssl_pkcs11_priv_sign - return rv=%ld",
@@ -1664,8 +2085,8 @@ openssl_pkcs11_finish(RSA *rsa) {
msg (
D_PKCS11_DEBUG,
- "PKCS#11: openssl_pkcs11_finish - entered - rsa=%p",
- rsa
+ "PKCS#11: openssl_pkcs11_finish - entered rsa=%p",
+ (void *)rsa
);
openssl_session = (openssl_session_t)RSA_get_app_data (rsa);
@@ -1703,27 +2124,37 @@ openssl_pkcs11_finish(RSA *rsa) {
return 1;
}
-static RSA_METHOD *
-openssl_pkcs11_get_rsa_method(RSA *rsa)
+void
+openssl_pkcs11_set_rsa(const openssl_session_t openssl_session, RSA *rsa)
{
- static RSA_METHOD smart_rsa;
const RSA_METHOD *def = RSA_get_default_method();
- ASSERT (rsa);
+ ASSERT (openssl_session!=NULL);
+ ASSERT (rsa!=NULL);
+
+ memmove (&openssl_session->smart_rsa, def, sizeof(RSA_METHOD));
- /* use the OpenSSL version */
- memmove (&smart_rsa, def, sizeof(smart_rsa));
+ openssl_session->orig_finish = def->finish;
- /* save original */
- ((openssl_session_t)RSA_get_app_data (rsa))->orig_finish = def->finish;
+ openssl_session->smart_rsa.name = "pkcs11";
+ openssl_session->smart_rsa.rsa_priv_enc = openssl_pkcs11_priv_enc;
+ openssl_session->smart_rsa.rsa_priv_dec = openssl_pkcs11_priv_dec;
+ openssl_session->smart_rsa.rsa_sign = openssl_pkcs11_sign;
+ openssl_session->smart_rsa.finish = openssl_pkcs11_finish;
+ openssl_session->smart_rsa.flags = RSA_METHOD_FLAG_NO_CHECK | RSA_FLAG_EXT_PKEY;
- smart_rsa.name = "pkcs11";
- smart_rsa.rsa_priv_enc = openssl_pkcs11_priv_enc;
- smart_rsa.rsa_priv_dec = openssl_pkcs11_priv_dec;
- smart_rsa.rsa_sign = openssl_pkcs11_sign;
- smart_rsa.finish = openssl_pkcs11_finish;
- smart_rsa.flags = RSA_METHOD_FLAG_NO_CHECK | RSA_FLAG_EXT_PKEY;
- return &smart_rsa;
+ RSA_set_method (rsa, &openssl_session->smart_rsa);
+ RSA_set_app_data (rsa, openssl_session);
+
+#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);
+ msg(M_WARN, "PKCS#11: OpenSSL engine support is broken! Workaround enabled");
+ }
+#endif
}
@@ -1737,6 +2168,150 @@ static void broken_openssl_init()
}
#endif
+/*==========================================
+ * openvpn interface
+ */
+
+static
+bool
+_openvpn_pkcs11_card_prompt (
+ IN const void *pData,
+ IN const char * const szLabel
+) {
+ static struct user_pass token_pass;
+ char szPrompt[1024];
+ char szTemp[1024];
+
+ ASSERT (szLabel!=NULL);
+
+ openvpn_snprintf (szPrompt, sizeof (szPrompt), "INSERT");
+
+ token_pass.defined = false;
+ token_pass.nocache = true;
+ get_user_pass (&token_pass, NULL, true, szPrompt, GET_USER_PASS_MANAGEMENT|GET_USER_PASS_SENSITIVE);
+ strncpynt (szTemp, token_pass.password, sizeof (szTemp));
+ purge_user_pass (&token_pass, true);
+
+ if (strlen (szTemp) == 0) {
+ return false;
+ }
+ else {
+ return true;
+ }
+}
+
+static
+bool
+_openvpn_pkcs11_pin_prompt (
+ IN const void *pData,
+ IN const char * const szLabel,
+ OUT char * const szPIN,
+ IN const size_t nMaxPIN
+) {
+ static struct user_pass token_pass;
+ char szPrompt[1024];
+
+ ASSERT (szLabel!=NULL);
+
+ openvpn_snprintf (szPrompt, sizeof (szPrompt), "%s token", szLabel);
+
+ token_pass.defined = false;
+ token_pass.nocache = true;
+ get_user_pass (&token_pass, NULL, true, szPrompt, GET_USER_PASS_MANAGEMENT|GET_USER_PASS_SENSITIVE);
+ strncpynt (szPIN, token_pass.password, nMaxPIN);
+ purge_user_pass (&token_pass, true);
+
+ if (strlen (szPIN) == 0) {
+ return false;
+ }
+ else {
+ return true;
+ }
+}
+
+void
+init_pkcs11 (
+ const int nPINCachePeriod
+) {
+ CK_RV rv;
+
+ msg (
+ D_PKCS11_DEBUG,
+ "PKCS#11: init_pkcs11 - entered"
+ );
+
+ if ((rv = pkcs11_initialize ()) != CKR_OK) {
+ msg (M_FATAL, "PKCS#11: Cannot initialize %ld-'%s'", rv, pkcs11_getMessage (rv));
+ }
+/*Until REQUEST/REPLY interface.
+ if ((rv = pkcs11_setCardPromptHook (_openvpn_pkcs11_card_prompt, NULL)) != CKR_OK) {
+ msg (M_FATAL, "PKCS#11: Cannot set hooks %ld-'%s'", rv, pkcs11_getMessage (rv));
+ }
+*/
+ if ((rv = pkcs11_setPINPromptHook (_openvpn_pkcs11_pin_prompt, NULL)) != CKR_OK) {
+ msg (M_FATAL, "PKCS#11: Cannot set hooks %ld-'%s'", rv, pkcs11_getMessage (rv));
+ }
+
+ if ((rv = pkcs11_setPINCachePeriod (nPINCachePeriod)) != CKR_OK) {
+ msg (M_FATAL, "PKCS#11: Cannot set PIN cache period %ld-'%s'", rv, pkcs11_getMessage (rv));
+ }
+
+ msg (
+ D_PKCS11_DEBUG,
+ "PKCS#11: init_pkcs11 - return"
+ );
+}
+
+void
+free_pkcs11 () {
+ msg (
+ D_PKCS11_DEBUG,
+ "PKCS#11: free_pkcs11 - entered"
+ );
+
+ pkcs11_terminate ();
+
+ msg (
+ D_PKCS11_DEBUG,
+ "PKCS#11: free_pkcs11 - return"
+ );
+}
+
+void
+fork_fix_pkcs11 () {
+ pkcs11_forkFixup ();
+}
+
+void
+add_pkcs11 (
+ IN const char * const provider,
+ IN const char * const sign_mode
+) {
+ CK_RV rv;
+
+ msg (
+ D_PKCS11_DEBUG,
+ "PKCS#11: add_pkcs11 - entered - provider='%s', sign_mode='%s'",
+ provider,
+ sign_mode == NULL ? "default" : sign_mode
+ );
+
+ msg (
+ M_INFO,
+ "PKCS#11: Adding PKCS#11 provider '%s'",
+ provider
+ );
+
+ if ((rv = pkcs11_addProvider (provider, sign_mode)) != CKR_OK) {
+ msg (M_WARN, "PKCS#11: Cannot initialize provider '%s' %ld-'%s'", provider, rv, pkcs11_getMessage (rv));
+ }
+
+ msg (
+ D_PKCS11_DEBUG,
+ "PKCS#11: add_pkcs11 - return"
+ );
+}
+
int
SSL_CTX_use_pkcs11 (
IN OUT SSL_CTX * const ssl_ctx,
@@ -1744,7 +2319,6 @@ SSL_CTX_use_pkcs11 (
IN const char * const pkcs11_slot,
IN const char * const pkcs11_id_type,
IN const char * const pkcs11_id,
- IN const char * const pin,
IN const bool pkcs11_protected_authentication
) {
X509 *x509 = NULL;
@@ -1755,14 +2329,14 @@ SSL_CTX_use_pkcs11 (
CK_RV rv = CKR_OK;
unsigned char certificate[10*1024];
- int certificate_size;
+ size_t certificate_size;
unsigned char *p;
bool fOK = true;
msg (
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', pkcs11_protected_authentication=%d",
- ssl_ctx,
+ (void *)ssl_ctx,
pkcs11_slot_type,
pkcs11_slot,
pkcs11_id_type,
@@ -1775,9 +2349,6 @@ SSL_CTX_use_pkcs11 (
ASSERT (pkcs11_slot!=NULL);
ASSERT (pkcs11_id_type!=NULL);
ASSERT (pkcs11_id!=NULL);
- if (!pkcs11_protected_authentication) {
- ASSERT (pin!=NULL);
- }
if (
fOK &&
@@ -1798,7 +2369,6 @@ SSL_CTX_use_pkcs11 (
pkcs11_slot,
pkcs11_id_type,
pkcs11_id,
- pin,
pkcs11_protected_authentication,
&openssl_session->pkcs11_session
)) != CKR_OK
@@ -1862,23 +2432,12 @@ SSL_CTX_use_pkcs11 (
}
if (fOK) {
- RSA_set_app_data (rsa, openssl_session);
- RSA_set_method (rsa, openssl_pkcs11_get_rsa_method (rsa));
+ openssl_pkcs11_set_rsa (openssl_session, rsa);
rsa->flags |= RSA_FLAG_SIGN_VER;
/* it will be freed when rsa usage count will be zero */
fShouldFreeOpenSSLSession = false;
}
-
-#ifdef BROKEN_OPENSSL_ENGINE
- if (fOK) {
- if (!rsa->engine)
- rsa->engine = ENGINE_get_default_RSA();
-
- ENGINE_set_RSA(ENGINE_get_default_RSA(), openssl_pkcs11_get_rsa_method(rsa));
- msg(M_WARN, "PKCS#11: OpenSSL engine support is broken! Workaround enabled");
- }
-#endif
if (
fOK &&
@@ -1936,51 +2495,6 @@ SSL_CTX_use_pkcs11 (
}
void
-add_pkcs11 (
- IN const char * const provider,
- IN const char * const sign_mode
-) {
- CK_RV rv;
-
- msg (
- D_PKCS11_DEBUG,
- "PKCS#11: add_pkcs11 - entered - provider='%s', sign_mode='%s'",
- provider,
- sign_mode == NULL ? "default" : sign_mode
- );
-
- msg (
- M_INFO,
- "PKCS#11: Adding PKCS#11 provider '%s'",
- provider
- );
-
- if ((rv = pkcs11_addProvider (provider, sign_mode)) != CKR_OK) {
- msg (M_WARN, "PKCS#11: Cannot initialize provider '%s' %ld-'%s'", provider, rv, pkcs11_getMessage (rv));
- }
-
- msg (
- D_PKCS11_DEBUG,
- "PKCS#11: add_pkcs11 - return"
- );
-}
-
-void
-free_pkcs11 () {
- msg (
- D_PKCS11_DEBUG,
- "PKCS#11: free_pkcs11 - entered"
- );
-
- pkcs11_finalize ();
-
- msg (
- D_PKCS11_DEBUG,
- "PKCS#11: free_pkcs11 - return"
- );
-}
-
-void
show_pkcs11_slots (
IN const int msglev,
IN const int warnlev,
@@ -1992,14 +2506,30 @@ show_pkcs11_slots (
CK_SLOT_ID s;
CK_RV rv;
+ pkcs11_provider_t pkcs11_provider;
+
ASSERT (provider!=NULL);
if (
+ (rv = pkcs11_initialize ()) != CKR_OK
+ ) {
+ msg (M_FATAL, "PKCS#11: Cannot initialize interface %ld-'%s'", rv, pkcs11_getMessage (rv));
+ }
+
+ if (
(rv = pkcs11_addProvider (provider, NULL)) != CKR_OK
) {
msg (M_FATAL, "PKCS#11: Cannot initialize provider %ld-'%s'", rv, pkcs11_getMessage (rv));
}
+ /*
+ * our provider is head
+ */
+ pkcs11_provider = pkcs11_data->providers;
+ if (pkcs11_provider == NULL || !pkcs11_provider->fEnabled) {
+ msg (M_FATAL, "PKCS#11: Cannot get provider %ld-'%s'", rv, pkcs11_getMessage (rv));
+ }
+
if (
(rv = pkcs11_provider->f->C_GetInfo (&info)) != CKR_OK
) {
@@ -2009,7 +2539,7 @@ show_pkcs11_slots (
char szManufacturerID[sizeof (info.manufacturerID)+1];
_fixupFixedString (
- info.manufacturerID,
+ (char *)info.manufacturerID,
szManufacturerID,
sizeof (info.manufacturerID)
);
@@ -2062,7 +2592,7 @@ show_pkcs11_slots (
char szCurrentName[sizeof (info.slotDescription)+1];
_fixupFixedString (
- info.slotDescription,
+ (char *)info.slotDescription,
szCurrentName,
sizeof (info.slotDescription)
);
@@ -2072,7 +2602,19 @@ show_pkcs11_slots (
}
}
- pkcs11_finalize ();
+ pkcs11_terminate ();
+}
+
+static
+bool
+_show_pkcs11_objects_pin_prompt (
+ IN const void *pData,
+ IN const char * const szLabel,
+ OUT char * const szPIN,
+ IN const size_t nMaxPIN
+) {
+ strncpy (szPIN, (char *)pData, nMaxPIN);
+ return true;
}
void
@@ -2090,6 +2632,8 @@ show_pkcs11_objects (
CK_SLOT_ID s;
CK_RV rv;
+ pkcs11_provider_t pkcs11_provider;
+
ASSERT (provider!=NULL);
ASSERT (slot!=NULL);
ASSERT (pin!=NULL);
@@ -2097,11 +2641,31 @@ show_pkcs11_objects (
s = atoi (slot);
if (
+ (rv = pkcs11_initialize ()) != CKR_OK
+ ) {
+ msg (M_FATAL, "PKCS#11: Cannot initialize interface %ld-'%s'", rv, pkcs11_getMessage (rv));
+ }
+
+ if (
+ (rv = pkcs11_setPINPromptHook (_show_pkcs11_objects_pin_prompt, (void *)pin)) != CKR_OK
+ ) {
+ msg (M_FATAL, "PKCS#11: Cannot set hooks %ld-'%s'", rv, pkcs11_getMessage (rv));
+ }
+
+ if (
(rv = pkcs11_addProvider (provider, NULL)) != CKR_OK
) {
msg (M_FATAL, "PKCS#11: Cannot initialize provider %ld-'%s'", rv, pkcs11_getMessage (rv));
}
+ /*
+ * our provider is head
+ */
+ pkcs11_provider = pkcs11_data->providers;
+ if (pkcs11_provider == NULL || !pkcs11_provider->fEnabled) {
+ msg (M_FATAL, "PKCS#11: Cannot get provider %ld-'%s'", rv, pkcs11_getMessage (rv));
+ }
+
if (
(rv = pkcs11_provider->f->C_GetTokenInfo (
s,
@@ -2117,22 +2681,22 @@ show_pkcs11_objects (
char szSerialNumber[sizeof (info.serialNumber)+1];
_fixupFixedString (
- info.label,
+ (char *)info.label,
szLabel,
sizeof (info.label)
);
_fixupFixedString (
- info.manufacturerID,
+ (char *)info.manufacturerID,
szManufacturerID,
sizeof (info.manufacturerID)
);
_fixupFixedString (
- info.model,
+ (char *)info.model,
szModel,
sizeof (info.model)
);
_fixupFixedString (
- info.serialNumber,
+ (char *)info.serialNumber,
szSerialNumber,
sizeof (info.serialNumber)
);
@@ -2385,9 +2949,9 @@ show_pkcs11_objects (
pkcs11_provider->f->C_FindObjectsFinal (session);
pkcs11_provider->f->C_Logout (session);
pkcs11_provider->f->C_CloseSession (session);
- pkcs11_finalize ();
+ pkcs11_terminate ();
}
#else
static void dummy (void) {}
-#endif /* USE_OPENSC && USE_SSL && USE_CRYPTO */
+#endif /* ENABLE_PKCS11 */
diff --git a/pkcs11.h b/pkcs11.h
index fdb1b91..a6f0f89 100644
--- a/pkcs11.h
+++ b/pkcs11.h
@@ -29,6 +29,23 @@
#include <openssl/ssl.h>
+void
+init_pkcs11 (
+ const int nPINCachePeriod
+);
+
+void
+free_pkcs11 ();
+
+void
+fork_fix_pkcs11 ();
+
+void
+add_pkcs11 (
+ const char * const provider,
+ const char * const sign_mode
+);
+
int
SSL_CTX_use_pkcs11 (
SSL_CTX * const ssl_ctx,
@@ -36,20 +53,10 @@ SSL_CTX_use_pkcs11 (
const char * const pkcs11_slot,
const char * const pkcs11_id_type,
const char * const pkcs11_id,
- const char * const pin,
const bool pkcs11_protected_authentication
);
void
-add_pkcs11 (
- const char * const provider,
- const char * const sign_mode
-);
-
-void
-free_pkcs11 ();
-
-void
show_pkcs11_slots (
const int msglev,
const int warnlev,
@@ -65,6 +72,6 @@ show_pkcs11_objects (
const char * const pin
);
-#endif
+#endif /* ENABLE_PKCS11 */
-#endif
+#endif /* OPENVPN_PKCS11_H */
diff --git a/ssl.c b/ssl.c
index 05bd85f..dc2381e 100644
--- a/ssl.c
+++ b/ssl.c
@@ -854,17 +854,8 @@ init_ssl (const struct options *options)
#ifdef ENABLE_PKCS11
if (options->pkcs11_providers[0])
{
- char password[256];
- password[0] = '\0';
- if (
- !options->pkcs11_protected_authentication &&
- options->key_pass_file
- ) {
- pem_password_callback (password, sizeof(password) - 1, 0, NULL);
- }
-
/* 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, password, options->pkcs11_protected_authentication))
+ if (!SSL_CTX_use_pkcs11 (ctx, options->pkcs11_slot_type, options->pkcs11_slot, options->pkcs11_id_type, options->pkcs11_id, options->pkcs11_protected_authentication))
msg (M_SSLERR, "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);
}