Browse code

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

james authored on 2005/10/17 16:39:41
Showing 8 changed files
... ...
@@ -3,6 +3,10 @@ Copyright (C) 2002-2005 OpenVPN Solutions LLC <info@openvpn.net>
3 3
 
4 4
 $Id$
5 5
 
6
+2005.10.xx -- Version 2.1-beta5
7
+
8
+* More PKCS#11 additions/changes (Alon Bar-Lev).
9
+
6 10
 2005.10.17 -- Version 2.1-beta4
7 11
 
8 12
 * Fixed bug introduced in 2.1-beta3 where management
... ...
@@ -25,7 +25,7 @@ dnl Process this file with autoconf to produce a configure script.
25 25
 
26 26
 AC_PREREQ(2.50)
27 27
 
28
-AC_INIT([OpenVPN], [2.1_beta4], [openvpn-users@lists.sourceforge.net], [openvpn])
28
+AC_INIT([OpenVPN], [2.1_beta5], [openvpn-users@lists.sourceforge.net], [openvpn])
29 29
 AM_CONFIG_HEADER(config.h)
30 30
 AC_CONFIG_SRCDIR(syshead.h)
31 31
 
... ...
@@ -111,15 +111,16 @@ context_init_1 (struct context *c)
111 111
   /* Certificate password input */
112 112
   if (c->options.key_pass_file)
113 113
     pem_password_setup (c->options.key_pass_file);
114
+#endif
114 115
 
115 116
 #if defined(ENABLE_PKCS11)
116 117
   {
117 118
     int i;
119
+    init_pkcs11 (c->options.pkcs11_pin_cache_period);
118 120
     for (i=0;i<MAX_PARMS && c->options.pkcs11_providers[i] != NULL;i++)
119 121
      add_pkcs11 (c->options.pkcs11_providers[i], c->options.pkcs11_sign_mode[i]);
120 122
   }
121 123
 #endif
122
-#endif
123 124
   
124 125
 #if P2MP
125 126
   /* Auth user/pass input */
... ...
@@ -232,13 +233,11 @@ uninit_static (void)
232 232
 
233 233
 #ifdef USE_CRYPTO
234 234
   free_ssl_lib ();
235
+#endif
235 236
 
236
-#ifdef USE_SSL
237 237
 #ifdef ENABLE_PKCS11
238 238
   free_pkcs11 ();
239 239
 #endif
240
-#endif
241
-#endif
242 240
 
243 241
 #if defined(MEASURE_TLS_HANDSHAKE_STATS) && defined(USE_CRYPTO) && defined(USE_SSL)
244 242
   show_tls_performance_stats ();
... ...
@@ -375,6 +374,11 @@ possibly_become_daemon (const struct options *options, const bool first_time)
375 375
 	msg (M_ERR, "daemon() failed");
376 376
       if (options->log)
377 377
 	set_std_files_to_null (true);
378
+
379
+#if defined(ENABLE_PKCS11)
380
+      fork_fix_pkcs11 ();
381
+#endif
382
+
378 383
       ret = true;
379 384
     }
380 385
   return ret;
... ...
@@ -425,24 +425,6 @@ static const char usage_message[] =
425 425
   "--key file      : Local private key in .pem format.\n"
426 426
   "--pkcs12 file   : PKCS#12 file containing local private key, local certificate\n"
427 427
   "                  and optionally the root CA certificate.\n"
428
-#ifdef ENABLE_PKCS11
429
-  "--pkcs11-providers provider ... : PKCS#11 provider to load.\n"
430
-  "--pkcs11-sign-mode mode ... : PKCS#11 signature method.\n"
431
-  "                              auto    : Try  to determind automatically (default).\n"
432
-  "                              recover : Use SignRecover.\n"
433
-  "                              sign    : Use Sign.\n"
434
-  "--pkcs11-slot-type method   : Slot locate method:\n"
435
-  "                              id      : By slot id (numeric [prov#:]slot#).\n"
436
-  "                              name    : By slot name.\n"
437
-  "                              label   : By the card label that resides in slot.\n"
438
-  "--pkcs11-slot name          : The slot name.\n"
439
-  "--pkcs11-id-type method     : Certificate and key locate method:\n"
440
-  "                              id      : By the object id (hex format).\n"
441
-  "                              label   : By the object label (string).\n"
442
-  "                              subject : By certificate subject (String).\n"
443
-  "--pkcs11-id name            : The object name.\n"
444
-  "--pkcs11-protected-authentication : Use PKCS#11 protected authentication path.\n"
445
-#endif
446 428
 #ifdef WIN32
447 429
   "--cryptoapicert select-string : Load the certificate and private key from the\n"
448 430
   "                  Windows Certificate System Store.\n"
... ...
@@ -479,7 +461,29 @@ static const char usage_message[] =
479 479
   "--ns-cert-type t: Require that peer certificate was signed with an explicit\n"
480 480
   "                  nsCertType designation t = 'client' | 'server'.\n"
481 481
 #endif				/* USE_SSL */
482
+#ifdef ENABLE_PKCS11
482 483
   "\n"
484
+  "PKCS#11 Options:\n"
485
+  "--pkcs11-providers provider ... : PKCS#11 provider to load.\n"
486
+  "--pkcs11-sign-mode mode ... : PKCS#11 signature method.\n"
487
+  "                              auto    : Try  to determind automatically (default).\n"
488
+  "                              recover : Use SignRecover.\n"
489
+  "                              sign    : Use Sign.\n"
490
+  "--pkcs11-slot-type method   : Slot locate method:\n"
491
+  "                              id      : By slot id (numeric [prov#:]slot#).\n"
492
+  "                              name    : By slot name.\n"
493
+  "                              label   : By the card label that resides in slot.\n"
494
+  "--pkcs11-slot name          : The slot name.\n"
495
+  "--pkcs11-id-type method     : Certificate and key locate method:\n"
496
+  "                              id      : By the object id (hex format).\n"
497
+  "                              label   : By the object label (string).\n"
498
+  "                              subject : By certificate subject (String).\n"
499
+  "--pkcs11-id name            : The object name.\n"
500
+  "--pkcs11-pin-cache seconds  : Number of seconds to cache PIN. The default is -1\n"
501
+  "                              cache until token removed.\n"
502
+  "--pkcs11-protected-authentication : Use PKCS#11 protected authentication path.\n"
503
+#endif			/* ENABLE_PKCS11 */
504
+ "\n"
483 505
   "SSL Library information:\n"
484 506
   "--show-ciphers  : Show cipher algorithms to use with --cipher option.\n"
485 507
   "--show-digests  : Show message digest algorithms to use with --auth option.\n"
... ...
@@ -554,14 +558,12 @@ static const char usage_message[] =
554 554
   "--dev tunX|tapX : tun/tap device\n"
555 555
   "--dev-type dt   : Device type.  See tunnel options above for details.\n"
556 556
 #endif
557
-#ifdef USE_SSL
558 557
 #ifdef ENABLE_PKCS11
559 558
   "\n"
560
-  "PKCS#11 specific:\n"
559
+  "PKCS#11 standalone options:\n"
561 560
   "--show-pkcs11-slots provider        : Show PKCS#11 provider available slots.\n"
562 561
   "--show-pkcs11-objects provider slot : Show PKCS#11 token objects.\n" 
563
-#endif
564
-#endif
562
+#endif				/* ENABLE_PKCS11 */
565 563
  ;
566 564
 
567 565
 #endif /* !ENABLE_SMALL */
... ...
@@ -646,11 +648,12 @@ init_options (struct options *o)
646 646
   o->renegotiate_seconds = 3600;
647 647
   o->handshake_window = 60;
648 648
   o->transition_window = 3600;
649
-#ifdef ENABLE_PKCS11
650
-  o->pkcs11_protected_authentication = false;
651
-#endif
652 649
 #endif
653 650
 #endif
651
+#ifdef ENABLE_PKCS11
652
+  o->pkcs11_pin_cache_period = -1;
653
+  o->pkcs11_protected_authentication = false;
654
+#endif			/* ENABLE_PKCS11 */
654 655
 }
655 656
 
656 657
 void
... ...
@@ -1178,23 +1181,6 @@ show_settings (const struct options *o)
1178 1178
   SHOW_STR (cert_file);
1179 1179
   SHOW_STR (priv_key_file);
1180 1180
   SHOW_STR (pkcs12_file);
1181
-#ifdef ENABLE_PKCS11
1182
-  {
1183
-    int i;
1184
-    for (i=0;i<MAX_PARMS && o->pkcs11_providers[i] != NULL;i++)
1185
-      SHOW_PARM (pkcs11_providers, o->pkcs11_providers[i], "%s");
1186
-  }
1187
-  {
1188
-    int i;
1189
-    for (i=0;i<MAX_PARMS && o->pkcs11_sign_mode[i] != NULL;i++)
1190
-      SHOW_PARM (pkcs11_sign_mode, o->pkcs11_sign_mode[i], "%s");
1191
-  }
1192
-  SHOW_STR (pkcs11_slot_type);
1193
-  SHOW_STR (pkcs11_slot);
1194
-  SHOW_STR (pkcs11_id_type);
1195
-  SHOW_STR (pkcs11_id);
1196
-  SHOW_BOOL (pkcs11_protected_authentication);
1197
-#endif
1198 1181
 #ifdef WIN32
1199 1182
   SHOW_STR (cryptoapi_cert);
1200 1183
 #endif
... ...
@@ -1220,6 +1206,25 @@ show_settings (const struct options *o)
1220 1220
 #endif
1221 1221
 #endif
1222 1222
 
1223
+#ifdef ENABLE_PKCS11
1224
+  {
1225
+    int i;
1226
+    for (i=0;i<MAX_PARMS && o->pkcs11_providers[i] != NULL;i++)
1227
+      SHOW_PARM (pkcs11_providers, o->pkcs11_providers[i], "%s");
1228
+  }
1229
+  {
1230
+    int i;
1231
+    for (i=0;i<MAX_PARMS && o->pkcs11_sign_mode[i] != NULL;i++)
1232
+      SHOW_PARM (pkcs11_sign_mode, o->pkcs11_sign_mode[i], "%s");
1233
+  }
1234
+  SHOW_STR (pkcs11_slot_type);
1235
+  SHOW_STR (pkcs11_slot);
1236
+  SHOW_STR (pkcs11_id_type);
1237
+  SHOW_STR (pkcs11_id);
1238
+  SHOW_INT (pkcs11_pin_cache_period);
1239
+  SHOW_BOOL (pkcs11_protected_authentication);
1240
+#endif			/* ENABLE_PKCS11 */
1241
+
1223 1242
 #if P2MP
1224 1243
   show_p2mp_parms (o);
1225 1244
 #endif
... ...
@@ -1702,11 +1707,6 @@ options_postprocess (struct options *options, bool first_time)
1702 1702
 
1703 1703
 	notnull (options->pkcs11_id, "PKCS#11 id (--pkcs11-id)");
1704 1704
 
1705
-	if (options->pkcs11_protected_authentication && options->key_pass_file != NULL)
1706
-	  msg(M_USAGE, "Parameter --askpass cannot be used when --pkcs11-protected-authentication is also specified.");
1707
-	if (!options->pkcs11_protected_authentication && options->key_pass_file == NULL)
1708
-	  msg (M_USAGE, "Please specify one of --askpass or --pkcs11-protected-autentication options.");
1709
-
1710 1705
 	if (options->cert_file)
1711 1706
 	  msg(M_USAGE, "Parameter --cert cannot be used when --pkcs11-provider is also specified.");
1712 1707
 	if (options->priv_key_file)
... ...
@@ -4733,83 +4733,6 @@ add_option (struct options *options,
4733 4733
       VERIFY_PERMISSION (OPT_P_GENERAL);
4734 4734
       options->cert_file = p[1];
4735 4735
     }
4736
-#ifdef ENABLE_PKCS11
4737
-  else if (streq (p[0], "show-pkcs11-slots") && p[1])
4738
-    {
4739
-      char *module =  p[i++];
4740
-      VERIFY_PERMISSION (OPT_P_GENERAL);
4741
-      show_pkcs11_slots (M_INFO|M_NOPREFIX, M_WARN|M_NOPREFIX, module);
4742
-      openvpn_exit (OPENVPN_EXIT_STATUS_GOOD); /* exit point */
4743
-    }
4744
-  else if (streq (p[0], "show-pkcs11-objects") && p[1] && p[2])
4745
-    {
4746
-      char *provider =  p[i++];
4747
-      char *slot = p[i++];
4748
-      struct gc_arena gc = gc_new ();
4749
-      struct buffer pass_prompt = alloc_buf_gc (128, &gc);
4750
-      char pin[256];
4751
-
4752
-      VERIFY_PERMISSION (OPT_P_GENERAL);
4753
-
4754
-      buf_printf (&pass_prompt, "PIN:");
4755
-
4756
-      if (!get_console_input (BSTR (&pass_prompt), false, pin, sizeof (pin)))
4757
-        msg (M_FATAL, "Cannot read password from stdin");
4758
-      
4759
-      gc_free (&gc);
4760
-      
4761
-      show_pkcs11_objects (M_INFO|M_NOPREFIX, M_WARN|M_NOPREFIX, provider, slot, pin);
4762
-      openvpn_exit (OPENVPN_EXIT_STATUS_GOOD); /* exit point */
4763
-    }
4764
-  else if (streq (p[0], "pkcs11-providers") && p[1])
4765
-    {
4766
-      int j;
4767
-      
4768
-      VERIFY_PERMISSION (OPT_P_GENERAL);
4769
-
4770
-      for (j = 1; j < MAX_PARMS && p[j] != NULL; ++j, ++i)
4771
-      	options->pkcs11_providers[j-1] = p[j];
4772
-    }
4773
-  else if (streq (p[0], "pkcs11-sign-mode") && p[1])
4774
-    {
4775
-      int j;
4776
-      
4777
-      VERIFY_PERMISSION (OPT_P_GENERAL);
4778
-
4779
-      for (j = 1; j < MAX_PARMS && p[j] != NULL; ++j, ++i)
4780
-      	options->pkcs11_sign_mode[j-1] = p[j];
4781
-    }
4782
-  else if (streq (p[0], "pkcs11-slot-type") && p[1])
4783
-    {
4784
-      ++i;
4785
-      VERIFY_PERMISSION (OPT_P_GENERAL);
4786
-      options->pkcs11_slot_type = p[1];
4787
-    }
4788
-  else if (streq (p[0], "pkcs11-slot") && p[1])
4789
-    {
4790
-      ++i;
4791
-      VERIFY_PERMISSION (OPT_P_GENERAL);
4792
-      options->pkcs11_slot = p[1];
4793
-    }
4794
-  else if (streq (p[0], "pkcs11-id-type") && p[1])
4795
-    {
4796
-      ++i;
4797
-      VERIFY_PERMISSION (OPT_P_GENERAL);
4798
-      options->pkcs11_id_type = p[1];
4799
-    }
4800
-  else if (streq (p[0], "pkcs11-id") && p[1])
4801
-    {
4802
-      ++i;
4803
-      VERIFY_PERMISSION (OPT_P_GENERAL);
4804
-      options->pkcs11_id = p[1];
4805
-    }
4806
-  else if (streq (p[0], "pkcs11-protected-authentication"))
4807
-    {
4808
-      ++i;
4809
-      VERIFY_PERMISSION (OPT_P_GENERAL);
4810
-      options->pkcs11_protected_authentication = true;
4811
-    }
4812
-#endif
4813 4736
 #ifdef WIN32
4814 4737
   else if (streq (p[0], "cryptoapicert") && p[1])
4815 4738
     {
... ...
@@ -4968,6 +4891,89 @@ add_option (struct options *options,
4968 4968
     }
4969 4969
 #endif /* USE_SSL */
4970 4970
 #endif /* USE_CRYPTO */
4971
+#ifdef ENABLE_PKCS11
4972
+  else if (streq (p[0], "show-pkcs11-slots") && p[1])
4973
+    {
4974
+      char *module =  p[i++];
4975
+      VERIFY_PERMISSION (OPT_P_GENERAL);
4976
+      show_pkcs11_slots (M_INFO|M_NOPREFIX, M_WARN|M_NOPREFIX, module);
4977
+      openvpn_exit (OPENVPN_EXIT_STATUS_GOOD); /* exit point */
4978
+    }
4979
+  else if (streq (p[0], "show-pkcs11-objects") && p[1] && p[2])
4980
+    {
4981
+      char *provider =  p[i++];
4982
+      char *slot = p[i++];
4983
+      struct gc_arena gc = gc_new ();
4984
+      struct buffer pass_prompt = alloc_buf_gc (128, &gc);
4985
+      char pin[256];
4986
+
4987
+      VERIFY_PERMISSION (OPT_P_GENERAL);
4988
+
4989
+      buf_printf (&pass_prompt, "PIN:");
4990
+
4991
+      if (!get_console_input (BSTR (&pass_prompt), false, pin, sizeof (pin)))
4992
+        msg (M_FATAL, "Cannot read password from stdin");
4993
+      
4994
+      gc_free (&gc);
4995
+      
4996
+      show_pkcs11_objects (M_INFO|M_NOPREFIX, M_WARN|M_NOPREFIX, provider, slot, pin);
4997
+      openvpn_exit (OPENVPN_EXIT_STATUS_GOOD); /* exit point */
4998
+    }
4999
+  else if (streq (p[0], "pkcs11-providers") && p[1])
5000
+    {
5001
+      int j;
5002
+      
5003
+      VERIFY_PERMISSION (OPT_P_GENERAL);
5004
+
5005
+      for (j = 1; j < MAX_PARMS && p[j] != NULL; ++j, ++i)
5006
+      	options->pkcs11_providers[j-1] = p[j];
5007
+    }
5008
+  else if (streq (p[0], "pkcs11-sign-mode") && p[1])
5009
+    {
5010
+      int j;
5011
+      
5012
+      VERIFY_PERMISSION (OPT_P_GENERAL);
5013
+
5014
+      for (j = 1; j < MAX_PARMS && p[j] != NULL; ++j, ++i)
5015
+      	options->pkcs11_sign_mode[j-1] = p[j];
5016
+    }
5017
+  else if (streq (p[0], "pkcs11-slot-type") && p[1])
5018
+    {
5019
+      ++i;
5020
+      VERIFY_PERMISSION (OPT_P_GENERAL);
5021
+      options->pkcs11_slot_type = p[1];
5022
+    }
5023
+  else if (streq (p[0], "pkcs11-slot") && p[1])
5024
+    {
5025
+      ++i;
5026
+      VERIFY_PERMISSION (OPT_P_GENERAL);
5027
+      options->pkcs11_slot = p[1];
5028
+    }
5029
+  else if (streq (p[0], "pkcs11-id-type") && p[1])
5030
+    {
5031
+      ++i;
5032
+      VERIFY_PERMISSION (OPT_P_GENERAL);
5033
+      options->pkcs11_id_type = p[1];
5034
+    }
5035
+  else if (streq (p[0], "pkcs11-id") && p[1])
5036
+    {
5037
+      ++i;
5038
+      VERIFY_PERMISSION (OPT_P_GENERAL);
5039
+      options->pkcs11_id = p[1];
5040
+    }
5041
+   else if (streq (p[0], "pkcs11-pin-cache") && p[1])
5042
+    {
5043
+      ++i;
5044
+      VERIFY_PERMISSION (OPT_P_GENERAL);
5045
+      options->pkcs11_pin_cache_period = atoi (p[1]);
5046
+    }
5047
+  else if (streq (p[0], "pkcs11-protected-authentication"))
5048
+    {
5049
+      ++i;
5050
+      VERIFY_PERMISSION (OPT_P_GENERAL);
5051
+      options->pkcs11_protected_authentication = true;
5052
+    }
5053
+#endif
4971 5054
 #ifdef TUNSETPERSIST
4972 5055
   else if (streq (p[0], "rmtun"))
4973 5056
     {
... ...
@@ -385,6 +385,7 @@ struct options
385 385
   const char *pkcs11_slot;
386 386
   const char *pkcs11_id_type;
387 387
   const char *pkcs11_id;
388
+  int pkcs11_pin_cache_period;
388 389
   bool pkcs11_protected_authentication;
389 390
 #ifdef WIN32
390 391
   const char *cryptoapi_cert;
... ...
@@ -58,6 +58,12 @@
58 58
 #include "pkcs11.h"
59 59
 
60 60
 /*===========================================
61
+ * MACROS
62
+ */
63
+
64
+#define snprintf openvpn_snprintf
65
+
66
+/*===========================================
61 67
  * Constants
62 68
  */
63 69
 
... ...
@@ -78,6 +84,25 @@
78 78
  * Types
79 79
  */
80 80
 
81
+typedef bool (*pkcs11_hook_card_prompt_t)(
82
+	IN const void *pData,
83
+	IN const char * const szLabel
84
+);
85
+
86
+typedef bool (*pkcs11_hook_pin_prompt_t)(
87
+	IN const void *pData,
88
+	IN const char * const szLabel,
89
+	OUT char * const szPIN,
90
+	IN const size_t nMaxPIN
91
+);
92
+	
93
+typedef struct pkcs11_hooks_s {
94
+	void *card_prompt_data;
95
+	void *pin_prompt_data;
96
+	pkcs11_hook_card_prompt_t card_prompt;
97
+	pkcs11_hook_pin_prompt_t pin_prompt;
98
+} *pkcs11_hooks_t;
99
+
81 100
 typedef struct pkcs11_provider_s {
82 101
 	struct pkcs11_provider_s *next;
83 102
 
... ...
@@ -91,27 +116,39 @@ typedef struct pkcs11_provider_s {
91 91
 	CK_FUNCTION_LIST_PTR f;
92 92
 	bool fShouldFinalize;
93 93
 	char *szSignMode;
94
+
94 95
 } *pkcs11_provider_t;
95 96
 
96 97
 typedef struct pkcs11_session_s {
97 98
 
98 99
 	pkcs11_provider_t provider;
99 100
 
101
+	bool fProtectedAuthentication;
102
+
103
+	char szLabel[sizeof (((CK_TOKEN_INFO *)NULL)->label)+1];
104
+	CK_CHAR serialNumber[sizeof (((CK_TOKEN_INFO *)NULL)->serialNumber)];
105
+	
100 106
 	unsigned char *certificate;
101
-	int certificate_size;
107
+	size_t certificate_size;
102 108
 	unsigned char *certificate_id;
103
-	int certificate_id_size;
104
-
105
-	char *szPIN;
106
-	bool fLoginFailed;
109
+	size_t certificate_id_size;
107 110
 
108 111
 	CK_SLOT_ID slot;
109 112
 	bool fKeySignRecover;
110 113
 
111 114
 	CK_SESSION_HANDLE session;
112 115
 	CK_OBJECT_HANDLE key;
116
+
117
+	time_t timePINExpire;
113 118
 } *pkcs11_session_t;
114 119
 
120
+typedef struct pkcs11_data_s {
121
+	bool fInitialized;
122
+	int nPINCachePeriod;
123
+	pkcs11_provider_t providers;
124
+	pkcs11_hooks_t hooks;
125
+} *pkcs11_data_t;
126
+
115 127
 /*===========================================
116 128
  * Low level prototypes
117 129
  */
... ...
@@ -121,14 +158,14 @@ void
121 121
 _fixupFixedString (
122 122
 	IN const char * const szSource,
123 123
 	OUT char * const szTarget,			/* MUST BE >= nLength+1 */
124
-	IN const int nLength				/* FIXED STRING LENGTH */
124
+	IN const size_t nLength				/* FIXED STRING LENGTH */
125 125
 );
126 126
 static
127 127
 void
128 128
 _hexToBinary (
129 129
 	IN const char * const szSource,
130 130
 	OUT unsigned char * const target,
131
-	IN OUT int * const target_size
131
+	IN OUT size_t * const target_size
132 132
 );
133 133
 static
134 134
 CK_RV
... ...
@@ -154,11 +191,21 @@ _pkcs11_getObjectById (
154 154
 	IN const pkcs11_session_t pkcs11_session,
155 155
 	IN const CK_OBJECT_CLASS class,
156 156
 	IN const unsigned char * const id,
157
-	IN const int id_size,
157
+	IN const size_t id_size,
158 158
 	OUT CK_OBJECT_HANDLE * const handle
159 159
 );
160 160
 static
161 161
 CK_RV
162
+_pkcs11_setSessionTokenInfo (
163
+	IN const pkcs11_session_t pkcs11_session
164
+);
165
+static
166
+CK_RV
167
+_pkcs11_resetSlot (
168
+	IN const pkcs11_session_t pkcs11_session
169
+);
170
+static
171
+CK_RV
162 172
 _pkcs11_loadCertificate (
163 173
 	IN const pkcs11_session_t pkcs11_session,
164 174
 	IN const char * const szIdType,
... ...
@@ -173,15 +220,66 @@ static
173 173
 bool
174 174
 _isBetterCertificate (
175 175
 	IN const unsigned char * const pCurrent,
176
-	IN const int nCurrentSize,
176
+	IN const size_t nCurrentSize,
177 177
 	IN const unsigned char * const pNew,
178
-	IN const int nNewSize
178
+	IN const size_t nNewSize
179
+);
180
+static
181
+CK_RV
182
+_pkcs11_validateSession (
183
+	IN const pkcs11_session_t pkcs11_session
184
+);
185
+static
186
+CK_RV
187
+_pkcs11_login (
188
+	IN const pkcs11_session_t pkcs11_session
189
+);
190
+static
191
+CK_RV
192
+_pkcs11_logout (
193
+	IN const pkcs11_session_t pkcs11_session
179 194
 );
180 195
 
181 196
 /*=========================================
182 197
  * Simplified functions prototypes
183 198
  */
184
-
199
+static
200
+bool
201
+_pkcs11_hooks_card_prompt_default (
202
+	IN const void *pData,
203
+	IN const char * const szLabel
204
+);
205
+static
206
+bool
207
+_pkcs11_hooks_pin_prompt_default (
208
+	IN const void *pData,
209
+	IN const char * const szLabel,
210
+	OUT char * const szPIN,
211
+	IN const size_t nMaxPIN
212
+);
213
+static
214
+CK_RV
215
+pkcs11_initialize ();
216
+static
217
+CK_RV
218
+pkcs11_terminate ();
219
+static
220
+CK_RV
221
+pkcs11_setCardPromptHook (
222
+	IN const pkcs11_hook_card_prompt_t hook,
223
+	IN void * const pData
224
+);
225
+static
226
+CK_RV
227
+pkcs11_setPINPromptHook (
228
+	IN const pkcs11_hook_pin_prompt_t hook,
229
+	IN void * const pData
230
+);
231
+static
232
+CK_RV
233
+pkcs11_setPINCachePeriod (
234
+	IN const int nPINCachePeriod
235
+);
185 236
 static
186 237
 CK_RV
187 238
 pkcs11_addProvider (
... ...
@@ -190,7 +288,7 @@ pkcs11_addProvider (
190 190
 );
191 191
 static
192 192
 CK_RV
193
-pkcs11_finalize ();
193
+pkcs11_forkFixup ();
194 194
 static
195 195
 CK_RV
196 196
 pkcs11_createSession (
... ...
@@ -198,7 +296,6 @@ pkcs11_createSession (
198 198
 	IN const char * const szSlot,
199 199
 	IN const char * const szIdType,
200 200
 	IN const char * const szId,
201
-	IN const char * const szPIN,
202 201
 	IN const bool fProtectedAuthentication,
203 202
 	OUT pkcs11_session_t * const pkcs11_session
204 203
 );
... ...
@@ -209,23 +306,13 @@ pkcs11_freeSession (
209 209
 );
210 210
 static
211 211
 CK_RV
212
-pkcs11_login (
213
-	IN const pkcs11_session_t pkcs11_session
214
-);
215
-static
216
-CK_RV
217
-pkcs11_logout (
218
-	IN const pkcs11_session_t pkcs11_session
219
-);
220
-static
221
-CK_RV
222 212
 pkcs11_sign (
223 213
 	IN const pkcs11_session_t pkcs11_session,
224 214
 	IN const CK_MECHANISM_TYPE mech_type,
225 215
 	IN const unsigned char * const source,
226
-	IN const int source_size,
216
+	IN const size_t source_size,
227 217
 	OUT unsigned char * const target,
228
-	IN OUT int * const target_size
218
+	IN OUT size_t * const target_size
229 219
 );
230 220
 static
231 221
 CK_RV
... ...
@@ -233,9 +320,9 @@ pkcs11_signRecover (
233 233
 	IN const pkcs11_session_t pkcs11_session,
234 234
 	IN const CK_MECHANISM_TYPE mech_type,
235 235
 	IN const unsigned char * const source,
236
-	IN const int source_size,
236
+	IN const size_t source_size,
237 237
 	OUT unsigned char * const target,
238
-	IN OUT int * const target_size
238
+	IN OUT size_t * const target_size
239 239
 );
240 240
 static
241 241
 CK_RV
... ...
@@ -243,16 +330,16 @@ pkcs11_decrypt (
243 243
 	IN const pkcs11_session_t pkcs11_session,
244 244
 	IN const CK_MECHANISM_TYPE mech_type,
245 245
 	IN const unsigned char * const source,
246
-	IN const int source_size,
246
+	IN const size_t source_size,
247 247
 	OUT unsigned char * const target,
248
-	IN OUT int * const target_size
248
+	IN OUT size_t * const target_size
249 249
 );
250 250
 static
251 251
 CK_RV
252 252
 pkcs11_getCertificate (
253 253
 	IN const pkcs11_session_t pkcs11_session,
254
-	OUT char * const certificate,
255
-	IN OUT int * const certificate_size
254
+	OUT unsigned char * const certificate,
255
+	IN OUT size_t * const certificate_size
256 256
 );
257 257
 static
258 258
 char *
... ...
@@ -264,7 +351,7 @@ pkcs11_getMessage (
264 264
  * Static data
265 265
  */
266 266
 
267
-static pkcs11_provider_t pkcs11_provider = NULL;
267
+static pkcs11_data_t pkcs11_data = NULL;
268 268
 
269 269
 /*==========================================
270 270
  * Internal utility functions
... ...
@@ -275,7 +362,7 @@ void
275 275
 _fixupFixedString (
276 276
 	IN const char * const szSource,
277 277
 	OUT char * const szTarget,			/* MUST BE >= nLength+1 */
278
-	IN const int nLength				/* FIXED STRING LENGTH */
278
+	IN const size_t nLength				/* FIXED STRING LENGTH */
279 279
 ) {
280 280
 	char *p;
281 281
 
... ...
@@ -297,9 +384,9 @@ void
297 297
 _hexToBinary (
298 298
 	IN const char * const szSource,
299 299
 	OUT unsigned char * const target,
300
-	IN OUT int * const target_size
300
+	IN OUT size_t * const target_size
301 301
 ) {
302
-	int target_max_size;
302
+	size_t target_max_size;
303 303
 	const char *p;
304 304
 	char buf[3] = {'\0', '\0', '\0'};
305 305
 	int i = 0;
... ...
@@ -317,7 +404,7 @@ _hexToBinary (
317 317
 			buf[i%2] = *p;
318 318
 
319 319
 			if ((i%2) == 1) {
320
-				int v;
320
+				unsigned v;
321 321
 				sscanf (buf, "%x", &v);
322 322
 				target[*target_size] = v & 0xff;
323 323
 				(*target_size)++;
... ...
@@ -333,9 +420,9 @@ static
333 333
 bool
334 334
 _isBetterCertificate (
335 335
 	IN const unsigned char * const pCurrent,
336
-	IN const int nCurrentSize,
336
+	IN const size_t nCurrentSize,
337 337
 	IN const unsigned char * const pNew,
338
-	IN const int nNewSize
338
+	IN const size_t nNewSize
339 339
 ) {
340 340
 	/*
341 341
 	 * This function compare the notBefore
... ...
@@ -427,7 +514,7 @@ _pkcs11_getSlotById (
427 427
 	}
428 428
 
429 429
 	for (
430
-		i=0, provider=pkcs11_provider;
430
+		i=0, provider=pkcs11_data->providers;
431 431
 		i < provider_number && provider != NULL;
432 432
 		i++, provider = provider->next
433 433
 	);
... ...
@@ -453,9 +540,6 @@ _pkcs11_getSlotByName (
453 453
 	IN const pkcs11_session_t pkcs11_session,
454 454
 	IN const char * const szName
455 455
 ) {
456
-	CK_SLOT_ID slots[1024];
457
-	CK_ULONG slotnum;
458
-	CK_SLOT_ID s;
459 456
 	CK_RV rv;
460 457
 
461 458
 	pkcs11_provider_t provider;
... ...
@@ -465,13 +549,16 @@ _pkcs11_getSlotByName (
465 465
 	ASSERT (szName!=NULL);
466 466
 
467 467
 	for (
468
-		provider = pkcs11_provider;
468
+		provider = pkcs11_data->providers;
469 469
 		(
470 470
 			provider != NULL &&
471 471
 			!fFound
472 472
 		);
473 473
 		provider = provider->next
474 474
 	) {
475
+		CK_SLOT_ID slots[1024];
476
+		CK_ULONG slotnum;
477
+
475 478
 		if (!provider->fEnabled) {
476 479
 			continue;
477 480
 		}
... ...
@@ -484,6 +571,8 @@ _pkcs11_getSlotByName (
484 484
 				&slotnum
485 485
 			)) == CKR_OK
486 486
 		) {
487
+			CK_SLOT_ID s;
488
+
487 489
 			for (s=0;!fFound && s<slotnum;s++) {
488 490
 				CK_SLOT_INFO info;
489 491
 
... ...
@@ -496,7 +585,7 @@ _pkcs11_getSlotByName (
496 496
 					char szCurrentName[sizeof (info.slotDescription)+1];
497 497
 	
498 498
 					_fixupFixedString (
499
-						info.slotDescription,
499
+						(char *)info.slotDescription,
500 500
 						szCurrentName,
501 501
 						sizeof (info.slotDescription)
502 502
 					);
... ...
@@ -520,9 +609,6 @@ _pkcs11_getSlotByLabel (
520 520
 	IN const pkcs11_session_t pkcs11_session,
521 521
 	IN const char * const szLabel
522 522
 ) {
523
-	CK_SLOT_ID slots[1024];
524
-	CK_ULONG slotnum;
525
-	CK_SLOT_ID s;
526 523
 	CK_RV rv;
527 524
 
528 525
 	pkcs11_provider_t provider;
... ...
@@ -532,13 +618,16 @@ _pkcs11_getSlotByLabel (
532 532
 	ASSERT (szLabel!=NULL);
533 533
 
534 534
 	for (
535
-		provider = pkcs11_provider;
535
+		provider = pkcs11_data->providers;
536 536
 		(
537 537
 			provider != NULL &&
538 538
 			!fFound
539 539
 		);
540 540
 		provider = provider->next
541 541
 	) {
542
+		CK_SLOT_ID slots[1024];
543
+		CK_ULONG slotnum;
544
+
542 545
 		if (!provider->fEnabled) {
543 546
 			continue;
544 547
 		}
... ...
@@ -551,6 +640,8 @@ _pkcs11_getSlotByLabel (
551 551
 				&slotnum
552 552
 			)) == CKR_OK
553 553
 		) {
554
+			CK_SLOT_ID s;
555
+
554 556
 			for (s=0;!fFound && s<slotnum;s++) {
555 557
 				CK_TOKEN_INFO info;
556 558
 
... ...
@@ -563,7 +654,7 @@ _pkcs11_getSlotByLabel (
563 563
 					char szCurrentLabel[sizeof (info.label)+1];
564 564
 			
565 565
 					_fixupFixedString (
566
-						info.label,
566
+						(char *)info.label,
567 567
 						szCurrentLabel,
568 568
 						sizeof (info.label)
569 569
 					);
... ...
@@ -583,16 +674,105 @@ _pkcs11_getSlotByLabel (
583 583
 
584 584
 static
585 585
 CK_RV
586
+_pkcs11_setSessionTokenInfo (
587
+	IN const pkcs11_session_t pkcs11_session
588
+) {
589
+	CK_TOKEN_INFO info;
590
+	CK_RV rv;
591
+
592
+	ASSERT (pkcs11_session!=NULL);
593
+
594
+	if (
595
+		(rv = pkcs11_session->provider->f->C_GetTokenInfo (
596
+			pkcs11_session->slot,
597
+			&info
598
+		)) == CKR_OK
599
+	) {
600
+		_fixupFixedString (
601
+			(char *)info.label,
602
+			pkcs11_session->szLabel,
603
+			sizeof (info.label)
604
+		);
605
+		
606
+		memmove (
607
+			pkcs11_session->serialNumber,
608
+			info.serialNumber,
609
+			sizeof (pkcs11_session->serialNumber)
610
+		);
611
+	}
612
+
613
+	return rv;
614
+}
615
+
616
+static
617
+CK_RV
618
+_pkcs11_resetSlot (
619
+	IN const pkcs11_session_t pkcs11_session
620
+) {
621
+	CK_SLOT_ID slots[1024];
622
+	CK_ULONG slotnum;
623
+	CK_RV rv;
624
+	bool fFound = false;
625
+	bool fCancel = false;
626
+
627
+	ASSERT (pkcs11_session!=NULL);
628
+
629
+	do {
630
+		slotnum = sizeof (slots) / sizeof (CK_SLOT_ID);
631
+		if (
632
+			(rv = pkcs11_session->provider->f->C_GetSlotList (
633
+				TRUE,
634
+				slots,
635
+				&slotnum
636
+			)) == CKR_OK
637
+		) {
638
+			CK_SLOT_ID s;
639
+
640
+			for (s=0;!fFound && s<slotnum;s++) {
641
+				CK_TOKEN_INFO info;
642
+
643
+				if (
644
+					(rv = pkcs11_session->provider->f->C_GetTokenInfo (
645
+						slots[s],
646
+						&info
647
+					)) == CKR_OK
648
+				) {
649
+					if (
650
+						!memcmp (
651
+							pkcs11_session->serialNumber,
652
+							info.serialNumber,
653
+							sizeof (pkcs11_session->serialNumber)
654
+						)
655
+					) {
656
+						pkcs11_session->slot = slots[s];
657
+						fFound = true;
658
+					}
659
+				}
660
+			}
661
+		}
662
+
663
+		if (!fFound) {
664
+			fCancel = !pkcs11_data->hooks->card_prompt (
665
+				pkcs11_data->hooks->card_prompt_data,
666
+				pkcs11_session->szLabel
667
+			);
668
+		}
669
+	} while (!fFound && !fCancel);
670
+
671
+	return fFound ? CKR_OK : CKR_SLOT_ID_INVALID;
672
+}
673
+
674
+static
675
+CK_RV
586 676
 _pkcs11_getObjectById (
587 677
 	IN const pkcs11_session_t pkcs11_session,
588 678
 	IN const CK_OBJECT_CLASS class,
589 679
 	IN const unsigned char * const id,
590
-	IN const int id_size,
680
+	IN const size_t id_size,
591 681
 	OUT CK_OBJECT_HANDLE * const handle
592 682
 ) {
593 683
 	CK_ULONG count;
594
-	bool fFound = false;
595
-	CK_RV rv;
684
+	CK_RV rv = CKR_OK;
596 685
 
597 686
 	CK_ATTRIBUTE filter[] = {
598 687
 		{CKA_CLASS, (void *)&class, sizeof (class)},
... ...
@@ -603,34 +783,35 @@ _pkcs11_getObjectById (
603 603
 	ASSERT (id!=NULL);
604 604
 	ASSERT (handle!=NULL);
605 605
 
606
-	if (
607
-		(rv = pkcs11_session->provider->f->C_FindObjectsInit (
606
+	if (rv == CKR_OK) {
607
+		rv = pkcs11_session->provider->f->C_FindObjectsInit (
608 608
 			pkcs11_session->session,
609 609
 			filter,
610 610
 			sizeof (filter) / sizeof (CK_ATTRIBUTE)
611
-		)) != CKR_OK
612
-	) {
613
-		return rv;
611
+		);
614 612
 	}
615 613
 
616
-	if (
617
-		(rv = pkcs11_session->provider->f->C_FindObjects (
614
+	if (rv == CKR_OK) {
615
+		rv = pkcs11_session->provider->f->C_FindObjects (
618 616
 			pkcs11_session->session,
619 617
 			handle,
620 618
 			1,
621 619
 			&count
622
-		)) == CKR_OK 
620
+		);
621
+	}
622
+
623
+	if (
624
+		rv == CKR_OK &&
625
+		count == 0
623 626
 	) {
624
-		if (count > 0) {
625
-			fFound = true;
626
-		}
627
+		rv = CKR_FUNCTION_REJECTED;
627 628
 	}
628 629
 
629 630
 	pkcs11_session->provider->f->C_FindObjectsFinal (
630 631
 		pkcs11_session->session
631 632
 	);
632 633
 
633
-	return fFound ? CKR_OK : CKR_FUNCTION_REJECTED;
634
+	return rv;
634 635
 }
635 636
 
636 637
 static
... ...
@@ -674,7 +855,7 @@ _pkcs11_loadCertificate (
674 674
 		);
675 675
 	}
676 676
 	else if (!strcmp (szIdType, "id")) {
677
-		int s = sizeof (cert_filter_by);
677
+		size_t s = sizeof (cert_filter_by);
678 678
 
679 679
 		cert_filter[1].type = CKA_ID;
680 680
 		_hexToBinary (
... ...
@@ -876,11 +1057,303 @@ _pkcs11_loadKeyProperties (
876 876
 	return CKR_OK;
877 877
 }
878 878
 
879
+static
880
+CK_RV
881
+_pkcs11_validateSession (
882
+	IN const pkcs11_session_t pkcs11_session
883
+) {
884
+	if (
885
+		pkcs11_session->timePINExpire != (time_t)0 &&
886
+		pkcs11_session->timePINExpire < time (NULL)
887
+	) {
888
+		_pkcs11_logout (pkcs11_session);
889
+	}
890
+	return CKR_OK;
891
+}
892
+
893
+static
894
+CK_RV
895
+_pkcs11_login (
896
+	IN const pkcs11_session_t pkcs11_session
897
+) {
898
+	CK_RV rv = CKR_OK;
899
+
900
+
901
+	ASSERT (pkcs11_session!=NULL);
902
+
903
+	_pkcs11_logout (pkcs11_session);
904
+
905
+	if (rv == CKR_OK) {
906
+		rv = _pkcs11_resetSlot (pkcs11_session);
907
+	}
908
+
909
+	if (rv == CKR_OK) {
910
+		rv = pkcs11_session->provider->f->C_OpenSession (
911
+			pkcs11_session->slot,
912
+			CKF_SERIAL_SESSION,
913
+			NULL_PTR,
914
+			NULL_PTR,
915
+			&pkcs11_session->session
916
+		);
917
+	}
918
+
919
+	if (rv == CKR_OK) {
920
+		int nRetryCount = 0;
921
+		do {
922
+			CK_UTF8CHAR_PTR utfPIN = NULL;
923
+			CK_ULONG lPINLength = 0;
924
+			char szPIN[1024];
925
+
926
+			/*
927
+			 * Assume OK for next iteration
928
+			 */
929
+			rv = CKR_OK;
930
+
931
+			if (
932
+				rv == CKR_OK &&
933
+				!pkcs11_session->fProtectedAuthentication
934
+			) {
935
+				if (
936
+					!pkcs11_data->hooks->pin_prompt (
937
+						pkcs11_data->hooks->pin_prompt_data,
938
+						pkcs11_session->szLabel,
939
+						szPIN,
940
+						sizeof (szPIN)
941
+					)
942
+				) {
943
+					rv = CKR_FUNCTION_FAILED;
944
+				}
945
+				else {
946
+					utfPIN = (CK_UTF8CHAR_PTR)szPIN;
947
+					lPINLength = strlen (szPIN);
948
+				}
949
+			}
950
+
951
+			if (pkcs11_data->nPINCachePeriod == -1) {
952
+				pkcs11_session->timePINExpire = 0;
953
+			}
954
+			else {
955
+				pkcs11_session->timePINExpire = (
956
+					time (NULL) +
957
+					(time_t)pkcs11_data->nPINCachePeriod
958
+				);
959
+			}
960
+			if (
961
+				rv == CKR_OK &&
962
+				(rv = pkcs11_session->provider->f->C_Login (
963
+					pkcs11_session->session,
964
+					CKU_USER,
965
+					utfPIN,
966
+					lPINLength
967
+				)) != CKR_OK
968
+			) {
969
+				if (rv == CKR_USER_ALREADY_LOGGED_IN) {
970
+					rv = CKR_OK;
971
+				}
972
+			}
973
+
974
+			/*
975
+			 * Clean PIN buffer
976
+			 */
977
+			memset (szPIN, 0, sizeof (szPIN));
978
+		} while (
979
+			++nRetryCount < 3 &&
980
+			(
981
+				rv == CKR_PIN_INCORRECT ||
982
+				rv == CKR_PIN_INVALID
983
+			)
984
+		);
985
+	}
986
+
987
+	if (
988
+		rv == CKR_OK &&
989
+		pkcs11_session->certificate_id != NULL
990
+	) {
991
+		rv = _pkcs11_getObjectById (
992
+			pkcs11_session,
993
+			CKO_PRIVATE_KEY,
994
+			pkcs11_session->certificate_id,
995
+			pkcs11_session->certificate_id_size,
996
+			&pkcs11_session->key
997
+		);
998
+	}
999
+
1000
+	return rv;
1001
+}
1002
+
1003
+static
1004
+CK_RV
1005
+_pkcs11_logout (
1006
+	IN const pkcs11_session_t pkcs11_session
1007
+) {
1008
+	ASSERT (pkcs11_session!=NULL);
1009
+
1010
+	if (pkcs11_session->session != (CK_SESSION_HANDLE)-1) {
1011
+		pkcs11_session->provider->f->C_Logout (pkcs11_session->session);
1012
+		pkcs11_session->provider->f->C_CloseSession (pkcs11_session->session);
1013
+		pkcs11_session->key = (CK_OBJECT_HANDLE)-1;
1014
+		pkcs11_session->session = (CK_SESSION_HANDLE)-1;
1015
+	}
1016
+
1017
+	return CKR_OK;
1018
+}
1019
+
1020
+
879 1021
 /*=======================================
880 1022
  * Simplified PKCS#11 functions
881 1023
  */
882 1024
 
883 1025
 static
1026
+bool
1027
+_pkcs11_hooks_card_prompt_default (
1028
+	IN const void * pData,
1029
+	IN const char * const szLabel
1030
+) {
1031
+	return false;
1032
+}
1033
+
1034
+static
1035
+bool
1036
+_pkcs11_hooks_pin_prompt_default (
1037
+	IN const void * pData,
1038
+	IN const char * const szLabel,
1039
+	OUT char * const szPIN,
1040
+	IN const size_t nMaxPIN
1041
+) {
1042
+	return false;
1043
+}
1044
+
1045
+static
1046
+CK_RV
1047
+pkcs11_initialize () {
1048
+
1049
+	pkcs11_terminate ();
1050
+
1051
+	pkcs11_data = (pkcs11_data_t)malloc (sizeof (struct pkcs11_data_s));
1052
+	if (pkcs11_data == NULL) {
1053
+		return CKR_HOST_MEMORY;
1054
+	}
1055
+
1056
+	memset (pkcs11_data, 0, sizeof (struct pkcs11_data_s));
1057
+
1058
+	pkcs11_data->nPINCachePeriod = -1;
1059
+
1060
+	pkcs11_data->hooks = (pkcs11_hooks_t)malloc (sizeof (struct pkcs11_hooks_s));
1061
+	if (pkcs11_data->hooks == NULL) {
1062
+		return CKR_HOST_MEMORY;
1063
+	}
1064
+
1065
+	memset (pkcs11_data->hooks, 0, sizeof (struct pkcs11_hooks_s));
1066
+
1067
+	pkcs11_data->fInitialized = true;
1068
+
1069
+	pkcs11_setCardPromptHook (_pkcs11_hooks_card_prompt_default, NULL);
1070
+	pkcs11_setPINPromptHook (_pkcs11_hooks_pin_prompt_default, NULL);
1071
+
1072
+	return CKR_OK;
1073
+}
1074
+
1075
+static
1076
+CK_RV
1077
+pkcs11_terminate () {
1078
+
1079
+	if (pkcs11_data != NULL) {
1080
+		pkcs11_provider_t last = NULL;
1081
+
1082
+		for (
1083
+			;
1084
+			pkcs11_data->providers != NULL;
1085
+			pkcs11_data->providers = pkcs11_data->providers->next
1086
+		) {
1087
+			if (last != NULL) {
1088
+				free (last);
1089
+			}
1090
+			last = pkcs11_data->providers;
1091
+		
1092
+			if (pkcs11_data->providers->szSignMode != NULL) {
1093
+				free (pkcs11_data->providers->szSignMode);
1094
+				pkcs11_data->providers->szSignMode = NULL;
1095
+			}
1096
+	
1097
+			if (pkcs11_data->providers->fShouldFinalize) {
1098
+				pkcs11_data->providers->f->C_Finalize (NULL);
1099
+				pkcs11_data->providers->fShouldFinalize = false;
1100
+			}
1101
+
1102
+			if (pkcs11_data->providers->f != NULL) {
1103
+				pkcs11_data->providers->f = NULL;
1104
+			}
1105
+	
1106
+			if (pkcs11_data->providers->hLibrary != NULL) {
1107
+#if defined(WIN32)
1108
+				FreeLibrary (pkcs11_data->providers->hLibrary);
1109
+#else
1110
+				dlclose (pkcs11_data->providers->hLibrary);
1111
+#endif
1112
+				pkcs11_data->providers->hLibrary = NULL;
1113
+			}
1114
+		}
1115
+
1116
+		if (last != NULL) {
1117
+			free (last);
1118
+		}
1119
+
1120
+		if (pkcs11_data->hooks != NULL) {
1121
+			free (pkcs11_data->hooks);
1122
+			pkcs11_data->hooks = NULL;
1123
+		}
1124
+
1125
+		free (pkcs11_data);
1126
+		pkcs11_data = NULL;
1127
+	}
1128
+
1129
+	return CKR_OK;
1130
+}
1131
+
1132
+static
1133
+CK_RV
1134
+pkcs11_setPINPromptHook (
1135
+	IN const pkcs11_hook_pin_prompt_t hook,
1136
+	IN void * const pData
1137
+) {
1138
+	ASSERT (pkcs11_data!=NULL);
1139
+	ASSERT (pkcs11_data->fInitialized);
1140
+
1141
+	pkcs11_data->hooks->pin_prompt = hook;
1142
+	pkcs11_data->hooks->pin_prompt_data = pData;
1143
+
1144
+	return CKR_OK;
1145
+}
1146
+
1147
+static
1148
+CK_RV
1149
+pkcs11_setCardPromptHook (
1150
+	IN const pkcs11_hook_card_prompt_t hook,
1151
+	IN void * const pData
1152
+) {
1153
+	ASSERT (pkcs11_data!=NULL);
1154
+	ASSERT (pkcs11_data->fInitialized);
1155
+
1156
+	pkcs11_data->hooks->card_prompt = hook;
1157
+	pkcs11_data->hooks->card_prompt_data = pData;
1158
+
1159
+	return CKR_OK;
1160
+}
1161
+
1162
+static
1163
+CK_RV
1164
+pkcs11_setPINCachePeriod (
1165
+	IN const int nPINCachePeriod
1166
+) {
1167
+	ASSERT (pkcs11_data!=NULL);
1168
+	ASSERT (pkcs11_data->fInitialized);
1169
+
1170
+	pkcs11_data->nPINCachePeriod = nPINCachePeriod;
1171
+
1172
+	return CKR_OK;
1173
+}
1174
+
1175
+static
884 1176
 CK_RV
885 1177
 pkcs11_addProvider (
886 1178
 	IN const char * const szProvider,
... ...
@@ -890,6 +1363,8 @@ pkcs11_addProvider (
890 890
 	CK_C_GetFunctionList gfl = NULL;
891 891
 	CK_RV rv = CKR_OK;
892 892
 
893
+	ASSERT (pkcs11_data!=NULL);
894
+	ASSERT (pkcs11_data->fInitialized);
893 895
 	ASSERT (szProvider!=NULL);
894 896
 
895 897
 	if (
... ...
@@ -930,10 +1405,18 @@ pkcs11_addProvider (
930 930
 			"C_GetFunctionList"
931 931
 		);
932 932
 #else
933
-		gfl = (CK_C_GetFunctionList)dlsym (
933
+		/*
934
+		 * Make compiler happy!
935
+		 */
936
+		void *p = dlsym (
934 937
 			provider->hLibrary,
935 938
 			"C_GetFunctionList"
936 939
 		);
940
+		memmove (
941
+			&gfl, 
942
+			&p,
943
+			sizeof (void *)
944
+		);
937 945
 #endif
938 946
 		if (gfl == NULL) {
939 947
 			rv = CKR_FUNCTION_FAILED;
... ...
@@ -960,14 +1443,14 @@ pkcs11_addProvider (
960 960
 	}
961 961
 
962 962
 	if (provider != NULL) {
963
-		if (pkcs11_provider == NULL) {
964
-			pkcs11_provider = provider;
963
+		if (pkcs11_data->providers == NULL) {
964
+			pkcs11_data->providers = provider;
965 965
 		}
966 966
 		else {
967 967
 			pkcs11_provider_t last = NULL;
968 968
 	
969 969
 			for (
970
-				last = pkcs11_provider;
970
+				last = pkcs11_data->providers;
971 971
 				last->next != NULL;
972 972
 				last = last->next
973 973
 			);
... ...
@@ -977,54 +1460,29 @@ pkcs11_addProvider (
977 977
 
978 978
 	return rv;
979 979
 }
980
-	
980
+
981 981
 static
982 982
 CK_RV
983
-pkcs11_finalize () {
984
-	
985
-	pkcs11_provider_t last = NULL;
983
+pkcs11_forkFixup () {
984
+
985
+	pkcs11_provider_t current;
986
+
987
+	ASSERT (pkcs11_data!=NULL);
988
+	ASSERT (pkcs11_data->fInitialized);
986 989
 
987 990
 	for (
988
-		;
989
-		pkcs11_provider != NULL;
990
-		pkcs11_provider = pkcs11_provider->next
991
+		current = pkcs11_data->providers;
992
+		current != NULL;
993
+		current = current->next
991 994
 	) {
992
-		if (last != NULL) {
993
-			free (last);
994
-		}
995
-		last = pkcs11_provider;
996
-		
997
-		if (pkcs11_provider->szSignMode != NULL) {
998
-			free (pkcs11_provider->szSignMode);
999
-			pkcs11_provider->szSignMode = NULL;
1000
-		}
1001
-	
1002
-		if (pkcs11_provider->fShouldFinalize) {
1003
-			pkcs11_provider->f->C_Finalize (NULL);
1004
-			pkcs11_provider->fShouldFinalize = false;
1005
-		}
1006
-
1007
-		if (pkcs11_provider->f != NULL) {
1008
-			pkcs11_provider->f = NULL;
995
+		if (current->fEnabled) {
996
+			current->f->C_Initialize (NULL);
1009 997
 		}
1010
-	
1011
-		if (pkcs11_provider->hLibrary != NULL) {
1012
-#if defined(WIN32)
1013
-			FreeLibrary (pkcs11_provider->hLibrary);
1014
-#else
1015
-			dlclose (pkcs11_provider->hLibrary);
1016
-#endif
1017
-			pkcs11_provider->hLibrary = NULL;
1018
-		}
1019
-	}
1020
-
1021
-	if (last != NULL) {
1022
-		free (last);
1023 998
 	}
1024 999
 
1025 1000
 	return CKR_OK;
1026 1001
 }
1027
-
1002
+	
1028 1003
 static
1029 1004
 CK_RV
1030 1005
 pkcs11_createSession (
... ...
@@ -1032,18 +1490,18 @@ pkcs11_createSession (
1032 1032
 	IN const char * const szSlot,
1033 1033
 	IN const char * const szIdType,
1034 1034
 	IN const char * const szId,
1035
-	IN const char * const szPIN,
1036 1035
 	IN const bool fProtectedAuthentication,
1037 1036
 	OUT pkcs11_session_t * const p_pkcs11_session
1038 1037
 ) {
1039 1038
 	pkcs11_session_t pkcs11_session;
1040 1039
 	CK_RV rv = CKR_OK;
1041 1040
 
1041
+	ASSERT (pkcs11_data!=NULL);
1042
+	ASSERT (pkcs11_data->fInitialized);
1042 1043
 	ASSERT (szSlotType!=NULL);
1043 1044
 	ASSERT (szSlot!=NULL);
1044 1045
 	ASSERT (szIdType!=NULL);
1045 1046
 	ASSERT (szId!=NULL);
1046
-	ASSERT (szPIN!=NULL);
1047 1047
 	ASSERT (p_pkcs11_session!=NULL);
1048 1048
 	
1049 1049
 	if (
... ...
@@ -1058,36 +1516,46 @@ pkcs11_createSession (
1058 1058
 		memset (pkcs11_session, 0, sizeof (struct pkcs11_session_s));
1059 1059
 	}
1060 1060
 	
1061
-	if (
1062
-		rv == CKR_OK &&
1063
-		!fProtectedAuthentication
1064
-	) {
1065
-		if ((pkcs11_session->szPIN = strdup (szPIN)) == NULL) {
1066
-			rv = CKR_HOST_MEMORY;
1067
-		}
1068
-	}
1069
-
1070 1061
 	if (rv == CKR_OK) {
1071
-		pkcs11_session->fLoginFailed = false;
1072 1062
 		pkcs11_session->key = (CK_OBJECT_HANDLE)-1;
1073 1063
 		pkcs11_session->session = (CK_SESSION_HANDLE)-1;
1064
+		pkcs11_session->fProtectedAuthentication = fProtectedAuthentication;
1065
+	}
1074 1066
 
1075
-		if (!strcmp (szSlotType, "id")) {
1076
-			rv = _pkcs11_getSlotById (pkcs11_session, szSlot);
1077
-		}
1078
-		else if (!strcmp (szSlotType, "name")) {
1079
-			rv = _pkcs11_getSlotByName (pkcs11_session, szSlot);
1080
-		}
1081
-		else if (!strcmp (szSlotType, "label")) {
1082
-			rv = _pkcs11_getSlotByLabel (pkcs11_session, szSlot);
1083
-		}
1084
-		else {
1085
-			rv = CKR_ARGUMENTS_BAD;
1086
-		}
1067
+	if (rv == CKR_OK) {
1068
+		bool fCancel = false;
1069
+
1070
+		do {
1071
+			if (!strcmp (szSlotType, "id")) {
1072
+				rv = _pkcs11_getSlotById (pkcs11_session, szSlot);
1073
+			}
1074
+			else if (!strcmp (szSlotType, "name")) {
1075
+				rv = _pkcs11_getSlotByName (pkcs11_session, szSlot);
1076
+			}
1077
+			else if (!strcmp (szSlotType, "label")) {
1078
+				rv = _pkcs11_getSlotByLabel (pkcs11_session, szSlot);
1079
+			}
1080
+			else {
1081
+				rv = CKR_ARGUMENTS_BAD;
1082
+			}
1083
+
1084
+			if (rv == CKR_SLOT_ID_INVALID) {
1085
+				char szLabel[1024];
1086
+				snprintf (szLabel, sizeof (szLabel), "SLOT(%s=%s)", szSlotType, szSlot);
1087
+				fCancel = !pkcs11_data->hooks->card_prompt (
1088
+					pkcs11_data->hooks->card_prompt_data,
1089
+					szLabel
1090
+				);
1091
+			}
1092
+		} while (rv == CKR_SLOT_ID_INVALID && !fCancel);
1093
+	}
1094
+
1095
+	if (rv == CKR_OK) {
1096
+		rv = _pkcs11_setSessionTokenInfo (pkcs11_session);
1087 1097
 	}
1088 1098
 
1089 1099
 	if (rv == CKR_OK) {
1090
-		rv = pkcs11_login (
1100
+		rv = _pkcs11_login (
1091 1101
 			pkcs11_session
1092 1102
 		);
1093 1103
 	}
... ...
@@ -1106,88 +1574,10 @@ pkcs11_createSession (
1106 1106
 		);
1107 1107
 	}
1108 1108
 	
1109
-	pkcs11_logout (
1110
-		pkcs11_session
1111
-	);
1112
-
1113
-	return rv;
1114
-}
1115
-
1116
-CK_RV
1117
-pkcs11_freeSession (
1118
-	IN const pkcs11_session_t pkcs11_session
1119
-) {
1120
-	if (pkcs11_session != NULL) {
1121
-		pkcs11_logout (pkcs11_session);
1122
-
1123
-		if (pkcs11_session->szPIN != NULL) {
1124
-			free (pkcs11_session->szPIN);
1125
-		}
1126
-		if (pkcs11_session->certificate != NULL) {
1127
-			free (pkcs11_session->certificate);
1128
-		}
1129
-		if (pkcs11_session->certificate_id != NULL) {
1130
-			free (pkcs11_session->certificate_id);
1131
-		}
1132
-
1133
-		free (pkcs11_session);
1134
-	}
1135
-
1136
-	return CKR_OK;
1137
-}
1138
-
1139
-static
1140
-CK_RV
1141
-pkcs11_login (
1142
-	IN const pkcs11_session_t pkcs11_session
1143
-) {
1144
-	CK_RV rv = CKR_OK;
1145
-
1146
-	ASSERT (pkcs11_session!=NULL);
1147
-
1148
-	pkcs11_logout (pkcs11_session);
1149
-
1150
-	if (rv == CKR_OK) {
1151
-		rv = pkcs11_session->provider->f->C_OpenSession (
1152
-			pkcs11_session->slot,
1153
-			CKF_SERIAL_SESSION,
1154
-			NULL_PTR,
1155
-			NULL_PTR,
1156
-			&pkcs11_session->session
1157
-		);
1158
-	}
1159
-
1160 1109
 	/*
1161
-	 * Do not lock the token
1110
+	 * Complete missing login process
1162 1111
 	 */
1163
-	if (
1164
-		rv == CKR_OK &&
1165
-		pkcs11_session->fLoginFailed
1166
-	) {
1167
-		rv = CKR_PIN_INVALID;
1168
-	}
1169
-
1170
-	if (
1171
-		rv == CKR_OK &&
1172
-		(rv = pkcs11_session->provider->f->C_Login (
1173
-			pkcs11_session->session,
1174
-			CKU_USER,
1175
-			pkcs11_session->szPIN,
1176
-			pkcs11_session->szPIN == NULL ? 0 : (CK_ULONG)strlen (pkcs11_session->szPIN)
1177
-		)) != CKR_OK
1178
-	) {
1179
-		if (rv == CKR_USER_ALREADY_LOGGED_IN) {
1180
-			rv = CKR_OK;
1181
-		}
1182
-		else {
1183
-			pkcs11_session->fLoginFailed = true;
1184
-		}
1185
-	}
1186
-
1187
-	if (
1188
-		rv == CKR_OK &&
1189
-		pkcs11_session->certificate_id != NULL
1190
-	) {
1112
+	if (rv == CKR_OK) {
1191 1113
 		rv = _pkcs11_getObjectById (
1192 1114
 			pkcs11_session,
1193 1115
 			CKO_PRIVATE_KEY,
... ...
@@ -1197,25 +1587,27 @@ pkcs11_login (
1197 1197
 		);
1198 1198
 	}
1199 1199
 
1200
-	if (rv != CKR_OK) {
1201
-		pkcs11_logout (pkcs11_session);
1202
-	}
1203
-
1204 1200
 	return rv;
1205 1201
 }
1206 1202
 
1207
-static
1208 1203
 CK_RV
1209
-pkcs11_logout (
1204
+pkcs11_freeSession (
1210 1205
 	IN const pkcs11_session_t pkcs11_session
1211 1206
 ) {
1212
-	ASSERT (pkcs11_session!=NULL);
1207
+	ASSERT (pkcs11_data!=NULL);
1208
+	ASSERT (pkcs11_data->fInitialized);
1213 1209
 
1214
-	if (pkcs11_session->session != (CK_SESSION_HANDLE)-1) {
1215
-		pkcs11_session->provider->f->C_Logout (pkcs11_session->session);
1216
-		pkcs11_session->provider->f->C_CloseSession (pkcs11_session->session);
1217
-		pkcs11_session->key = (CK_OBJECT_HANDLE)-1;
1218
-		pkcs11_session->session = (CK_SESSION_HANDLE)-1;
1210
+	if (pkcs11_session != NULL) {
1211
+		_pkcs11_logout (pkcs11_session);
1212
+
1213
+		if (pkcs11_session->certificate != NULL) {
1214
+			free (pkcs11_session->certificate);
1215
+		}
1216
+		if (pkcs11_session->certificate_id != NULL) {
1217
+			free (pkcs11_session->certificate_id);
1218
+		}
1219
+
1220
+		free (pkcs11_session);
1219 1221
 	}
1220 1222
 
1221 1223
 	return CKR_OK;
... ...
@@ -1227,40 +1619,55 @@ pkcs11_sign (
1227 1227
 	IN const pkcs11_session_t pkcs11_session,
1228 1228
 	IN const CK_MECHANISM_TYPE mech_type,
1229 1229
 	IN const unsigned char * const source,
1230
-	IN const int source_size,
1230
+	IN const size_t source_size,
1231 1231
 	OUT unsigned char * const target,
1232
-	IN OUT int * const target_size
1232
+	IN OUT size_t * const target_size
1233 1233
 ) {
1234 1234
 	CK_MECHANISM mech = {
1235 1235
 		mech_type, NULL, 0
1236 1236
 	};
1237
-	CK_ULONG size;
1238
-	CK_RV rv;
1237
+	CK_RV rv = CKR_OK;
1238
+	bool fLogonRetry = false;
1239
+	bool fOpSuccess = false;
1239 1240
 
1241
+	ASSERT (pkcs11_data!=NULL);
1242
+	ASSERT (pkcs11_data->fInitialized);
1240 1243
 	ASSERT (pkcs11_session!=NULL);
1241 1244
 	ASSERT (source!=NULL);
1242 1245
 	ASSERT (target_size!=NULL);
1243 1246
 
1244
-	if (
1245
-		(rv = pkcs11_session->provider->f->C_SignInit (
1247
+	rv = _pkcs11_validateSession (pkcs11_session);
1248
+
1249
+	while (rv == CKR_OK && !fOpSuccess) {
1250
+		rv = pkcs11_session->provider->f->C_SignInit (
1246 1251
 			pkcs11_session->session,
1247 1252
 			&mech,
1248 1253
 			pkcs11_session->key
1249
-		)) != CKR_OK
1250
-	) {
1251
-		return rv;
1254
+		);
1255
+
1256
+		if (rv == CKR_OK) {
1257
+			fOpSuccess = true;
1258
+		}
1259
+		else {
1260
+			if (!fLogonRetry) {
1261
+				fLogonRetry = true;
1262
+				rv = _pkcs11_login (pkcs11_session);
1263
+			}
1264
+		}
1252 1265
 	}
1253 1266
 
1254
-	size = *target_size;
1255
-	rv = pkcs11_session->provider->f->C_Sign (
1256
-		pkcs11_session->session,
1257
-		(CK_BYTE_PTR)source,
1258
-		source_size,
1259
-		(CK_BYTE_PTR)target,
1260
-		&size
1261
-	);
1267
+	if (rv == CKR_OK) {
1268
+		CK_ULONG size = *target_size;
1269
+		rv = pkcs11_session->provider->f->C_Sign (
1270
+			pkcs11_session->session,
1271
+			(CK_BYTE_PTR)source,
1272
+			source_size,
1273
+			(CK_BYTE_PTR)target,
1274
+			&size
1275
+		);
1262 1276
 
1263
-	*target_size = (int)size;
1277
+		*target_size = (int)size;
1278
+	}
1264 1279
 
1265 1280
 	return rv;
1266 1281
 }
... ...
@@ -1271,40 +1678,55 @@ pkcs11_signRecover (
1271 1271
 	IN const pkcs11_session_t pkcs11_session,
1272 1272
 	IN const CK_MECHANISM_TYPE mech_type,
1273 1273
 	IN const unsigned char * const source,
1274
-	IN const int source_size,
1274
+	IN const size_t source_size,
1275 1275
 	OUT unsigned char * const target,
1276
-	IN OUT int * const target_size
1276
+	IN OUT size_t * const target_size
1277 1277
 ) {
1278 1278
 	CK_MECHANISM mech = {
1279 1279
 		mech_type, NULL, 0
1280 1280
 	};
1281
-	CK_ULONG size;
1282
-	CK_RV rv;
1281
+	CK_RV rv = CKR_OK;
1282
+	bool fLogonRetry = false;
1283
+	bool fOpSuccess = false;
1283 1284
 
1285
+	ASSERT (pkcs11_data!=NULL);
1286
+	ASSERT (pkcs11_data->fInitialized);
1284 1287
 	ASSERT (pkcs11_session!=NULL);
1285 1288
 	ASSERT (source!=NULL);
1286 1289
 	ASSERT (target_size!=NULL);
1287 1290
 
1288
-	if (
1289
-		(rv = pkcs11_session->provider->f->C_SignRecoverInit (
1291
+	rv = _pkcs11_validateSession (pkcs11_session);
1292
+
1293
+	while (rv == CKR_OK && !fOpSuccess) {
1294
+		rv = pkcs11_session->provider->f->C_SignRecoverInit (
1290 1295
 			pkcs11_session->session,
1291 1296
 			&mech,
1292 1297
 			pkcs11_session->key
1293
-		)) != CKR_OK
1294
-	) {
1295
-		return rv;
1298
+		);
1299
+
1300
+		if (rv == CKR_OK) {
1301
+			fOpSuccess = true;
1302
+		}
1303
+		else {
1304
+			if (!fLogonRetry) {
1305
+				fLogonRetry = true;
1306
+				rv = _pkcs11_login (pkcs11_session);
1307
+			}
1308
+		}
1296 1309
 	}
1297 1310
 
1298
-	size = *target_size;
1299
-	rv = pkcs11_session->provider->f->C_SignRecover (
1300
-		pkcs11_session->session,
1301
-		(CK_BYTE_PTR)source,
1302
-		source_size,
1303
-		(CK_BYTE_PTR)target,
1304
-		&size
1305
-	);
1311
+	if (rv == CKR_OK) {
1312
+		CK_ULONG size = *target_size;
1313
+		rv = pkcs11_session->provider->f->C_SignRecover (
1314
+			pkcs11_session->session,
1315
+			(CK_BYTE_PTR)source,
1316
+			source_size,
1317
+			(CK_BYTE_PTR)target,
1318
+			&size
1319
+		);
1306 1320
 
1307
-	*target_size = (int)size;
1321
+		*target_size = (int)size;
1322
+	}
1308 1323
 
1309 1324
 	return rv;
1310 1325
 }
... ...
@@ -1315,40 +1737,56 @@ pkcs11_decrypt (
1315 1315
 	IN const pkcs11_session_t pkcs11_session,
1316 1316
 	IN const CK_MECHANISM_TYPE mech_type,
1317 1317
 	IN const unsigned char * const source,
1318
-	IN const int source_size,
1318
+	IN const size_t source_size,
1319 1319
 	OUT unsigned char * const target,
1320
-	IN OUT int * const target_size
1320
+	IN OUT size_t * const target_size
1321 1321
 ) {
1322 1322
 	CK_MECHANISM mech = {
1323 1323
 		mech_type, NULL, 0
1324 1324
 	};
1325 1325
 	CK_ULONG size;
1326
-	CK_RV rv;
1326
+	CK_RV rv = CKR_OK;
1327
+	bool fLogonRetry = false;
1328
+	bool fOpSuccess = false;
1327 1329
 
1330
+	ASSERT (pkcs11_data!=NULL);
1331
+	ASSERT (pkcs11_data->fInitialized);
1328 1332
 	ASSERT (pkcs11_session!=NULL);
1329 1333
 	ASSERT (source!=NULL);
1330 1334
 	ASSERT (target_size!=NULL);
1331 1335
 
1332
-	if (
1333
-		(rv = pkcs11_session->provider->f->C_DecryptInit (
1336
+	rv = _pkcs11_validateSession (pkcs11_session);
1337
+
1338
+	while (rv == CKR_OK && !fOpSuccess) {
1339
+		rv = pkcs11_session->provider->f->C_DecryptInit (
1334 1340
 			pkcs11_session->session,
1335 1341
 			&mech,
1336 1342
 			pkcs11_session->key
1337
-		)) != CKR_OK
1338
-	) {
1339
-		return rv;
1343
+		);
1344
+
1345
+		if (rv == CKR_OK) {
1346
+			fOpSuccess = true;
1347
+		}
1348
+		else {
1349
+			if (!fLogonRetry) {
1350
+				fLogonRetry = true;
1351
+				rv = _pkcs11_login (pkcs11_session);
1352
+			}
1353
+		}
1340 1354
 	}
1341 1355
 
1342
-	size = *target_size;
1343
-	rv = pkcs11_session->provider->f->C_Decrypt (
1344
-		pkcs11_session->session,
1345
-		(CK_BYTE_PTR)source,
1346
-		source_size,
1347
-		(CK_BYTE_PTR)target,
1348
-		&size
1349
-	);
1356
+	if (rv == CKR_OK) {
1357
+		size = *target_size;
1358
+		rv = pkcs11_session->provider->f->C_Decrypt (
1359
+			pkcs11_session->session,
1360
+			(CK_BYTE_PTR)source,
1361
+			source_size,
1362
+			(CK_BYTE_PTR)target,
1363
+			&size
1364
+		);
1350 1365
 
1351
-	*target_size = (int)size;
1366
+		*target_size = (int)size;
1367
+	}
1352 1368
 
1353 1369
 	return rv;
1354 1370
 }
... ...
@@ -1357,9 +1795,11 @@ static
1357 1357
 CK_RV
1358 1358
 pkcs11_getCertificate (
1359 1359
 	IN const pkcs11_session_t pkcs11_session,
1360
-	OUT char * const certificate,
1361
-	IN OUT int * const certificate_size
1360
+	OUT unsigned char * const certificate,
1361
+	IN OUT size_t * const certificate_size
1362 1362
 ) {
1363
+	ASSERT (pkcs11_data!=NULL);
1364
+	ASSERT (pkcs11_data->fInitialized);
1363 1365
 	ASSERT (certificate_size!=NULL);
1364 1366
 
1365 1367
 	*certificate_size = pkcs11_session->certificate_size;
... ...
@@ -1474,10 +1914,11 @@ pkcs11_getMessage (
1474 1474
 }
1475 1475
 
1476 1476
 /*==========================================
1477
- * openvpn interface
1477
+ * openssl interface
1478 1478
  */
1479 1479
 
1480 1480
 typedef struct openssl_session_s {
1481
+	RSA_METHOD smart_rsa;
1481 1482
 	int (*orig_finish)(RSA *rsa);
1482 1483
 	pkcs11_session_t pkcs11_session;
1483 1484
 } *openssl_session_t;
... ...
@@ -1525,7 +1966,7 @@ openssl_pkcs11_priv_dec (
1525 1525
 		flen,
1526 1526
 		from,
1527 1527
 		to,
1528
-		rsa,
1528
+		(void *)rsa,
1529 1529
 		padding
1530 1530
 	);
1531 1531
 
... ...
@@ -1543,27 +1984,18 @@ openssl_pkcs11_priv_dec (
1543 1543
 
1544 1544
 	if (
1545 1545
 		rv == CKR_OK &&
1546
-		(rv = pkcs11_login (pkcs11_session)) != CKR_OK
1547
-	) {
1548
-		msg (M_WARN, "PKCS#11: Cannot login to token %ld:'%s'", rv, pkcs11_getMessage (rv));
1549
-	}
1550
-	
1551
-	if (
1552
-		rv == CKR_OK &&
1553 1546
 		(rv = pkcs11_decrypt (
1554 1547
 			pkcs11_session,
1555 1548
 			CKM_RSA_PKCS,
1556 1549
 			from,
1557 1550
 			flen,
1558 1551
 			to,
1559
-			&flen
1552
+			(size_t *)&flen
1560 1553
 		)) != CKR_OK
1561 1554
 	) {
1562 1555
 		msg (M_WARN, "PKCS#11: Cannot decrypt using private key %ld:'%s'", rv, pkcs11_getMessage (rv));
1563 1556
 	}
1564 1557
 
1565
-	pkcs11_logout (pkcs11_session);
1566
-
1567 1558
 	msg (
1568 1559
 		D_PKCS11_DEBUG,
1569 1560
 		"PKCS#11: openssl_pkcs11_priv_dec - return rv=%ld",
... ...
@@ -1593,8 +2025,8 @@ openssl_pkcs11_sign (
1593 1593
 		m,
1594 1594
 		m_len,
1595 1595
 		sigret,
1596
-		siglen,
1597
-		rsa
1596
+		(void *)siglen,
1597
+		(void *)rsa
1598 1598
 	);
1599 1599
 
1600 1600
 	ASSERT (m!=NULL);
... ...
@@ -1607,46 +2039,35 @@ openssl_pkcs11_sign (
1607 1607
 
1608 1608
 	*siglen = RSA_size(rsa);
1609 1609
 
1610
-	if (
1611
-		rv == CKR_OK &&
1612
-		(rv = pkcs11_login (pkcs11_session)) != CKR_OK
1613
-	) {
1614
-		msg (M_WARN, "PKCS#11: Cannot login to token %ld:'%s'", rv, pkcs11_getMessage (rv));
1615
-	}
1616
-	
1617
-	if (rv == CKR_OK) {
1618
-		if (pkcs11_session->fKeySignRecover) {
1619
-			if (
1620
-				(rv = pkcs11_signRecover (
1621
-					pkcs11_session,
1622
-					CKM_RSA_PKCS,
1623
-					m,
1624
-					m_len,
1625
-					sigret,
1626
-					siglen
1627
-				)) != CKR_OK
1628
-			) {
1629
-				msg (M_WARN, "PKCS#11: Cannot perform signature-recover %ld:'%s'", rv, pkcs11_getMessage (rv));
1630
-			}
1610
+	if (pkcs11_session->fKeySignRecover) {
1611
+		if (
1612
+			(rv = pkcs11_signRecover (
1613
+				pkcs11_session,
1614
+				CKM_RSA_PKCS,
1615
+				m,
1616
+				m_len,
1617
+				sigret,
1618
+				siglen
1619
+			)) != CKR_OK
1620
+		) {
1621
+			msg (M_WARN, "PKCS#11: Cannot perform signature-recover %ld:'%s'", rv, pkcs11_getMessage (rv));
1631 1622
 		}
1632
-		else {
1633
-			if (
1634
-				(rv = pkcs11_sign (
1635
-					pkcs11_session,
1636
-					CKM_RSA_PKCS,
1637
-					m,
1638
-					m_len,
1639
-					sigret,
1640
-					siglen
1641
-				)) != CKR_OK
1642
-			) {
1643
-				msg (M_WARN, "PKCS#11: Cannot perform signature %ld:'%s'", rv, pkcs11_getMessage (rv));
1644
-			}
1623
+	}
1624
+	else {
1625
+		if (
1626
+			(rv = pkcs11_sign (
1627
+				pkcs11_session,
1628
+				CKM_RSA_PKCS,
1629
+				m,
1630
+				m_len,
1631
+				sigret,
1632
+				siglen
1633
+			)) != CKR_OK
1634
+		) {
1635
+			msg (M_WARN, "PKCS#11: Cannot perform signature %ld:'%s'", rv, pkcs11_getMessage (rv));
1645 1636
 		}
1646 1637
 	}
1647 1638
 
1648
-	pkcs11_logout (pkcs11_session);
1649
-
1650 1639
 	msg (
1651 1640
 		D_PKCS11_DEBUG,
1652 1641
 		"PKCS#11: openssl_pkcs11_priv_sign - return rv=%ld",
... ...
@@ -1664,8 +2085,8 @@ openssl_pkcs11_finish(RSA *rsa) {
1664 1664
 
1665 1665
 	msg (
1666 1666
 		D_PKCS11_DEBUG,
1667
-		"PKCS#11: openssl_pkcs11_finish - entered - rsa=%p",
1668
-		rsa
1667
+		"PKCS#11: openssl_pkcs11_finish - entered rsa=%p",
1668
+		(void *)rsa
1669 1669
 	);
1670 1670
 
1671 1671
 	openssl_session = (openssl_session_t)RSA_get_app_data (rsa);
... ...
@@ -1703,27 +2124,37 @@ openssl_pkcs11_finish(RSA *rsa) {
1703 1703
 	return 1;
1704 1704
 }
1705 1705
 
1706
-static RSA_METHOD *
1707
-openssl_pkcs11_get_rsa_method(RSA *rsa)
1706
+void
1707
+openssl_pkcs11_set_rsa(const openssl_session_t openssl_session, RSA *rsa)
1708 1708
 {
1709
-	static RSA_METHOD smart_rsa;
1710 1709
 	const RSA_METHOD *def = RSA_get_default_method();
1711 1710
 
1712
-	ASSERT (rsa);
1711
+	ASSERT (openssl_session!=NULL);
1712
+	ASSERT (rsa!=NULL);
1713
+
1714
+	memmove (&openssl_session->smart_rsa, def, sizeof(RSA_METHOD));
1713 1715
 
1714
-	/* use the OpenSSL version */
1715
-	memmove (&smart_rsa, def, sizeof(smart_rsa));
1716
+	openssl_session->orig_finish = def->finish;
1716 1717
 
1717
-	/* save original */
1718
-	((openssl_session_t)RSA_get_app_data (rsa))->orig_finish = def->finish;
1718
+	openssl_session->smart_rsa.name = "pkcs11";
1719
+	openssl_session->smart_rsa.rsa_priv_enc = openssl_pkcs11_priv_enc;
1720
+	openssl_session->smart_rsa.rsa_priv_dec = openssl_pkcs11_priv_dec;
1721
+	openssl_session->smart_rsa.rsa_sign = openssl_pkcs11_sign;
1722
+	openssl_session->smart_rsa.finish = openssl_pkcs11_finish;
1723
+	openssl_session->smart_rsa.flags  = RSA_METHOD_FLAG_NO_CHECK | RSA_FLAG_EXT_PKEY;
1719 1724
 
1720
-	smart_rsa.name = "pkcs11";
1721
-	smart_rsa.rsa_priv_enc = openssl_pkcs11_priv_enc;
1722
-	smart_rsa.rsa_priv_dec = openssl_pkcs11_priv_dec;
1723
-	smart_rsa.rsa_sign = openssl_pkcs11_sign;
1724
-	smart_rsa.finish = openssl_pkcs11_finish;
1725
-	smart_rsa.flags  = RSA_METHOD_FLAG_NO_CHECK | RSA_FLAG_EXT_PKEY;
1726
-	return &smart_rsa;
1725
+	RSA_set_method (rsa, &openssl_session->smart_rsa);
1726
+	RSA_set_app_data (rsa, openssl_session);
1727
+	
1728
+#ifdef BROKEN_OPENSSL_ENGINE
1729
+	if (fOK) {
1730
+		if (!rsa->engine)
1731
+			rsa->engine = ENGINE_get_default_RSA();
1732
+
1733
+		ENGINE_set_RSA(ENGINE_get_default_RSA(), openssl_session->smart_rsa);
1734
+		msg(M_WARN, "PKCS#11: OpenSSL engine support is broken! Workaround enabled");
1735
+	}
1736
+#endif
1727 1737
 }
1728 1738
 
1729 1739
 
... ...
@@ -1737,6 +2168,150 @@ static void  broken_openssl_init()
1737 1737
 }
1738 1738
 #endif
1739 1739
 
1740
+/*==========================================
1741
+ * openvpn interface
1742
+ */
1743
+
1744
+static
1745
+bool
1746
+_openvpn_pkcs11_card_prompt (
1747
+	IN const void *pData,
1748
+	IN const char * const szLabel
1749
+) {
1750
+	static struct user_pass token_pass;
1751
+	char szPrompt[1024];
1752
+	char szTemp[1024];
1753
+
1754
+	ASSERT (szLabel!=NULL);
1755
+
1756
+	openvpn_snprintf (szPrompt, sizeof (szPrompt), "INSERT");
1757
+
1758
+	token_pass.defined = false;
1759
+	token_pass.nocache = true;
1760
+	get_user_pass (&token_pass, NULL, true, szPrompt, GET_USER_PASS_MANAGEMENT|GET_USER_PASS_SENSITIVE);
1761
+	strncpynt (szTemp, token_pass.password, sizeof (szTemp));
1762
+	purge_user_pass (&token_pass, true);
1763
+
1764
+	if (strlen (szTemp) == 0) {
1765
+		return false;
1766
+	}
1767
+	else {
1768
+		return true;
1769
+	}
1770
+}
1771
+
1772
+static
1773
+bool
1774
+_openvpn_pkcs11_pin_prompt (
1775
+	IN const void *pData,
1776
+	IN const char * const szLabel,
1777
+	OUT char * const szPIN,
1778
+	IN const size_t nMaxPIN
1779
+) {
1780
+	static struct user_pass token_pass;
1781
+	char szPrompt[1024];
1782
+
1783
+	ASSERT (szLabel!=NULL);
1784
+
1785
+	openvpn_snprintf (szPrompt, sizeof (szPrompt), "%s token", szLabel);
1786
+
1787
+	token_pass.defined = false;
1788
+	token_pass.nocache = true;
1789
+	get_user_pass (&token_pass, NULL, true, szPrompt, GET_USER_PASS_MANAGEMENT|GET_USER_PASS_SENSITIVE);
1790
+	strncpynt (szPIN, token_pass.password, nMaxPIN);
1791
+	purge_user_pass (&token_pass, true);
1792
+
1793
+	if (strlen (szPIN) == 0) {
1794
+		return false;
1795
+	}
1796
+	else {
1797
+		return true;
1798
+	}
1799
+}
1800
+
1801
+void
1802
+init_pkcs11 (
1803
+	const int nPINCachePeriod
1804
+) {
1805
+	CK_RV rv;
1806
+
1807
+	msg (
1808
+		D_PKCS11_DEBUG,
1809
+		"PKCS#11: init_pkcs11 - entered"
1810
+	);
1811
+
1812
+	if ((rv = pkcs11_initialize ()) != CKR_OK) {
1813
+		msg (M_FATAL, "PKCS#11: Cannot initialize %ld-'%s'", rv, pkcs11_getMessage (rv));
1814
+	}
1815
+/*Until REQUEST/REPLY interface.
1816
+	if ((rv = pkcs11_setCardPromptHook (_openvpn_pkcs11_card_prompt, NULL)) != CKR_OK) {
1817
+		msg (M_FATAL, "PKCS#11: Cannot set hooks %ld-'%s'", rv, pkcs11_getMessage (rv));
1818
+	}
1819
+*/
1820
+	if ((rv = pkcs11_setPINPromptHook (_openvpn_pkcs11_pin_prompt, NULL)) != CKR_OK) {
1821
+		msg (M_FATAL, "PKCS#11: Cannot set hooks %ld-'%s'", rv, pkcs11_getMessage (rv));
1822
+	}
1823
+
1824
+	if ((rv = pkcs11_setPINCachePeriod (nPINCachePeriod)) != CKR_OK) {
1825
+		msg (M_FATAL, "PKCS#11: Cannot set PIN cache period %ld-'%s'", rv, pkcs11_getMessage (rv));
1826
+	}
1827
+
1828
+	msg (
1829
+		D_PKCS11_DEBUG,
1830
+		"PKCS#11: init_pkcs11 - return"
1831
+	);
1832
+}
1833
+
1834
+void
1835
+free_pkcs11 () {
1836
+	msg (
1837
+		D_PKCS11_DEBUG,
1838
+		"PKCS#11: free_pkcs11 - entered"
1839
+	);
1840
+
1841
+	pkcs11_terminate ();
1842
+
1843
+	msg (
1844
+		D_PKCS11_DEBUG,
1845
+		"PKCS#11: free_pkcs11 - return"
1846
+	);
1847
+}
1848
+
1849
+void
1850
+fork_fix_pkcs11 () {
1851
+	pkcs11_forkFixup ();
1852
+}
1853
+
1854
+void
1855
+add_pkcs11 (
1856
+	IN const char * const provider,
1857
+	IN const char * const sign_mode
1858
+) {
1859
+	CK_RV rv;
1860
+
1861
+	msg (
1862
+		D_PKCS11_DEBUG,
1863
+		"PKCS#11: add_pkcs11 - entered - provider='%s', sign_mode='%s'",
1864
+		provider,
1865
+		sign_mode == NULL ? "default" : sign_mode
1866
+	);
1867
+
1868
+	msg (
1869
+		M_INFO,
1870
+		"PKCS#11: Adding PKCS#11 provider '%s'",
1871
+		provider
1872
+	);
1873
+
1874
+	if ((rv = pkcs11_addProvider (provider, sign_mode)) != CKR_OK) {
1875
+		msg (M_WARN, "PKCS#11: Cannot initialize provider '%s' %ld-'%s'", provider, rv, pkcs11_getMessage (rv));
1876
+	}
1877
+
1878
+	msg (
1879
+		D_PKCS11_DEBUG,
1880
+		"PKCS#11: add_pkcs11 - return"
1881
+	);
1882
+}
1883
+
1740 1884
 int
1741 1885
 SSL_CTX_use_pkcs11 (
1742 1886
 	IN OUT SSL_CTX * const ssl_ctx,
... ...
@@ -1744,7 +2319,6 @@ SSL_CTX_use_pkcs11 (
1744 1744
 	IN const char * const pkcs11_slot,
1745 1745
 	IN const char * const pkcs11_id_type,
1746 1746
 	IN const char * const pkcs11_id,
1747
-	IN const char * const pin,
1748 1747
 	IN const bool pkcs11_protected_authentication
1749 1748
 ) {
1750 1749
 	X509 *x509 = NULL;
... ...
@@ -1755,14 +2329,14 @@ SSL_CTX_use_pkcs11 (
1755 1755
 	CK_RV rv = CKR_OK;
1756 1756
 
1757 1757
 	unsigned char certificate[10*1024];
1758
-	int certificate_size;
1758
+	size_t certificate_size;
1759 1759
 	unsigned char *p;
1760 1760
 	bool fOK = true;
1761 1761
 
1762 1762
 	msg (
1763 1763
 		D_PKCS11_DEBUG,
1764 1764
 		"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",
1765
-		ssl_ctx,
1765
+		(void *)ssl_ctx,
1766 1766
 		pkcs11_slot_type,
1767 1767
 		pkcs11_slot,
1768 1768
 		pkcs11_id_type,
... ...
@@ -1775,9 +2349,6 @@ SSL_CTX_use_pkcs11 (
1775 1775
 	ASSERT (pkcs11_slot!=NULL);
1776 1776
 	ASSERT (pkcs11_id_type!=NULL);
1777 1777
 	ASSERT (pkcs11_id!=NULL);
1778
-	if (!pkcs11_protected_authentication) {
1779
-		ASSERT (pin!=NULL);
1780
-	}
1781 1778
 
1782 1779
 	if (
1783 1780
 		fOK &&
... ...
@@ -1798,7 +2369,6 @@ SSL_CTX_use_pkcs11 (
1798 1798
 			pkcs11_slot,
1799 1799
 			pkcs11_id_type,
1800 1800
 			pkcs11_id,
1801
-			pin,
1802 1801
 			pkcs11_protected_authentication,
1803 1802
 			&openssl_session->pkcs11_session
1804 1803
 		)) != CKR_OK
... ...
@@ -1862,23 +2432,12 @@ SSL_CTX_use_pkcs11 (
1862 1862
 	}
1863 1863
 
1864 1864
 	if (fOK) {
1865
-		RSA_set_app_data (rsa, openssl_session);
1866
-		RSA_set_method (rsa, openssl_pkcs11_get_rsa_method (rsa));
1865
+		openssl_pkcs11_set_rsa (openssl_session, rsa);
1867 1866
 		rsa->flags |= RSA_FLAG_SIGN_VER;
1868 1867
 
1869 1868
 		/* it will be freed when rsa usage count will be zero */
1870 1869
 		fShouldFreeOpenSSLSession = false;
1871 1870
 	}
1872
-	
1873
-#ifdef BROKEN_OPENSSL_ENGINE
1874
-	if (fOK) {
1875
-		if (!rsa->engine)
1876
-			rsa->engine = ENGINE_get_default_RSA();
1877
-
1878
-		ENGINE_set_RSA(ENGINE_get_default_RSA(), openssl_pkcs11_get_rsa_method(rsa));
1879
-		msg(M_WARN, "PKCS#11: OpenSSL engine support is broken! Workaround enabled");
1880
-	}
1881
-#endif
1882 1871
 
1883 1872
 	if (
1884 1873
 		fOK &&
... ...
@@ -1936,51 +2495,6 @@ SSL_CTX_use_pkcs11 (
1936 1936
 }
1937 1937
 
1938 1938
 void
1939
-add_pkcs11 (
1940
-	IN const char * const provider,
1941
-	IN const char * const sign_mode
1942
-) {
1943
-	CK_RV rv;
1944
-
1945
-	msg (
1946
-		D_PKCS11_DEBUG,
1947
-		"PKCS#11: add_pkcs11 - entered - provider='%s', sign_mode='%s'",
1948
-		provider,
1949
-		sign_mode == NULL ? "default" : sign_mode
1950
-	);
1951
-
1952
-	msg (
1953
-		M_INFO,
1954
-		"PKCS#11: Adding PKCS#11 provider '%s'",
1955
-		provider
1956
-	);
1957
-
1958
-	if ((rv = pkcs11_addProvider (provider, sign_mode)) != CKR_OK) {
1959
-		msg (M_WARN, "PKCS#11: Cannot initialize provider '%s' %ld-'%s'", provider, rv, pkcs11_getMessage (rv));
1960
-	}
1961
-
1962
-	msg (
1963
-		D_PKCS11_DEBUG,
1964
-		"PKCS#11: add_pkcs11 - return"
1965
-	);
1966
-}
1967
-
1968
-void
1969
-free_pkcs11 () {
1970
-	msg (
1971
-		D_PKCS11_DEBUG,
1972
-		"PKCS#11: free_pkcs11 - entered"
1973
-	);
1974
-
1975
-	pkcs11_finalize ();
1976
-
1977
-	msg (
1978
-		D_PKCS11_DEBUG,
1979
-		"PKCS#11: free_pkcs11 - return"
1980
-	);
1981
-}
1982
-
1983
-void
1984 1939
 show_pkcs11_slots (
1985 1940
 	IN const int msglev,
1986 1941
 	IN const int warnlev,
... ...
@@ -1992,14 +2506,30 @@ show_pkcs11_slots (
1992 1992
 	CK_SLOT_ID s;
1993 1993
 	CK_RV rv;
1994 1994
 
1995
+	pkcs11_provider_t pkcs11_provider;
1996
+
1995 1997
 	ASSERT (provider!=NULL);
1996 1998
 
1997 1999
 	if (
2000
+		(rv = pkcs11_initialize ()) != CKR_OK
2001
+	) {
2002
+		msg (M_FATAL, "PKCS#11: Cannot initialize interface %ld-'%s'", rv, pkcs11_getMessage (rv));
2003
+	}
2004
+
2005
+	if (
1998 2006
 		(rv = pkcs11_addProvider (provider, NULL)) != CKR_OK
1999 2007
 	) {
2000 2008
 		msg (M_FATAL, "PKCS#11: Cannot initialize provider %ld-'%s'", rv, pkcs11_getMessage (rv));
2001 2009
 	}
2002 2010
 
2011
+	/*
2012
+	 * our provider is head
2013
+	 */
2014
+	pkcs11_provider = pkcs11_data->providers;
2015
+	if (pkcs11_provider == NULL || !pkcs11_provider->fEnabled) {
2016
+		msg (M_FATAL, "PKCS#11: Cannot get provider %ld-'%s'", rv, pkcs11_getMessage (rv));
2017
+	}
2018
+
2003 2019
 	if (
2004 2020
 		(rv = pkcs11_provider->f->C_GetInfo (&info)) != CKR_OK
2005 2021
 	) {
... ...
@@ -2009,7 +2539,7 @@ show_pkcs11_slots (
2009 2009
 		char szManufacturerID[sizeof (info.manufacturerID)+1];
2010 2010
 
2011 2011
 		_fixupFixedString (
2012
-			info.manufacturerID,
2012
+			(char *)info.manufacturerID,
2013 2013
 			szManufacturerID,
2014 2014
 			sizeof (info.manufacturerID)
2015 2015
 		);
... ...
@@ -2062,7 +2592,7 @@ show_pkcs11_slots (
2062 2062
 				char szCurrentName[sizeof (info.slotDescription)+1];
2063 2063
 			
2064 2064
 				_fixupFixedString (
2065
-					info.slotDescription,
2065
+					(char *)info.slotDescription,
2066 2066
 					szCurrentName,
2067 2067
 					sizeof (info.slotDescription)
2068 2068
 				);
... ...
@@ -2072,7 +2602,19 @@ show_pkcs11_slots (
2072 2072
 		}
2073 2073
 	}
2074 2074
 
2075
-	pkcs11_finalize ();
2075
+	pkcs11_terminate ();
2076
+}
2077
+
2078
+static
2079
+bool
2080
+_show_pkcs11_objects_pin_prompt (
2081
+	IN const void *pData,
2082
+	IN const char * const szLabel,
2083
+	OUT char * const szPIN,
2084
+	IN const size_t nMaxPIN
2085
+) {
2086
+	strncpy (szPIN, (char *)pData, nMaxPIN);
2087
+	return true;
2076 2088
 }
2077 2089
 
2078 2090
 void
... ...
@@ -2090,6 +2632,8 @@ show_pkcs11_objects (
2090 2090
 	CK_SLOT_ID s;
2091 2091
 	CK_RV rv;
2092 2092
 
2093
+	pkcs11_provider_t pkcs11_provider;
2094
+
2093 2095
 	ASSERT (provider!=NULL);
2094 2096
 	ASSERT (slot!=NULL);
2095 2097
 	ASSERT (pin!=NULL);
... ...
@@ -2097,11 +2641,31 @@ show_pkcs11_objects (
2097 2097
 	s = atoi (slot);
2098 2098
 
2099 2099
 	if (
2100
+		(rv = pkcs11_initialize ()) != CKR_OK
2101
+	) {
2102
+		msg (M_FATAL, "PKCS#11: Cannot initialize interface %ld-'%s'", rv, pkcs11_getMessage (rv));
2103
+	}
2104
+
2105
+	if (
2106
+		(rv = pkcs11_setPINPromptHook (_show_pkcs11_objects_pin_prompt, (void *)pin)) != CKR_OK
2107
+	) {
2108
+		msg (M_FATAL, "PKCS#11: Cannot set hooks %ld-'%s'", rv, pkcs11_getMessage (rv));
2109
+	}
2110
+
2111
+	if (
2100 2112
 		(rv = pkcs11_addProvider (provider, NULL)) != CKR_OK
2101 2113
 	) {
2102 2114
 		msg (M_FATAL, "PKCS#11: Cannot initialize provider %ld-'%s'", rv, pkcs11_getMessage (rv));
2103 2115
 	}
2104 2116
 
2117
+  	/*
2118
+	 * our provider is head
2119
+	 */
2120
+	pkcs11_provider = pkcs11_data->providers;
2121
+	if (pkcs11_provider == NULL || !pkcs11_provider->fEnabled) {
2122
+		msg (M_FATAL, "PKCS#11: Cannot get provider %ld-'%s'", rv, pkcs11_getMessage (rv));
2123
+	}
2124
+
2105 2125
 	if (
2106 2126
 		(rv = pkcs11_provider->f->C_GetTokenInfo (
2107 2127
 			s,
... ...
@@ -2117,22 +2681,22 @@ show_pkcs11_objects (
2117 2117
 		char szSerialNumber[sizeof (info.serialNumber)+1];
2118 2118
 		
2119 2119
 		_fixupFixedString (
2120
-			info.label,
2120
+			(char *)info.label,
2121 2121
 			szLabel,
2122 2122
 			sizeof (info.label)
2123 2123
 		);
2124 2124
 		_fixupFixedString (
2125
-			info.manufacturerID,
2125
+			(char *)info.manufacturerID,
2126 2126
 			szManufacturerID,
2127 2127
 			sizeof (info.manufacturerID)
2128 2128
 		);
2129 2129
 		_fixupFixedString (
2130
-			info.model,
2130
+			(char *)info.model,
2131 2131
 			szModel,
2132 2132
 			sizeof (info.model)
2133 2133
 		);
2134 2134
 		_fixupFixedString (
2135
-			info.serialNumber,
2135
+			(char *)info.serialNumber,
2136 2136
 			szSerialNumber,
2137 2137
 			sizeof (info.serialNumber)
2138 2138
 		);
... ...
@@ -2385,9 +2949,9 @@ show_pkcs11_objects (
2385 2385
 	pkcs11_provider->f->C_FindObjectsFinal (session);
2386 2386
 	pkcs11_provider->f->C_Logout (session);
2387 2387
 	pkcs11_provider->f->C_CloseSession (session);
2388
-	pkcs11_finalize ();
2388
+	pkcs11_terminate ();
2389 2389
 }
2390 2390
 
2391 2391
 #else
2392 2392
 static void dummy (void) {}
2393
-#endif /* USE_OPENSC && USE_SSL && USE_CRYPTO */
2393
+#endif /* ENABLE_PKCS11 */
... ...
@@ -29,6 +29,23 @@
29 29
 
30 30
 #include <openssl/ssl.h>
31 31
 
32
+void
33
+init_pkcs11 (
34
+	const int nPINCachePeriod
35
+);
36
+
37
+void
38
+free_pkcs11 ();
39
+
40
+void
41
+fork_fix_pkcs11 ();
42
+
43
+void
44
+add_pkcs11 (
45
+	const char * const provider,
46
+	const char * const sign_mode
47
+);
48
+
32 49
 int
33 50
 SSL_CTX_use_pkcs11 (
34 51
 	SSL_CTX * const ssl_ctx,
... ...
@@ -36,20 +53,10 @@ SSL_CTX_use_pkcs11 (
36 36
 	const char * const pkcs11_slot,
37 37
 	const char * const pkcs11_id_type,
38 38
 	const char * const pkcs11_id,
39
-	const char * const pin,
40 39
 	const bool pkcs11_protected_authentication
41 40
 );
42 41
 
43 42
 void
44
-add_pkcs11 (
45
-	const char * const provider,
46
-	const char * const sign_mode
47
-);
48
-
49
-void
50
-free_pkcs11 ();
51
-
52
-void
53 43
 show_pkcs11_slots (
54 44
 	const int msglev,
55 45
 	const int warnlev,
... ...
@@ -65,6 +72,6 @@ show_pkcs11_objects (
65 65
 	const char * const pin
66 66
 );
67 67
 
68
-#endif
68
+#endif			/* ENABLE_PKCS11 */
69 69
 
70
-#endif
70
+#endif			/* OPENVPN_PKCS11_H */
... ...
@@ -854,17 +854,8 @@ init_ssl (const struct options *options)
854 854
 #ifdef ENABLE_PKCS11
855 855
       if (options->pkcs11_providers[0])
856 856
        {
857
-	char password[256];
858
-	password[0] = '\0';
859
-	if (
860
-		!options->pkcs11_protected_authentication &&
861
-		options->key_pass_file
862
-	) {
863
-	  pem_password_callback (password, sizeof(password) - 1, 0, NULL);
864
-	}
865
-
866 857
         /* Load Certificate and Private Key */
867
-	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))
858
+	if (!SSL_CTX_use_pkcs11 (ctx, options->pkcs11_slot_type, options->pkcs11_slot, options->pkcs11_id_type, options->pkcs11_id, options->pkcs11_protected_authentication))
868 859
 	  msg (M_SSLERR, "Cannot load certificate \"%s:%s\" from slot \"%s:%s\" using PKCS#11 interface",
869 860
                options->pkcs11_id_type, options->pkcs11_id, options->pkcs11_slot_type, options->pkcs11_slot);
870 861
        }