Browse code

I've recently worked on a better version of pkcs11-helper. I've also merged it into QCA (Qt Cryptographic Architecture), so that KDE 4 will finally be able to use smartcards.

The changes allows the following features:

1. Thread safe, is activated if USE_PTHREAD.

2. Slot event - Will allow us in the future to disconnect VPN when smartcard
is removed. In order to support this OpenVPN must support threading... At
least SIGUSR1 from a different thread. Threading should be supported in both
Windows and Linux. -- currently disabled.

When I talk about threading support it is just support in configuration script
and that the method that SIGUSR1 self can be called from a different thread.
I already handle the monitor threads.

3. Certificate enumeration - Will allow us to finally have one configuration
file for all users! When you add the plugin GUI stuff you talked about, we will
be able to display a list of available certificates for the user to select.
-- currently disabled.

4. Data object manipulation - Will allow us to store tls-auth on the smartcard
as well. -- currently disabled.

5. Many other minor improvements.

Alon Bar-Lev


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

james authored on 2006/04/05 16:17:02
Showing 10 changed files
... ...
@@ -140,9 +140,10 @@ context_init_1 (struct context *c)
140 140
 #if defined(ENABLE_PKCS11)
141 141
   if (c->first_time) {
142 142
     int i;
143
-    pkcs11_initialize (c->options.pkcs11_pin_cache_period);
143
+    pkcs11_initialize (true, c->options.pkcs11_pin_cache_period);
144 144
     for (i=0;i<MAX_PARMS && c->options.pkcs11_providers[i] != NULL;i++)
145
-     pkcs11_addProvider (c->options.pkcs11_providers[i], c->options.pkcs11_sign_mode[i]);
145
+     pkcs11_addProvider (c->options.pkcs11_providers[i], c->options.pkcs11_protected_authentication[i],
146
+       c->options.pkcs11_sign_mode[i], c->options.pkcs11_cert_private[i]);
146 147
   }
147 148
 #endif
148 149
 
... ...
@@ -205,15 +205,15 @@ openvpn \- secure IP tunnel daemon.
205 205
 [\ \fB\-\-ping\-restart\fR\ \fIn\fR\ ]
206 206
 [\ \fB\-\-ping\-timer\-rem\fR\ ]
207 207
 [\ \fB\-\-ping\fR\ \fIn\fR\ ]
208
+[\ \fB\-\-pkcs11\-cert\-private\fR\ \fI[0|1]...\fR\ ]
209
+[\ \fB\-\-pkcs11\-id\fR\ \fIname\fR\ ]
210
+[\ \fB\-\-pkcs11\-id\-type\fR\ \fItype\fR\ ]
211
+[\ \fB\-\-pkcs11\-pin\-cache\fR\ \fIseconds\fR\ ]
212
+[\ \fB\-\-pkcs11\-protected\-authentication\fR\ \fI[0|1]...\fR\ ]
208 213
 [\ \fB\-\-pkcs11\-providers\fR\ \fIprovider...\fR\ ]
209 214
 [\ \fB\-\-pkcs11\-sign\-mode\fR\ \fImode...\fR\ ]
210
-[\ \fB\-\-pkcs11\-slot\-type\fR\ \fItype\fR\ ]
211 215
 [\ \fB\-\-pkcs11\-slot\fR\ \fIname\fR\ ]
212
-[\ \fB\-\-pkcs11\-id\-type\fR\ \fItype\fR\ ]
213
-[\ \fB\-\-pkcs11\-id\fR\ \fIname\fR\ ]
214
-[\ \fB\-\-pkcs11\-pin\-cache\fR\ \fIseconds\fR\ ]
215
-[\ \fB\-\-pkcs11\-protected\-authentication\fR\ ]
216
-[\ \fB\-\-pkcs11\-cert\-private\fR\ ]
216
+[\ \fB\-\-pkcs11\-slot\-type\fR\ \fItype\fR\ ]
217 217
 [\ \fB\-\-pkcs12\fR\ \fIfile\fR\ ]
218 218
 [\ \fB\-\-plugin\fR\ \fImodule\-pathname\ init\-string\fR\ ]
219 219
 [\ \fB\-\-port\fR\ \fIport\fR\ ]
... ...
@@ -257,8 +257,8 @@ openvpn \- secure IP tunnel daemon.
257 257
 [\ \fB\-\-show\-ciphers\fR\ ]
258 258
 [\ \fB\-\-show\-digests\fR\ ]
259 259
 [\ \fB\-\-show\-engines\fR\ ]
260
-[\ \fB\-\-show\-pkcs11\-slots\fR\ \fIprovider\fR\ ]
261 260
 [\ \fB\-\-show\-pkcs11\-objects\fR\ \fIprovider\ slot\fR\ ]
261
+[\ \fB\-\-show\-pkcs11\-slots\fR\ \fIprovider\fR\ ]
262 262
 [\ \fB\-\-show\-net\-up\fR\ ]
263 263
 [\ \fB\-\-show\-net\fR\ ]
264 264
 [\ \fB\-\-show\-tls\fR\ ]
... ...
@@ -3620,6 +3620,39 @@ and
3620 3620
 .B --key.
3621 3621
 .\"*********************************************************
3622 3622
 .TP
3623
+.B --pkcs11-cert-private [0|1]...
3624
+Set if access to certificate object should be performed after login.
3625
+Every provider has its own setting.
3626
+.\"*********************************************************
3627
+.TP
3628
+.B --pkcs11-id name
3629
+Specify a name of the object to search for.
3630
+.\"*********************************************************
3631
+.TP
3632
+.B --pkcs11-id-type type
3633
+Specify how to locate the correct objects. Type can be one of the following:
3634
+
3635
+.B 'id'
3636
+-- Locate by the id attribte, name should be hex encoded string.
3637
+.br
3638
+.B 'label'
3639
+-- Locate by the label attribute, name should be string.
3640
+.br
3641
+.B 'subject'
3642
+-- Locate by certificate subject attribute, name should be string.
3643
+.br
3644
+.\"*********************************************************
3645
+.TP
3646
+.B --pkcs11-pin-cache seconds
3647
+Specify how many seconds the PIN can be cached, the default is until the token is removed.
3648
+.\"*********************************************************
3649
+.TP
3650
+.B --pkcs11-protected-authentication [0|1]...
3651
+Use PKCS#11 protected authentication path, useful for biometric and external
3652
+keypad devices.
3653
+Every provider has its own setting.
3654
+.\"*********************************************************
3655
+.TP
3623 3656
 .B --pkcs11-providers provider...
3624 3657
 Specify a RSA Security Inc. PKCS #11 Cryptographic Token Interface (Cryptoki) providers
3625 3658
 to load.
... ...
@@ -3636,21 +3669,30 @@ for each provider. Mode can be one of the following:
3636 3636
 .B 'auto'
3637 3637
 (default) -- Try to determind automatically.
3638 3638
 .br
3639
+.B 'sign'
3640
+-- Use Sign.
3641
+.br
3639 3642
 .B 'recover'
3640 3643
 -- Use SignRecover.
3641 3644
 .br
3642
-.B 'sign'
3645
+.B 'any'
3646
+-- Use Sign and if not supported use SignRecover.
3643 3647
 .br
3644 3648
 .\"*********************************************************
3645 3649
 .TP
3650
+.B --pkcs11-slot name
3651
+Specify a name of the slot to search for.
3652
+.\"*********************************************************
3653
+.TP
3646 3654
 .B --pkcs11-slot-type type
3647 3655
 Specify how to locate the correct slot. Type can be one of the following:
3648 3656
 
3649 3657
 .B 'id'
3650
-is encoded as 1:2. If you have only one provider you can omit the provider number.
3651
-The provider number is set by the order specified in the --pkcs11-providers option.
3658
+-- Locate the slot by a numeric id. The format is [provider:]id, for example, slot 2 of provider a.so 
3659
+should be encoded as a.so:2. If you have only one provider you can omit the provider name.
3660
+The provider name is set by the name specified in the
3661
+.B --pkcs11-providers
3662
+option.
3652 3663
 .br
3653 3664
 .B 'name'
3654 3665
 -- Locate the slot by its name.
... ...
@@ -3660,41 +3702,6 @@ The provider number is set by the order specified in the --pkcs11-providers opti
3660 3660
 .br
3661 3661
 .\"*********************************************************
3662 3662
 .TP
3663
-.B --pkcs11-slot name
3664
-Specify a name of the slot to search for.
3665
-.\"*********************************************************
3666
-.TP
3667
-.B --pkcs11-id-type type
3668
-Specify how to locate the correct objects. Type can be one of the following:
3669
-
3670
-.B 'id'
3671
-.br
3672
-.B 'label'
3673
-.br
3674
-.B 'subject'
3675
-.br
3676
-.\"*********************************************************
3677
-.TP
3678
-.B --pkcs11-id name
3679
-Specify a name of the object to search for.
3680
-.\"*********************************************************
3681
-.TP
3682
-.B --pkcs11-pin-cache seconds
3683
-Specify how many seconds the PIN can be cached, the default is until the token is removed.
3684
-.\"*********************************************************
3685
-.TP
3686
-.B --pkcs11-protected-authentication
3687
-Use PKCS#11 protected authentication path, useful for biometric and external
3688
-keypad devices.
3689
-.\"*********************************************************
3690
-.TP
3691
-.B --pkcs11-cert-private
3692
-Set if access to certificate object should be performed after login.
3693
-.\"*********************************************************
3694
-.TP
3695 3663
 .B --cryptoapicert select-string
3696 3664
 Load the certificate and private key from the
3697 3665
 Windows Certificate System Store (Windows Only).
... ...
@@ -492,12 +492,19 @@ static const char usage_message[] =
492 492
   "\n"
493 493
   "PKCS#11 Options:\n"
494 494
   "--pkcs11-providers provider ... : PKCS#11 provider to load.\n"
495
+  "--pkcs11-protected-authentication [0|1] ... : Use PKCS#11 protected authentication\n"
496
+  "                              path. Set for each provider.\n"
495 497
   "--pkcs11-sign-mode mode ... : PKCS#11 signature method.\n"
496 498
   "                              auto    : Try  to determind automatically (default).\n"
497
-  "                              recover : Use SignRecover.\n"
498 499
   "                              sign    : Use Sign.\n"
500
+  "                              recover : Use SignRecover.\n"
501
+  "                              any     : Use Sign and then SignRecover.\n"
502
+  "--pkcs11-cert-private [0|1] ... : Set if login should be performed before\n"
503
+  "                              certificate can be accessed. Set for each provider.\n"
504
+  "--pkcs11-pin-cache seconds  : Number of seconds to cache PIN. The default is -1\n"
505
+  "                              cache until token is removed.\n"
499 506
   "--pkcs11-slot-type method   : Slot locate method:\n"
500
-  "                              id      : By slot id (numeric [prov#:]slot#).\n"
507
+  "                              id      : By slot id (numeric [prov:]slot#).\n"
501 508
   "                              name    : By slot name.\n"
502 509
   "                              label   : By the card label that resides in slot.\n"
503 510
   "--pkcs11-slot name          : The slot name.\n"
... ...
@@ -506,11 +513,6 @@ static const char usage_message[] =
506 506
   "                              label   : By the object label (string).\n"
507 507
   "                              subject : By certificate subject (String).\n"
508 508
   "--pkcs11-id name            : The object name.\n"
509
-  "--pkcs11-pin-cache seconds  : Number of seconds to cache PIN. The default is -1\n"
510
-  "                              cache until token removed.\n"
511
-  "--pkcs11-protected-authentication : Use PKCS#11 protected authentication path.\n"
512
-  "--pkcs11-cert-private       : Set if login should be performed before\n"
513
-  "                              certificate can be accessed.\n"
514 509
 #endif			/* ENABLE_PKCS11 */
515 510
  "\n"
516 511
   "SSL Library information:\n"
... ...
@@ -688,8 +690,6 @@ init_options (struct options *o)
688 688
 #endif
689 689
 #ifdef ENABLE_PKCS11
690 690
   o->pkcs11_pin_cache_period = -1;
691
-  o->pkcs11_protected_authentication = false;
692
-  o->pkcs11_cert_private = false;
693 691
 #endif			/* ENABLE_PKCS11 */
694 692
 }
695 693
 
... ...
@@ -1265,16 +1265,24 @@ show_settings (const struct options *o)
1265 1265
   }
1266 1266
   {
1267 1267
     int i;
1268
+    for (i=0;i<MAX_PARMS;i++)
1269
+      SHOW_PARM (pkcs11_protected_authentication, o->pkcs11_protected_authentication[i] ? "ENABLED" : "DISABLED", "%s");
1270
+  }
1271
+  {
1272
+    int i;
1268 1273
     for (i=0;i<MAX_PARMS && o->pkcs11_sign_mode[i] != NULL;i++)
1269 1274
       SHOW_PARM (pkcs11_sign_mode, o->pkcs11_sign_mode[i], "%s");
1270 1275
   }
1276
+  {
1277
+    int i;
1278
+    for (i=0;i<MAX_PARMS;i++)
1279
+      SHOW_PARM (pkcs11_cert_private, o->pkcs11_cert_private[i] ? "ENABLED" : "DISABLED", "%s");
1280
+  }
1281
+  SHOW_INT (pkcs11_pin_cache_period);
1271 1282
   SHOW_STR (pkcs11_slot_type);
1272 1283
   SHOW_STR (pkcs11_slot);
1273 1284
   SHOW_STR (pkcs11_id_type);
1274 1285
   SHOW_STR (pkcs11_id);
1275
-  SHOW_INT (pkcs11_pin_cache_period);
1276
-  SHOW_BOOL (pkcs11_protected_authentication);
1277
-  SHOW_BOOL (pkcs11_cert_private);
1278 1286
 #endif			/* ENABLE_PKCS11 */
1279 1287
 
1280 1288
 #if P2MP
... ...
@@ -5080,6 +5088,15 @@ add_option (struct options *options,
5080 5080
       for (j = 1; j < MAX_PARMS && p[j] != NULL; ++j)
5081 5081
       	options->pkcs11_providers[j-1] = p[j];
5082 5082
     }
5083
+  else if (streq (p[0], "pkcs11-protected-authentication"))
5084
+    {
5085
+      int j;
5086
+
5087
+      VERIFY_PERMISSION (OPT_P_GENERAL);
5088
+
5089
+      for (j = 1; j < MAX_PARMS && p[j] != NULL; ++j)
5090
+        options->pkcs11_protected_authentication[j-1] = atoi (p[j]) != 0 ? 1 : 0;
5091
+    }
5083 5092
   else if (streq (p[0], "pkcs11-sign-mode") && p[1])
5084 5093
     {
5085 5094
       int j;
... ...
@@ -5089,6 +5106,20 @@ add_option (struct options *options,
5089 5089
       for (j = 1; j < MAX_PARMS && p[j] != NULL; ++j)
5090 5090
       	options->pkcs11_sign_mode[j-1] = p[j];
5091 5091
     }
5092
+  else if (streq (p[0], "pkcs11-cert-private"))
5093
+    {
5094
+      int j;
5095
+
5096
+      VERIFY_PERMISSION (OPT_P_GENERAL);
5097
+
5098
+      for (j = 1; j < MAX_PARMS && p[j] != NULL; ++j)
5099
+        options->pkcs11_cert_private[j-1] = atoi (p[j]) != 0 ? 1 : 0;
5100
+    }
5101
+   else if (streq (p[0], "pkcs11-pin-cache") && p[1])
5102
+    {
5103
+      VERIFY_PERMISSION (OPT_P_GENERAL);
5104
+      options->pkcs11_pin_cache_period = atoi (p[1]);
5105
+    }
5092 5106
   else if (streq (p[0], "pkcs11-slot-type") && p[1])
5093 5107
     {
5094 5108
       VERIFY_PERMISSION (OPT_P_GENERAL);
... ...
@@ -5109,21 +5140,6 @@ add_option (struct options *options,
5109 5109
       VERIFY_PERMISSION (OPT_P_GENERAL);
5110 5110
       options->pkcs11_id = p[1];
5111 5111
     }
5112
-   else if (streq (p[0], "pkcs11-pin-cache") && p[1])
5113
-    {
5114
-      VERIFY_PERMISSION (OPT_P_GENERAL);
5115
-      options->pkcs11_pin_cache_period = atoi (p[1]);
5116
-    }
5117
-  else if (streq (p[0], "pkcs11-protected-authentication"))
5118
-    {
5119
-      VERIFY_PERMISSION (OPT_P_GENERAL);
5120
-      options->pkcs11_protected_authentication = true;
5121
-    }
5122
-  else if (streq (p[0], "pkcs11-cert-private"))
5123
-    {
5124
-      VERIFY_PERMISSION (OPT_P_GENERAL);
5125
-      options->pkcs11_cert_private = true;
5126
-    }
5127 5112
 #endif
5128 5113
 #ifdef TUNSETPERSIST
5129 5114
   else if (streq (p[0], "rmtun"))
... ...
@@ -409,13 +409,13 @@ struct options
409 409
 #ifdef ENABLE_PKCS11
410 410
   const char *pkcs11_providers[MAX_PARMS];
411 411
   const char *pkcs11_sign_mode[MAX_PARMS];
412
+  bool pkcs11_protected_authentication[MAX_PARMS];
413
+  bool pkcs11_cert_private[MAX_PARMS];
414
+  int pkcs11_pin_cache_period;
412 415
   const char *pkcs11_slot_type;
413 416
   const char *pkcs11_slot;
414 417
   const char *pkcs11_id_type;
415 418
   const char *pkcs11_id;
416
-  int pkcs11_pin_cache_period;
417
-  bool pkcs11_protected_authentication;
418
-  bool pkcs11_cert_private;
419 419
 #endif
420 420
 
421 421
 #ifdef WIN32
... ...
@@ -22,10 +22,10 @@
22 22
 *  59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
23 23
 */
24 24
 
25
-#ifndef __PKCS11_HELPER_CONFIG_H
26
-#define __PKCS11_HELPER_CONFIG_H
25
+#ifndef __PKCS11H_HELPER_CONFIG_H
26
+#define __PKCS11H_HELPER_CONFIG_H
27 27
 
28
-#if!defined(PKCS11H_NO_NEED_INCLUDE_CONFIG)
28
+#if !defined(PKCS11H_NO_NEED_INCLUDE_CONFIG)
29 29
 
30 30
 #if defined(WIN32)
31 31
 #include "config-win32.h"
... ...
@@ -38,33 +38,26 @@
38 38
 #endif /* PKCS11H_NO_NEED_INCLUDE_CONFIG */
39 39
 
40 40
 #ifdef ENABLE_PKCS11
41
-#define PKCS11H_ENABLE_HELPER
41
+#define ENABLE_PKCS11H_HELPER
42 42
 #endif
43 43
 
44
-#ifdef PKCS11H_ENABLE_HELPER
44
+#ifdef ENABLE_PKCS11H_HELPER
45 45
 
46 46
 #include "error.h"
47 47
 #include "misc.h"
48 48
 #include "ssl.h"
49 49
 
50
-#define PKCS11ASSERT		ASSERT
51
-#define PKCS11LOG		msg
52
-#define PKCS11DLOG		dmsg
53
-#define PKCS11_LOG_DEBUG2	D_PKCS11_DEBUG
54
-#define PKCS11_LOG_DEBUG1	D_SHOW_PKCS11
55
-#define PKCS11_LOG_INFO		M_INFO
56
-#define PKCS11_LOG_WARN		M_WARN
57
-#define PKCS11_LOG_ERROR	M_FATAL
50
+#undef PKCS11H_USE_CYGWIN	/* cygwin is not supported in openvpn */
58 51
 
59
-#undef PKCS11_USE_CYGWIN
60
-
61
-#if !defined(false)
62
-#define false 0
52
+#if !defined(FALSE)
53
+#define FALSE false
63 54
 #endif
64
-#if !defined(true)
65
-#define true (!false)
55
+#if !defined(TRUE)
56
+#define TRUE true
66 57
 #endif
67 58
 
59
+typedef bool PKCS11H_BOOL;
60
+
68 61
 #if !defined(IN)
69 62
 #define IN
70 63
 #endif
... ...
@@ -72,18 +65,34 @@
72 72
 #define OUT
73 73
 #endif
74 74
 
75
-#define PKCS11_PRM_SLOT_TYPE	"--pkcs11-slot-type"
76
-#define PKCS11_PRM_SLOT_ID	"--pkcs11-slot"
77
-#define PKCS11_PRM_OBJ_TYPE	"--pkcs11-id-type"
78
-#define PKCS11_PRM_OBJ_ID	"--pkcs11-id"
79
-
80
-#define PKCS11_TIME	openvpn_time
81
-
82
-#if defined(WIN32) || defined(PKCS11_USE_CYGWIN)
75
+#ifdef ENABLE_DEBUG
76
+#define ENABLE_PKCS11H_DEBUG
77
+#endif
78
+#ifdef USE_PTHREAD
79
+#define ENABLE_PKCS11H_THREADING
80
+#endif
81
+#undef  ENABLE_PKCS11H_TOKEN
82
+#undef  ENABLE_PKCS11H_DATA
83
+#define ENABLE_PKCS11H_CERTIFICATE
84
+#define ENABLE_PKCS11H_LOCATE
85
+#undef  ENABLE_PKCS11H_ENUM
86
+#undef  ENABLE_PKCS11H_SLOTEVENT
87
+#define ENABLE_PKCS11H_OPENSSL
88
+#define ENABLE_PKCS11H_STANDALONE
89
+
90
+#define PKCS11H_PRM_SLOT_TYPE	"--pkcs11-slot-type"
91
+#define PKCS11H_PRM_SLOT_ID	"--pkcs11-slot"
92
+#define PKCS11H_PRM_OBJ_TYPE	"--pkcs11-id-type"
93
+#define PKCS11H_PRM_OBJ_ID	"--pkcs11-id"
94
+
95
+#define PKCS11H_ASSERT		ASSERT
96
+#define PKCS11H_TIME		openvpn_time
97
+
98
+#if defined(WIN32) || defined(PKCS11H_USE_CYGWIN)
83 99
 #include "cryptoki-win32.h"
84 100
 #else
85 101
 #include "cryptoki.h"
86 102
 #endif
87 103
 
88
-#endif		/* PKCS11H_ENABLE_HELPER */
89
-#endif		/* __PKCS11_HELPER_CONFIG_H */
104
+#endif		/* PKCS11_ENABLE_HELPER */
105
+#endif		/* __PKCS11H_HELPER_CONFIG_H */
... ...
@@ -1,5 +1,5 @@
1 1
 /*
2
- * Copyright (c) 2005 Alon Bar-Lev <alon.barlev@gmail.com>
2
+ * Copyright (c) 2005-2006 Alon Bar-Lev <alon.barlev@gmail.com>
3 3
  * All rights reserved.
4 4
  *
5 5
  * Redistribution and use in source and binary forms, with or without modifi-
... ...
@@ -36,7 +36,7 @@
36 36
 
37 37
 #include "pkcs11-helper-config.h"
38 38
 
39
-#if defined(PKCS11H_ENABLE_HELPER)
39
+#if defined(ENABLE_PKCS11H_HELPER)
40 40
 
41 41
 #include "pkcs11-helper.h"
42 42
 
... ...
@@ -44,12 +44,6 @@
44 44
  * Constants
45 45
  */
46 46
 
47
-#if OPENSSL_VERSION_NUMBER < 0x00908000L
48
-typedef unsigned char *pkcs11_openssl_d2i_t;
49
-#else
50
-typedef const unsigned char *pkcs11_openssl_d2i_t;
51
-#endif
52
-
53 47
 #if OPENSSL_VERSION_NUMBER < 0x00907000L && defined(CRYPTO_LOCK_ENGINE)
54 48
 # define RSA_get_default_method RSA_get_default_openssl_method
55 49
 #else
... ...
@@ -65,69 +59,382 @@ typedef const unsigned char *pkcs11_openssl_d2i_t;
65 65
 #define PKCS11H_INVALID_SESSION_HANDLE	((CK_SESSION_HANDLE)-1)
66 66
 #define PKCS11H_INVALID_OBJECT_HANDLE	((CK_OBJECT_HANDLE)-1)
67 67
 
68
+#define PKCS11H_DEFAULT_SLOTEVENT_POLL		5000
69
+#define PKCS11H_DEFAULT_MAX_LOGIN_RETRY		3
70
+#define PKCS11H_DEFAULT_PIN_CACHE_PERIOD	PKCS11H_PIN_CACHE_INFINITE
71
+
72
+enum _pkcs11h_private_op_e {
73
+	_pkcs11h_private_op_sign=0,
74
+	_pkcs11h_private_op_sign_recover,
75
+	_pkcs11h_private_op_decrypt
76
+};
77
+
78
+/*===========================================
79
+ * Macros
80
+ */
81
+
82
+#define PKCS11H_MSG_LEVEL_TEST(flags) (((unsigned int)flags) <= s_pkcs11h_loglevel)
83
+
84
+#if defined(HAVE_CPP_VARARG_MACRO_ISO) && !defined(__LCLINT__)
85
+# define PKCS11H_LOG(flags, ...) do { if (PKCS11H_MSG_LEVEL_TEST(flags)) _pkcs11h_log((flags), __VA_ARGS__); } while (FALSE)
86
+# ifdef ENABLE_PKCS11H_DEBUG
87
+#  define PKCS11H_DEBUG(flags, ...) do { if (PKCS11H_MSG_LEVEL_TEST(flags)) _pkcs11h_log((flags), __VA_ARGS__); } while (FALSE)
88
+# else
89
+#  define PKCS11H_DEBUG(flags, ...)
90
+# endif
91
+#elif defined(HAVE_CPP_VARARG_MACRO_GCC) && !defined(__LCLINT__)
92
+# define PKCS11H_LOG(flags, args...) do { if (PKCS11H_MSG_LEVEL_TEST(flags)) _pkcs11h_log((flags), args); } while (FALSE)
93
+# ifdef ENABLE_PKCS11H_DEBUG
94
+#  define PKCS11H_DEBUG(flags, args...) do { if (PKCS11H_MSG_LEVEL_TEST(flags)) _pkcs11h_log((flags), args); } while (FALSE)
95
+# else
96
+#  define PKCS11H_DEBUG(flags, args...)
97
+# endif
98
+#else
99
+# define PKCS11H_LOG _pkcs11h_log
100
+# define PKCS11H_DEBUG _pkcs11h_log
101
+#endif
102
+
68 103
 /*===========================================
69
- * Low level prototypes
104
+ * Types
70 105
  */
71 106
 
107
+struct pkcs11h_provider_s;
108
+struct pkcs11h_session_s;
109
+struct pkcs11h_data_s;
110
+typedef struct pkcs11h_provider_s *pkcs11h_provider_t;
111
+typedef struct pkcs11h_session_s *pkcs11h_session_t;
112
+typedef struct pkcs11h_data_s *pkcs11h_data_t;
113
+
114
+#if OPENSSL_VERSION_NUMBER < 0x00908000L
115
+typedef unsigned char *pkcs11_openssl_d2i_t;
116
+#else
117
+typedef const unsigned char *pkcs11_openssl_d2i_t;
118
+#endif
119
+
120
+#if defined(ENABLE_PKCS11H_THREADING)
121
+
122
+#define PKCS11H_COND_INFINITE	0xffffffff
123
+
124
+#if defined(WIN32)
125
+#define PKCS11H_THREAD_NULL	NULL
126
+typedef HANDLE pkcs11h_cond_t;
127
+typedef HANDLE pkcs11h_mutex_t;
128
+typedef HANDLE pkcs11h_thread_t;
129
+#else
130
+#define PKCS11H_THREAD_NULL	0l
131
+typedef pthread_mutex_t pkcs11h_mutex_t;
132
+typedef pthread_t pkcs11h_thread_t;
133
+
134
+typedef struct {
135
+	pthread_cond_t cond;
136
+	pthread_mutex_t mut;
137
+} pkcs11h_cond_t;
138
+
139
+typedef struct __pkcs11h_mutex_entry_s {
140
+	struct __pkcs11h_mutex_entry_s *next;
141
+	pkcs11h_mutex_t *p_mutex;
142
+	PKCS11H_BOOL fLocked;
143
+} *__pkcs11h_mutex_entry_t;
144
+#endif
145
+
146
+typedef void * (*pkcs11h_thread_start_t)(void *);
147
+
148
+typedef struct {
149
+	pkcs11h_thread_start_t start;
150
+	void *data;
151
+} __pkcs11h_thread_data_t;
152
+
153
+#endif				/* ENABLE_PKCS11H_THREADING */
154
+
155
+struct pkcs11h_provider_s {
156
+	pkcs11h_provider_t next;
157
+
158
+	PKCS11H_BOOL fEnabled;
159
+	char szReferenceName[1024];
160
+	char manufacturerID[sizeof (((CK_TOKEN_INFO *)NULL)->manufacturerID)+1];
161
+	
162
+#if defined(WIN32)
163
+	HANDLE hLibrary;
164
+#else
165
+	void *hLibrary;
166
+#endif
167
+
168
+	CK_FUNCTION_LIST_PTR f;
169
+	PKCS11H_BOOL fShouldFinalize;
170
+	PKCS11H_BOOL fProtectedAuthentication;
171
+	PKCS11H_BOOL fCertIsPrivate;
172
+	unsigned maskSignMode;
173
+	int nSlotEventMethod;
174
+	int nSlotEventPollInterval;
175
+
176
+#if defined(ENABLE_PKCS11H_SLOTEVENT)
177
+	pkcs11h_thread_t threadSlotEvent;
178
+#endif
179
+};
180
+
181
+struct pkcs11h_session_s {
182
+	pkcs11h_session_t next;
183
+
184
+	int nReferenceCount;
185
+	PKCS11H_BOOL fValid;
186
+
187
+	pkcs11h_provider_t provider;
188
+
189
+	pkcs11h_token_id_t token_id;
190
+
191
+	CK_SESSION_HANDLE hSession;
192
+
193
+	PKCS11H_BOOL fProtectedAuthenticationSupported;
194
+	int nPINCachePeriod;
195
+	time_t timePINExpire;
196
+
197
+#if defined(ENABLE_PKCS11H_ENUM)
198
+#if defined(ENABLE_PKCS11H_CERTIFICATE)
199
+	pkcs11h_certificate_id_list_t cached_certs;
200
+	PKCS11H_BOOL fTouch;
201
+#endif
202
+#endif
203
+
204
+#if defined(ENABLE_PKCS11H_THREADING)
205
+	pkcs11h_mutex_t mutexSession;
206
+#endif
207
+};
208
+
209
+#if defined (ENABLE_PKCS11H_CERTIFICATE)
210
+
211
+struct pkcs11h_certificate_s {
212
+
213
+	pkcs11h_certificate_id_t id;
214
+	int nPINCachePeriod;
215
+
216
+	unsigned maskSignMode;
217
+
218
+	pkcs11h_session_t session;
219
+	CK_OBJECT_HANDLE hKey;
220
+
221
+	PKCS11H_BOOL fOperationActive;
222
+
223
+#if defined(ENABLE_PKCS11H_THREADING)
224
+	pkcs11h_mutex_t mutexCertificate;
225
+#endif
226
+};
227
+
228
+#endif				/* ENABLE_PKCS11H_CERTIFICATE */
229
+
230
+struct pkcs11h_data_s {
231
+	PKCS11H_BOOL fInitialized;
232
+	int nPINCachePeriod;
233
+
234
+	pkcs11h_provider_t providers;
235
+	pkcs11h_session_t sessions;
236
+
237
+	struct {
238
+		void *log_data;
239
+		void *slotevent_data;
240
+		void *token_prompt_data;
241
+		void *pin_prompt_data;
242
+		pkcs11h_hook_log_t log;
243
+		pkcs11h_hook_slotevent_t slotevent;
244
+		pkcs11h_hook_token_prompt_t token_prompt;
245
+		pkcs11h_hook_pin_prompt_t pin_prompt;
246
+	} hooks;
247
+
248
+	PKCS11H_BOOL fProtectedAuthentication;
249
+	int nMaxLoginRetries;
250
+
251
+#if defined(ENABLE_PKCS11H_THREADING)
252
+	pkcs11h_mutex_t mutexGlobal;
253
+	pkcs11h_mutex_t mutexSession;
254
+	pkcs11h_mutex_t mutexCache;
255
+#endif
256
+
257
+#if defined(ENABLE_PKCS11H_SLOTEVENT)
258
+	PKCS11H_BOOL fSlotEventInitialized;
259
+	PKCS11H_BOOL fSlotEventShouldTerminate;
260
+	PKCS11H_BOOL fSlotEventSkipEvent;
261
+	pkcs11h_cond_t condSlotEvent;
262
+	pkcs11h_thread_t threadSlotEvent;
263
+#endif
264
+};
265
+
266
+#if defined(ENABLE_PKCS11H_OPENSSL)
267
+struct pkcs11h_openssl_session_s {
268
+	int nReferenceCount;
269
+	PKCS11H_BOOL fInitialized;
270
+	X509 *x509;
271
+	RSA_METHOD smart_rsa;
272
+	int (*orig_finish)(RSA *rsa);
273
+	pkcs11h_certificate_t certificate;
274
+};
275
+#endif
276
+
277
+/*======================================================================*
278
+ * MEMORY INTERFACE
279
+ *======================================================================*/
280
+
281
+static
282
+CK_RV
283
+_pkcs11h_malloc (
284
+	OUT const void ** const p,
285
+	IN const size_t s
286
+);
287
+static
288
+CK_RV
289
+_pkcs11h_free (
290
+	IN const void ** const p
291
+);
292
+static
293
+CK_RV
294
+_pkcs11h_dupmem (
295
+	OUT const void ** const dest,
296
+	OUT size_t * const dest_size,
297
+	IN const void * const src,
298
+	IN const size_t mem_size
299
+);
300
+
301
+#if defined(ENABLE_PKCS11H_THREADING)
302
+/*======================================================================*
303
+ * THREADING INTERFACE
304
+ *======================================================================*/
305
+
306
+static
307
+void
308
+_pkcs11h_sleep (
309
+	IN const unsigned milli
310
+);
311
+static
312
+CK_RV
313
+_pkcs11h_mutexInit (
314
+	OUT pkcs11h_mutex_t * const mutex
315
+);
316
+static
317
+CK_RV
318
+_pkcs11h_mutexLock (
319
+	IN OUT pkcs11h_mutex_t *const mutex
320
+);
321
+static
322
+CK_RV
323
+_pkcs11h_mutexRelease (
324
+	IN OUT pkcs11h_mutex_t *const mutex
325
+);
326
+static
327
+CK_RV
328
+_pkcs11h_mutexFree (
329
+	IN OUT pkcs11h_mutex_t *const mutex
330
+);
331
+#if !defined(WIN32)
332
+static
333
+void
334
+__pkcs1h_mutexLockAll ();
335
+static
336
+void
337
+__pkcs1h_mutexReleaseAll ();
338
+#endif
339
+static
340
+CK_RV
341
+_pkcs11h_condSignal (
342
+	IN OUT pkcs11h_cond_t *const cond
343
+);
344
+static
345
+CK_RV
346
+_pkcs11h_condInit (
347
+	OUT pkcs11h_cond_t * const cond
348
+);
349
+static
350
+CK_RV
351
+_pkcs11h_condWait (
352
+	IN OUT pkcs11h_cond_t *const cond,
353
+	IN const unsigned milli
354
+);
355
+static
356
+CK_RV
357
+_pkcs11h_condFree (
358
+	IN OUT pkcs11h_cond_t *const cond
359
+);
360
+static
361
+CK_RV
362
+_pkcs11h_threadStart (
363
+	OUT pkcs11h_thread_t * const thread,
364
+	IN pkcs11h_thread_start_t const start,
365
+	IN void * data
366
+);
367
+static
368
+CK_RV
369
+_pkcs11h_threadJoin (
370
+	IN pkcs11h_thread_t * const thread
371
+);
372
+#endif				/* ENABLE_PKCS11H_THREADING */
373
+
374
+/*======================================================================*
375
+ * COMMON INTERNAL INTERFACE
376
+ *======================================================================*/
377
+
72 378
 static
73 379
 void
74 380
 _pkcs11h_fixupFixedString (
75
-	IN const char * const szSource,
76 381
 	OUT char * const szTarget,			/* MUST BE >= nLength+1 */
382
+	IN const char * const szSource,
77 383
 	IN const size_t nLength				/* FIXED STRING LENGTH */
78 384
 );
79 385
 static
80 386
 void
81
-_hexToBinary (
82
-	IN const char * const szSource,
83
-	OUT unsigned char * const target,
84
-	IN OUT size_t * const target_size
387
+_pkcs11h_log (
388
+	IN const unsigned flags,
389
+	IN const char * const szFormat,
390
+	IN ...
391
+)
392
+#ifdef __GNUC__
393
+    __attribute__ ((format (printf, 2, 3)))
394
+#endif
395
+    ;
396
+
397
+static
398
+CK_RV
399
+_pkcs11h_getSlotList (
400
+	IN const pkcs11h_provider_t provider,
401
+	IN const CK_BBOOL tokenPresent,
402
+	OUT CK_SLOT_ID_PTR * const pSlotList,
403
+	OUT CK_ULONG_PTR pulCount
85 404
 );
86 405
 static
87
-bool
88
-_isBetterCertificate (
89
-	IN const unsigned char * const pCurrent,
90
-	IN const size_t nCurrentSize,
91
-	IN const unsigned char * const pNew,
92
-	IN const size_t nNewSize
406
+CK_RV
407
+_pkcs11h_getObjectAttributes (
408
+	IN const pkcs11h_session_t session,
409
+	IN const CK_OBJECT_HANDLE object,
410
+	IN OUT const CK_ATTRIBUTE_PTR attrs,
411
+	IN const unsigned count
93 412
 );
94 413
 static
95 414
 CK_RV
96
-_pkcs11h_getSlotById (
97
-	IN const char * const szSlot,
98
-	OUT pkcs11h_provider_t * const provider,
99
-	OUT CK_SLOT_ID * const slot
415
+_pkcs11h_freeObjectAttributes (
416
+	IN OUT const CK_ATTRIBUTE_PTR attrs,
417
+	IN const unsigned count
100 418
 );
101 419
 static
102 420
 CK_RV
103
-_pkcs11h_getSlotByName (
104
-	IN const char * const szName,
105
-	OUT pkcs11h_provider_t * const provider,
106
-	OUT CK_SLOT_ID * const slot
421
+_pkcs11h_findObjects (
422
+	IN const pkcs11h_session_t session,
423
+	IN const CK_ATTRIBUTE * const filter,
424
+	IN const CK_ULONG filter_attrs,
425
+	OUT CK_OBJECT_HANDLE **const p_objects,
426
+	OUT CK_ULONG *p_objects_found
107 427
 );
108 428
 static
109 429
 CK_RV
110
-_pkcs11h_getSlotByLabel (
111
-	IN const char * const szLabel,
112
-	OUT pkcs11h_provider_t * const provider,
113
-	OUT CK_SLOT_ID * const slot
430
+_pkcs11h_getTokenId (
431
+	IN const CK_TOKEN_INFO_PTR info,
432
+	OUT pkcs11h_token_id_t * const p_token_id
114 433
 );
115 434
 static
116 435
 CK_RV
117
-_pkcs11h_getSlot (
118
-	IN const char * const szSlotType,
119
-	IN const char * const szSlot,
120
-	OUT pkcs11h_provider_t * const provider,
121
-	OUT CK_SLOT_ID * const slot
436
+_pkcs11h_newTokenId (
437
+	OUT pkcs11h_token_id_t * const token_id
122 438
 );
123 439
 static
124 440
 CK_RV
125
-_pkcs11h_getSession (
126
-	IN const char * const szSlotType,
127
-	IN const char * const szSlot,
128
-	IN const bool fProtectedAuthentication,
129
-	IN const int nPINCachePeriod,
130
-	OUT pkcs11h_session_t * const session
441
+_pkcs11h_getSessionByTokenId (
442
+	IN const pkcs11h_token_id_t token_id,
443
+	OUT pkcs11h_session_t * const p_session
131 444
 );
132 445
 static
133 446
 CK_RV
... ...
@@ -138,16 +445,17 @@ static
138 138
 CK_RV
139 139
 _pkcs11h_resetSession (
140 140
 	IN const pkcs11h_session_t session,
141
-	OUT CK_SLOT_ID * const slot
141
+	IN const unsigned maskPrompt,
142
+	OUT CK_SLOT_ID * const p_slot
142 143
 );
143 144
 static
144 145
 CK_RV
145 146
 _pkcs11h_getObjectById (
146
-	IN const pkcs11h_session_t pkcs11h_certificate,
147
+	IN const pkcs11h_session_t certificate,
147 148
 	IN const CK_OBJECT_CLASS class,
148
-	IN const unsigned char * const id,
149
+	IN const CK_BYTE_PTR id,
149 150
 	IN const size_t id_size,
150
-	OUT CK_OBJECT_HANDLE * const handle
151
+	OUT CK_OBJECT_HANDLE * const p_handle
151 152
 );
152 153
 static
153 154
 CK_RV
... ...
@@ -158,34 +466,241 @@ static
158 158
 CK_RV
159 159
 _pkcs11h_login (
160 160
 	IN const pkcs11h_session_t session,
161
-	IN const bool fPublicOnly
161
+	IN const PKCS11H_BOOL fPublicOnly,
162
+	IN const PKCS11H_BOOL fReadOnly,
163
+	IN const unsigned maskPrompt
162 164
 );
163 165
 static
164 166
 CK_RV
165 167
 _pkcs11h_logout (
166 168
 	IN const pkcs11h_session_t session
167 169
 );
170
+
171
+static
172
+void
173
+_pkcs11h_hooks_default_log (
174
+	IN const void * pData,
175
+	IN const unsigned flags,
176
+	IN const char * const szFormat,
177
+	IN va_list args
178
+);
179
+
180
+static
181
+PKCS11H_BOOL
182
+_pkcs11h_hooks_default_token_prompt (
183
+	IN const void * pData,
184
+	IN const pkcs11h_token_id_t token
185
+);
186
+
187
+static
188
+PKCS11H_BOOL
189
+_pkcs11h_hooks_default_pin_prompt (
190
+	IN const void * pData,
191
+	IN const pkcs11h_token_id_t token,
192
+	OUT char * const szPIN,
193
+	IN const size_t nMaxPIN
194
+);
195
+
196
+#if !defined(WIN32)
197
+#if defined(ENABLE_PKCS11H_THREADING)
198
+static
199
+void
200
+__pkcs11h_atfork_prepare  ();
201
+static
202
+void
203
+__pkcs11h_atfork_parent ();
204
+static
205
+void
206
+__pkcs11h_atfork_child ();
207
+#endif
168 208
 static
169 209
 CK_RV
170
-_pkcs11h_setCertificateSession_Certificate (
171
-	IN const pkcs11h_certificate_t pkcs11h_certificate,
172
-	IN const char * const szIdType,
173
-	IN const char * const szId
210
+_pkcs11h_forkFixup ();
211
+#endif
212
+
213
+#if defined(ENABLE_PKCS11H_CERTIFICATE)
214
+/*======================================================================*
215
+ * CERTIFICATE INTERFACE
216
+ *======================================================================*/
217
+
218
+static
219
+void
220
+_pkcs11h_isBetterCertificate_getExpiration (
221
+	IN const unsigned char * const pCertificate,
222
+	IN const size_t nCertificateSize,
223
+	OUT char * const szNotBefore,
224
+	IN const int nNotBeforeSize
225
+);
226
+static
227
+PKCS11H_BOOL
228
+_pkcs11h_isBetterCertificate (
229
+	IN const unsigned char * const pCurrent,
230
+	IN const size_t nCurrentSize,
231
+	IN const unsigned char * const pNew,
232
+	IN const size_t nNewSize
174 233
 );
175 234
 static
176 235
 CK_RV
177
-_pkcs11h_resetCertificateSession (
178
-	IN const pkcs11h_certificate_t pkcs11h_certificate
236
+_pkcs11h_newCertificateId (
237
+	OUT pkcs11h_certificate_id_t * const certificate_id
238
+);
239
+static
240
+CK_RV
241
+_pkcs11h_loadCertificate (
242
+	IN const pkcs11h_certificate_t certificate
243
+);
244
+static
245
+CK_RV
246
+_pkcs11h_updateCertificateIdDescription (
247
+	IN OUT pkcs11h_certificate_id_t certificate_id
248
+);
249
+static
250
+CK_RV
251
+_pkcs11h_ensureCertificateBlob (
252
+	IN const pkcs11h_certificate_t certificate
179 253
 );
180 254
 static
181 255
 CK_RV
182 256
 _pkcs11h_getCertificateKeyAttributes (
183
-	IN const pkcs11h_certificate_t pkcs11h_certificate
257
+	IN const pkcs11h_certificate_t certificate
258
+);
259
+static
260
+CK_RV
261
+_pkcs11h_validateCertificateSession (
262
+	IN const pkcs11h_certificate_t certificate
263
+);
264
+static
265
+CK_RV
266
+_pkcs11h_resetCertificateSession (
267
+	IN const pkcs11h_certificate_t certificate,
268
+	IN const PKCS11H_BOOL fPublicOnly,
269
+	IN const unsigned maskPrompt
184 270
 );
271
+static
272
+CK_RV
273
+_pkcs11h_certificate_private_op (
274
+	IN const pkcs11h_certificate_t certificate,
275
+	IN const enum _pkcs11h_private_op_e op,
276
+	IN const CK_MECHANISM_TYPE mech_type,
277
+	IN const unsigned char * const source,
278
+	IN const size_t source_size,
279
+	OUT unsigned char * const target,
280
+	IN OUT size_t * const p_target_size
281
+);
282
+#endif				/* ENABLE_PKCS11H_CERTIFICATE */
185 283
 
186
-/*==========================================
187
- * openssl interface
188
- */
284
+#if defined(ENABLE_PKCS11H_LOCATE)
285
+/*======================================================================*
286
+ * LOCATE INTERFACE
287
+ *======================================================================*/
288
+
289
+static
290
+CK_RV
291
+_pkcs11h_locate_getTokenIdBySlotId (
292
+	IN const char * const szSlot,
293
+	OUT pkcs11h_token_id_t * const p_token_id
294
+);
295
+static
296
+CK_RV
297
+_pkcs11h_locate_getTokenIdBySlotName (
298
+	IN const char * const szName,
299
+	OUT pkcs11h_token_id_t * const p_token_id
300
+);
301
+static
302
+CK_RV
303
+_pkcs11h_locate_getTokenIdByLabel (
304
+	IN const char * const szLabel,
305
+	OUT pkcs11h_token_id_t * const p_token_id
306
+);
307
+
308
+#if defined(ENABLE_PKCS11H_CERTIFICATE)
309
+
310
+static
311
+void
312
+_pkcs11h_locate_hexToBinary (
313
+	OUT unsigned char * const target,
314
+	IN const char * const szSource,
315
+	IN OUT size_t * const p_target_size
316
+);
317
+static
318
+CK_RV
319
+_pkcs11h_locate_getCertificateIdByLabel (
320
+	IN const pkcs11h_session_t session,
321
+	IN OUT const pkcs11h_certificate_id_t certificate_id,
322
+	IN const char * const szLabel
323
+);
324
+static
325
+CK_RV
326
+_pkcs11h_locate_getCertificateIdBySubject (
327
+	IN const pkcs11h_session_t session,
328
+	IN OUT const pkcs11h_certificate_id_t certificate_id,
329
+	IN const char * const szSubject
330
+);
331
+
332
+#endif				/* ENABLE_PKCS11H_CERTIFICATE */
333
+#endif				/* ENABLE_PKCS11H_LOCATE */
334
+
335
+#if defined(ENABLE_PKCS11H_ENUM)
336
+/*======================================================================*
337
+ * ENUM INTERFACE
338
+ *======================================================================*/
339
+
340
+#if defined(ENABLE_PKCS11H_CERTIFICATE)
341
+
342
+static
343
+CK_RV
344
+_pkcs11h_enum_getSessionCertificates (
345
+	IN const pkcs11h_session_t session
346
+);
347
+static
348
+CK_RV
349
+_pkcs11h_enum_splitCertificateIdList (
350
+	IN const pkcs11h_certificate_id_list_t cert_id_all,
351
+	OUT pkcs11h_certificate_id_list_t * const p_cert_id_issuers_list,
352
+	OUT pkcs11h_certificate_id_list_t * const p_cert_id_end_list
353
+);
354
+
355
+#endif				/* ENABLE_PKCS11H_CERTIFICATE */
356
+
357
+#endif				/* ENABLE_PKCS11H_ENUM */
358
+
359
+#if defined(ENABLE_PKCS11H_SLOTEVENT)
360
+/*======================================================================*
361
+ * SLOTEVENT INTERFACE
362
+ *======================================================================*/
363
+
364
+static
365
+unsigned long
366
+_pkcs11h_slotevent_checksum (
367
+	IN const unsigned char * const p,
368
+	IN const size_t s
369
+);
370
+static
371
+void *
372
+_pkcs11h_slotevent_provider (
373
+	IN void *p
374
+);
375
+static
376
+void *
377
+_pkcs11h_slotevent_manager (
378
+	IN void *p
379
+);
380
+static
381
+CK_RV
382
+_pkcs11h_slotevent_init ();
383
+static
384
+CK_RV
385
+_pkcs11h_slotevent_notify ();
386
+static
387
+CK_RV
388
+_pkcs11h_slotevent_terminate ();
389
+
390
+#endif				/* ENABLE_PKCS11H_SLOTEVENT */
391
+
392
+#if defined(ENABLE_PKCS11H_OPENSSL)
393
+/*======================================================================*
394
+ * OPENSSL INTERFACE
395
+ *======================================================================*/
189 396
 
190 397
 static
191 398
 int
... ...
@@ -235,7 +750,7 @@ _pkcs11h_openssl_sign (
235 235
 #endif
236 236
 static
237 237
 pkcs11h_openssl_session_t
238
-_pkcs11h_openssl_get_pkcs11h_openssl_session (
238
+_pkcs11h_openssl_get_openssl_session (
239 239
 	IN OUT const RSA *rsa
240 240
 );  
241 241
 static
... ...
@@ -243,501 +758,1691 @@ pkcs11h_certificate_t
243 243
 _pkcs11h_openssl_get_pkcs11h_certificate (
244 244
 	IN OUT const RSA *rsa
245 245
 );  
246
+#endif				/* ENABLE_PKCS11H_OPENSSL */
246 247
 
247 248
 /*==========================================
248 249
  * Static data
249 250
  */
250 251
 
251
-pkcs11h_data_t pkcs11h_data = NULL;
252
+#if defined(ENABLE_PKCS11H_THREADING)
253
+#if !defined(WIN32)
254
+static struct {
255
+	pkcs11h_mutex_t mutex;
256
+	__pkcs11h_mutex_entry_t head;
257
+} __s_pkcs11h_mutex_list = {
258
+	PTHREAD_MUTEX_INITIALIZER,
259
+	NULL
260
+};
261
+#endif
262
+#endif
252 263
 
253
-/*==========================================
254
- * Internal utility functions
255
- */
264
+pkcs11h_data_t s_pkcs11h_data = NULL;
265
+unsigned int s_pkcs11h_loglevel = PKCS11H_LOG_INFO;
256 266
 
257
-static
258
-void
259
-_pkcs11h_fixupFixedString (
260
-	IN const char * const szSource,
261
-	OUT char * const szTarget,			/* MUST BE >= nLength+1 */
262
-	IN const size_t nLength				/* FIXED STRING LENGTH */
267
+/*======================================================================*
268
+ * PUBLIC INTERFACE
269
+ *======================================================================*/
270
+
271
+char *
272
+pkcs11h_getMessage (
273
+	IN const int rv
263 274
 ) {
264
-	char *p;
275
+	switch (rv) {
276
+		case CKR_OK: return "CKR_OK";
277
+		case CKR_CANCEL: return "CKR_CANCEL";
278
+		case CKR_HOST_MEMORY: return "CKR_HOST_MEMORY";
279
+		case CKR_SLOT_ID_INVALID: return "CKR_SLOT_ID_INVALID";
280
+		case CKR_GENERAL_ERROR: return "CKR_GENERAL_ERROR";
281
+		case CKR_FUNCTION_FAILED: return "CKR_FUNCTION_FAILED";
282
+		case CKR_ARGUMENTS_BAD: return "CKR_ARGUMENTS_BAD";
283
+		case CKR_NO_EVENT: return "CKR_NO_EVENT";
284
+		case CKR_NEED_TO_CREATE_THREADS: return "CKR_NEED_TO_CREATE_THREADS";
285
+		case CKR_CANT_LOCK: return "CKR_CANT_LOCK";
286
+		case CKR_ATTRIBUTE_READ_ONLY: return "CKR_ATTRIBUTE_READ_ONLY";
287
+		case CKR_ATTRIBUTE_SENSITIVE: return "CKR_ATTRIBUTE_SENSITIVE";
288
+		case CKR_ATTRIBUTE_TYPE_INVALID: return "CKR_ATTRIBUTE_TYPE_INVALID";
289
+		case CKR_ATTRIBUTE_VALUE_INVALID: return "CKR_ATTRIBUTE_VALUE_INVALID";
290
+		case CKR_DATA_INVALID: return "CKR_DATA_INVALID";
291
+		case CKR_DATA_LEN_RANGE: return "CKR_DATA_LEN_RANGE";
292
+		case CKR_DEVICE_ERROR: return "CKR_DEVICE_ERROR";
293
+		case CKR_DEVICE_MEMORY: return "CKR_DEVICE_MEMORY";
294
+		case CKR_DEVICE_REMOVED: return "CKR_DEVICE_REMOVED";
295
+		case CKR_ENCRYPTED_DATA_INVALID: return "CKR_ENCRYPTED_DATA_INVALID";
296
+		case CKR_ENCRYPTED_DATA_LEN_RANGE: return "CKR_ENCRYPTED_DATA_LEN_RANGE";
297
+		case CKR_FUNCTION_CANCELED: return "CKR_FUNCTION_CANCELED";
298
+		case CKR_FUNCTION_NOT_PARALLEL: return "CKR_FUNCTION_NOT_PARALLEL";
299
+		case CKR_FUNCTION_NOT_SUPPORTED: return "CKR_FUNCTION_NOT_SUPPORTED";
300
+		case CKR_KEY_HANDLE_INVALID: return "CKR_KEY_HANDLE_INVALID";
301
+		case CKR_KEY_SIZE_RANGE: return "CKR_KEY_SIZE_RANGE";
302
+		case CKR_KEY_TYPE_INCONSISTENT: return "CKR_KEY_TYPE_INCONSISTENT";
303
+		case CKR_KEY_NOT_NEEDED: return "CKR_KEY_NOT_NEEDED";
304
+		case CKR_KEY_CHANGED: return "CKR_KEY_CHANGED";
305
+		case CKR_KEY_NEEDED: return "CKR_KEY_NEEDED";
306
+		case CKR_KEY_INDIGESTIBLE: return "CKR_KEY_INDIGESTIBLE";
307
+		case CKR_KEY_FUNCTION_NOT_PERMITTED: return "CKR_KEY_FUNCTION_NOT_PERMITTED";
308
+		case CKR_KEY_NOT_WRAPPABLE: return "CKR_KEY_NOT_WRAPPABLE";
309
+		case CKR_KEY_UNEXTRACTABLE: return "CKR_KEY_UNEXTRACTABLE";
310
+		case CKR_MECHANISM_INVALID: return "CKR_MECHANISM_INVALID";
311
+		case CKR_MECHANISM_PARAM_INVALID: return "CKR_MECHANISM_PARAM_INVALID";
312
+		case CKR_OBJECT_HANDLE_INVALID: return "CKR_OBJECT_HANDLE_INVALID";
313
+		case CKR_OPERATION_ACTIVE: return "CKR_OPERATION_ACTIVE";
314
+		case CKR_OPERATION_NOT_INITIALIZED: return "CKR_OPERATION_NOT_INITIALIZED";
315
+		case CKR_PIN_INCORRECT: return "CKR_PIN_INCORRECT";
316
+		case CKR_PIN_INVALID: return "CKR_PIN_INVALID";
317
+		case CKR_PIN_LEN_RANGE: return "CKR_PIN_LEN_RANGE";
318
+		case CKR_PIN_EXPIRED: return "CKR_PIN_EXPIRED";
319
+		case CKR_PIN_LOCKED: return "CKR_PIN_LOCKED";
320
+		case CKR_SESSION_CLOSED: return "CKR_SESSION_CLOSED";
321
+		case CKR_SESSION_COUNT: return "CKR_SESSION_COUNT";
322
+		case CKR_SESSION_HANDLE_INVALID: return "CKR_SESSION_HANDLE_INVALID";
323
+		case CKR_SESSION_PARALLEL_NOT_SUPPORTED: return "CKR_SESSION_PARALLEL_NOT_SUPPORTED";
324
+		case CKR_SESSION_READ_ONLY: return "CKR_SESSION_READ_ONLY";
325
+		case CKR_SESSION_EXISTS: return "CKR_SESSION_EXISTS";
326
+		case CKR_SESSION_READ_ONLY_EXISTS: return "CKR_SESSION_READ_ONLY_EXISTS";
327
+		case CKR_SESSION_READ_WRITE_SO_EXISTS: return "CKR_SESSION_READ_WRITE_SO_EXISTS";
328
+		case CKR_SIGNATURE_INVALID: return "CKR_SIGNATURE_INVALID";
329
+		case CKR_SIGNATURE_LEN_RANGE: return "CKR_SIGNATURE_LEN_RANGE";
330
+		case CKR_TEMPLATE_INCOMPLETE: return "CKR_TEMPLATE_INCOMPLETE";
331
+		case CKR_TEMPLATE_INCONSISTENT: return "CKR_TEMPLATE_INCONSISTENT";
332
+		case CKR_TOKEN_NOT_PRESENT: return "CKR_TOKEN_NOT_PRESENT";
333
+		case CKR_TOKEN_NOT_RECOGNIZED: return "CKR_TOKEN_NOT_RECOGNIZED";
334
+		case CKR_TOKEN_WRITE_PROTECTED: return "CKR_TOKEN_WRITE_PROTECTED";
335
+		case CKR_UNWRAPPING_KEY_HANDLE_INVALID: return "CKR_UNWRAPPING_KEY_HANDLE_INVALID";
336
+		case CKR_UNWRAPPING_KEY_SIZE_RANGE: return "CKR_UNWRAPPING_KEY_SIZE_RANGE";
337
+		case CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT: return "CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT";
338
+		case CKR_USER_ALREADY_LOGGED_IN: return "CKR_USER_ALREADY_LOGGED_IN";
339
+		case CKR_USER_NOT_LOGGED_IN: return "CKR_USER_NOT_LOGGED_IN";
340
+		case CKR_USER_PIN_NOT_INITIALIZED: return "CKR_USER_PIN_NOT_INITIALIZED";
341
+		case CKR_USER_TYPE_INVALID: return "CKR_USER_TYPE_INVALID";
342
+		case CKR_USER_ANOTHER_ALREADY_LOGGED_IN: return "CKR_USER_ANOTHER_ALREADY_LOGGED_IN";
343
+		case CKR_USER_TOO_MANY_TYPES: return "CKR_USER_TOO_MANY_TYPES";
344
+		case CKR_WRAPPED_KEY_INVALID: return "CKR_WRAPPED_KEY_INVALID";
345
+		case CKR_WRAPPED_KEY_LEN_RANGE: return "CKR_WRAPPED_KEY_LEN_RANGE";
346
+		case CKR_WRAPPING_KEY_HANDLE_INVALID: return "CKR_WRAPPING_KEY_HANDLE_INVALID";
347
+		case CKR_WRAPPING_KEY_SIZE_RANGE: return "CKR_WRAPPING_KEY_SIZE_RANGE";
348
+		case CKR_WRAPPING_KEY_TYPE_INCONSISTENT: return "CKR_WRAPPING_KEY_TYPE_INCONSISTENT";
349
+		case CKR_RANDOM_SEED_NOT_SUPPORTED: return "CKR_RANDOM_SEED_NOT_SUPPORTED";
350
+		case CKR_RANDOM_NO_RNG: return "CKR_RANDOM_NO_RNG";
351
+		case CKR_DOMAIN_PARAMS_INVALID: return "CKR_DOMAIN_PARAMS_INVALID";
352
+		case CKR_BUFFER_TOO_SMALL: return "CKR_BUFFER_TOO_SMALL";
353
+		case CKR_SAVED_STATE_INVALID: return "CKR_SAVED_STATE_INVALID";
354
+		case CKR_INFORMATION_SENSITIVE: return "CKR_INFORMATION_SENSITIVE";
355
+		case CKR_STATE_UNSAVEABLE: return "CKR_STATE_UNSAVEABLE";
356
+		case CKR_CRYPTOKI_NOT_INITIALIZED: return "CKR_CRYPTOKI_NOT_INITIALIZED";
357
+		case CKR_CRYPTOKI_ALREADY_INITIALIZED: return "CKR_CRYPTOKI_ALREADY_INITIALIZED";
358
+		case CKR_MUTEX_BAD: return "CKR_MUTEX_BAD";
359
+		case CKR_MUTEX_NOT_LOCKED: return "CKR_MUTEX_NOT_LOCKED";
360
+		case CKR_FUNCTION_REJECTED: return "CKR_FUNCTION_REJECTED";
361
+		case CKR_VENDOR_DEFINED: return "CKR_VENDOR_DEFINED";
362
+		default: return "Unknown PKCS#11 error";
363
+	}
364
+}
365
+
366
+CK_RV
367
+pkcs11h_initialize () {
368
+
369
+#if defined(ENABLE_PKCS11H_THREADING)
370
+	PKCS11H_BOOL fMutexLocked = FALSE;
371
+#endif
372
+	CK_RV rv = CKR_OK;
373
+
374
+	PKCS11H_DEBUG (
375
+		PKCS11H_LOG_DEBUG2,
376
+		"PKCS#11: pkcs11h_initialize entry"
377
+	);
378
+
379
+	pkcs11h_terminate ();
380
+
381
+	if (rv == CKR_OK) {
382
+		rv = _pkcs11h_malloc ((void*)&s_pkcs11h_data, sizeof (struct pkcs11h_data_s));
383
+	}
265 384
 
266
-	PKCS11ASSERT (szSource!=NULL);
267
-	PKCS11ASSERT (szTarget!=NULL);
385
+#if defined(ENABLE_PKCS11H_THREADING)
386
+	if (rv == CKR_OK) {
387
+		rv = _pkcs11h_mutexInit (&s_pkcs11h_data->mutexGlobal); 
388
+	}
389
+	if (rv == CKR_OK) {
390
+		rv = _pkcs11h_mutexInit (&s_pkcs11h_data->mutexSession); 
391
+	}
392
+	if (rv == CKR_OK) {
393
+		rv = _pkcs11h_mutexInit (&s_pkcs11h_data->mutexCache); 
394
+	}
395
+#if !defined(WIN32)
396
+	if (
397
+		rv == CKR_OK &&
398
+		pthread_atfork (
399
+			__pkcs11h_atfork_prepare,
400
+			__pkcs11h_atfork_parent,
401
+			__pkcs11h_atfork_child
402
+		)
403
+	) {
404
+		rv = CKR_FUNCTION_FAILED;
405
+	}
406
+#endif
407
+	if (
408
+		rv == CKR_OK &&
409
+		(rv = _pkcs11h_mutexLock (&s_pkcs11h_data->mutexGlobal)) == CKR_OK
410
+	) {
411
+		fMutexLocked = TRUE;
412
+	}
413
+#endif
414
+
415
+	if (rv == CKR_OK) {
416
+		s_pkcs11h_data->nMaxLoginRetries = PKCS11H_DEFAULT_MAX_LOGIN_RETRY;
417
+		s_pkcs11h_data->fProtectedAuthentication = TRUE;
418
+		s_pkcs11h_data->nPINCachePeriod = PKCS11H_DEFAULT_PIN_CACHE_PERIOD;
419
+		s_pkcs11h_data->fInitialized = TRUE;
420
+	}
421
+
422
+	if (rv == CKR_OK) {
423
+		pkcs11h_setLogHook (_pkcs11h_hooks_default_log, NULL);
424
+		pkcs11h_setTokenPromptHook (_pkcs11h_hooks_default_token_prompt, NULL);
425
+		pkcs11h_setPINPromptHook (_pkcs11h_hooks_default_pin_prompt, NULL);
426
+	}
268 427
 	
269
-	p = szTarget+nLength;
270
-	memmove (szTarget, szSource, nLength);
271
-	*p = '\0';
272
-	p--;
273
-	while (p >= szTarget && *p == ' ') {
274
-		*p = '\0';
275
-		p--;
428
+#if defined(ENABLE_PKCS11H_THREADING)
429
+	if (fMutexLocked) {
430
+		_pkcs11h_mutexRelease (&s_pkcs11h_data->mutexGlobal);
431
+		fMutexLocked = FALSE;
276 432
 	}
433
+#endif
434
+
435
+	PKCS11H_DEBUG (
436
+		PKCS11H_LOG_DEBUG2,
437
+		"PKCS#11: pkcs11h_initialize return rv=%ld-'%s'",
438
+		rv,
439
+		pkcs11h_getMessage (rv)
440
+	);
441
+
442
+	return rv;
277 443
 }
278 444
 
279
-static
280
-void
281
-_hexToBinary (
282
-	IN const char * const szSource,
283
-	OUT unsigned char * const target,
284
-	IN OUT size_t * const target_size
285
-) {
286
-	size_t target_max_size;
287
-	const char *p;
288
-	char buf[3] = {'\0', '\0', '\0'};
289
-	int i = 0;
445
+CK_RV
446
+pkcs11h_terminate () {
290 447
 
291
-	PKCS11ASSERT (szSource!=NULL);
292
-	PKCS11ASSERT (target!=NULL);
293
-	PKCS11ASSERT (target_size!=NULL);
448
+	PKCS11H_DEBUG (
449
+		PKCS11H_LOG_DEBUG2,
450
+		"PKCS#11: pkcs11h_terminate entry"
451
+	);
294 452
 
295
-	target_max_size = *target_size;
296
-	p = szSource;
297
-	*target_size = 0;
453
+	if (s_pkcs11h_data != NULL) {
454
+		pkcs11h_provider_t current_provider = NULL;
298 455
 
299
-	while (*p != '\0' && *target_size < target_max_size) {
300
-		if (isxdigit (*p)) {
301
-			buf[i%2] = *p;
456
+		PKCS11H_DEBUG (
457
+			PKCS11H_LOG_DEBUG1,
458
+			"PKCS#11: Removing providers"
459
+		);
302 460
 
303
-			if ((i%2) == 1) {
304
-				unsigned v;
305
-				if (sscanf (buf, "%x", &v) != 1) {
306
-					v = 0;
307
-				}
308
-				target[*target_size] = v & 0xff;
309
-				(*target_size)++;
461
+		for (
462
+			current_provider = s_pkcs11h_data->providers;
463
+			current_provider != NULL;
464
+			current_provider = current_provider->next
465
+		) {
466
+			pkcs11h_removeProvider (current_provider->szReferenceName);
467
+		}
468
+
469
+#if defined(ENABLE_PKCS11H_THREADING)
470
+		_pkcs11h_mutexLock (&s_pkcs11h_data->mutexCache);
471
+		_pkcs11h_mutexLock (&s_pkcs11h_data->mutexSession);
472
+		_pkcs11h_mutexLock (&s_pkcs11h_data->mutexGlobal);
473
+#endif
474
+
475
+		PKCS11H_DEBUG (
476
+			PKCS11H_LOG_DEBUG1,
477
+			"PKCS#11: Releasing sessions"
478
+		);
479
+
480
+		while (s_pkcs11h_data->sessions != NULL) {
481
+			pkcs11h_session_t current = s_pkcs11h_data->sessions;
482
+			s_pkcs11h_data->sessions = s_pkcs11h_data->sessions->next;
483
+
484
+#if defined(ENABLE_PKCS11H_THREADING)
485
+			_pkcs11h_mutexLock (&current->mutexSession);
486
+#endif
487
+
488
+			current->fValid = FALSE;
489
+
490
+			if (current->nReferenceCount != 0) {
491
+				PKCS11H_DEBUG (
492
+					PKCS11H_LOG_DEBUG1,
493
+					"PKCS#11: Warning: Found session with references"
494
+				);
310 495
 			}
311 496
 
312
-			i++;
497
+			if (current->token_id != NULL) {
498
+				pkcs11h_freeTokenId (current->token_id);
499
+				current->token_id = NULL;
500
+			}
501
+
502
+#if defined(ENABLE_PKCS11H_ENUM)
503
+#if defined(ENABLE_PKCS11H_CERTIFICATE)
504
+			pkcs11h_freeCertificateIdList (current->cached_certs);
505
+#endif
506
+#endif
507
+
508
+			current->provider = NULL;
509
+
510
+#if defined(ENABLE_PKCS11H_THREADING)
511
+			_pkcs11h_mutexFree (&current->mutexSession);
512
+#endif
513
+
514
+			_pkcs11h_free ((void *)&current);
313 515
 		}
314
-		p++;
516
+
517
+#if defined(ENABLE_PKCS11H_SLOTEVENT)
518
+		PKCS11H_DEBUG (
519
+			PKCS11H_LOG_DEBUG1,
520
+			"PKCS#11: Terminating slotevent"
521
+		);
522
+
523
+		_pkcs11h_slotevent_terminate ();
524
+#endif
525
+		PKCS11H_DEBUG (
526
+			PKCS11H_LOG_DEBUG1,
527
+			"PKCS#11: Marking as uninitialized"
528
+		);
529
+		
530
+		s_pkcs11h_data->fInitialized = FALSE;
531
+
532
+		while (s_pkcs11h_data->providers != NULL) {
533
+			pkcs11h_provider_t current = s_pkcs11h_data->providers;
534
+			s_pkcs11h_data->providers = s_pkcs11h_data->providers->next;
535
+
536
+			_pkcs11h_free ((void *)&current);
537
+		}
538
+
539
+#if defined(ENABLE_PKCS11H_THREADING)
540
+		_pkcs11h_mutexFree (&s_pkcs11h_data->mutexCache);
541
+		_pkcs11h_mutexFree (&s_pkcs11h_data->mutexGlobal); 
542
+		_pkcs11h_mutexFree (&s_pkcs11h_data->mutexSession); 
543
+#endif
544
+
545
+		_pkcs11h_free ((void *)&s_pkcs11h_data);
315 546
 	}
547
+
548
+	PKCS11H_DEBUG (
549
+		PKCS11H_LOG_DEBUG2,
550
+		"PKCS#11: pkcs11h_terminate return"
551
+	);
552
+
553
+	return CKR_OK;
316 554
 }
317 555
 
318
-static
319 556
 void
320
-_isBetterCertificate_getExpiration (
321
-	IN const unsigned char * const pCertificate,
322
-	IN const size_t nCertificateSize,
323
-	OUT char * const szNotBefore,
324
-	IN const int nNotBeforeSize
557
+pkcs11h_setLogLevel (
558
+	IN const unsigned flags
325 559
 ) {
326
-	/*
327
-	 * This function compare the notBefore
328
-	 * and select the most recent certificate
329
-	 * it does not deal with timezones...
330
-	 * When openssl will have ASN1_TIME compare function
331
-	 * it should be used.
332
-	 */
560
+	s_pkcs11h_loglevel = flags;
561
+}
333 562
 
334
-	X509 *x509 = NULL;
563
+unsigned
564
+pkcs11h_getLogLevel () {
565
+	PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
566
+	PKCS11H_ASSERT (s_pkcs11h_data->fInitialized);
335 567
 
336
-	PKCS11ASSERT (pCertificate!=NULL);
337
-	PKCS11ASSERT (szNotBefore!=NULL);
338
-	PKCS11ASSERT (nNotBeforeSize>0);
568
+	return s_pkcs11h_loglevel;
569
+}
339 570
 
340
-	szNotBefore[0] = '\0';
571
+CK_RV
572
+pkcs11h_setLogHook (
573
+	IN const pkcs11h_hook_log_t hook,
574
+	IN void * const pData
575
+) {
576
+	PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
577
+	PKCS11H_ASSERT (s_pkcs11h_data->fInitialized);
578
+	PKCS11H_ASSERT (hook!=NULL);
341 579
 
342
-	x509 = X509_new ();
580
+	s_pkcs11h_data->hooks.log = hook;
581
+	s_pkcs11h_data->hooks.log_data = pData;
343 582
 
344
-	if (x509 != NULL) {
345
-		pkcs11_openssl_d2i_t d2i = (pkcs11_openssl_d2i_t)pCertificate;
583
+	return CKR_OK;
584
+}
346 585
 
347
-		if (
348
-			d2i_X509 (&x509, &d2i, nCertificateSize)
349
-		) {
350
-			ASN1_TIME *notBefore = X509_get_notBefore (x509);
351
-			ASN1_TIME *notAfter = X509_get_notAfter (x509);
586
+CK_RV
587
+pkcs11h_setSlotEventHook (
588
+	IN const pkcs11h_hook_slotevent_t hook,
589
+	IN void * const pData
590
+) {
591
+	PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
592
+	PKCS11H_ASSERT (s_pkcs11h_data->fInitialized);
593
+	PKCS11H_ASSERT (hook!=NULL);
352 594
 
353
-			if (
354
-				notBefore != NULL &&
355
-				X509_cmp_current_time (notBefore) <= 0 &&
356
-				X509_cmp_current_time (notAfter) >= 0 &&
357
-				notBefore->length < nNotBeforeSize - 1
358
-			) {
359
-				memmove (szNotBefore, notBefore->data, notBefore->length);
360
-				szNotBefore[notBefore->length] = '\0';
361
-			}
362
-		}
363
-	}
595
+#if defined(ENABLE_PKCS11H_SLOTEVENT)
596
+	s_pkcs11h_data->hooks.slotevent = hook;
597
+	s_pkcs11h_data->hooks.slotevent_data = pData;
364 598
 
365
-	if (x509 != NULL) {
366
-		X509_free (x509);
367
-		x509 = NULL;
368
-	}
599
+	return _pkcs11h_slotevent_init ();
600
+#else
601
+	return CKR_FUNCTION_NOT_SUPPORTED;
602
+#endif
369 603
 }
370 604
 
371
-static
372
-bool
373
-_isBetterCertificate (
374
-	IN const unsigned char * const pCurrent,
375
-	IN const size_t nCurrentSize,
376
-	IN const unsigned char * const pNew,
377
-	IN const size_t nNewSize
605
+CK_RV
606
+pkcs11h_setPINPromptHook (
607
+	IN const pkcs11h_hook_pin_prompt_t hook,
608
+	IN void * const pData
378 609
 ) {
379
-	/*
380
-	 * This function compare the notBefore
381
-	 * and select the most recent certificate
382
-	 * it does not deal with timezones...
383
-	 * When openssl will have ASN1_TIME compare function
384
-	 * it should be used.
385
-	 */
610
+	PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
611
+	PKCS11H_ASSERT (s_pkcs11h_data->fInitialized);
612
+	PKCS11H_ASSERT (hook!=NULL);
386 613
 
387
-	bool fBetter = false;
614
+	s_pkcs11h_data->hooks.pin_prompt = hook;
615
+	s_pkcs11h_data->hooks.pin_prompt_data = pData;
388 616
 
389
-	PKCS11DLOG (
390
-		PKCS11_LOG_DEBUG2,
391
-		"PKCS#11: _isBetterCertificate entry pCurrent=%p, nCurrentSize=%u, pNew=%p, nNewSize=%u",
392
-		pCurrent,
393
-		nCurrentSize,
394
-		pNew,
395
-		nNewSize
617
+	return CKR_OK;
618
+}
619
+
620
+CK_RV
621
+pkcs11h_setTokenPromptHook (
622
+	IN const pkcs11h_hook_token_prompt_t hook,
623
+	IN void * const pData
624
+) {
625
+	PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
626
+	PKCS11H_ASSERT (s_pkcs11h_data->fInitialized);
627
+	PKCS11H_ASSERT (hook!=NULL);
628
+
629
+	s_pkcs11h_data->hooks.token_prompt = hook;
630
+	s_pkcs11h_data->hooks.token_prompt_data = pData;
631
+
632
+	return CKR_OK;
633
+}
634
+
635
+CK_RV
636
+pkcs11h_setPINCachePeriod (
637
+	IN const int nPINCachePeriod
638
+) {
639
+	PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
640
+	PKCS11H_ASSERT (s_pkcs11h_data->fInitialized);
641
+
642
+	s_pkcs11h_data->nPINCachePeriod = nPINCachePeriod;
643
+
644
+	return CKR_OK;
645
+}
646
+
647
+CK_RV
648
+pkcs11h_setMaxLoginRetries (
649
+	IN const int nMaxLoginRetries
650
+) {
651
+	PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
652
+	PKCS11H_ASSERT (s_pkcs11h_data->fInitialized);
653
+
654
+	s_pkcs11h_data->nMaxLoginRetries = nMaxLoginRetries;
655
+
656
+	return CKR_OK;
657
+}
658
+
659
+CK_RV
660
+pkcs11h_setProtectedAuthentication (
661
+	IN const PKCS11H_BOOL fProtectedAuthentication
662
+) {
663
+	PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
664
+	PKCS11H_ASSERT (s_pkcs11h_data->fInitialized);
665
+
666
+	s_pkcs11h_data->fProtectedAuthentication = fProtectedAuthentication;
667
+
668
+	return CKR_OK;
669
+}
670
+
671
+CK_RV
672
+pkcs11h_addProvider (
673
+	IN const char * const szReferenceName,
674
+	IN const char * const szProvider,
675
+	IN const PKCS11H_BOOL fProtectedAuthentication,
676
+	IN const unsigned maskSignMode,
677
+	IN const int nSlotEventMethod,
678
+	IN const int nSlotEventPollInterval,
679
+	IN const PKCS11H_BOOL fCertIsPrivate
680
+) {
681
+#if defined(ENABLE_PKCS11H_THREADING)
682
+	PKCS11H_BOOL fMutexLocked = FALSE;
683
+#endif
684
+#if defined(WIN32)
685
+	int mypid = 0;
686
+#else
687
+	pid_t mypid = getpid ();
688
+#endif
689
+	pkcs11h_provider_t provider = NULL;
690
+	CK_C_GetFunctionList gfl = NULL;
691
+	CK_INFO info;
692
+	CK_RV rv = CKR_OK;
693
+
694
+	PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
695
+	PKCS11H_ASSERT (s_pkcs11h_data->fInitialized);
696
+	PKCS11H_ASSERT (szProvider!=NULL);
697
+	/*PKCS11H_ASSERT (szSignMode!=NULL); NOT NEEDED*/
698
+
699
+	PKCS11H_DEBUG (
700
+		PKCS11H_LOG_DEBUG2,
701
+		"PKCS#11: pkcs11h_addProvider entry pid=%d, szReferenceName=%s, szProvider='%s', fProtectedAuthentication=%d, maskSignMode=%08x, fCertIsPrivate=%d",
702
+		mypid,
703
+		szReferenceName,
704
+		szProvider,
705
+		fProtectedAuthentication ? 1 : 0,
706
+		maskSignMode,
707
+		fCertIsPrivate ? 1 : 0
396 708
 	);
397 709
 
398
-	/*
399
-	 * First certificae
400
-	 * always select
401
-	 */
402
-	if (nCurrentSize == 0) {
403
-		fBetter = true;
710
+	PKCS11H_DEBUG (
711
+		PKCS11H_LOG_DEBUG1,
712
+		"PKCS#11: Adding provider '%s'-'%s'",
713
+		szReferenceName,
714
+		szProvider
715
+	);
716
+
717
+#if defined(ENABLE_PKCS11H_THREADING)
718
+	if (
719
+		rv == CKR_OK &&
720
+		(rv = _pkcs11h_mutexLock (&s_pkcs11h_data->mutexGlobal)) == CKR_OK
721
+	) {
722
+		fMutexLocked = TRUE;
404 723
 	}
405
-	else {
406
-		char szNotBeforeCurrent[1024], szNotBeforeNew[1024];
724
+#endif
407 725
 
408
-		_isBetterCertificate_getExpiration (
409
-			pCurrent,
410
-			nCurrentSize,
411
-			szNotBeforeCurrent,
412
-			sizeof (szNotBeforeCurrent)
726
+	if (
727
+		rv == CKR_OK &&
728
+		(rv = _pkcs11h_malloc ((void *)&provider, sizeof (struct pkcs11h_provider_s))) == CKR_OK
729
+	) {
730
+		strncpy (
731
+			provider->szReferenceName,
732
+			szReferenceName,
733
+			sizeof (provider->szReferenceName)-1
413 734
 		);
414
-		_isBetterCertificate_getExpiration (
415
-			pNew,
416
-			nNewSize,
417
-			szNotBeforeNew,
418
-			sizeof (szNotBeforeNew)
735
+		provider->szReferenceName[sizeof (provider->szReferenceName)-1] = '\x0';
736
+		strncpy (
737
+			provider->manufacturerID,
738
+			(
739
+			 	strlen (szProvider) < sizeof (provider->manufacturerID) ?
740
+				szProvider :
741
+				szProvider+strlen (szProvider)-sizeof (provider->manufacturerID)+1
742
+			),
743
+			sizeof (provider->manufacturerID)-1
419 744
 		);
745
+		provider->manufacturerID[sizeof (provider->manufacturerID)-1] = '\x0';
746
+		provider->fProtectedAuthentication = fProtectedAuthentication;
747
+		provider->maskSignMode = maskSignMode;
748
+		provider->nSlotEventMethod = nSlotEventMethod;
749
+		provider->nSlotEventPollInterval = nSlotEventPollInterval;
750
+		provider->fCertIsPrivate = fCertIsPrivate;
751
+	}
752
+		
753
+	if (rv == CKR_OK) {
754
+#if defined(WIN32)
755
+		provider->hLibrary = LoadLibraryA (szProvider);
756
+#else
757
+		provider->hLibrary = dlopen (szProvider, RTLD_NOW);
758
+#endif
759
+		if (provider->hLibrary == NULL) {
760
+			rv = CKR_FUNCTION_FAILED;
761
+		}
762
+	}
420 763
 
421
-		PKCS11DLOG (
422
-			PKCS11_LOG_DEBUG2,
423
-			"PKCS#11: _isBetterCertificate szNotBeforeCurrent=%s, szNotBeforeNew=%s",
424
-			szNotBeforeCurrent,
425
-			szNotBeforeNew
764
+	if (rv == CKR_OK) {
765
+#if defined(WIN32)
766
+		gfl = (CK_C_GetFunctionList)GetProcAddress (
767
+			provider->hLibrary,
768
+			"C_GetFunctionList"
769
+		);
770
+#else
771
+		/*
772
+		 * Make compiler happy!
773
+		 */
774
+		void *p = dlsym (
775
+			provider->hLibrary,
776
+			"C_GetFunctionList"
777
+		);
778
+		memmove (
779
+			&gfl, 
780
+			&p,
781
+			sizeof (void *)
426 782
 		);
783
+#endif
784
+		if (gfl == NULL) {
785
+			rv = CKR_FUNCTION_FAILED;
786
+		}
787
+	}
427 788
 
428
-		fBetter = strcmp (szNotBeforeCurrent, szNotBeforeNew) < 0;
789
+	if (rv == CKR_OK) {
790
+		rv = gfl (&provider->f);
429 791
 	}
430 792
 
431
-	PKCS11DLOG (
432
-		PKCS11_LOG_DEBUG2,
433
-		"PKCS#11: _isBetterCertificate return fBetter=%d",
434
-		fBetter ? 1 : 0
435
-	);
793
+	if (rv == CKR_OK) {
794
+		if ((rv = provider->f->C_Initialize (NULL)) != CKR_OK) {
795
+			if (rv == CKR_CRYPTOKI_ALREADY_INITIALIZED) {
796
+				rv = CKR_OK;
797
+			}
798
+		}
799
+		else {
800
+			provider->fShouldFinalize = TRUE;
801
+		}
802
+	}
803
+
804
+	if (
805
+		rv == CKR_OK &&
806
+		(rv = provider->f->C_GetInfo (&info)) == CKR_OK
807
+	) {
808
+		_pkcs11h_fixupFixedString (
809
+			provider->manufacturerID,
810
+			(char *)info.manufacturerID,
811
+			sizeof (info.manufacturerID)
812
+		);
813
+	}
814
+
815
+	if (rv == CKR_OK) {
816
+		provider->fEnabled = TRUE;
817
+	}
818
+
819
+	if (provider != NULL) {
820
+		if (s_pkcs11h_data->providers == NULL) {
821
+			s_pkcs11h_data->providers = provider;
822
+		}
823
+		else {
824
+			pkcs11h_provider_t last = NULL;
436 825
 	
437
-	return fBetter;
438
-}
826
+			for (
827
+				last = s_pkcs11h_data->providers;
828
+				last->next != NULL;
829
+				last = last->next
830
+			);
831
+			last->next = provider;
832
+		}
833
+	}
439 834
 
440
-/*========================================
441
- * Low level PKCS#11 functions
442
- */
835
+#if defined(ENABLE_PKCS11H_THREADING)
836
+	if (fMutexLocked) {
837
+		_pkcs11h_mutexRelease (&s_pkcs11h_data->mutexGlobal);
838
+		fMutexLocked = FALSE;
839
+	}
840
+#endif
841
+
842
+#if defined(ENABLE_PKCS11H_SLOTEVENT)
843
+	_pkcs11h_slotevent_notify ();
844
+#endif
845
+
846
+	PKCS11H_DEBUG (
847
+		PKCS11H_LOG_DEBUG1,
848
+		"PKCS#11: Provider '%s' added rv=%ld-'%s'",
849
+		szReferenceName,
850
+		rv,
851
+		pkcs11h_getMessage (rv)
852
+	);
853
+
854
+	PKCS11H_DEBUG (
855
+		PKCS11H_LOG_DEBUG2,
856
+		"PKCS#11: pkcs11h_addProvider return rv=%ld-'%s'",
857
+		rv,
858
+		pkcs11h_getMessage (rv)
859
+	);
860
+
861
+	return rv;
862
+}
443 863
 
444
-static
445 864
 CK_RV
446
-_pkcs11h_getSlotById (
447
-	IN const char * const szSlot,
448
-	OUT pkcs11h_provider_t * const provider,
449
-	OUT CK_SLOT_ID * const slot
865
+pkcs11h_removeProvider (
866
+	IN const char * const szReferenceName
450 867
 ) {
451
-	int provider_number;
452
-	int slot_number;
868
+#if defined(ENABLE_PKCS11H_THREADING)
869
+	pkcs11h_session_t current_session = NULL;
870
+#endif
871
+	pkcs11h_provider_t provider = NULL;
453 872
 	CK_RV rv = CKR_OK;
454 873
 
455
-	PKCS11ASSERT (szSlot!=NULL);
456
-	PKCS11ASSERT (provider!=NULL);
457
-	PKCS11ASSERT (slot!=NULL);
874
+	PKCS11H_ASSERT (szReferenceName!=NULL);
458 875
 
459
-	PKCS11DLOG (
460
-		PKCS11_LOG_DEBUG2,
461
-		"PKCS#11: _pkcs11h_getSlotById entry szSlot=%s, provider=%p, slot=%p",
462
-		szSlot,
463
-		(void *)provider,
464
-		(void *)slot
876
+	PKCS11H_DEBUG (
877
+		PKCS11H_LOG_DEBUG2,
878
+		"PKCS#11: pkcs11h_removeProvider entry szReferenceName='%s'",
879
+		szReferenceName
880
+	);
881
+
882
+	PKCS11H_DEBUG (
883
+		PKCS11H_LOG_DEBUG1,
884
+		"PKCS#11: Removing provider '%s'",
885
+		szReferenceName
465 886
 	);
466 887
 
888
+#if defined(ENABLE_PKCS11H_THREADING)
889
+	_pkcs11h_mutexLock (&s_pkcs11h_data->mutexCache);
890
+	_pkcs11h_mutexLock (&s_pkcs11h_data->mutexSession);
891
+	_pkcs11h_mutexLock (&s_pkcs11h_data->mutexGlobal);
892
+
893
+	for (
894
+		current_session = s_pkcs11h_data->sessions;
895
+		current_session != NULL;
896
+		current_session = current_session->next
897
+	) {
898
+		_pkcs11h_mutexLock (&current_session->mutexSession);
899
+	}
900
+#endif
901
+
902
+	provider = s_pkcs11h_data->providers;
903
+	while (
904
+		rv == CKR_OK &&
905
+		provider != NULL &&
906
+		strcmp (szReferenceName, provider->szReferenceName)
907
+	) {
908
+		provider = provider->next;
909
+	}
910
+
911
+	if (rv == CKR_OK && provider == NULL) {
912
+		rv = CKR_OBJECT_HANDLE_INVALID;
913
+	}
914
+
467 915
 	if (rv == CKR_OK) {
468
-		if (strchr (szSlot, ':') == NULL) {
469
-			provider_number = 0;
470
-			slot_number = atoi (szSlot);
916
+		provider->fEnabled = FALSE;
917
+		provider->szReferenceName[0] = '\0';
918
+
919
+		if (provider->fShouldFinalize) {
920
+			provider->f->C_Finalize (NULL);
921
+			provider->fShouldFinalize = FALSE;
471 922
 		}
472
-		else {
473
-			if (sscanf (szSlot, "%d:%d", &provider_number, &slot_number) != 2) {
474
-				rv = CKR_FUNCTION_FAILED;
475
-			}
923
+
924
+#if defined(ENABLE_PKCS11H_SLOTEVENT)
925
+		_pkcs11h_slotevent_notify ();
926
+		
927
+		/*
928
+		 * Wait until manager join this thread
929
+		 * this happens saldom so I can poll
930
+		 */
931
+		while (provider->threadSlotEvent != PKCS11H_THREAD_NULL) {
932
+			_pkcs11h_sleep (500);
476 933
 		}
934
+#endif
935
+
936
+		if (provider->f != NULL) {
937
+			provider->f = NULL;
938
+		}
939
+
940
+		if (provider->hLibrary != NULL) {
941
+#if defined(WIN32)
942
+			FreeLibrary (provider->hLibrary);
943
+#else
944
+			dlclose (provider->hLibrary);
945
+#endif
946
+			provider->hLibrary = NULL;
947
+		}
948
+	}
949
+
950
+#if defined(ENABLE_PKCS11H_THREADING)
951
+	for (
952
+		current_session = s_pkcs11h_data->sessions;
953
+		current_session != NULL;
954
+		current_session = current_session->next
955
+	) {
956
+		_pkcs11h_mutexRelease (&current_session->mutexSession);
477 957
 	}
958
+
959
+	_pkcs11h_mutexRelease (&s_pkcs11h_data->mutexCache);
960
+	_pkcs11h_mutexRelease (&s_pkcs11h_data->mutexSession);
961
+	_pkcs11h_mutexRelease (&s_pkcs11h_data->mutexGlobal);
962
+#endif
478 963
 	
479
-	if (rv == CKR_OK) {
480
-		pkcs11h_provider_t current_provider;
481
-		int i;
964
+	PKCS11H_DEBUG (
965
+		PKCS11H_LOG_DEBUG2,
966
+		"PKCS#11: pkcs11h_removeProvider return rv=%ld-'%s'",
967
+		rv,
968
+		pkcs11h_getMessage (rv)
969
+	);
970
+
971
+	return rv;
972
+}
973
+
974
+CK_RV
975
+pkcs11h_forkFixup () {
976
+#if defined(WIN32)
977
+	return CKR_OK;
978
+#else
979
+#if defined(ENABLE_PKCS11H_THREADING)
980
+	return CKR_OK;
981
+#else
982
+	return _pkcs11h_forkFixup ();
983
+#endif
984
+#endif
985
+}
986
+
987
+CK_RV
988
+pkcs11h_plugAndPlay () {
989
+#if defined(WIN32)
990
+	int mypid = 0;
991
+#else
992
+	pid_t mypid = getpid ();
993
+#endif
994
+
995
+	PKCS11H_DEBUG (
996
+		PKCS11H_LOG_DEBUG2,
997
+		"PKCS#11: pkcs11h_forkFixup entry pid=%d",
998
+		mypid
999
+	);
1000
+
1001
+	if (s_pkcs11h_data != NULL && s_pkcs11h_data->fInitialized) {
1002
+		pkcs11h_provider_t current;
1003
+#if defined(ENABLE_PKCS11H_SLOTEVENT)
1004
+		PKCS11H_BOOL fSlotEventActive = FALSE;
1005
+#endif
482 1006
 
1007
+#if defined(ENABLE_PKCS11H_THREADING)
1008
+		_pkcs11h_mutexLock (&s_pkcs11h_data->mutexGlobal);
1009
+#endif
483 1010
 		for (
484
-			i=0, current_provider=pkcs11h_data->providers;
485
-			(
486
-				i < provider_number &&
487
-				current_provider != NULL &&
488
-				rv == CKR_OK
489
-			);
490
-			i++, current_provider = current_provider->next
1011
+			current = s_pkcs11h_data->providers;
1012
+			current != NULL;
1013
+			current = current->next
1014
+		) {
1015
+			if (current->fEnabled) {
1016
+				current->f->C_Finalize (NULL);
1017
+			}
1018
+		}
1019
+
1020
+#if defined(ENABLE_PKCS11H_SLOTEVENT)
1021
+		if (s_pkcs11h_data->fSlotEventInitialized) {
1022
+			fSlotEventActive = TRUE;
1023
+			_pkcs11h_slotevent_terminate ();
1024
+		}
1025
+#endif
1026
+
1027
+		for (
1028
+			current = s_pkcs11h_data->providers;
1029
+			current != NULL;
1030
+			current = current->next
1031
+		) {
1032
+			if (current->fEnabled) {
1033
+				current->f->C_Initialize (NULL);
1034
+			}
1035
+		}
1036
+
1037
+#if defined(ENABLE_PKCS11H_SLOTEVENT)
1038
+		if (fSlotEventActive) {
1039
+			_pkcs11h_slotevent_init ();
1040
+		}
1041
+#endif
1042
+
1043
+#if defined(ENABLE_PKCS11H_THREADING)
1044
+		_pkcs11h_mutexRelease (&s_pkcs11h_data->mutexGlobal);
1045
+#endif
1046
+	}
1047
+
1048
+	PKCS11H_DEBUG (
1049
+		PKCS11H_LOG_DEBUG2,
1050
+		"PKCS#11: pkcs11h_forkFixup return"
1051
+	);
1052
+
1053
+	return CKR_OK;
1054
+}
1055
+
1056
+CK_RV
1057
+pkcs11h_freeTokenId (
1058
+	IN pkcs11h_token_id_t token_id
1059
+) {
1060
+	PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
1061
+	PKCS11H_ASSERT (s_pkcs11h_data->fInitialized);
1062
+	PKCS11H_ASSERT (token_id!=NULL);
1063
+
1064
+	PKCS11H_DEBUG (
1065
+		PKCS11H_LOG_DEBUG2,
1066
+		"PKCS#11: pkcs11h_freeTokenId entry certificate_id=%p",
1067
+		(void *)token_id
1068
+	);
1069
+
1070
+	_pkcs11h_free ((void *)&token_id);
1071
+
1072
+	PKCS11H_DEBUG (
1073
+		PKCS11H_LOG_DEBUG2,
1074
+		"PKCS#11: pkcs11h_freeTokenId return"
1075
+	);
1076
+
1077
+	return CKR_OK;
1078
+}
1079
+
1080
+CK_RV
1081
+pkcs11h_duplicateTokenId (
1082
+	OUT pkcs11h_token_id_t * const to,
1083
+	IN const pkcs11h_token_id_t from
1084
+) {
1085
+	CK_RV rv = CKR_OK;
1086
+
1087
+	PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
1088
+	PKCS11H_ASSERT (s_pkcs11h_data->fInitialized);
1089
+	PKCS11H_ASSERT (to!=NULL);
1090
+	PKCS11H_ASSERT (from!=NULL);
1091
+
1092
+	PKCS11H_DEBUG (
1093
+		PKCS11H_LOG_DEBUG2,
1094
+		"PKCS#11: pkcs11h_duplicateTokenId entry to=%p form=%p",
1095
+		(void *)to,
1096
+		(void *)from
1097
+	);
1098
+
1099
+	*to = NULL;
1100
+
1101
+	if (rv == CKR_OK) {
1102
+		rv = _pkcs11h_dupmem (
1103
+			(void*)to,
1104
+			NULL,
1105
+			from,
1106
+			sizeof (struct pkcs11h_token_id_s)
491 1107
 		);
1108
+	}
1109
+
1110
+	PKCS11H_DEBUG (
1111
+		PKCS11H_LOG_DEBUG2,
1112
+		"PKCS#11: pkcs11h_duplicateTokenId return rv=%ld-'%s', *to=%p",
1113
+		rv,
1114
+		pkcs11h_getMessage (rv),
1115
+		(void *)*to
1116
+	);
492 1117
 	
1118
+	return rv;
1119
+}
1120
+
1121
+PKCS11H_BOOL
1122
+pkcs11h_sameTokenId (
1123
+	IN const pkcs11h_token_id_t a,
1124
+	IN const pkcs11h_token_id_t b
1125
+) {
1126
+	PKCS11H_ASSERT (a!=NULL);
1127
+	PKCS11H_ASSERT (b!=NULL);
1128
+
1129
+	return (
1130
+		!strcmp (a->manufacturerID, b->manufacturerID) &&
1131
+		!strcmp (a->model, b->model) &&
1132
+		!strcmp (a->serialNumber, b->serialNumber)
1133
+	);
1134
+}
1135
+
1136
+/*======================================================================*
1137
+ * MEMORY INTERFACE
1138
+ *======================================================================*/
1139
+
1140
+static
1141
+CK_RV
1142
+_pkcs11h_malloc (
1143
+	OUT const void ** const p,
1144
+	IN const size_t s
1145
+) {
1146
+	CK_RV rv = CKR_OK;
1147
+
1148
+	PKCS11H_ASSERT (p!=NULL);
1149
+	PKCS11H_ASSERT (s!=0);
1150
+
1151
+	*p = NULL;
1152
+
1153
+	if (s > 0) {
493 1154
 		if (
494
-			current_provider == NULL ||
495
-			(
496
-				current_provider != NULL &&
497
-				!current_provider->fEnabled
498
-			)
1155
+			(*p = (void *)malloc (s)) == NULL
499 1156
 		) {
500
-			rv = CKR_SLOT_ID_INVALID;
1157
+			rv = CKR_HOST_MEMORY;
501 1158
 		}
502 1159
 		else {
503
-			*provider = current_provider;
504
-			*slot = slot_number;
1160
+			memset ((void *)*p, 0, s);
505 1161
 		}
506 1162
 	}
507 1163
 
508
-	PKCS11DLOG (
509
-		PKCS11_LOG_DEBUG2,
510
-		"PKCS#11: _pkcs11h_getSlotById return rv=%ld-'%s'",
511
-		rv,
512
-		pkcs11h_getMessage (rv)
513
-	);
514
-
515 1164
 	return rv;
516 1165
 }
517 1166
 
518 1167
 static
519 1168
 CK_RV
520
-_pkcs11h_getSlotByName (
521
-	IN const char * const szName,
522
-	OUT pkcs11h_provider_t * const provider,
523
-	OUT CK_SLOT_ID * const slot
1169
+_pkcs11h_free (
1170
+	IN const void ** const p
1171
+) {
1172
+	PKCS11H_ASSERT (p!=NULL);
1173
+
1174
+	free ((void *)*p);
1175
+	*p = NULL;
1176
+
1177
+	return CKR_OK;
1178
+}
1179
+
1180
+static
1181
+CK_RV
1182
+_pkcs11h_dupmem (
1183
+	OUT const void ** const dest,
1184
+	OUT size_t * const p_dest_size,
1185
+	IN const void * const src,
1186
+	IN const size_t mem_size
524 1187
 ) {
525 1188
 	CK_RV rv = CKR_OK;
526 1189
 
527
-	pkcs11h_provider_t current_provider;
528
-	bool fFound = false;
1190
+	PKCS11H_ASSERT (dest!=NULL);
1191
+	/*PKCS11H_ASSERT (dest_size!=NULL); NOT NEEDED*/
1192
+	PKCS11H_ASSERT (!(mem_size!=0&&src==NULL));
529 1193
 
530
-	PKCS11ASSERT (szName!=NULL);
531
-	PKCS11ASSERT (provider!=NULL);
532
-	PKCS11ASSERT (slot!=NULL);
1194
+	*dest = NULL;
1195
+	if (p_dest_size != NULL) {
1196
+		*p_dest_size = 0;
1197
+	}
533 1198
 
534
-	PKCS11DLOG (
535
-		PKCS11_LOG_DEBUG2,
536
-		"PKCS#11: _pkcs11h_getSlotByName entry szName=%s, provider=%p, slot=%p",
537
-		szName,
538
-		(void *)provider,
539
-		(void *)slot
540
-	);
1199
+	if (src != NULL) {
1200
+		if (
1201
+			rv == CKR_OK &&
1202
+			(rv = _pkcs11h_malloc (dest, mem_size)) == CKR_OK
1203
+		) {
1204
+			if (p_dest_size != NULL) {
1205
+				*p_dest_size = mem_size;
1206
+			}
1207
+			memmove ((void*)*dest, src, mem_size);
1208
+		}
1209
+	}
541 1210
 
542
-	for (
543
-		current_provider = pkcs11h_data->providers;
544
-		(
545
-			current_provider != NULL &&
546
-			!fFound
547
-		);
548
-		current_provider = current_provider->next
1211
+	return rv;
1212
+}
1213
+
1214
+#if defined(ENABLE_PKCS11H_THREADING)
1215
+/*======================================================================*
1216
+ * THREADING INTERFACE
1217
+ *======================================================================*/
1218
+
1219
+static
1220
+void
1221
+_pkcs11h_sleep (
1222
+	IN const unsigned milli
1223
+) {
1224
+#if defined(WIN32)
1225
+	Sleep (milli);
1226
+#else
1227
+	usleep (milli*1000);
1228
+#endif
1229
+}
1230
+
1231
+static
1232
+CK_RV
1233
+_pkcs11h_mutexInit (
1234
+	OUT pkcs11h_mutex_t * const mutex
1235
+) {
1236
+	CK_RV rv = CKR_OK;
1237
+#if defined(WIN32)
1238
+	if (
1239
+		rv == CKR_OK &&
1240
+		(*mutex = CreateMutex (NULL, FALSE, NULL)) == NULL
549 1241
 	) {
550
-		CK_SLOT_ID slots[1024];
551
-		CK_ULONG slotnum;
1242
+		rv = CKR_FUNCTION_FAILED;
1243
+	}
1244
+#else
1245
+	{
1246
+		__pkcs11h_mutex_entry_t entry = NULL;
1247
+		PKCS11H_BOOL fMutexLocked = FALSE;
552 1248
 
553
-		if (!current_provider->fEnabled) {
554
-			continue;
1249
+		if (
1250
+			rv == CKR_OK &&
1251
+			(rv = _pkcs11h_mutexLock (&__s_pkcs11h_mutex_list.mutex)) == CKR_OK
1252
+		) {
1253
+			fMutexLocked = TRUE;
1254
+		}
1255
+		
1256
+		if (rv == CKR_OK) {
1257
+			rv = _pkcs11h_malloc (
1258
+				(void *)&entry,
1259
+				sizeof (struct __pkcs11h_mutex_entry_s)
1260
+			);
555 1261
 		}
556 1262
 
557
-		slotnum = sizeof (slots) / sizeof (CK_SLOT_ID);
558 1263
 		if (
559
-			(rv = current_provider->f->C_GetSlotList (
560
-				TRUE,
561
-				slots,
562
-				&slotnum
563
-			)) == CKR_OK
1264
+			rv == CKR_OK &&
1265
+			pthread_mutex_init (mutex, NULL)
564 1266
 		) {
565
-			CK_SLOT_ID s;
1267
+			rv = CKR_FUNCTION_FAILED;
1268
+		}
566 1269
 
567
-			for (s=0;!fFound && s<slotnum;s++) {
568
-				CK_SLOT_INFO info;
1270
+		if (rv == CKR_OK) {
1271
+			entry->p_mutex = mutex;
1272
+			entry->next = __s_pkcs11h_mutex_list.head;
1273
+			__s_pkcs11h_mutex_list.head = entry;
1274
+			entry = NULL;
1275
+		}
569 1276
 
570
-				if (
571
-					(rv = current_provider->f->C_GetSlotInfo (
572
-						slots[s],
573
-						&info
574
-					)) == CKR_OK
575
-				) {
576
-					char szCurrentName[sizeof (info.slotDescription)+1];
577
-	
578
-					_pkcs11h_fixupFixedString (
579
-						(char *)info.slotDescription,
580
-						szCurrentName,
581
-						sizeof (info.slotDescription)
582
-					);
1277
+		if (entry != NULL) {
1278
+			_pkcs11h_free ((void *)&entry);
1279
+		}
583 1280
 
584
-					if (!strcmp (szCurrentName, szName)) {
585
-						fFound = true;
586
-						*provider = current_provider;
587
-						*slot = slots[s];
588
-					}
589
-				}
590
-			}
1281
+		if (fMutexLocked) {
1282
+			_pkcs11h_mutexRelease (&__s_pkcs11h_mutex_list.mutex);
1283
+			fMutexLocked = FALSE;
591 1284
 		}
592 1285
 	}
1286
+#endif
1287
+	return rv;
1288
+}
593 1289
 
594
-	PKCS11DLOG (
595
-		PKCS11_LOG_DEBUG2,
596
-		"PKCS#11: _pkcs11h_getSlotByName return fFound=%d-'%s'",
597
-		fFound ? 1 : 0,
598
-		pkcs11h_getMessage (rv)
599
-	);
1290
+static
1291
+CK_RV
1292
+_pkcs11h_mutexLock (
1293
+	IN OUT pkcs11h_mutex_t *const mutex
1294
+) {
1295
+	CK_RV rv = CKR_OK;
1296
+#if defined(WIN32)
1297
+	if (
1298
+		rv == CKR_OK &&
1299
+		WaitForSingleObject (*mutex, INFINITE) == WAIT_FAILED
1300
+	) {
1301
+		rv = CKR_FUNCTION_FAILED;
1302
+	}
1303
+#else
1304
+	if (
1305
+		rv == CKR_OK &&
1306
+		pthread_mutex_lock (mutex)
1307
+	) {
1308
+		rv = CKR_FUNCTION_FAILED;
1309
+	}
1310
+#endif
1311
+	return rv;
1312
+}
600 1313
 
601
-	return fFound ? CKR_OK : CKR_SLOT_ID_INVALID;
1314
+static
1315
+CK_RV
1316
+_pkcs11h_mutexRelease (
1317
+	IN OUT pkcs11h_mutex_t *const mutex
1318
+) {
1319
+	CK_RV rv = CKR_OK;
1320
+#if defined(WIN32)
1321
+	if (
1322
+		rv == CKR_OK &&
1323
+		!ReleaseMutex (*mutex)
1324
+	) {
1325
+		rv = CKR_FUNCTION_FAILED;
1326
+	}
1327
+#else
1328
+	if (
1329
+		rv == CKR_OK &&
1330
+		pthread_mutex_unlock (mutex)
1331
+	) {
1332
+		rv = CKR_FUNCTION_FAILED;
1333
+	}
1334
+#endif
1335
+	return rv;
602 1336
 }
603 1337
 
604 1338
 static
605 1339
 CK_RV
606
-_pkcs11h_getSlotByLabel (
607
-	IN const char * const szLabel,
608
-	OUT pkcs11h_provider_t * const provider,
609
-	OUT CK_SLOT_ID * const slot
1340
+_pkcs11h_mutexFree (
1341
+	IN OUT pkcs11h_mutex_t *const mutex
610 1342
 ) {
611
-	CK_RV rv;
1343
+#if defined(WIN32)
1344
+	if (*mutex != NULL) {
1345
+		CloseHandle (*mutex);
1346
+		*mutex = NULL;
1347
+	}
1348
+#else
1349
+	{
1350
+		__pkcs11h_mutex_entry_t last = NULL;
1351
+		__pkcs11h_mutex_entry_t entry = NULL;
1352
+		PKCS11H_BOOL fMutexLocked = FALSE;
612 1353
 
613
-	pkcs11h_provider_t current_provider;
614
-	bool fFound = false;
1354
+		if (_pkcs11h_mutexLock (&__s_pkcs11h_mutex_list.mutex) == CKR_OK) {
1355
+			fMutexLocked = TRUE;
1356
+		}
615 1357
 
616
-	PKCS11ASSERT (szLabel!=NULL);
617
-	PKCS11ASSERT (provider!=NULL);
618
-	PKCS11ASSERT (slot!=NULL);
1358
+		entry =  __s_pkcs11h_mutex_list.head;
1359
+		while (
1360
+			entry != NULL &&
1361
+			entry->p_mutex != mutex
1362
+		) {
1363
+			last = entry;
1364
+			entry = entry->next;
1365
+		}
619 1366
 
620
-	PKCS11DLOG (
621
-		PKCS11_LOG_DEBUG2,
622
-		"PKCS#11: _pkcs11h_getSlotByLabel entry szLabel=%s, provider=%p, slot=%p",
623
-		szLabel,
624
-		(void *)provider,
625
-		(void *)slot
626
-	);
1367
+		if (entry != NULL) {
1368
+			if (last == NULL) {
1369
+				__s_pkcs11h_mutex_list.head = entry->next;
1370
+			}
1371
+			else {
1372
+				last->next = entry->next;
1373
+			}
1374
+			_pkcs11h_free ((void *)&entry);
1375
+		}
1376
+
1377
+		pthread_mutex_destroy (mutex);
1378
+
1379
+		if (fMutexLocked) {
1380
+			_pkcs11h_mutexRelease (&__s_pkcs11h_mutex_list.mutex);
1381
+			fMutexLocked = FALSE;
1382
+		}
1383
+	}
1384
+#endif
1385
+	return CKR_OK;
1386
+}
1387
+
1388
+#if !defined(WIN32)
1389
+/*
1390
+ * This function is required in order
1391
+ * to lock all mutexes before fork is called,
1392
+ * and to avoid dedlocks.
1393
+ * The loop is required because there is no
1394
+ * way to lock all mutex in one system call...
1395
+ */
1396
+static
1397
+void
1398
+__pkcs1h_mutexLockAll () {
1399
+	__pkcs11h_mutex_entry_t entry = NULL;
1400
+	PKCS11H_BOOL fMutexLocked = FALSE;
1401
+	PKCS11H_BOOL fAllLocked = FALSE;
1402
+
1403
+	if (_pkcs11h_mutexLock (&__s_pkcs11h_mutex_list.mutex) == CKR_OK) {
1404
+		fMutexLocked = TRUE;
1405
+	}
627 1406
 
628 1407
 	for (
629
-		current_provider = pkcs11h_data->providers;
1408
+		entry = __s_pkcs11h_mutex_list.head;
1409
+		entry != NULL;
1410
+		entry = entry->next
1411
+	) {
1412
+		entry->fLocked = FALSE;
1413
+	}
1414
+
1415
+	while (!fAllLocked) {
1416
+		PKCS11H_BOOL fOK = TRUE;
1417
+		
1418
+		for (
1419
+			entry = __s_pkcs11h_mutex_list.head;
1420
+			entry != NULL && fOK;
1421
+			entry = entry->next
1422
+		) {
1423
+			if (!pthread_mutex_trylock (entry->p_mutex)) {
1424
+				entry->fLocked = TRUE;
1425
+			}
1426
+			else {
1427
+				fOK = FALSE;
1428
+			}
1429
+		}
1430
+
1431
+		if (!fOK) {
1432
+			for (
1433
+				entry = __s_pkcs11h_mutex_list.head;
1434
+				entry != NULL;
1435
+				entry = entry->next
1436
+			) {
1437
+				if (entry->fLocked == TRUE) {
1438
+					pthread_mutex_unlock (entry->p_mutex);
1439
+					entry->fLocked = FALSE;
1440
+				}
1441
+			}
1442
+
1443
+			_pkcs11h_mutexRelease (&__s_pkcs11h_mutex_list.mutex);
1444
+			_pkcs11h_sleep (1000);
1445
+			_pkcs11h_mutexLock (&__s_pkcs11h_mutex_list.mutex);
1446
+		}
1447
+		else {
1448
+			fAllLocked  = TRUE;
1449
+		}
1450
+	}
1451
+
1452
+	if (fMutexLocked) {
1453
+		_pkcs11h_mutexRelease (&__s_pkcs11h_mutex_list.mutex);
1454
+		fMutexLocked = FALSE;
1455
+	}
1456
+}
1457
+
1458
+static
1459
+void
1460
+__pkcs1h_mutexReleaseAll () {
1461
+	__pkcs11h_mutex_entry_t entry = NULL;
1462
+	PKCS11H_BOOL fMutexLocked = FALSE;
1463
+
1464
+	if (_pkcs11h_mutexLock (&__s_pkcs11h_mutex_list.mutex) == CKR_OK) {
1465
+		fMutexLocked = TRUE;
1466
+	}
1467
+
1468
+	for (
1469
+		entry = __s_pkcs11h_mutex_list.head;
1470
+		entry != NULL;
1471
+		entry = entry->next
1472
+	) {
1473
+		pthread_mutex_unlock (entry->p_mutex);
1474
+		entry->fLocked = FALSE;
1475
+	}
1476
+
1477
+	if (fMutexLocked) {
1478
+		_pkcs11h_mutexRelease (&__s_pkcs11h_mutex_list.mutex);
1479
+		fMutexLocked = FALSE;
1480
+	}
1481
+}
1482
+#endif
1483
+
1484
+CK_RV
1485
+_pkcs11h_condSignal (
1486
+	IN OUT pkcs11h_cond_t *const cond
1487
+) {
1488
+	CK_RV rv = CKR_OK;
1489
+#if defined(WIN32)
1490
+	if (
1491
+		rv == CKR_OK &&
1492
+		!SetEvent (*cond)
1493
+	) {
1494
+		rv = CKR_FUNCTION_FAILED;
1495
+	}
1496
+#else
1497
+	if (
1498
+		rv == CKR_OK &&
630 1499
 		(
631
-			current_provider != NULL &&
632
-			!fFound
633
-		);
634
-		current_provider = current_provider->next
1500
+			pthread_mutex_lock (&cond->mut) ||
1501
+			pthread_cond_signal (&cond->cond) ||
1502
+			pthread_mutex_unlock (&cond->mut)
1503
+		)
635 1504
 	) {
636
-		CK_SLOT_ID slots[1024];
637
-		CK_ULONG slotnum;
1505
+		rv = CKR_FUNCTION_FAILED;
1506
+	}
1507
+#endif
638 1508
 
639
-		if (!current_provider->fEnabled) {
640
-			continue;
1509
+	return rv;
1510
+}
1511
+
1512
+static
1513
+CK_RV
1514
+_pkcs11h_condInit (
1515
+	OUT pkcs11h_cond_t * const cond
1516
+) {
1517
+	CK_RV rv = CKR_OK;
1518
+#if defined(WIN32)
1519
+	if (
1520
+		rv == CKR_OK &&
1521
+		(*cond = CreateEvent (NULL, FALSE, FALSE, NULL)) == NULL
1522
+	) {
1523
+		rv = CKR_FUNCTION_FAILED;
1524
+	}
1525
+#else
1526
+	if (
1527
+		rv == CKR_OK &&
1528
+		(
1529
+			pthread_mutex_init (&cond->mut, NULL) ||
1530
+			pthread_cond_init (&cond->cond, NULL) ||
1531
+			pthread_mutex_lock (&cond->mut)
1532
+		)
1533
+	) {
1534
+		rv = CKR_FUNCTION_FAILED;
1535
+	}
1536
+#endif
1537
+	return rv;
1538
+}
1539
+
1540
+static
1541
+CK_RV
1542
+_pkcs11h_condWait (
1543
+	IN OUT pkcs11h_cond_t *const cond,
1544
+	IN const unsigned milli
1545
+) {
1546
+	CK_RV rv = CKR_OK;
1547
+
1548
+#if defined(WIN32)
1549
+	DWORD dwMilli;
1550
+
1551
+	if (milli == PKCS11H_COND_INFINITE) {
1552
+		dwMilli = INFINITE;
1553
+	}
1554
+	else {
1555
+		dwMilli = milli;
1556
+	}
1557
+
1558
+	if (
1559
+		rv == CKR_OK &&
1560
+		WaitForSingleObject (*cond, dwMilli) == WAIT_FAILED
1561
+	) {
1562
+		rv = CKR_FUNCTION_FAILED;
1563
+	}
1564
+#else
1565
+	if (milli == PKCS11H_COND_INFINITE) {
1566
+		if (
1567
+			rv == CKR_OK &&
1568
+			pthread_cond_wait (&cond->cond, &cond->mut)
1569
+		) {
1570
+			rv = CKR_FUNCTION_FAILED;
641 1571
 		}
1572
+	}
1573
+	else {
1574
+		struct timeval now;
1575
+		struct timespec timeout;
642 1576
 
643
-		slotnum = sizeof (slots) / sizeof (CK_SLOT_ID);
644 1577
 		if (
645
-			(rv = current_provider->f->C_GetSlotList (
646
-				TRUE,
647
-				slots,
648
-				&slotnum
649
-			)) == CKR_OK
1578
+			rv == CKR_OK &&
1579
+			gettimeofday (&now, NULL)
650 1580
 		) {
651
-			CK_SLOT_ID s;
1581
+			rv = CKR_FUNCTION_FAILED;
1582
+		}
1583
+		
1584
+		if (rv == CKR_OK) {
1585
+			timeout.tv_sec = now.tv_sec + milli/1000;
1586
+			timeout.tv_nsec = now.tv_usec*1000 + milli%1000;
1587
+		}
1588
+		
1589
+		if (
1590
+			rv == CKR_OK &&
1591
+			pthread_cond_timedwait (&cond->cond, &cond->mut, &timeout)
1592
+		) {
1593
+			rv = CKR_FUNCTION_FAILED;
1594
+		}
1595
+	}
1596
+#endif
1597
+	return rv;
1598
+}
652 1599
 
653
-			for (s=0;!fFound && s<slotnum;s++) {
654
-				CK_TOKEN_INFO info;
1600
+static
1601
+CK_RV
1602
+_pkcs11h_condFree (
1603
+	IN OUT pkcs11h_cond_t *const cond
1604
+) {
1605
+#if defined(WIN32)
1606
+	CloseHandle (*cond);
1607
+	*cond = NULL;
1608
+#else
1609
+	pthread_mutex_unlock (&cond->mut);
1610
+#endif
1611
+	return CKR_OK;
1612
+}
655 1613
 
656
-				if (
657
-					(rv = current_provider->f->C_GetTokenInfo (
658
-						slots[s],
659
-						&info
660
-					)) == CKR_OK
661
-				) {
662
-					char szCurrentLabel[sizeof (info.label)+1];
663
-			
664
-					_pkcs11h_fixupFixedString (
665
-						(char *)info.label,
666
-						szCurrentLabel,
667
-						sizeof (info.label)
668
-					);
1614
+#if defined(WIN32)
1615
+static
1616
+unsigned
1617
+__stdcall
1618
+__pkcs11h_thread_start (void *p) {
1619
+	__pkcs11h_thread_data_t *_data = (__pkcs11h_thread_data_t *)p;
1620
+	unsigned ret;
669 1621
 
670
-					if (!strcmp (szCurrentLabel, szLabel)) {
671
-						fFound = true;
672
-						*provider = current_provider;
673
-						*slot = slots[s];
674
-					}
675
-				}
676
-			}
1622
+	ret = (unsigned)_data->start (_data->data);
1623
+
1624
+	_pkcs11h_free ((void *)&_data);
1625
+
1626
+	return ret;
1627
+}
1628
+#else
1629
+static
1630
+void *
1631
+__pkcs11h_thread_start (void *p) {
1632
+	__pkcs11h_thread_data_t *_data = (__pkcs11h_thread_data_t *)p;
1633
+	void *ret;
1634
+	int i;
1635
+
1636
+	/*
1637
+	 * Ignore any signal in
1638
+	 * this thread
1639
+	 */
1640
+	for (i=1;i<16;i++) {
1641
+		signal (i, SIG_IGN);
1642
+	}
1643
+
1644
+	ret = _data->start (_data->data);
1645
+
1646
+	_pkcs11h_free ((void *)&_data);
1647
+
1648
+	return ret;
1649
+}
1650
+#endif
1651
+
1652
+static
1653
+CK_RV
1654
+_pkcs11h_threadStart (
1655
+	OUT pkcs11h_thread_t * const thread,
1656
+	IN pkcs11h_thread_start_t const start,
1657
+	IN void * data
1658
+) {
1659
+	__pkcs11h_thread_data_t *_data = NULL;
1660
+	CK_RV rv = CKR_OK;
1661
+
1662
+	if (rv == CKR_OK) {
1663
+		rv = _pkcs11h_malloc (
1664
+			(void *)&_data,
1665
+			sizeof (__pkcs11h_thread_data_t)
1666
+		);
1667
+	}
1668
+
1669
+	if (rv == CKR_OK) {
1670
+		_data->start = start;
1671
+		_data->data = data;
1672
+	}
1673
+
1674
+#if defined(WIN32)
1675
+	{
1676
+		unsigned tmp;
1677
+
1678
+		if (
1679
+			rv == CKR_OK &&
1680
+			(*thread = (HANDLE)_beginthreadex (
1681
+				NULL,
1682
+				0,
1683
+				__pkcs11h_thread_start,
1684
+				_data,
1685
+				0,
1686
+				&tmp
1687
+			)) == NULL
1688
+		) {
1689
+			rv = CKR_FUNCTION_FAILED;
677 1690
 		}
678 1691
 	}
1692
+#else
1693
+	if (
1694
+		rv == CKR_OK &&
1695
+		pthread_create (thread, NULL, __pkcs11h_thread_start, _data)
1696
+	) {
1697
+		rv = CKR_FUNCTION_FAILED;
1698
+	}
1699
+#endif
1700
+	return rv;
1701
+}
1702
+
1703
+static
1704
+CK_RV
1705
+_pkcs11h_threadJoin (
1706
+	IN pkcs11h_thread_t * const thread
1707
+) {
1708
+#if defined(WIN32)
1709
+	WaitForSingleObject (*thread, INFINITE);
1710
+	CloseHandle (*thread);
1711
+	*thread = NULL;
1712
+#else
1713
+	pthread_join (*thread, NULL);
1714
+	*thread = 0l;
1715
+#endif
1716
+	return CKR_OK;
1717
+}
1718
+
1719
+#endif		/* ENABLE_PKCS11H_THREADING */
1720
+
1721
+/*======================================================================*
1722
+ * COMMON INTERNAL INTERFACE
1723
+ *======================================================================*/
1724
+
1725
+static
1726
+void
1727
+_pkcs11h_fixupFixedString (
1728
+	OUT char * const szTarget,			/* MUST BE >= nLength+1 */
1729
+	IN const char * const szSource,
1730
+	IN const size_t nLength				/* FIXED STRING LENGTH */
1731
+) {
1732
+	char *p;
1733
+
1734
+	PKCS11H_ASSERT (szSource!=NULL);
1735
+	PKCS11H_ASSERT (szTarget!=NULL);
1736
+	
1737
+	p = szTarget+nLength;
1738
+	memmove (szTarget, szSource, nLength);
1739
+	*p = '\0';
1740
+	p--;
1741
+	while (p >= szTarget && *p == ' ') {
1742
+		*p = '\0';
1743
+		p--;
1744
+	}
1745
+}
679 1746
 
680
-	PKCS11DLOG (
681
-		PKCS11_LOG_DEBUG2,
682
-		"PKCS#11: _pkcs11h_getSlotByLabel return fFound=%d",
683
-		fFound ? 1 : 0
684
-	);
1747
+static
1748
+void
1749
+_pkcs11h_log (
1750
+	IN const unsigned flags,
1751
+	IN const char * const szFormat,
1752
+	IN ...
1753
+) {
1754
+	va_list args;
685 1755
 
686
-	return fFound ? CKR_OK : CKR_SLOT_ID_INVALID;
1756
+	PKCS11H_ASSERT (szFormat!=NULL);
1757
+
1758
+	va_start (args, szFormat);
1759
+
1760
+	if (
1761
+		s_pkcs11h_data != NULL &&
1762
+		s_pkcs11h_data->fInitialized
1763
+	) { 
1764
+		if (PKCS11H_MSG_LEVEL_TEST (flags)) {
1765
+			if (s_pkcs11h_data->hooks.log == NULL) {
1766
+				_pkcs11h_hooks_default_log (
1767
+					NULL,
1768
+					flags,
1769
+					szFormat,
1770
+					args
1771
+				);
1772
+			}
1773
+			else {
1774
+				s_pkcs11h_data->hooks.log (
1775
+					s_pkcs11h_data->hooks.log_data,
1776
+					flags,
1777
+					szFormat,
1778
+					args
1779
+				);
1780
+			}
1781
+		}
1782
+	}
1783
+
1784
+	va_end (args);
687 1785
 }
688 1786
 
689 1787
 static
690 1788
 CK_RV
691
-_pkcs11h_getSlot (
692
-	IN const char * const szSlotType,
693
-	IN const char * const szSlot,
694
-	OUT pkcs11h_provider_t * const provider,
695
-	OUT CK_SLOT_ID * const slot
1789
+_pkcs11h_getSlotList (
1790
+	IN const pkcs11h_provider_t provider,
1791
+	IN const CK_BBOOL tokenPresent,
1792
+	OUT CK_SLOT_ID_PTR * const pSlotList,
1793
+	OUT CK_ULONG_PTR pulCount
696 1794
 ) {
1795
+	CK_SLOT_ID_PTR _slots = NULL;
1796
+	CK_ULONG _slotnum = 0;
697 1797
 	CK_RV rv = CKR_OK;
698 1798
 
699
-	PKCS11ASSERT (szSlotType!=NULL);
700
-	PKCS11ASSERT (szSlot!=NULL);
701
-	PKCS11ASSERT (provider!=NULL);
702
-	PKCS11ASSERT (slot!=NULL);
1799
+	PKCS11H_ASSERT (provider!=NULL);
1800
+	PKCS11H_ASSERT (pSlotList!=NULL);
1801
+	PKCS11H_ASSERT (pulCount!=NULL);
703 1802
 
704
-	PKCS11DLOG (
705
-		PKCS11_LOG_DEBUG2,
706
-		"PKCS#11: _pkcs11h_getSlot entry szSlotType=%s, szSlot=%s, provider=%p, slot=%p",
707
-		szSlotType,
708
-		szSlot,
1803
+	PKCS11H_DEBUG (
1804
+		PKCS11H_LOG_DEBUG2,
1805
+		"PKCS#11: _pkcs11h_getSlotList entry provider=%p, tokenPresent=%d, pSlotList=%p, pulCount=%p",
709 1806
 		(void *)provider,
710
-		(void *)slot
1807
+		tokenPresent,
1808
+		(void *)pSlotList,
1809
+		(void *)pulCount
711 1810
 	);
712 1811
 
713
-	if (!strcmp (szSlotType, "id")) {
714
-		rv = _pkcs11h_getSlotById (
715
-			szSlot,
716
-			provider,
717
-			slot
1812
+	*pSlotList = NULL;
1813
+	*pulCount = 0;
1814
+
1815
+	if (rv == CKR_OK) {
1816
+		rv = provider->f->C_GetSlotList (
1817
+			tokenPresent,
1818
+			NULL_PTR,
1819
+			&_slotnum
718 1820
 		);
719 1821
 	}
720
-	else if (!strcmp (szSlotType, "name")) {
721
-		rv = _pkcs11h_getSlotByName (
722
-			szSlot,
723
-			provider,
724
-			slot
1822
+
1823
+	if (rv == CKR_OK && _slotnum > 0) {
1824
+		rv = _pkcs11h_malloc ((void *)&_slots, _slotnum * sizeof (CK_SLOT_ID));
1825
+	}
1826
+
1827
+	if (rv == CKR_OK && _slotnum > 0) {
1828
+		rv = provider->f->C_GetSlotList (
1829
+			tokenPresent,
1830
+			_slots,
1831
+			&_slotnum
725 1832
 		);
726 1833
 	}
727
-	else if (!strcmp (szSlotType, "label")) {
728
-		rv = _pkcs11h_getSlotByLabel (
729
-			szSlot,
730
-			provider,
731
-			slot
1834
+
1835
+	if (rv == CKR_OK) {
1836
+		*pSlotList = _slots;
1837
+		_slots = NULL;
1838
+		*pulCount = _slotnum;
1839
+	}
1840
+
1841
+	if (_slots != NULL) {
1842
+		_pkcs11h_free ((void *)&_slots);
1843
+	}
1844
+
1845
+	PKCS11H_DEBUG (
1846
+		PKCS11H_LOG_DEBUG2,
1847
+		"PKCS#11: _pkcs11h_getSlotList return rv=%ld-'%s' *pulCount=%ld",
1848
+		rv,
1849
+		pkcs11h_getMessage (rv),
1850
+		*pulCount
1851
+	);
1852
+
1853
+	return rv;
1854
+}
1855
+
1856
+static
1857
+CK_RV
1858
+_pkcs11h_getObjectAttributes (
1859
+	IN const pkcs11h_session_t session,
1860
+	IN const CK_OBJECT_HANDLE object,
1861
+	IN OUT const CK_ATTRIBUTE_PTR attrs,
1862
+	IN const unsigned count
1863
+) {
1864
+#if defined(ENABLE_PKCS11H_THREADING)
1865
+	PKCS11H_BOOL fMutexLocked = FALSE;
1866
+#endif
1867
+	CK_RV rv = CKR_OK;
1868
+
1869
+	PKCS11H_ASSERT (attrs!=NULL);
1870
+
1871
+	PKCS11H_DEBUG (
1872
+		PKCS11H_LOG_DEBUG2,
1873
+		"PKCS#11: _pkcs11h_getObjectAttributes entry session=%p, object=%ld, attrs=%p, count=%d",
1874
+		(void *)session,
1875
+		object,
1876
+		(void *)attrs,
1877
+		count
1878
+	);
1879
+
1880
+#if defined(ENABLE_PKCS11H_THREADING)
1881
+	if (
1882
+		rv == CKR_OK &&
1883
+		(rv = _pkcs11h_mutexLock (&session->mutexSession)) == CKR_OK
1884
+	) {
1885
+		fMutexLocked = TRUE;
1886
+	}
1887
+#endif
1888
+
1889
+	if (
1890
+		rv == CKR_OK &&
1891
+		(rv = session->provider->f->C_GetAttributeValue (
1892
+			session->hSession,
1893
+			object,
1894
+			attrs,
1895
+			count
1896
+		)) == CKR_OK
1897
+	) {
1898
+		unsigned i;
1899
+		for (i=0;rv == CKR_OK && i<count;i++) {
1900
+			if (attrs[i].ulValueLen == (CK_ULONG)-1) {
1901
+				rv = CKR_ATTRIBUTE_VALUE_INVALID;
1902
+			}
1903
+			else {
1904
+				rv = _pkcs11h_malloc (
1905
+					(void *)&attrs[i].pValue,
1906
+					attrs[i].ulValueLen
1907
+				);
1908
+			}
1909
+		}
1910
+	}
1911
+
1912
+	if (rv == CKR_OK) {
1913
+		rv = session->provider->f->C_GetAttributeValue (
1914
+			session->hSession,
1915
+			object,
1916
+			attrs,
1917
+			count
732 1918
 		);
733 1919
 	}
734
-	else {
735
-		rv = CKR_ARGUMENTS_BAD;
1920
+
1921
+#if defined(ENABLE_PKCS11H_THREADING)
1922
+	if (fMutexLocked) {
1923
+		_pkcs11h_mutexRelease (&session->mutexSession);
1924
+		fMutexLocked = FALSE;
736 1925
 	}
1926
+#endif
737 1927
 
738
-	PKCS11DLOG (
739
-		PKCS11_LOG_DEBUG2,
740
-		"PKCS#11: _pkcs11h_getSlot return rv=%ld-'%s'",
1928
+	PKCS11H_DEBUG (
1929
+		PKCS11H_LOG_DEBUG2,
1930
+		"PKCS#11: _pkcs11h_getObjectAttributes return rv=%ld-'%s'",
741 1931
 		rv,
742 1932
 		pkcs11h_getMessage (rv)
743 1933
 	);
... ...
@@ -747,177 +2452,424 @@ _pkcs11h_getSlot (
747 747
 
748 748
 static
749 749
 CK_RV
750
-_pkcs11h_getSession (
751
-	IN const char * const szSlotType,
752
-	IN const char * const szSlot,
753
-	IN const bool fProtectedAuthentication,
754
-	IN const int nPINCachePeriod,
755
-	OUT pkcs11h_session_t * const session
750
+_pkcs11h_freeObjectAttributes (
751
+	IN OUT const CK_ATTRIBUTE_PTR attrs,
752
+	IN const unsigned count
756 753
 ) {
757
-	CK_TOKEN_INFO info;
758
-	CK_SLOT_ID slot = PKCS11H_INVALID_SLOT_ID;
754
+	unsigned i;
755
+
759 756
 	CK_RV rv = CKR_OK;
760 757
 
761
-	pkcs11h_provider_t provider = NULL;
758
+	PKCS11H_ASSERT (attrs!=NULL);
762 759
 
763
-	PKCS11ASSERT (szSlotType!=NULL);
764
-	PKCS11ASSERT (szSlot!=NULL);
765
-	PKCS11ASSERT (session!=NULL);
760
+	PKCS11H_DEBUG (
761
+		PKCS11H_LOG_DEBUG2,
762
+		"PKCS#11: _pkcs11h_freeObjectAttributes entry attrs=%p, count=%d",
763
+		(void *)attrs,
764
+		count
765
+	);
766 766
 
767
-	PKCS11DLOG (
768
-		PKCS11_LOG_DEBUG2,
769
-		"PKCS#11: _pkcs11h_getSession entry szSlotType=%s, szSlot=%s, fProtectedAuthentication=%d, nPINCachePeriod=%d, session=%p",
770
-		szSlotType,
771
-		szSlot,
772
-		fProtectedAuthentication ? 1 : 0,
773
-		nPINCachePeriod,
774
-		(void *)session
767
+	for (i=0;i<count;i++) {
768
+		if (attrs[i].pValue != NULL) {
769
+			_pkcs11h_free ((void *)&attrs[i].pValue);
770
+			attrs[i].pValue = NULL;
771
+		}
772
+	}
773
+
774
+	PKCS11H_DEBUG (
775
+		PKCS11H_LOG_DEBUG2,
776
+		"PKCS#11: _pkcs11h_freeObjectAttributes return rv=%ld-'%s'",
777
+		rv,
778
+		pkcs11h_getMessage (rv)
775 779
 	);
776 780
 
777
-	if (rv == CKR_OK) {
778
-		do {
779
-			rv = _pkcs11h_getSlot (
780
-				szSlotType,
781
-				szSlot,
782
-				&provider,
783
-				&slot
784
-			);
785
-
786
-			if (rv == CKR_SLOT_ID_INVALID) {
787
-				char szLabel[1024];
788
-				strcpy (szLabel, "SLOT(");
789
-				strncat (szLabel, szSlotType, sizeof (szLabel)-1-strlen (szLabel));
790
-				strncat (szLabel, "=", sizeof (szLabel)-1-strlen (szLabel));
791
-				strncat (szLabel, szSlot, sizeof (szLabel)-1-strlen (szLabel));
792
-				strncat (szLabel, ")", sizeof (szLabel)-1-strlen (szLabel));
793
-				szLabel[sizeof (szLabel)-1] = 0;
794
-				PKCS11DLOG (
795
-					PKCS11_LOG_DEBUG1,
796
-					"PKCS#11: Calling card_prompt hook for %s",
797
-					szLabel
798
-				);
799
-				if (
800
-					!pkcs11h_data->hooks->card_prompt (
801
-						pkcs11h_data->hooks->card_prompt_data,
802
-						szLabel
803
-					)
804
-				) {
805
-					rv = CKR_CANCEL;
806
-				}
807
-				PKCS11DLOG (
808
-					PKCS11_LOG_DEBUG1,
809
-					"PKCS#11: card_prompt returned rv=%ld",
810
-					rv
781
+	return rv;
782
+}
783
+
784
+static
785
+CK_RV
786
+_pkcs11h_findObjects (
787
+	IN const pkcs11h_session_t session,
788
+	IN const CK_ATTRIBUTE * const filter,
789
+	IN const CK_ULONG filter_attrs,
790
+	OUT CK_OBJECT_HANDLE **const p_objects,
791
+	OUT CK_ULONG *p_objects_found
792
+) {
793
+#if defined(ENABLE_PKCS11H_THREADING)
794
+	PKCS11H_BOOL fMutexLocked = FALSE;
795
+#endif
796
+	PKCS11H_BOOL fShouldFindObjectFinal = FALSE;
797
+
798
+	CK_OBJECT_HANDLE *objects = NULL;
799
+	CK_ULONG objects_size = 0;
800
+	CK_OBJECT_HANDLE objects_buffer[100];
801
+	CK_ULONG objects_found;
802
+	CK_OBJECT_HANDLE oLast = PKCS11H_INVALID_OBJECT_HANDLE;
803
+	CK_RV rv = CKR_OK;
804
+
805
+	PKCS11H_ASSERT (session!=NULL);
806
+	PKCS11H_ASSERT (!(filter==NULL && filter_attrs!=0) || filter!=NULL);
807
+	PKCS11H_ASSERT (p_objects!=NULL);
808
+	PKCS11H_ASSERT (p_objects_found!=NULL);
809
+	
810
+	PKCS11H_DEBUG (
811
+		PKCS11H_LOG_DEBUG2,
812
+		"PKCS#11: _pkcs11h_findObjects entry session=%p, filter=%p, filter_attrs=%ld, p_objects=%p, p_objects_found=%p",
813
+		(void *)session,
814
+		(void *)filter,
815
+		filter_attrs,
816
+		(void *)p_objects,
817
+		(void *)p_objects_found
818
+	);
819
+
820
+	*p_objects = NULL;
821
+	*p_objects_found = 0;
822
+
823
+#if defined(ENABLE_PKCS11H_THREADING)
824
+	if (
825
+		rv == CKR_OK &&
826
+		(rv = _pkcs11h_mutexLock (&session->mutexSession)) == CKR_OK
827
+	) {
828
+		fMutexLocked = TRUE;
829
+	}
830
+#endif
831
+
832
+	if (
833
+		rv == CKR_OK &&
834
+		(rv = session->provider->f->C_FindObjectsInit (
835
+			session->hSession,
836
+			(CK_ATTRIBUTE *)filter,
837
+			filter_attrs
838
+		)) == CKR_OK
839
+	) {
840
+		fShouldFindObjectFinal = TRUE;
841
+	}
842
+
843
+	while (
844
+		rv == CKR_OK &&
845
+		(rv = session->provider->f->C_FindObjects (
846
+			session->hSession,
847
+			objects_buffer,
848
+			sizeof (objects_buffer) / sizeof (CK_OBJECT_HANDLE),
849
+			&objects_found
850
+		)) == CKR_OK &&
851
+		objects_found > 0
852
+	) { 
853
+		CK_OBJECT_HANDLE *temp = NULL;
854
+		
855
+		/*
856
+		 * Begin workaround
857
+		 *
858
+		 * Workaround iKey bug
859
+		 * It returns the same objects over and over
860
+		 */
861
+		if (oLast == objects_buffer[0]) {
862
+			PKCS11H_LOG (
863
+				PKCS11H_LOG_WARN,
864
+				"PKCS#11: Bad PKCS#11 C_FindObjects implementation detected, workaround applied"
865
+			);
866
+			break;
867
+		}
868
+		oLast = objects_buffer[0];
869
+		/* End workaround */
870
+		
871
+		if (
872
+			(rv = _pkcs11h_malloc (
873
+				(void *)&temp,
874
+				(objects_size+objects_found) * sizeof (CK_OBJECT_HANDLE)
875
+			)) == CKR_OK
876
+		) {
877
+			if (objects != NULL) {
878
+				memmove (
879
+					temp,
880
+					objects,
881
+					objects_size * sizeof (CK_OBJECT_HANDLE)
811 882
 				);
812 883
 			}
813
-		} while (rv == CKR_SLOT_ID_INVALID);
884
+			memmove (
885
+				temp + objects_size,
886
+				objects_buffer,
887
+				objects_found * sizeof (CK_OBJECT_HANDLE)
888
+			);
889
+		}
890
+
891
+		if (rv == CKR_OK) {
892
+			_pkcs11h_free ((void *)&objects);
893
+			objects = temp;
894
+			objects_size += objects_found;
895
+			temp = NULL;
896
+		}
897
+
898
+		if (temp != NULL) {
899
+			_pkcs11h_free ((void *)&temp);
900
+			temp = NULL;
901
+		}
814 902
 	}
815 903
 
904
+	if (fShouldFindObjectFinal) {
905
+		session->provider->f->C_FindObjectsFinal (
906
+			session->hSession
907
+		);
908
+		fShouldFindObjectFinal = FALSE;
909
+	}
910
+	
911
+#if defined(ENABLE_PKCS11H_THREADING)
912
+	if (fMutexLocked) {
913
+		_pkcs11h_mutexRelease (&session->mutexSession);
914
+		fMutexLocked = FALSE;
915
+	}
916
+#endif
917
+
816 918
 	if (rv == CKR_OK) {
817
-		rv = provider->f->C_GetTokenInfo (
818
-			slot,
819
-			&info
919
+		*p_objects = objects;
920
+		*p_objects_found = objects_size;
921
+		objects = NULL;
922
+		objects_size = 0;
923
+	}
924
+
925
+	if (objects != NULL) {
926
+		_pkcs11h_free ((void *)&objects);
927
+		objects = NULL;
928
+		objects_size = 0;
929
+	}
930
+
931
+	PKCS11H_DEBUG (
932
+		PKCS11H_LOG_DEBUG2,
933
+		"PKCS#11: _pkcs11h_findObjects return rv=%ld-'%s', *p_objects_found=%ld",
934
+		rv,
935
+		pkcs11h_getMessage (rv),
936
+		*p_objects_found
937
+	);
938
+
939
+	return rv;
940
+}
941
+
942
+static
943
+CK_RV
944
+_pkcs11h_getTokenId (
945
+	IN const CK_TOKEN_INFO_PTR info,
946
+	OUT pkcs11h_token_id_t * const p_token_id
947
+) {
948
+	pkcs11h_token_id_t token_id;
949
+	CK_RV rv = CKR_OK;
950
+	
951
+	PKCS11H_ASSERT (info!=NULL);
952
+	PKCS11H_ASSERT (p_token_id!=NULL);
953
+	
954
+	PKCS11H_DEBUG (
955
+		PKCS11H_LOG_DEBUG2,
956
+		"PKCS#11: _pkcs11h_getTokenId entry p_token_id=%p",
957
+		(void *)p_token_id
958
+	);
959
+
960
+	*p_token_id = NULL;
961
+
962
+	if (
963
+		rv == CKR_OK &&
964
+		(rv = _pkcs11h_newTokenId (&token_id)) == CKR_OK
965
+	) {
966
+		_pkcs11h_fixupFixedString (
967
+			token_id->label,
968
+			(char *)info->label,
969
+			sizeof (info->label)
970
+		);
971
+		_pkcs11h_fixupFixedString (
972
+			token_id->manufacturerID,
973
+			(char *)info->manufacturerID,
974
+			sizeof (info->manufacturerID)
820 975
 		);
976
+		_pkcs11h_fixupFixedString (
977
+			token_id->model,
978
+			(char *)info->model,
979
+			sizeof (info->model)
980
+		);
981
+		_pkcs11h_fixupFixedString (
982
+			token_id->serialNumber,
983
+			(char *)info->serialNumber,
984
+			sizeof (info->serialNumber)
985
+		);
986
+	}
987
+
988
+	if (rv == CKR_OK) {
989
+		*p_token_id = token_id;
990
+		token_id = NULL;
991
+	}
992
+
993
+	if (token_id != NULL) {
994
+		_pkcs11h_free ((void *)&token_id);
821 995
 	}
822 996
 
997
+	PKCS11H_DEBUG (
998
+		PKCS11H_LOG_DEBUG2,
999
+		"PKCS#11: _pkcs11h_getTokenId return rv=%ld-'%s', *p_token_id=%p",
1000
+		rv,
1001
+		pkcs11h_getMessage (rv),
1002
+		(void *)*p_token_id
1003
+	);
1004
+
1005
+	return rv;
1006
+}
1007
+
1008
+static
1009
+CK_RV
1010
+_pkcs11h_newTokenId (
1011
+	OUT pkcs11h_token_id_t * const p_token_id
1012
+) {
1013
+	CK_RV rv = CKR_OK;
1014
+
1015
+	PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
1016
+	PKCS11H_ASSERT (s_pkcs11h_data->fInitialized);
1017
+	PKCS11H_ASSERT (p_token_id!=NULL);
1018
+
1019
+	PKCS11H_DEBUG (
1020
+		PKCS11H_LOG_DEBUG2,
1021
+		"PKCS#11: _pkcs11h_newTokenId entry p_token_id=%p",
1022
+		(void *)p_token_id
1023
+	);
1024
+
1025
+	*p_token_id = NULL;
1026
+
1027
+	if (rv == CKR_OK) {
1028
+		rv = _pkcs11h_malloc ((void *)p_token_id, sizeof (struct pkcs11h_token_id_s));
1029
+	}
1030
+
1031
+	PKCS11H_DEBUG (
1032
+		PKCS11H_LOG_DEBUG2,
1033
+		"PKCS#11: _pkcs11h_newTokenId return rv=%ld-'%s', *p_token_id=%p",
1034
+		rv,
1035
+		pkcs11h_getMessage (rv),
1036
+		(void *)*p_token_id
1037
+	);
1038
+
1039
+	return rv;
1040
+}
1041
+
1042
+static
1043
+CK_RV
1044
+_pkcs11h_getSessionByTokenId (
1045
+	IN const pkcs11h_token_id_t token_id,
1046
+	OUT pkcs11h_session_t * const p_session
1047
+) {
1048
+#if defined(ENABLE_PKCS11H_THREADING)
1049
+	PKCS11H_BOOL fMutexLocked = FALSE;
1050
+#endif
1051
+	pkcs11h_session_t session = NULL;
1052
+	PKCS11H_BOOL fNewSession = FALSE;
1053
+	CK_RV rv = CKR_OK;
1054
+
1055
+	PKCS11H_ASSERT (token_id!=NULL);
1056
+	PKCS11H_ASSERT (p_session!=NULL);
1057
+
1058
+	PKCS11H_DEBUG (
1059
+		PKCS11H_LOG_DEBUG2,
1060
+		"PKCS#11: _pkcs11h_getSessionByTokenId entry token_id=%p, p_session=%p",
1061
+		(void *)token_id,
1062
+		(void *)p_session
1063
+	);
1064
+
1065
+	*p_session = NULL;
1066
+
1067
+#if defined(ENABLE_PKCS11H_THREADING)
1068
+	if (
1069
+		rv == CKR_OK &&
1070
+		(rv = _pkcs11h_mutexLock (&s_pkcs11h_data->mutexSession)) == CKR_OK
1071
+	) {
1072
+		fMutexLocked = TRUE;
1073
+	}
1074
+#endif
1075
+
823 1076
 	if (rv == CKR_OK) {
824 1077
 		pkcs11h_session_t current_session;
825 1078
 
826 1079
 		for (
827
-			current_session = pkcs11h_data->sessions, *session=NULL;
828
-			current_session != NULL && *session == NULL;
1080
+			current_session = s_pkcs11h_data->sessions;
1081
+			current_session != NULL && session == NULL;
829 1082
 			current_session = current_session->next
830 1083
 		) {
831 1084
 			if (
832
-				current_session->provider == provider &&
833
-				!memcmp (
834
-					current_session->serialNumber,
835
-					info.serialNumber,
836
-					sizeof (current_session->serialNumber)
1085
+				pkcs11h_sameTokenId (
1086
+					current_session->token_id,
1087
+					token_id
837 1088
 				)
838 1089
 			) {
839
-				*session = current_session;
1090
+				PKCS11H_DEBUG (
1091
+					PKCS11H_LOG_DEBUG1,
1092
+					"PKCS#11: Using cached session"
1093
+				);
1094
+				session = current_session;
1095
+				session->nReferenceCount++;
840 1096
 			}
841 1097
 		}
842 1098
 	}
843 1099
 
844
-	if (rv == CKR_OK) {
845
-		if (*session == NULL) {
846
-			
847
-			if (
848
-				rv == CKR_OK &&
849
-				(*session = (pkcs11h_session_t)malloc (
850
-					sizeof (struct pkcs11h_session_s)
851
-				)) == NULL
852
-			) {
853
-				rv = CKR_HOST_MEMORY;
854
-			}
1100
+	if (
1101
+		rv == CKR_OK &&
1102
+		session == NULL
1103
+	) {
1104
+		fNewSession = TRUE;
1105
+	}
855 1106
 
856
-			if (rv == CKR_OK) {
857
-				memset (*session, 0, sizeof (struct pkcs11h_session_s));
1107
+	if (fNewSession) {
1108
+		PKCS11H_DEBUG (
1109
+			PKCS11H_LOG_DEBUG1,
1110
+			"PKCS#11: Creating a new session"
1111
+		);
858 1112
 
859
-				(*session)->fValid = true;
860
-				(*session)->nReferenceCount = 1;
861
-				(*session)->fProtectedAuthentication = fProtectedAuthentication;
862
-				(*session)->hSession = PKCS11H_INVALID_SESSION_HANDLE;
863
-				
864
-				(*session)->provider = provider;
1113
+		if (
1114
+			rv == CKR_OK &&
1115
+			(rv = _pkcs11h_malloc ((void *)&session, sizeof (struct pkcs11h_session_s))) == CKR_OK
1116
+		) {
1117
+			session->nReferenceCount = 1;
1118
+			session->hSession = PKCS11H_INVALID_SESSION_HANDLE;
1119
+			
1120
+			session->nPINCachePeriod = s_pkcs11h_data->nPINCachePeriod;
865 1121
 
866
-				if (nPINCachePeriod == PKCS11H_PIN_CACHE_INFINITE) {
867
-					(*session)->nPINCachePeriod = pkcs11h_data->nPINCachePeriod;
868
-				}
869
-				else {
870
-					(*session)->nPINCachePeriod = nPINCachePeriod;
871
-				}
1122
+		}
872 1123
 
873
-				provider = NULL;
874
-				
875
-				_pkcs11h_fixupFixedString (
876
-					(char *)info.label,
877
-					(*session)->szLabel,
878
-					sizeof (info.label)
879
-				);
880
-		
881
-				memmove (
882
-					(*session)->serialNumber,
883
-					info.serialNumber,
884
-					sizeof (info.serialNumber)
885
-				);
1124
+		if (rv == CKR_OK) {
1125
+			rv = pkcs11h_duplicateTokenId (
1126
+				&session->token_id,
1127
+				token_id
1128
+			);
1129
+		}
886 1130
 
887
-				(*session)->next = pkcs11h_data->sessions;
888
-				pkcs11h_data->sessions = *session;
889
-			}
1131
+#if defined(ENABLE_PKCS11H_THREADING)
1132
+		if (rv == CKR_OK) {
1133
+			rv = _pkcs11h_mutexInit (&session->mutexSession);
1134
+		}
1135
+#endif
1136
+
1137
+		if (rv == CKR_OK) {
1138
+			session->fValid = TRUE;
1139
+			session->next = s_pkcs11h_data->sessions;
1140
+			s_pkcs11h_data->sessions = session;
890 1141
 		}
891 1142
 		else {
892
-			(*session)->nReferenceCount++;
893
-			if (nPINCachePeriod != PKCS11H_PIN_CACHE_INFINITE) {
894
-				if ((*session)->nPINCachePeriod != PKCS11H_PIN_CACHE_INFINITE) {
895
-					if ((*session)->nPINCachePeriod > nPINCachePeriod) {
896
-						(*session)->timePINExpire = (
897
-							(*session)->timePINExpire -
898
-							(time_t)(*session)->nPINCachePeriod +
899
-							(time_t)nPINCachePeriod
900
-						);
901
-						(*session)->nPINCachePeriod = nPINCachePeriod;
902
-					}
903
-				}
904
-				else {
905
-					(*session)->timePINExpire = (
906
-						PKCS11_TIME (NULL) +
907
-						(time_t)nPINCachePeriod
908
-					);
909
-					(*session)->nPINCachePeriod = nPINCachePeriod;
910
-				}
911
-				rv = _pkcs11h_validateSession (*session);
912
-			}	
1143
+#if defined(ENABLE_PKCS11H_THREADING)
1144
+			_pkcs11h_mutexFree (&session->mutexSession);
1145
+#endif
1146
+			_pkcs11h_free ((void *)&session);
913 1147
 		}
914 1148
 	}
915 1149
 
916
-	PKCS11DLOG (
917
-		PKCS11_LOG_DEBUG2,
918
-		"PKCS#11: _pkcs11h_getSession return rv=%ld-'%s'",
1150
+	if (rv == CKR_OK) {
1151
+		*p_session = session;
1152
+		session = NULL;
1153
+	}
1154
+
1155
+#if defined(ENABLE_PKCS11H_THREADING)
1156
+	if (fMutexLocked) {
1157
+		_pkcs11h_mutexRelease (&s_pkcs11h_data->mutexSession);
1158
+		fMutexLocked = FALSE;
1159
+	}
1160
+#endif
1161
+
1162
+	PKCS11H_DEBUG (
1163
+		PKCS11H_LOG_DEBUG2,
1164
+		"PKCS#11: _pkcs11h_getSessionByTokenId return rv=%ld-'%s', *p_session=%p",
919 1165
 		rv,
920
-		pkcs11h_getMessage (rv)
1166
+		pkcs11h_getMessage (rv),
1167
+		(void *)*p_session
921 1168
 	);
922 1169
 
923 1170
 	return rv;
... ...
@@ -928,114 +2880,269 @@ CK_RV
928 928
 _pkcs11h_releaseSession (
929 929
 	IN const pkcs11h_session_t session
930 930
 ) {
931
-	PKCS11ASSERT (session!=NULL);
932
-	PKCS11ASSERT (session->nReferenceCount>=0);
931
+#if defined(ENABLE_PKCS11H_THREADING)
932
+	PKCS11H_BOOL fMutexLocked = FALSE;
933
+#endif
934
+	CK_RV rv = CKR_OK;
933 935
 
934
-	PKCS11DLOG (
935
-		PKCS11_LOG_DEBUG2,
936
+	PKCS11H_ASSERT (session!=NULL);
937
+	PKCS11H_ASSERT (session->nReferenceCount>=0);
938
+
939
+	PKCS11H_DEBUG (
940
+		PKCS11H_LOG_DEBUG2,
936 941
 		"PKCS#11: _pkcs11h_releaseSession session=%p",
937 942
 		(void *)session
938 943
 	);
939 944
 
945
+#if defined(ENABLE_PKCS11H_THREADING)
946
+	if (
947
+		rv == CKR_OK &&
948
+		(rv = _pkcs11h_mutexLock (&session->mutexSession)) == CKR_OK
949
+	) {
950
+		fMutexLocked = TRUE;
951
+	}
952
+#endif
953
+
940 954
 	/*
941 955
 	 * Never logout for now
942 956
 	 */
943
-	
944
-	if (session->nReferenceCount > 0) {
945
-		session->nReferenceCount--;
957
+	if (rv == CKR_OK) {
958
+		if (session->nReferenceCount > 0) {
959
+			session->nReferenceCount--;
960
+		}
946 961
 	}
947 962
 
948
-	PKCS11DLOG (
949
-		PKCS11_LOG_DEBUG2,
950
-		"PKCS#11: _pkcs11h_releaseSession return"
963
+#if defined(ENABLE_PKCS11H_THREADING)
964
+	if (fMutexLocked) {
965
+		_pkcs11h_mutexRelease (&session->mutexSession);
966
+		fMutexLocked = FALSE;
967
+	}
968
+#endif
969
+
970
+	PKCS11H_DEBUG (
971
+		PKCS11H_LOG_DEBUG2,
972
+		"PKCS#11: _pkcs11h_releaseSession return rv=%ld-'%s'",
973
+		rv,
974
+		pkcs11h_getMessage (rv)
951 975
 	);
952 976
 
953
-	return CKR_OK;
977
+	return rv;
954 978
 }
955 979
 
956 980
 static
957 981
 CK_RV
958 982
 _pkcs11h_resetSession (
959 983
 	IN const pkcs11h_session_t session,
960
-	OUT CK_SLOT_ID * const slot
984
+	IN const unsigned maskPrompt,
985
+	OUT CK_SLOT_ID * const p_slot
961 986
 ) {
962
-	CK_SLOT_ID slots[1024];
963
-	CK_ULONG slotnum;
964
-	CK_RV rv;
965
-	bool fFound = false;
966
-	bool fCancel = false;
987
+	/*
988
+	 * This function MUST NOT touch session
989
+	 */
990
+	PKCS11H_BOOL fFound = FALSE;
991
+
992
+	CK_RV rv = CKR_OK;
967 993
 
968
-	PKCS11ASSERT (session!=NULL);
969
-	PKCS11ASSERT (slot!=NULL);
994
+	PKCS11H_ASSERT (session!=NULL);
995
+	PKCS11H_ASSERT (p_slot!=NULL);
970 996
 
971
-	PKCS11DLOG (
972
-		PKCS11_LOG_DEBUG2,
973
-		"PKCS#11: _pkcs11h_resetSession entry session=%p, slot=%p",
997
+	PKCS11H_DEBUG (
998
+		PKCS11H_LOG_DEBUG2,
999
+		"PKCS#11: _pkcs11h_resetSession entry session=%p, maskPrompt=%08x, p_slot=%p",
974 1000
 		(void *)session,
975
-		(void *)slot
1001
+		maskPrompt,
1002
+		(void *)p_slot
976 1003
 	);
977 1004
 
978
-	do {
979
-		slotnum = sizeof (slots) / sizeof (CK_SLOT_ID);
1005
+	*p_slot = PKCS11H_INVALID_SLOT_ID;
1006
+
1007
+	while (
1008
+		rv == CKR_OK &&
1009
+		!fFound
1010
+	) {
1011
+		pkcs11h_provider_t current_provider = NULL;
1012
+#if defined(ENABLE_PKCS11H_THREADING)
1013
+		PKCS11H_BOOL fMutexLocked = FALSE;
1014
+#endif
1015
+
1016
+#if defined(ENABLE_PKCS11H_THREADING)
980 1017
 		if (
981
-			(rv = session->provider->f->C_GetSlotList (
982
-				TRUE,
983
-				slots,
984
-				&slotnum
985
-			)) == CKR_OK
1018
+			rv == CKR_OK &&
1019
+			(rv = _pkcs11h_mutexLock (&session->mutexSession)) == CKR_OK
1020
+		) {
1021
+			fMutexLocked = TRUE;
1022
+		}
1023
+#endif
1024
+
1025
+		for (
1026
+			current_provider = s_pkcs11h_data->providers;
1027
+			(
1028
+				rv == CKR_OK &&
1029
+				current_provider != NULL &&
1030
+				!fFound
1031
+			);
1032
+			current_provider = current_provider->next
986 1033
 		) {
987
-			CK_SLOT_ID s;
1034
+			CK_SLOT_ID_PTR slots = NULL;
1035
+			CK_ULONG slotnum;
1036
+			CK_SLOT_ID slot_index;
1037
+
1038
+			/*
1039
+			 * Skip disabled providers
1040
+			 * Skip all other providers,
1041
+			 * if one was set in the past
1042
+			 */
1043
+			if (session->provider != NULL) {
1044
+				if (!session->provider->fEnabled) {
1045
+					continue;
1046
+				}
1047
+				if (session->provider != current_provider) {
1048
+					continue;
1049
+				}
1050
+			}
1051
+		
1052
+			if (rv == CKR_OK) {
1053
+				rv = _pkcs11h_getSlotList (
1054
+					current_provider,
1055
+					CK_TRUE,
1056
+					&slots,
1057
+					&slotnum
1058
+				);
1059
+			}
988 1060
 
989
-			for (s=0;!fFound && s<slotnum;s++) {
1061
+			for (
1062
+				slot_index=0;
1063
+				(
1064
+					slot_index < slotnum &&
1065
+					rv == CKR_OK && 
1066
+					!fFound
1067
+				);
1068
+				slot_index++
1069
+			) {
1070
+				pkcs11h_token_id_t token_id = NULL;
990 1071
 				CK_TOKEN_INFO info;
991 1072
 
992
-				if (
993
-					(rv = session->provider->f->C_GetTokenInfo (
994
-						slots[s],
1073
+				if (rv == CKR_OK) {
1074
+					rv = current_provider->f->C_GetTokenInfo (
1075
+						slots[slot_index],
995 1076
 						&info
996
-					)) == CKR_OK
1077
+					);
1078
+				}
1079
+
1080
+				if (
1081
+					rv == CKR_OK &&
1082
+					(rv = _pkcs11h_getTokenId (
1083
+						&info,
1084
+						&token_id
1085
+					)) == CKR_OK &&
1086
+					pkcs11h_sameTokenId (
1087
+						session->token_id,
1088
+						token_id
1089
+					)
997 1090
 				) {
998
-					if (
999
-						!memcmp (
1000
-							session->serialNumber,
1001
-							info.serialNumber,
1002
-							sizeof (session->serialNumber)
1003
-						)
1004
-					) {
1005
-						*slot = slots[s];
1006
-						fFound = true;
1091
+					fFound = TRUE;
1092
+					*p_slot = slots[slot_index];
1093
+					if (session->provider == NULL) {
1094
+						session->provider = current_provider;
1095
+						_pkcs11h_fixupFixedString (
1096
+							token_id->label,
1097
+							(char *)info.label,
1098
+							sizeof (info.label)
1099
+						);
1100
+						session->fProtectedAuthenticationSupported = (info.flags & CKF_PROTECTED_AUTHENTICATION_PATH) != 0;
1007 1101
 					}
1008 1102
 				}
1103
+
1104
+				if (rv != CKR_OK) {
1105
+					PKCS11H_DEBUG (
1106
+						PKCS11H_LOG_DEBUG1,
1107
+						"PKCS#11: Cannot get token information for provider '%s' slot %ld rv=%ld-'%s'",
1108
+						current_provider->manufacturerID,
1109
+						slots[slot_index],
1110
+						rv,
1111
+						pkcs11h_getMessage (rv)
1112
+					);
1113
+
1114
+					/*
1115
+					 * Ignore error
1116
+					 */
1117
+					rv = CKR_OK;
1118
+				}
1119
+
1120
+				if (token_id != NULL) {
1121
+					pkcs11h_freeTokenId (token_id);
1122
+				}
1123
+			}
1124
+
1125
+			if (rv != CKR_OK) {
1126
+				PKCS11H_DEBUG (
1127
+					PKCS11H_LOG_DEBUG1,
1128
+					"PKCS#11: Cannot get slot list for provider '%s' rv=%ld-'%s'",
1129
+					current_provider->manufacturerID,
1130
+					rv,
1131
+					pkcs11h_getMessage (rv)
1132
+				);
1133
+
1134
+				/*
1135
+				 * Ignore error
1136
+				 */
1137
+				rv = CKR_OK;
1138
+			}
1139
+
1140
+			if (slots != NULL) {
1141
+				_pkcs11h_free ((void *)&slots);
1142
+				slots = NULL;
1009 1143
 			}
1010 1144
 		}
1011 1145
 
1012
-		if (!fFound) {	
1013
-			PKCS11DLOG (
1014
-				PKCS11_LOG_DEBUG1,
1015
-				"PKCS#11: Calling card_prompt hook for %s",
1016
-				session->szLabel
1017
-			);
1018
-	
1019
-			fCancel = !pkcs11h_data->hooks->card_prompt (
1020
-				pkcs11h_data->hooks->card_prompt_data,
1021
-				session->szLabel
1022
-			);
1146
+#if defined(ENABLE_PKCS11H_THREADING)
1147
+		if (fMutexLocked) {
1148
+			_pkcs11h_mutexRelease (&session->mutexSession);
1149
+			fMutexLocked = FALSE;
1150
+		}
1151
+#endif
1023 1152
 
1024
-			PKCS11DLOG (
1025
-				PKCS11_LOG_DEBUG1,
1026
-				"PKCS#11: card_prompt returned %d",
1027
-				fCancel ? 1 : 0
1028
-			);
1153
+		if (
1154
+			rv == CKR_OK &&
1155
+			!fFound
1156
+		) {
1157
+			if ((maskPrompt & PKCS11H_PROMPT_MAST_ALLOW_CARD_PROMPT) != 0) {
1158
+				PKCS11H_DEBUG (
1159
+					PKCS11H_LOG_DEBUG1,
1160
+					"PKCS#11: Calling token_prompt hook for '%s'",
1161
+					session->token_id->label
1162
+				);
1163
+		
1164
+				if (
1165
+					!s_pkcs11h_data->hooks.token_prompt (
1166
+						s_pkcs11h_data->hooks.token_prompt_data,
1167
+						session->token_id
1168
+					)
1169
+				) {
1170
+					rv = CKR_CANCEL;
1171
+				}
1172
+
1173
+				PKCS11H_DEBUG (
1174
+					PKCS11H_LOG_DEBUG1,
1175
+					"PKCS#11: token_prompt returned %ld",
1176
+					rv
1177
+				);
1178
+			}
1179
+			else {
1180
+				rv = CKR_TOKEN_NOT_PRESENT;
1181
+			}
1029 1182
 		}
1030
-	} while (!fFound && !fCancel);
1183
+	}
1031 1184
 
1032
-	PKCS11DLOG (
1033
-		PKCS11_LOG_DEBUG2,
1034
-		"PKCS#11: _pkcs11h_resetSession return fFound=%d",
1035
-		fFound ? 1 : 0
1185
+	PKCS11H_DEBUG (
1186
+		PKCS11H_LOG_DEBUG2,
1187
+		"PKCS#11: _pkcs11h_resetSession return rv=%ld-'%s', *p_slot=%ld",
1188
+		rv,
1189
+		pkcs11h_getMessage (rv),
1190
+		*p_slot
1036 1191
 	);
1037 1192
 
1038
-	return fFound ? CKR_OK : CKR_SLOT_ID_INVALID;
1193
+	return rv;
1039 1194
 }
1040 1195
 
1041 1196
 static
... ...
@@ -1043,73 +3150,69 @@ CK_RV
1043 1043
 _pkcs11h_getObjectById (
1044 1044
 	IN const pkcs11h_session_t session,
1045 1045
 	IN const CK_OBJECT_CLASS class,
1046
-	IN const unsigned char * const id,
1046
+	IN const CK_BYTE_PTR id,
1047 1047
 	IN const size_t id_size,
1048
-	OUT CK_OBJECT_HANDLE * const handle
1048
+	OUT CK_OBJECT_HANDLE * const p_handle
1049 1049
 ) {
1050
-	CK_ULONG count;
1051
-	CK_RV rv = CKR_OK;
1052
-
1053 1050
 	CK_ATTRIBUTE filter[] = {
1054 1051
 		{CKA_CLASS, (void *)&class, sizeof (class)},
1055 1052
 		{CKA_ID, (void *)id, id_size}
1056 1053
 	};
1054
+	CK_OBJECT_HANDLE *objects = NULL;
1055
+	CK_ULONG objects_found = 0;
1056
+	CK_RV rv = CKR_OK;
1057 1057
 	
1058
-	PKCS11ASSERT (session!=NULL);
1059
-	PKCS11ASSERT (id!=NULL);
1060
-	PKCS11ASSERT (handle!=NULL);
1058
+	/*PKCS11H_ASSERT (session!=NULL); NOT NEEDED*/
1059
+	PKCS11H_ASSERT (id!=NULL);
1060
+	PKCS11H_ASSERT (p_handle!=NULL);
1061 1061
 
1062
-	PKCS11DLOG (
1063
-		PKCS11_LOG_DEBUG2,
1064
-		"PKCS#11: _pkcs11h_getObjectById entry session=%p, class=%ld, id=%p, id_size=%u, handle=%p",
1062
+	PKCS11H_DEBUG (
1063
+		PKCS11H_LOG_DEBUG2,
1064
+		"PKCS#11: _pkcs11h_getObjectById entry session=%p, class=%ld, id=%p, id_size=%u, p_handle=%p",
1065 1065
 		(void *)session,
1066 1066
 		class,
1067 1067
 		id,
1068 1068
 		id_size,
1069
-		(void *)handle
1069
+		(void *)p_handle
1070 1070
 	);
1071 1071
 
1072
-	/*
1073
-	 * Don't try invalid session
1074
-	 */
1075
-	if (
1076
-		rv == CKR_OK &&
1077
-		session->hSession == PKCS11H_INVALID_SESSION_HANDLE
1078
-	) {
1079
-		rv = CKR_SESSION_HANDLE_INVALID;
1080
-	}
1072
+	*p_handle = PKCS11H_INVALID_OBJECT_HANDLE;
1081 1073
 
1082 1074
 	if (rv == CKR_OK) {
1083
-		rv = session->provider->f->C_FindObjectsInit (
1084
-			session->hSession,
1085
-			filter,
1086
-			sizeof (filter) / sizeof (CK_ATTRIBUTE)
1087
-		);
1075
+		rv = _pkcs11h_validateSession (session);
1088 1076
 	}
1089 1077
 
1090
-	if (rv == CKR_OK) {
1091
-		rv = session->provider->f->C_FindObjects (
1092
-			session->hSession,
1093
-			handle,
1094
-			1,
1095
-			&count
1078
+	if (rv == CKR_OK) { 
1079
+		rv = _pkcs11h_findObjects (
1080
+			session,
1081
+			filter,
1082
+			sizeof (filter) / sizeof (CK_ATTRIBUTE),
1083
+			&objects,
1084
+			&objects_found
1096 1085
 		);
1097 1086
 	}
1098 1087
 
1099 1088
 	if (
1100 1089
 		rv == CKR_OK &&
1101
-		count == 0
1090
+		objects_found == 0
1102 1091
 	) {
1103 1092
 		rv = CKR_FUNCTION_REJECTED;
1104 1093
 	}
1105 1094
 
1106
-	session->provider->f->C_FindObjectsFinal (session->hSession);
1095
+	if (rv == CKR_OK) {
1096
+		*p_handle = objects[0];
1097
+	}
1098
+
1099
+	if (objects != NULL) {
1100
+		_pkcs11h_free ((void *)&objects);
1101
+	}
1107 1102
 
1108
-	PKCS11DLOG (
1109
-		PKCS11_LOG_DEBUG2,
1110
-		"PKCS#11: _pkcs11h_getObjectById return rv=%ld-'%s'",
1103
+	PKCS11H_DEBUG (
1104
+		PKCS11H_LOG_DEBUG2,
1105
+		"PKCS#11: _pkcs11h_getObjectById return rv=%ld-'%s', *p_handle=%p",
1111 1106
 		rv,
1112
-		pkcs11h_getMessage (rv)
1107
+		pkcs11h_getMessage (rv),
1108
+		(void *)*p_handle
1113 1109
 	);
1114 1110
 
1115 1111
 	return rv;
... ...
@@ -1120,43 +3223,99 @@ CK_RV
1120 1120
 _pkcs11h_validateSession (
1121 1121
 	IN const pkcs11h_session_t session
1122 1122
 ) {
1123
-	PKCS11DLOG (
1124
-		PKCS11_LOG_DEBUG2,
1123
+#if defined(ENABLE_PKCS11H_THREADING)
1124
+	PKCS11H_BOOL fMutexLocked = FALSE;
1125
+#endif
1126
+	CK_RV rv = CKR_OK;
1127
+
1128
+	/*PKCS11H_ASSERT (session!=NULL); NOT NEEDED*/
1129
+
1130
+	PKCS11H_DEBUG (
1131
+		PKCS11H_LOG_DEBUG2,
1125 1132
 		"PKCS#11: _pkcs11h_validateSession entry session=%p",
1126 1133
 		(void *)session
1127 1134
 	);
1128 1135
 
1129 1136
 	if (
1137
+		rv == CKR_OK &&
1138
+		session == NULL
1139
+	) {
1140
+		rv = CKR_SESSION_HANDLE_INVALID;
1141
+	}
1142
+
1143
+#if defined(ENABLE_PKCS11H_THREADING)
1144
+	if (
1145
+		rv == CKR_OK &&
1146
+		(rv = _pkcs11h_mutexLock (&session->mutexSession)) == CKR_OK
1147
+	) {
1148
+		fMutexLocked = TRUE;
1149
+	}
1150
+#endif
1151
+
1152
+	if (
1153
+		rv == CKR_OK &&
1154
+		(
1155
+			session->provider == NULL ||
1156
+			!session->provider->fEnabled ||
1157
+			session->hSession == PKCS11H_INVALID_SESSION_HANDLE
1158
+		)
1159
+	) {
1160
+		rv = CKR_SESSION_HANDLE_INVALID;
1161
+	}
1162
+
1163
+	if (
1164
+		rv == CKR_OK &&
1130 1165
 		session->timePINExpire != (time_t)0 &&
1131
-		session->timePINExpire < PKCS11_TIME (NULL)
1166
+		session->timePINExpire < PKCS11H_TIME (NULL)
1132 1167
 	) {
1168
+		PKCS11H_DEBUG (
1169
+			PKCS11H_LOG_DEBUG1,
1170
+			"PKCS#11: Forcing logout due to pin timeout"
1171
+		);
1133 1172
 		_pkcs11h_logout (session);
1173
+		rv = CKR_SESSION_HANDLE_INVALID;
1134 1174
 	}
1135 1175
 
1136
-	PKCS11DLOG (
1137
-		PKCS11_LOG_DEBUG2,
1138
-		"PKCS#11: _pkcs11h_validateSession return"
1176
+#if defined(ENABLE_PKCS11H_THREADING)
1177
+	if (fMutexLocked) {
1178
+		_pkcs11h_mutexRelease (&session->mutexSession);
1179
+		fMutexLocked = FALSE;
1180
+	}
1181
+#endif
1182
+
1183
+	PKCS11H_DEBUG (
1184
+		PKCS11H_LOG_DEBUG2,
1185
+		"PKCS#11: _pkcs11h_validateSession return rv=%ld-'%s'",
1186
+		rv,
1187
+		pkcs11h_getMessage (rv)
1139 1188
 	);
1140 1189
 
1141
-	return CKR_OK;
1190
+	return rv;
1142 1191
 }
1143 1192
 
1144 1193
 static
1145 1194
 CK_RV
1146 1195
 _pkcs11h_login (
1147 1196
 	IN const pkcs11h_session_t session,
1148
-	IN const bool fPublicOnly
1197
+	IN const PKCS11H_BOOL fPublicOnly,
1198
+	IN const PKCS11H_BOOL fReadOnly,
1199
+	IN const unsigned maskPrompt
1149 1200
 ) {
1201
+#if defined(ENABLE_PKCS11H_THREADING)
1202
+	PKCS11H_BOOL fMutexLocked = FALSE;
1203
+#endif
1150 1204
 	CK_SLOT_ID slot = PKCS11H_INVALID_SLOT_ID;
1151 1205
 	CK_RV rv = CKR_OK;
1152 1206
 
1153
-	PKCS11ASSERT (session!=NULL);
1207
+	PKCS11H_ASSERT (session!=NULL);
1154 1208
 
1155
-	PKCS11DLOG (
1156
-		PKCS11_LOG_DEBUG2,
1157
-		"PKCS#11: _pkcs11h_login entry session=%p, fPublicOnly=%d",
1209
+	PKCS11H_DEBUG (
1210
+		PKCS11H_LOG_DEBUG2,
1211
+		"PKCS#11: _pkcs11h_login entry session=%p, fPublicOnly=%d, fReadOnly=%d, maskPrompt=%08x",
1158 1212
 		(void *)session,
1159
-		fPublicOnly ? 1 : 0
1213
+		fPublicOnly ? 1 : 0,
1214
+		fReadOnly ? 1 : 0,
1215
+		maskPrompt
1160 1216
 	);
1161 1217
 
1162 1218
 	if (rv == CKR_OK) {
... ...
@@ -1164,104 +3323,150 @@ _pkcs11h_login (
1164 1164
 	}
1165 1165
 
1166 1166
 	if (rv == CKR_OK) {
1167
-		rv = _pkcs11h_resetSession (session, &slot);
1167
+		rv = _pkcs11h_resetSession (session, maskPrompt, &slot);
1168 1168
 	}
1169 1169
 
1170
+#if defined(ENABLE_PKCS11H_THREADING)
1171
+	if (
1172
+		rv == CKR_OK &&
1173
+		(rv = _pkcs11h_mutexLock (&session->mutexSession)) == CKR_OK
1174
+	) {
1175
+		fMutexLocked = TRUE;
1176
+	}
1177
+#endif
1178
+
1170 1179
 	if (rv == CKR_OK) {
1171 1180
 		rv = session->provider->f->C_OpenSession (
1172 1181
 			slot,
1173
-			CKF_SERIAL_SESSION,
1182
+			(
1183
+				CKF_SERIAL_SESSION |
1184
+				(fReadOnly ? 0 : CKF_RW_SESSION)
1185
+			),
1174 1186
 			NULL_PTR,
1175 1187
 			NULL_PTR,
1176 1188
 			&session->hSession
1177 1189
 		);
1178 1190
 	}
1179 1191
 
1180
-	if (rv == CKR_OK) {
1181
-		if (!fPublicOnly) {
1182
-			int nRetryCount = 0;
1183
-			do {
1184
-				CK_UTF8CHAR_PTR utfPIN = NULL;
1185
-				CK_ULONG lPINLength = 0;
1186
-				char szPIN[1024];
1192
+	if (
1193
+		rv == CKR_OK &&
1194
+	   	(
1195
+			!fPublicOnly ||
1196
+			session->provider->fCertIsPrivate
1197
+		)
1198
+	) {
1199
+		PKCS11H_BOOL fSuccessLogin = FALSE;
1200
+		int nRetryCount = 0;
1187 1201
 
1188
-				/*
1189
-				 * Assume OK for next iteration
1190
-				 */
1191
-				rv = CKR_OK;
1202
+		if ((maskPrompt & PKCS11H_PROMPT_MASK_ALLOW_PIN_PROMPT) == 0) {
1203
+			rv = CKR_USER_NOT_LOGGED_IN;
1192 1204
 
1193
-				if (
1194
-					rv == CKR_OK &&
1195
-					!session->fProtectedAuthentication
1196
-				) {
1197
-					PKCS11DLOG (
1198
-						PKCS11_LOG_DEBUG1,
1199
-						"PKCS#11: Calling pin_prompt hook for %s",
1200
-						session->szLabel
1201
-					);
1202
-	
1203
-					if (
1204
-						!pkcs11h_data->hooks->pin_prompt (
1205
-							pkcs11h_data->hooks->pin_prompt_data,
1206
-							session->szLabel,
1207
-							szPIN,
1208
-							sizeof (szPIN)
1209
-						)
1210
-					) {
1211
-						rv = CKR_FUNCTION_FAILED;
1212
-					}
1213
-					else {
1214
-						utfPIN = (CK_UTF8CHAR_PTR)szPIN;
1215
-						lPINLength = strlen (szPIN);
1216
-					}
1205
+			PKCS11H_DEBUG (
1206
+				PKCS11H_LOG_DEBUG1,
1207
+				"PKCS#11: Calling pin_prompt hook denied because of prompt mask"
1208
+			);
1209
+		}
1217 1210
 
1218
-					PKCS11DLOG (
1219
-						PKCS11_LOG_DEBUG1,
1220
-						"PKCS#11: pin_prompt hook return rv=%ld",
1221
-						rv
1222
-					);
1223
-	
1224
-				}
1211
+		while (
1212
+			rv == CKR_OK &&
1213
+			!fSuccessLogin &&
1214
+			nRetryCount++ < s_pkcs11h_data->nMaxLoginRetries 
1215
+		) {
1216
+			CK_UTF8CHAR_PTR utfPIN = NULL;
1217
+			CK_ULONG lPINLength = 0;
1218
+			char szPIN[1024];
1225 1219
 
1226
-				if (session->nPINCachePeriod == PKCS11H_PIN_CACHE_INFINITE) {
1227
-					session->timePINExpire = 0;
1220
+			if (
1221
+				rv == CKR_OK &&
1222
+				!(
1223
+					s_pkcs11h_data->fProtectedAuthentication  &&
1224
+					session->provider->fProtectedAuthentication &&
1225
+					session->fProtectedAuthenticationSupported
1226
+				)
1227
+			) {
1228
+				PKCS11H_DEBUG (
1229
+					PKCS11H_LOG_DEBUG1,
1230
+					"PKCS#11: Calling pin_prompt hook for '%s'",
1231
+					session->token_id->label
1232
+				);
1233
+
1234
+				if (
1235
+					!s_pkcs11h_data->hooks.pin_prompt (
1236
+						s_pkcs11h_data->hooks.pin_prompt_data,
1237
+						session->token_id,
1238
+						szPIN,
1239
+						sizeof (szPIN)
1240
+					)
1241
+				) {
1242
+					rv = CKR_CANCEL;
1228 1243
 				}
1229 1244
 				else {
1230
-					session->timePINExpire = (
1231
-						PKCS11_TIME (NULL) +
1232
-						(time_t)session->nPINCachePeriod
1233
-					);
1245
+					utfPIN = (CK_UTF8CHAR_PTR)szPIN;
1246
+					lPINLength = strlen (szPIN);
1234 1247
 				}
1235
-				if (
1236
-					rv == CKR_OK &&
1237
-					(rv = session->provider->f->C_Login (
1238
-						session->hSession,
1239
-						CKU_USER,
1240
-						utfPIN,
1241
-						lPINLength
1242
-					)) != CKR_OK
1243
-				) {
1244
-					if (rv == CKR_USER_ALREADY_LOGGED_IN) {
1245
-						rv = CKR_OK;
1246
-					}
1248
+
1249
+				PKCS11H_DEBUG (
1250
+					PKCS11H_LOG_DEBUG1,
1251
+					"PKCS#11: pin_prompt hook return rv=%ld",
1252
+					rv
1253
+				);
1254
+
1255
+			}
1256
+
1257
+			if (session->nPINCachePeriod == PKCS11H_PIN_CACHE_INFINITE) {
1258
+				session->timePINExpire = 0;
1259
+			}
1260
+			else {
1261
+				session->timePINExpire = (
1262
+					PKCS11H_TIME (NULL) +
1263
+					(time_t)session->nPINCachePeriod
1264
+				);
1265
+			}
1266
+
1267
+			if (
1268
+				rv == CKR_OK &&
1269
+				(rv = session->provider->f->C_Login (
1270
+					session->hSession,
1271
+					CKU_USER,
1272
+					utfPIN,
1273
+					lPINLength
1274
+				)) != CKR_OK
1275
+			) {
1276
+				if (rv == CKR_USER_ALREADY_LOGGED_IN) {
1277
+					rv = CKR_OK;
1247 1278
 				}
1279
+			}
1248 1280
 
1281
+			/*
1282
+			 * Clean PIN buffer
1283
+			 */
1284
+			memset (szPIN, 0, sizeof (szPIN));
1285
+
1286
+			if (rv == CKR_OK) {
1287
+				fSuccessLogin = TRUE;
1288
+			}
1289
+			else if (
1290
+				rv == CKR_PIN_INCORRECT ||
1291
+				rv == CKR_PIN_INVALID
1292
+			) {
1249 1293
 				/*
1250
-				 * Clean PIN buffer
1294
+				 * Ignore these errors
1295
+				 * so retry can be performed
1251 1296
 				 */
1252
-				memset (szPIN, 0, sizeof (szPIN));
1253
-			} while (
1254
-				++nRetryCount < 3 &&
1255
-				(
1256
-					rv == CKR_PIN_INCORRECT ||
1257
-					rv == CKR_PIN_INVALID
1258
-				)
1259
-			);
1297
+				rv = CKR_OK;
1298
+			}
1260 1299
 		}
1261 1300
 	}
1262 1301
 
1263
-	PKCS11DLOG (
1264
-		PKCS11_LOG_DEBUG2,
1302
+#if defined(ENABLE_PKCS11H_THREADING)
1303
+	if (fMutexLocked) {
1304
+		_pkcs11h_mutexRelease (&session->mutexSession);
1305
+		fMutexLocked = FALSE;
1306
+	}
1307
+#endif
1308
+
1309
+	PKCS11H_DEBUG (
1310
+		PKCS11H_LOG_DEBUG2,
1265 1311
 		"PKCS#11: _pkcs11h_login return rv=%ld-'%s'",
1266 1312
 		rv,
1267 1313
 		pkcs11h_getMessage (rv)
... ...
@@ -1275,22 +3480,50 @@ CK_RV
1275 1275
 _pkcs11h_logout (
1276 1276
 	IN const pkcs11h_session_t session
1277 1277
 ) {
1278
-	PKCS11ASSERT (session!=NULL);
1278
+	/*PKCS11H_ASSERT (session!=NULL); NOT NEEDED*/
1279 1279
 
1280
-	PKCS11DLOG (
1281
-		PKCS11_LOG_DEBUG2,
1280
+	PKCS11H_DEBUG (
1281
+		PKCS11H_LOG_DEBUG2,
1282 1282
 		"PKCS#11: _pkcs11h_logout entry session=%p",
1283 1283
 		(void *)session
1284 1284
 	);
1285 1285
 
1286
-	if (session->hSession != PKCS11H_INVALID_SESSION_HANDLE) {
1287
-		session->provider->f->C_Logout (session->hSession);
1288
-		session->provider->f->C_CloseSession (session->hSession);
1289
-		session->hSession = PKCS11H_INVALID_SESSION_HANDLE;
1286
+	if (
1287
+		session != NULL &&
1288
+		session->hSession != PKCS11H_INVALID_SESSION_HANDLE
1289
+	) {
1290
+#if defined(ENABLE_PKCS11H_THREADING)
1291
+		PKCS11H_BOOL fMutexLocked = FALSE;
1292
+#endif
1293
+		CK_RV rv = CKR_OK;
1294
+
1295
+#if defined(ENABLE_PKCS11H_THREADING)
1296
+		if (
1297
+			rv == CKR_OK &&
1298
+			(rv = _pkcs11h_mutexLock (&session->mutexSession)) == CKR_OK
1299
+		) {
1300
+			fMutexLocked = TRUE;
1301
+		}
1302
+#endif
1303
+
1304
+		if (rv == CKR_OK) {
1305
+			if (session->provider != NULL) {
1306
+				session->provider->f->C_Logout (session->hSession);
1307
+				session->provider->f->C_CloseSession (session->hSession);
1308
+			}
1309
+			session->hSession = PKCS11H_INVALID_SESSION_HANDLE;
1310
+		}
1311
+
1312
+#if defined(ENABLE_PKCS11H_THREADING)
1313
+		if (fMutexLocked) {
1314
+			_pkcs11h_mutexRelease (&session->mutexSession);
1315
+			fMutexLocked = FALSE;
1316
+		}
1317
+#endif
1290 1318
 	}
1291 1319
 
1292
-	PKCS11DLOG (
1293
-		PKCS11_LOG_DEBUG2,
1320
+	PKCS11H_DEBUG (
1321
+		PKCS11H_LOG_DEBUG2,
1294 1322
 		"PKCS#11: _pkcs11h_logout return"
1295 1323
 	);
1296 1324
 
... ...
@@ -1298,234 +3531,1127 @@ _pkcs11h_logout (
1298 1298
 }
1299 1299
 
1300 1300
 static
1301
+void
1302
+_pkcs11h_hooks_default_log (
1303
+	IN const void * pData,
1304
+	IN const unsigned flags,
1305
+	IN const char * const szFormat,
1306
+	IN va_list args
1307
+) {
1308
+	(void)pData;
1309
+	(void)flags;
1310
+	(void)szFormat;
1311
+	(void)args;
1312
+}
1313
+
1314
+static
1315
+PKCS11H_BOOL
1316
+_pkcs11h_hooks_default_token_prompt (
1317
+	IN const void * pData,
1318
+	IN const pkcs11h_token_id_t token
1319
+) {
1320
+	PKCS11H_ASSERT (token!=NULL);
1321
+
1322
+	(void)pData;
1323
+
1324
+	PKCS11H_DEBUG (
1325
+		PKCS11H_LOG_DEBUG2,
1326
+		"PKCS#11: _pkcs11h_hooks_default_token_prompt pData=%p, szLabel='%s'",
1327
+		pData,
1328
+		token->label
1329
+	);
1330
+
1331
+	return FALSE;
1332
+}
1333
+
1334
+static
1335
+PKCS11H_BOOL
1336
+_pkcs11h_hooks_default_pin_prompt (
1337
+	IN const void * pData,
1338
+	IN const pkcs11h_token_id_t token,
1339
+	OUT char * const szPIN,
1340
+	IN const size_t nMaxPIN
1341
+) {
1342
+	PKCS11H_ASSERT (token!=NULL);
1343
+
1344
+	(void)pData;
1345
+	(void)szPIN;
1346
+	(void)nMaxPIN;
1347
+
1348
+	PKCS11H_DEBUG (
1349
+		PKCS11H_LOG_DEBUG2,
1350
+		"PKCS#11: _pkcs11h_hooks_default_pin_prompt pData=%p, szLabel='%s'",
1351
+		pData,
1352
+		token->label
1353
+	);
1354
+	
1355
+	return FALSE;
1356
+}
1357
+
1358
+#if !defined(WIN32)
1359
+#if defined(ENABLE_PKCS11H_THREADING)
1360
+
1361
+static
1362
+void
1363
+__pkcs11h_atfork_prepare  () {
1364
+	__pkcs1h_mutexLockAll ();
1365
+}
1366
+static
1367
+void
1368
+__pkcs11h_atfork_parent () {
1369
+	__pkcs1h_mutexReleaseAll ();
1370
+}
1371
+static
1372
+void
1373
+__pkcs11h_atfork_child () {
1374
+	__pkcs1h_mutexReleaseAll ();
1375
+	_pkcs11h_forkFixup ();
1376
+}
1377
+
1378
+#endif				/* ENABLE_PKCS11H_THREADING */
1379
+
1380
+static
1301 1381
 CK_RV
1302
-_pkcs11h_setCertificateSession_Certificate (
1303
-	IN const pkcs11h_certificate_t pkcs11h_certificate,
1304
-	IN const char * const szIdType,
1305
-	IN const char * const szId
1382
+_pkcs11h_forkFixup () {
1383
+#if defined(ENABLE_PKCS11H_THREADING)
1384
+	PKCS11H_BOOL fMutexLocked = FALSE;
1385
+#endif
1386
+	pid_t mypid = getpid ();
1387
+
1388
+	PKCS11H_DEBUG (
1389
+		PKCS11H_LOG_DEBUG2,
1390
+		"PKCS#11: pkcs11h_forkFixup entry pid=%d",
1391
+		mypid
1392
+	);
1393
+
1394
+	if (s_pkcs11h_data != NULL && s_pkcs11h_data->fInitialized) {
1395
+		pkcs11h_provider_t current;
1396
+
1397
+#if defined(ENABLE_PKCS11H_THREADING)
1398
+		if (_pkcs11h_mutexLock (&s_pkcs11h_data->mutexGlobal) == CKR_OK) {
1399
+			fMutexLocked = TRUE;
1400
+		}
1401
+#endif
1402
+
1403
+		for (
1404
+			current = s_pkcs11h_data->providers;
1405
+			current != NULL;
1406
+			current = current->next
1407
+		) {
1408
+			if (current->fEnabled) {
1409
+				current->f->C_Initialize (NULL);
1410
+			}
1411
+
1412
+#if defined(ENABLE_PKCS11H_SLOTEVENT)
1413
+			/*
1414
+			 * After fork we have no threads...
1415
+			 * So just initialized.
1416
+			 */
1417
+			if (s_pkcs11h_data->fSlotEventInitialized) {
1418
+				s_pkcs11h_data->fSlotEventInitialized = FALSE;
1419
+				_pkcs11h_slotevent_init ();
1420
+			}
1421
+#endif
1422
+		}
1423
+	}
1424
+
1425
+#if defined(ENABLE_PKCS11H_THREADING)
1426
+	if (fMutexLocked) {
1427
+		_pkcs11h_mutexRelease (&s_pkcs11h_data->mutexGlobal);
1428
+		fMutexLocked = FALSE;
1429
+	}
1430
+#endif
1431
+
1432
+	PKCS11H_DEBUG (
1433
+		PKCS11H_LOG_DEBUG2,
1434
+		"PKCS#11: pkcs11h_forkFixup return"
1435
+	);
1436
+
1437
+	return CKR_OK;
1438
+}
1439
+
1440
+#endif				/* !WIN32 */
1441
+
1442
+#if defined(ENABLE_PKCS11H_TOKEN)
1443
+/*======================================================================*
1444
+ * TOKEN INTERFACE
1445
+ *======================================================================*/
1446
+
1447
+CK_RV
1448
+pkcs11h_token_ensureAccess (
1449
+	IN const pkcs11h_token_id_t token_id,
1450
+	IN const unsigned maskPrompt
1306 1451
 ) {
1452
+	pkcs11h_session_t session = NULL;
1307 1453
 	CK_RV rv = CKR_OK;
1308 1454
 
1309
-	unsigned char selected_id[PKCS11H_MAX_ATTRIBUTE_SIZE];
1310
-	int selected_id_size = 0;
1311
-	unsigned char selected_certificate[PKCS11H_MAX_ATTRIBUTE_SIZE];
1312
-	int selected_certificate_size = 0;
1455
+	PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
1456
+	PKCS11H_ASSERT (s_pkcs11h_data->fInitialized);
1457
+	PKCS11H_ASSERT (token_id!=NULL);
1313 1458
 
1314
-	CK_OBJECT_CLASS cert_filter_class = CKO_CERTIFICATE;
1315
-	unsigned char cert_filter_by[PKCS11H_MAX_ATTRIBUTE_SIZE];
1316
-	CK_ATTRIBUTE cert_filter[] = {
1317
-		{CKA_CLASS, &cert_filter_class, sizeof (cert_filter_class)},
1318
-		{0, cert_filter_by, 0}
1459
+	PKCS11H_DEBUG (
1460
+		PKCS11H_LOG_DEBUG2,
1461
+		"PKCS#11: pkcs11h_token_ensureAccess entry token_id=%p, maskPrompt=%08x",
1462
+		(void *)token_id,
1463
+		maskPrompt
1464
+	);
1465
+
1466
+	if (rv == CKR_OK) {
1467
+		rv = _pkcs11h_getSessionByTokenId (
1468
+			token_id,
1469
+			&session
1470
+		);
1471
+	}
1472
+
1473
+	if (rv == CKR_OK) {
1474
+		CK_SLOT_ID slot;
1475
+
1476
+		rv = _pkcs11h_resetSession (
1477
+			session,
1478
+			maskPrompt,
1479
+			&slot
1480
+		);
1481
+	}
1482
+
1483
+	if (session != NULL) {
1484
+		_pkcs11h_releaseSession (session);
1485
+		session = NULL;
1486
+	}
1487
+
1488
+	PKCS11H_DEBUG (
1489
+		PKCS11H_LOG_DEBUG2,
1490
+		"PKCS#11: pkcs11h_token_ensureAccess return rv=%ld-'%s'",
1491
+		rv,
1492
+		pkcs11h_getMessage (rv)
1493
+	);
1494
+
1495
+	return rv;
1496
+}
1497
+
1498
+#endif				/* ENABLE_PKCS11H_TOKEN */
1499
+
1500
+#if defined(ENABLE_PKCS11H_DATA)
1501
+/*======================================================================*
1502
+ * DATA INTERFACE
1503
+ *======================================================================*/
1504
+
1505
+static
1506
+CK_RV
1507
+_pkcs11h_data_getObject (
1508
+	IN const pkcs11h_session_t session,
1509
+	IN const char * const szApplication,
1510
+	IN const char * const szLabel,
1511
+	OUT CK_OBJECT_HANDLE * const p_handle
1512
+) {
1513
+	CK_OBJECT_CLASS class = CKO_DATA;
1514
+	CK_ATTRIBUTE filter[] = {
1515
+		{CKA_CLASS, (void *)&class, sizeof (class)},
1516
+		{CKA_APPLICATION, (void *)szApplication, szApplication == NULL ? 0 : strlen (szApplication)},
1517
+		{CKA_LABEL, (void *)szLabel, szLabel == NULL ? 0 : strlen (szLabel)}
1319 1518
 	};
1320
-	int cert_filter_num = 1;
1519
+	CK_OBJECT_HANDLE *objects = NULL;
1520
+	CK_ULONG objects_found = 0;
1521
+	CK_RV rv = CKR_OK;
1522
+	
1523
+	/*PKCS11H_ASSERT (session!=NULL); NOT NEEDED*/
1524
+	PKCS11H_ASSERT (szApplication!=NULL);
1525
+	PKCS11H_ASSERT (szLabel!=NULL);
1321 1526
 
1322
-	PKCS11ASSERT (pkcs11h_certificate!=NULL);
1323
-	PKCS11ASSERT (szIdType!=NULL);
1324
-	PKCS11ASSERT (szId!=NULL);
1527
+	PKCS11H_DEBUG (
1528
+		PKCS11H_LOG_DEBUG2,
1529
+		"PKCS#11: _pkcs11h_data_getObject entry session=%p, szApplication='%s', szLabel='%s', p_handle=%p",
1530
+		(void *)session,
1531
+		szApplication,
1532
+		szLabel,
1533
+		(void *)p_handle
1534
+	);
1325 1535
 
1326
-	PKCS11DLOG (
1327
-		PKCS11_LOG_DEBUG2,
1328
-		"PKCS#11: _pkcs11h_setCertificateSession_Certificate entry pkcs11h_certificate=%p, szIdType=%s, szId=%s",
1329
-		(void *)pkcs11h_certificate,
1330
-		szIdType,
1331
-		szId
1536
+	*p_handle = PKCS11H_INVALID_OBJECT_HANDLE;
1537
+
1538
+	if (rv == CKR_OK) {
1539
+		rv = _pkcs11h_validateSession (session);
1540
+	}
1541
+
1542
+	if (rv == CKR_OK) {
1543
+		rv = _pkcs11h_findObjects (
1544
+			session,
1545
+			filter,
1546
+			sizeof (filter) / sizeof (CK_ATTRIBUTE),
1547
+			&objects,
1548
+			&objects_found
1549
+		);
1550
+	}
1551
+
1552
+	if (
1553
+		rv == CKR_OK &&
1554
+		objects_found == 0
1555
+	) {
1556
+		rv = CKR_FUNCTION_REJECTED;
1557
+	}
1558
+
1559
+	if (rv == CKR_OK) {
1560
+		*p_handle = objects[0];
1561
+	}
1562
+
1563
+	if (objects != NULL) {
1564
+		_pkcs11h_free ((void *)&objects);
1565
+	}
1566
+
1567
+	PKCS11H_DEBUG (
1568
+		PKCS11H_LOG_DEBUG2,
1569
+		"PKCS#11: _pkcs11h_data_getObject return rv=%ld-'%s', *p_handle=%p",
1570
+		rv,
1571
+		pkcs11h_getMessage (rv),
1572
+		(void *)*p_handle
1573
+	);
1574
+
1575
+	return rv;
1576
+}
1577
+
1578
+CK_RV
1579
+pkcs11h_data_get (
1580
+	IN const pkcs11h_token_id_t token_id,
1581
+	IN const PKCS11H_BOOL fPublic,
1582
+	IN const char * const szApplication,
1583
+	IN const char * const szLabel,
1584
+	OUT char * const blob,
1585
+	IN OUT size_t * const p_blob_size
1586
+) {
1587
+	CK_ATTRIBUTE attrs[] = {
1588
+		{CKA_VALUE, NULL, 0}
1589
+	};
1590
+	CK_OBJECT_HANDLE handle = PKCS11H_INVALID_OBJECT_HANDLE;
1591
+	CK_RV rv = CKR_OK;
1592
+
1593
+	pkcs11h_session_t session = NULL;
1594
+	size_t blob_size_max;
1595
+	PKCS11H_BOOL fOpSuccess = FALSE;
1596
+	PKCS11H_BOOL fLoginRetry = FALSE;
1597
+	PKCS11H_BOOL fMutexLocked = FALSE;
1598
+
1599
+	PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
1600
+	PKCS11H_ASSERT (s_pkcs11h_data->fInitialized);
1601
+	PKCS11H_ASSERT (token_id!=NULL);
1602
+	PKCS11H_ASSERT (szApplication!=NULL);
1603
+	PKCS11H_ASSERT (szLabel!=NULL);
1604
+	/*PKCS11H_ASSERT (blob!=NULL); NOT NEEDED*/
1605
+	PKCS11H_ASSERT (p_blob_size!=NULL);
1606
+
1607
+	PKCS11H_DEBUG (
1608
+		PKCS11H_LOG_DEBUG2,
1609
+		"PKCS#11: pkcs11h_data_get entry token_id=%p, szApplication='%s', szLabel='%s', blob=%p, p_blob_size=%p",
1610
+		(void *)token_id,
1611
+		szApplication,
1612
+		szLabel,
1613
+		blob,
1614
+		(void *)p_blob_size
1332 1615
 	);
1333 1616
 
1617
+	blob_size_max = *p_blob_size;
1618
+	*p_blob_size = 0;
1619
+
1334 1620
 	if (rv == CKR_OK) {
1335
-		if (!strcmp (szIdType, "label")) {
1336
-			cert_filter[1].type = CKA_LABEL;
1337
-			cert_filter[1].ulValueLen = (CK_ULONG)(
1338
-				strlen (szId) < sizeof (cert_filter_by)  ?
1339
-				strlen (szId) :
1340
-				sizeof (cert_filter_by)
1341
-			);
1342
-			memmove (
1343
-				cert_filter_by,
1344
-				szId,
1345
-				cert_filter[1].ulValueLen
1621
+		rv = _pkcs11h_getSessionByTokenId (
1622
+			token_id,
1623
+			&session
1624
+		);
1625
+	}
1626
+
1627
+	while (rv == CKR_OK && !fOpSuccess) {
1628
+
1629
+		if (rv == CKR_OK) {
1630
+			rv = _pkcs11h_validateSession (session);
1631
+		}
1632
+
1633
+#if defined(ENABLE_PKCS11H_THREADING)
1634
+		if (
1635
+			rv == CKR_OK &&
1636
+			(rv = _pkcs11h_mutexLock (&session->mutexSession)) == CKR_OK
1637
+		) {
1638
+			fMutexLocked = TRUE;
1639
+		}
1640
+#endif
1641
+
1642
+		if (rv == CKR_OK) {
1643
+			rv = _pkcs11h_data_getObject (
1644
+				session,
1645
+				szApplication,
1646
+				szLabel,
1647
+				&handle
1346 1648
 			);
1347
-			cert_filter_num++;
1348 1649
 		}
1349
-		else if (!strcmp (szIdType, "id")) {
1350
-			size_t s = sizeof (cert_filter_by);
1351
-	
1352
-			cert_filter[1].type = CKA_ID;
1353
-			_hexToBinary (
1354
-				szId,
1355
-				cert_filter_by,
1356
-				&s
1650
+
1651
+		if (rv == CKR_OK) {
1652
+			rv = _pkcs11h_getObjectAttributes (
1653
+				session,
1654
+				handle,
1655
+				attrs,
1656
+				sizeof (attrs)/sizeof (CK_ATTRIBUTE)
1357 1657
 			);
1358
-			cert_filter[1].ulValueLen = s;
1359
-			cert_filter_num++;
1360 1658
 		}
1361
-		else if (!strcmp (szIdType, "subject")) {
1362
-			memmove (&cert_filter[1], &cert_filter[0], sizeof (CK_ATTRIBUTE));
1659
+
1660
+#if defined(ENABLE_PKCS11H_THREADING)
1661
+		if (fMutexLocked) {
1662
+			_pkcs11h_mutexRelease (&session->mutexSession);
1663
+			fMutexLocked = FALSE;
1664
+		}
1665
+#endif
1666
+
1667
+		if (rv == CKR_OK) {
1668
+			fOpSuccess = TRUE;
1363 1669
 		}
1364 1670
 		else {
1365
-			rv = CKR_ARGUMENTS_BAD;
1671
+			if (!fLoginRetry) {
1672
+				PKCS11H_DEBUG (
1673
+					PKCS11H_LOG_DEBUG1,
1674
+					"PKCS#11: Read data object failed rv=%ld-'%s'",
1675
+					rv,
1676
+					pkcs11h_getMessage (rv)
1677
+				);
1678
+				fLoginRetry = TRUE;
1679
+				rv = _pkcs11h_login (
1680
+					session,
1681
+					fPublic,
1682
+					TRUE,
1683
+					(
1684
+						PKCS11H_PROMPT_MASK_ALLOW_PIN_PROMPT |
1685
+						PKCS11H_PROMPT_MAST_ALLOW_CARD_PROMPT 
1686
+					)
1687
+				);
1688
+			}
1366 1689
 		}
1367 1690
 	}
1368
-	
1691
+
1369 1692
 	if (rv == CKR_OK) {
1370
-		rv = pkcs11h_certificate->session->provider->f->C_FindObjectsInit (
1371
-			pkcs11h_certificate->session->hSession,
1372
-			cert_filter,
1373
-			cert_filter_num
1693
+		*p_blob_size = attrs[0].ulValueLen;
1694
+	}
1695
+
1696
+	if (rv == CKR_OK) {
1697
+		if (blob != NULL) {
1698
+			if (*p_blob_size > blob_size_max) {
1699
+				rv = CKR_BUFFER_TOO_SMALL;
1700
+			}
1701
+			else {
1702
+				memmove (blob, attrs[0].pValue, *p_blob_size);
1703
+			}
1704
+		}
1705
+	}
1706
+
1707
+	_pkcs11h_freeObjectAttributes (
1708
+		attrs,
1709
+		sizeof (attrs)/sizeof (CK_ATTRIBUTE)
1710
+	);
1711
+
1712
+	if (session != NULL) {
1713
+		_pkcs11h_releaseSession (session);
1714
+		session = NULL;
1715
+	}
1716
+
1717
+	PKCS11H_DEBUG (
1718
+		PKCS11H_LOG_DEBUG2,
1719
+		"PKCS#11: pkcs11h_data_get return rv=%ld-'%s', *p_blob_size=%d",
1720
+		rv,
1721
+		pkcs11h_getMessage (rv),
1722
+		*p_blob_size
1723
+	);
1724
+
1725
+	return rv;
1726
+}
1727
+
1728
+CK_RV
1729
+pkcs11h_data_put (
1730
+	IN const pkcs11h_token_id_t token_id,
1731
+	IN const PKCS11H_BOOL fPublic,
1732
+	IN const char * const szApplication,
1733
+	IN const char * const szLabel,
1734
+	OUT char * const blob,
1735
+	IN const size_t blob_size
1736
+) {
1737
+	CK_OBJECT_CLASS class = CKO_DATA;
1738
+	CK_BBOOL ck_true = CK_TRUE;
1739
+	CK_BBOOL ck_false = CK_FALSE;
1740
+
1741
+	CK_ATTRIBUTE attrs[] = {
1742
+		{CKA_CLASS, &class, sizeof (class)},
1743
+		{CKA_TOKEN, &ck_true, sizeof (ck_true)},
1744
+		{CKA_PRIVATE, fPublic ? &ck_false : &ck_true, sizeof (CK_BBOOL)},
1745
+		{CKA_APPLICATION, (void *)szApplication, strlen (szApplication)},
1746
+		{CKA_LABEL, (void *)szLabel, strlen (szLabel)},
1747
+		{CKA_VALUE, blob, blob_size}
1748
+	};
1749
+
1750
+	CK_OBJECT_HANDLE handle = PKCS11H_INVALID_OBJECT_HANDLE;
1751
+	CK_RV rv = CKR_OK;
1752
+
1753
+	pkcs11h_session_t session = NULL;
1754
+	PKCS11H_BOOL fOpSuccess = FALSE;
1755
+	PKCS11H_BOOL fLoginRetry = FALSE;
1756
+	PKCS11H_BOOL fMutexLocked = FALSE;
1757
+
1758
+	PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
1759
+	PKCS11H_ASSERT (s_pkcs11h_data->fInitialized);
1760
+	PKCS11H_ASSERT (token_id!=NULL);
1761
+	PKCS11H_ASSERT (szApplication!=NULL);
1762
+	PKCS11H_ASSERT (szLabel!=NULL);
1763
+	PKCS11H_ASSERT (blob!=NULL);
1764
+
1765
+	PKCS11H_DEBUG (
1766
+		PKCS11H_LOG_DEBUG2,
1767
+		"PKCS#11: pkcs11h_data_put entry token_id=%p, szApplication='%s', szLabel='%s', blob=%p, blob_size=%d",
1768
+		(void *)token_id,
1769
+		szApplication,
1770
+		szLabel,
1771
+		blob,
1772
+		blob_size
1773
+	);
1774
+
1775
+	if (rv == CKR_OK) {
1776
+		rv = _pkcs11h_getSessionByTokenId (
1777
+			token_id,
1778
+			&session
1374 1779
 		);
1375 1780
 	}
1376 1781
 
1782
+	while (rv == CKR_OK && !fOpSuccess) {
1783
+
1784
+		if (rv == CKR_OK) {
1785
+			rv = _pkcs11h_validateSession (session);
1786
+		}
1787
+
1788
+#if defined(ENABLE_PKCS11H_THREADING)
1789
+		if (
1790
+			rv == CKR_OK &&
1791
+			(rv = _pkcs11h_mutexLock (&session->mutexSession)) == CKR_OK
1792
+		) {
1793
+			fMutexLocked = TRUE;
1794
+		}
1795
+#endif
1796
+
1797
+		if (rv == CKR_OK) {
1798
+			rv = session->provider->f->C_CreateObject (
1799
+				session->hSession,
1800
+				attrs,
1801
+				sizeof (attrs)/sizeof (CK_ATTRIBUTE),
1802
+				&handle
1803
+			);
1804
+		}
1805
+
1806
+#if defined(ENABLE_PKCS11H_THREADING)
1807
+		if (fMutexLocked) {
1808
+			_pkcs11h_mutexRelease (&session->mutexSession);
1809
+			fMutexLocked = FALSE;
1810
+		}
1811
+#endif
1812
+
1813
+		if (rv == CKR_OK) {
1814
+			fOpSuccess = TRUE;
1815
+		}
1816
+		else {
1817
+			if (!fLoginRetry) {
1818
+				PKCS11H_DEBUG (
1819
+					PKCS11H_LOG_DEBUG1,
1820
+					"PKCS#11: Write data object failed rv=%ld-'%s'",
1821
+					rv,
1822
+					pkcs11h_getMessage (rv)
1823
+				);
1824
+				fLoginRetry = TRUE;
1825
+				rv = _pkcs11h_login (
1826
+					session,
1827
+					fPublic,
1828
+					FALSE,
1829
+					(
1830
+						PKCS11H_PROMPT_MASK_ALLOW_PIN_PROMPT |
1831
+						PKCS11H_PROMPT_MAST_ALLOW_CARD_PROMPT 
1832
+					)
1833
+				);
1834
+			}
1835
+		}
1836
+	}
1837
+
1838
+	if (session != NULL) {
1839
+		_pkcs11h_releaseSession (session);
1840
+		session = NULL;
1841
+	}
1842
+
1843
+	PKCS11H_DEBUG (
1844
+		PKCS11H_LOG_DEBUG2,
1845
+		"PKCS#11: pkcs11h_data_put return rv=%ld-'%s'",
1846
+		rv,
1847
+		pkcs11h_getMessage (rv)
1848
+	);
1849
+
1850
+	return rv;
1851
+}
1852
+
1853
+CK_RV
1854
+pkcs11h_data_del (
1855
+	IN const pkcs11h_token_id_t token_id,
1856
+	IN const PKCS11H_BOOL fPublic,
1857
+	IN const char * const szApplication,
1858
+	IN const char * const szLabel
1859
+) {
1860
+	CK_OBJECT_HANDLE handle = PKCS11H_INVALID_OBJECT_HANDLE;
1861
+	CK_RV rv = CKR_OK;
1862
+
1863
+	pkcs11h_session_t session = NULL;
1864
+	PKCS11H_BOOL fOpSuccess = FALSE;
1865
+	PKCS11H_BOOL fLoginRetry = FALSE;
1866
+	PKCS11H_BOOL fMutexLocked = FALSE;
1867
+
1868
+	PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
1869
+	PKCS11H_ASSERT (s_pkcs11h_data->fInitialized);
1870
+	PKCS11H_ASSERT (token_id!=NULL);
1871
+	PKCS11H_ASSERT (szApplication!=NULL);
1872
+	PKCS11H_ASSERT (szLabel!=NULL);
1873
+
1874
+	PKCS11H_DEBUG (
1875
+		PKCS11H_LOG_DEBUG2,
1876
+		"PKCS#11: pkcs11h_data_del entry token_id=%p, szApplication='%s', szLabel='%s'",
1877
+		(void *)token_id,
1878
+		szApplication,
1879
+		szLabel
1880
+	);
1881
+
1377 1882
 	if (rv == CKR_OK) {
1378
-		CK_OBJECT_HANDLE objects[10];
1379
-		CK_ULONG objects_found;
1380
-		CK_OBJECT_HANDLE oLast = PKCS11H_INVALID_OBJECT_HANDLE;
1883
+		rv = _pkcs11h_getSessionByTokenId (
1884
+			token_id,
1885
+			&session
1886
+		);
1887
+	}
1381 1888
 
1382
-		while (
1383
-			(rv = pkcs11h_certificate->session->provider->f->C_FindObjects (
1384
-				pkcs11h_certificate->session->hSession,
1385
-				objects,
1386
-				sizeof (objects) / sizeof (CK_OBJECT_HANDLE),
1387
-				&objects_found
1388
-			)) == CKR_OK &&
1389
-			objects_found > 0
1390
-		) { 
1391
-			CK_ULONG i;
1889
+	while (rv == CKR_OK && !fOpSuccess) {
1392 1890
 
1393
-			/*
1394
-			 * Begin workaround
1395
-			 *
1396
-			 * Workaround iKey bug
1397
-			 * It returns the same objects over and over
1398
-			 */
1399
-			if (oLast == objects[0]) {
1400
-				PKCS11LOG (
1401
-					PKCS11_LOG_WARN,
1402
-					"PKCS#11: Bad PKCS#11 C_FindObjects implementation detected, workaround applied"
1891
+		if (rv == CKR_OK) {
1892
+			rv = _pkcs11h_validateSession (session);
1893
+		}
1894
+
1895
+		if (rv == CKR_OK) {
1896
+			rv = _pkcs11h_data_getObject (
1897
+				session,
1898
+				szApplication,
1899
+				szLabel,
1900
+				&handle
1901
+			);
1902
+		}
1903
+
1904
+#if defined(ENABLE_PKCS11H_THREADING)
1905
+		if (
1906
+			rv == CKR_OK &&
1907
+			(rv = _pkcs11h_mutexLock (&session->mutexSession)) == CKR_OK
1908
+		) {
1909
+			fMutexLocked = TRUE;
1910
+		}
1911
+#endif
1912
+
1913
+		if (rv == CKR_OK) {
1914
+			rv = session->provider->f->C_DestroyObject (
1915
+				session->hSession,
1916
+				handle
1917
+			);
1918
+		}
1919
+
1920
+#if defined(ENABLE_PKCS11H_THREADING)
1921
+		if (fMutexLocked) {
1922
+			_pkcs11h_mutexRelease (&session->mutexSession);
1923
+			fMutexLocked = FALSE;
1924
+		}
1925
+#endif
1926
+
1927
+		if (rv == CKR_OK) {
1928
+			fOpSuccess = TRUE;
1929
+		}
1930
+		else {
1931
+			if (!fLoginRetry) {
1932
+				PKCS11H_DEBUG (
1933
+					PKCS11H_LOG_DEBUG1,
1934
+					"PKCS#11: Remove data object failed rv=%ld-'%s'",
1935
+					rv,
1936
+					pkcs11h_getMessage (rv)
1937
+				);
1938
+				fLoginRetry = TRUE;
1939
+				rv = _pkcs11h_login (
1940
+					session,
1941
+					fPublic,
1942
+					FALSE,
1943
+					(
1944
+						PKCS11H_PROMPT_MASK_ALLOW_PIN_PROMPT |
1945
+						PKCS11H_PROMPT_MAST_ALLOW_CARD_PROMPT 
1946
+					)
1403 1947
 				);
1404
-				break;
1405 1948
 			}
1406
-			oLast = objects[0];
1407
-			/* End workaround */
1408
-			
1409
-			for (i=0;i<objects_found;i++) {
1410
-				unsigned char attrs_id[PKCS11H_MAX_ATTRIBUTE_SIZE];
1411
-				unsigned char attrs_value[PKCS11H_MAX_ATTRIBUTE_SIZE];
1412
-				CK_ATTRIBUTE attrs[] = {
1413
-					{CKA_ID, attrs_id, sizeof (attrs_id)},
1414
-					{CKA_VALUE, attrs_value, sizeof (attrs_value)}
1415
-				};
1416
-		
1417
-				if (
1418
-					pkcs11h_certificate->session->provider->f->C_GetAttributeValue (
1419
-						pkcs11h_certificate->session->hSession,
1420
-						objects[i],
1421
-						attrs,
1422
-						sizeof (attrs) / sizeof (CK_ATTRIBUTE)
1423
-					) == CKR_OK
1424
-				) {
1425
-					bool fSelected = false;
1426
-	
1427
-					if (!strcmp (szIdType, "subject")) {
1428
-						X509 *x509 = NULL;
1429
-						char szSubject[1024];
1430
-						pkcs11_openssl_d2i_t d2i1;
1431
-	
1432
-						x509 = X509_new ();
1433
-	
1434
-						d2i1 = (pkcs11_openssl_d2i_t)attrs_value;
1435
-						if (d2i_X509 (&x509, &d2i1, attrs[1].ulValueLen)) {
1436
-							X509_NAME_oneline (
1437
-								X509_get_subject_name (x509),
1438
-								szSubject,
1439
-								sizeof (szSubject)
1440
-							);
1441
-							szSubject[sizeof (szSubject) - 1] = '\0';
1442
-						}
1443
-	
1444
-						if (x509 != NULL) {
1445
-							X509_free (x509);
1446
-							x509 = NULL;
1447
-						}
1949
+		}
1950
+	}
1951
+
1952
+	if (session != NULL) {
1953
+		_pkcs11h_releaseSession (session);
1954
+		session = NULL;
1955
+	}
1956
+
1957
+	PKCS11H_DEBUG (
1958
+		PKCS11H_LOG_DEBUG2,
1959
+		"PKCS#11: pkcs11h_data_del return rv=%ld-'%s'",
1960
+		rv,
1961
+		pkcs11h_getMessage (rv)
1962
+	);
1963
+
1964
+	return rv;
1965
+}
1966
+
1967
+#endif				/* ENABLE_PKCS11H_DATA */
1968
+
1969
+#if defined(ENABLE_PKCS11H_CERTIFICATE)
1970
+/*======================================================================*
1971
+ * CERTIFICATE INTERFACE
1972
+ *======================================================================*/
1973
+
1974
+static
1975
+void
1976
+_pkcs11h_isBetterCertificate_getExpiration (
1977
+	IN const unsigned char * const pCertificate,
1978
+	IN const size_t nCertificateSize,
1979
+	OUT char * const szNotBefore,
1980
+	IN const int nNotBeforeSize
1981
+) {
1982
+	/*
1983
+	 * This function compare the notBefore
1984
+	 * and select the most recent certificate
1985
+	 * it does not deal with timezones...
1986
+	 * When openssl will have ASN1_TIME compare function
1987
+	 * it should be used.
1988
+	 */
1989
+
1990
+	X509 *x509 = NULL;
1991
+
1992
+	PKCS11H_ASSERT (pCertificate!=NULL);
1993
+	PKCS11H_ASSERT (szNotBefore!=NULL);
1994
+	PKCS11H_ASSERT (nNotBeforeSize>0);
1995
+
1996
+	szNotBefore[0] = '\0';
1997
+
1998
+	x509 = X509_new ();
1999
+
2000
+	if (x509 != NULL) {
2001
+		pkcs11_openssl_d2i_t d2i = (pkcs11_openssl_d2i_t)pCertificate;
2002
+
2003
+		if (
2004
+			d2i_X509 (&x509, &d2i, nCertificateSize)
2005
+		) {
2006
+			ASN1_TIME *notBefore = X509_get_notBefore (x509);
2007
+			ASN1_TIME *notAfter = X509_get_notAfter (x509);
2008
+
2009
+			if (
2010
+				notBefore != NULL &&
2011
+				X509_cmp_current_time (notBefore) <= 0 &&
2012
+				X509_cmp_current_time (notAfter) >= 0 &&
2013
+				notBefore->length < nNotBeforeSize - 1
2014
+			) {
2015
+				memmove (szNotBefore, notBefore->data, notBefore->length);
2016
+				szNotBefore[notBefore->length] = '\0';
2017
+			}
2018
+		}
2019
+	}
2020
+
2021
+	if (x509 != NULL) {
2022
+		X509_free (x509);
2023
+		x509 = NULL;
2024
+	}
2025
+}
2026
+
2027
+static
2028
+PKCS11H_BOOL
2029
+_pkcs11h_isBetterCertificate (
2030
+	IN const unsigned char * const pCurrent,
2031
+	IN const size_t nCurrentSize,
2032
+	IN const unsigned char * const pNew,
2033
+	IN const size_t nNewSize
2034
+) {
2035
+	/*
2036
+	 * This function compare the notBefore
2037
+	 * and select the most recent certificate
2038
+	 * it does not deal with timezones...
2039
+	 * When openssl will have ASN1_TIME compare function
2040
+	 * it should be used.
2041
+	 */
2042
+
2043
+	PKCS11H_BOOL fBetter = FALSE;
2044
+
2045
+	/*PKCS11H_ASSERT (pCurrent!=NULL); NOT NEEDED */
2046
+	PKCS11H_ASSERT (pNew!=NULL);
2047
+
2048
+	PKCS11H_DEBUG (
2049
+		PKCS11H_LOG_DEBUG2,
2050
+		"PKCS#11: _pkcs11h_isBetterCertificate entry pCurrent=%p, nCurrentSize=%u, pNew=%p, nNewSize=%u",
2051
+		pCurrent,
2052
+		nCurrentSize,
2053
+		pNew,
2054
+		nNewSize
2055
+	);
2056
+
2057
+	/*
2058
+	 * First certificae
2059
+	 * always select
2060
+	 */
2061
+	if (nCurrentSize == 0 || pCurrent == NULL) {
2062
+		fBetter = TRUE;
2063
+	}
2064
+	else {
2065
+		char szNotBeforeCurrent[1024], szNotBeforeNew[1024];
2066
+
2067
+		_pkcs11h_isBetterCertificate_getExpiration (
2068
+			pCurrent,
2069
+			nCurrentSize,
2070
+			szNotBeforeCurrent,
2071
+			sizeof (szNotBeforeCurrent)
2072
+		);
2073
+		_pkcs11h_isBetterCertificate_getExpiration (
2074
+			pNew,
2075
+			nNewSize,
2076
+			szNotBeforeNew,
2077
+			sizeof (szNotBeforeNew)
2078
+		);
2079
+
2080
+		PKCS11H_DEBUG (
2081
+			PKCS11H_LOG_DEBUG2,
2082
+			"PKCS#11: _pkcs11h_isBetterCertificate szNotBeforeCurrent='%s', szNotBeforeNew='%s'",
2083
+			szNotBeforeCurrent,
2084
+			szNotBeforeNew
2085
+		);
2086
+
2087
+		fBetter = strcmp (szNotBeforeCurrent, szNotBeforeNew) < 0;
2088
+	}
2089
+
2090
+	PKCS11H_DEBUG (
2091
+		PKCS11H_LOG_DEBUG2,
2092
+		"PKCS#11: _pkcs11h_isBetterCertificate return fBetter=%d",
2093
+		fBetter ? 1 : 0
2094
+	);
1448 2095
 	
1449
-						if (!strcmp (szId, szSubject)) {
1450
-							fSelected = true;
1451
-						}
1452
-					}
1453
-					else {
1454
-						fSelected = true;
1455
-					}
2096
+	return fBetter;
2097
+}
2098
+
2099
+static
2100
+CK_RV
2101
+_pkcs11h_newCertificateId (
2102
+	OUT pkcs11h_certificate_id_t * const p_certificate_id
2103
+) {
2104
+	CK_RV rv = CKR_OK;
2105
+
2106
+	PKCS11H_ASSERT (p_certificate_id!=NULL);
2107
+
2108
+	PKCS11H_DEBUG (
2109
+		PKCS11H_LOG_DEBUG2,
2110
+		"PKCS#11: _pkcs11h_newCertificateId entry p_certificate_id=%p",
2111
+		(void *)p_certificate_id
2112
+	);
2113
+
2114
+	*p_certificate_id = NULL;
2115
+
2116
+	if (rv == CKR_OK) {
2117
+		rv = _pkcs11h_malloc ((void *)p_certificate_id, sizeof (struct pkcs11h_certificate_id_s));
2118
+	}
2119
+
2120
+	PKCS11H_DEBUG (
2121
+		PKCS11H_LOG_DEBUG2,
2122
+		"PKCS#11: _pkcs11h_newCertificateId return rv=%ld-'%s', *p_certificate_id=%p",
2123
+		rv,
2124
+		pkcs11h_getMessage (rv),
2125
+		(void *)*p_certificate_id
2126
+	);
2127
+
2128
+	return rv;
2129
+}
2130
+
2131
+static
2132
+CK_RV
2133
+_pkcs11h_loadCertificate (
2134
+	IN const pkcs11h_certificate_t certificate
2135
+) {
2136
+#if defined(ENABLE_PKCS11H_THREADING)
2137
+	PKCS11H_BOOL fMutexLocked = FALSE;
2138
+#endif
2139
+	CK_OBJECT_CLASS cert_filter_class = CKO_CERTIFICATE;
2140
+	CK_ATTRIBUTE cert_filter[] = {
2141
+		{CKA_CLASS, &cert_filter_class, sizeof (cert_filter_class)},
2142
+		{CKA_ID, NULL, 0}
2143
+	};
2144
+
2145
+	CK_OBJECT_HANDLE *objects = NULL;
2146
+	CK_ULONG objects_found = 0;
2147
+	CK_RV rv = CKR_OK;
2148
+
2149
+	CK_ULONG i;
2150
+
2151
+	PKCS11H_ASSERT (certificate!=NULL);
2152
+	PKCS11H_ASSERT (certificate->id!=NULL);
1456 2153
 	
1457
-					if (
1458
-						fSelected &&
1459
-						_isBetterCertificate (
1460
-							selected_certificate,
1461
-							selected_certificate_size,
1462
-							attrs_value,
1463
-							attrs[1].ulValueLen
1464
-						)
1465
-					) {
1466
-						selected_certificate_size = attrs[1].ulValueLen;
1467
-						memmove (
1468
-							selected_certificate,
1469
-							attrs_value,
1470
-							selected_certificate_size
1471
-						);
1472
-						selected_id_size = attrs[0].ulValueLen;
1473
-						memmove (
1474
-							selected_id,
1475
-							attrs_id,
1476
-							selected_id_size
1477
-						);
1478
-					}
2154
+	/* Must be after assert */
2155
+	cert_filter[1].pValue = certificate->id->attrCKA_ID;
2156
+	cert_filter[1].ulValueLen = certificate->id->attrCKA_ID_size;
2157
+
2158
+	PKCS11H_DEBUG (
2159
+		PKCS11H_LOG_DEBUG2,
2160
+		"PKCS#11: _pkcs11h_loadCertificate entry certificate=%p",
2161
+		(void *)certificate
2162
+	);
2163
+
2164
+	if (rv == CKR_OK) {
2165
+		rv = _pkcs11h_validateSession (certificate->session);
2166
+	}
2167
+
2168
+#if defined(ENABLE_PKCS11H_THREADING)
2169
+	if (
2170
+		rv == CKR_OK &&
2171
+		(rv = _pkcs11h_mutexLock (&certificate->mutexCertificate)) == CKR_OK
2172
+	) {
2173
+		fMutexLocked = TRUE;
2174
+	}
2175
+#endif
2176
+
2177
+	if (rv == CKR_OK) {
2178
+		rv = _pkcs11h_findObjects (
2179
+			certificate->session,
2180
+			cert_filter,
2181
+			sizeof (cert_filter) / sizeof (CK_ATTRIBUTE),
2182
+			&objects,
2183
+			&objects_found
2184
+		);
2185
+	}
2186
+
2187
+	for (i=0;rv == CKR_OK && i < objects_found;i++) {
2188
+		CK_ATTRIBUTE attrs[] = {
2189
+			{CKA_VALUE, NULL, 0}
2190
+		};
2191
+
2192
+		if (
2193
+			rv == CKR_OK &&
2194
+			(rv = _pkcs11h_getObjectAttributes (
2195
+				certificate->session,
2196
+				objects[i],
2197
+				attrs,
2198
+				sizeof (attrs) / sizeof (CK_ATTRIBUTE)
2199
+			)) == CKR_OK
2200
+		) {
2201
+			if (
2202
+				_pkcs11h_isBetterCertificate (
2203
+					certificate->id->certificate_blob,
2204
+					certificate->id->certificate_blob_size,
2205
+					attrs[0].pValue,
2206
+					attrs[0].ulValueLen
2207
+				)
2208
+			) {
2209
+				if (certificate->id->certificate_blob != NULL) {
2210
+					_pkcs11h_free ((void *)&certificate->id->certificate_blob);
1479 2211
 				}
2212
+
2213
+				rv = _pkcs11h_dupmem (
2214
+					(void*)&certificate->id->certificate_blob,
2215
+					&certificate->id->certificate_blob_size,
2216
+					attrs[0].pValue,
2217
+					attrs[0].ulValueLen
2218
+				);
1480 2219
 			}
1481 2220
 		}
1482
-	
1483
-		pkcs11h_certificate->session->provider->f->C_FindObjectsFinal (
1484
-			pkcs11h_certificate->session->hSession
2221
+
2222
+		if (rv != CKR_OK) {
2223
+			PKCS11H_DEBUG (
2224
+				PKCS11H_LOG_DEBUG1,
2225
+				"PKCS#11: Cannot get object attribute for provider '%s' object %ld rv=%ld-'%s'",
2226
+				certificate->session->provider->manufacturerID,
2227
+				objects[i],
2228
+				rv,
2229
+				pkcs11h_getMessage (rv)
2230
+			);
2231
+
2232
+			/*
2233
+			 * Ignore error
2234
+			 */
2235
+			rv = CKR_OK;
2236
+		}
2237
+
2238
+		_pkcs11h_freeObjectAttributes (
2239
+			attrs,
2240
+			sizeof (attrs) / sizeof (CK_ATTRIBUTE)
1485 2241
 		);
1486
-		rv = CKR_OK;
1487 2242
 	}
1488
-
2243
+	
1489 2244
 	if (
1490 2245
 		rv == CKR_OK &&
1491
-		selected_certificate_size == 0
2246
+		certificate->id->certificate_blob == NULL
1492 2247
 	) {
1493 2248
 		rv = CKR_ATTRIBUTE_VALUE_INVALID;
1494 2249
 	}
1495 2250
 
2251
+	if (objects != NULL) {
2252
+		_pkcs11h_free ((void *)&objects);
2253
+	}
2254
+
2255
+#if defined(ENABLE_PKCS11H_THREADING)
2256
+	if (fMutexLocked) {
2257
+		_pkcs11h_mutexRelease (&certificate->mutexCertificate);
2258
+		fMutexLocked = FALSE;
2259
+	}
2260
+#endif
2261
+
2262
+	/*
2263
+	 * No need to free allocated objects
2264
+	 * on error, since the certificate_id
2265
+	 * should be free by caller.
2266
+	 */
2267
+
2268
+	PKCS11H_DEBUG (
2269
+		PKCS11H_LOG_DEBUG2,
2270
+		"PKCS#11: _pkcs11h_loadCertificate return rv=%ld-'%s'",
2271
+		rv,
2272
+		pkcs11h_getMessage (rv)
2273
+	);
2274
+
2275
+	return rv;
2276
+}
2277
+
2278
+static
2279
+CK_RV
2280
+_pkcs11h_updateCertificateIdDescription (
2281
+	IN OUT pkcs11h_certificate_id_t certificate_id
2282
+) {
2283
+	static const char * szSeparator = " on ";
2284
+	static const char * szUnknown = "UNKNOWN";
2285
+	X509 *x509 = NULL;
2286
+	pkcs11_openssl_d2i_t d2i1;
2287
+
2288
+	PKCS11H_ASSERT (certificate_id!=NULL);
2289
+
2290
+	PKCS11H_DEBUG (
2291
+		PKCS11H_LOG_DEBUG2,
2292
+		"PKCS#11: _pkcs11h_updateCertificateIdDescription entry certificate_id=%p",
2293
+		(void *)certificate_id
2294
+	);
2295
+
2296
+	x509 = X509_new ();
2297
+
2298
+	d2i1 = (pkcs11_openssl_d2i_t)certificate_id->certificate_blob;
2299
+	if (d2i_X509 (&x509, &d2i1, certificate_id->certificate_blob_size)) {
2300
+		X509_NAME_oneline (
2301
+			X509_get_subject_name (x509),
2302
+			certificate_id->displayName,
2303
+			sizeof (certificate_id->displayName)
2304
+		);
2305
+	}
2306
+	else {
2307
+		strncpy (
2308
+			certificate_id->displayName,
2309
+			szUnknown,
2310
+			sizeof (certificate_id->displayName)-1
2311
+		);
2312
+	}
2313
+
2314
+	if (x509 != NULL) {
2315
+		X509_free (x509);
2316
+		x509 = NULL;
2317
+	}
2318
+
2319
+	/*
2320
+	 * Try to avoid using snprintf,
2321
+	 * may be unavailable
2322
+	 */
2323
+	strncat (
2324
+		certificate_id->displayName,
2325
+		szSeparator,
2326
+		sizeof (certificate_id->displayName)-1-strlen (certificate_id->displayName)
2327
+	);
2328
+	strncat (
2329
+		certificate_id->displayName,
2330
+		certificate_id->token_id->label,
2331
+		sizeof (certificate_id->displayName)-1-strlen (certificate_id->displayName)
2332
+	);
2333
+	certificate_id->displayName[sizeof (certificate_id->displayName) - 1] = '\0';
2334
+
2335
+	PKCS11H_DEBUG (
2336
+		PKCS11H_LOG_DEBUG2,
2337
+		"PKCS#11: _pkcs11h_updateCertificateIdDescription return displayName=%s",
2338
+		certificate_id->displayName
2339
+	);
2340
+
2341
+	return CKR_OK;
2342
+}
2343
+
2344
+static
2345
+CK_RV
2346
+_pkcs11h_ensureCertificateBlob (
2347
+	IN const pkcs11h_certificate_t certificate
2348
+) {
2349
+#if defined(ENABLE_PKCS11H_THREADING)
2350
+	PKCS11H_BOOL fMutexLocked = FALSE;
2351
+#endif
2352
+	PKCS11H_BOOL fOpSuccess = FALSE;
2353
+	PKCS11H_BOOL fLoginRetry = FALSE;
2354
+
2355
+	CK_RV rv = CKR_OK;
2356
+	
2357
+	PKCS11H_ASSERT (certificate!=NULL);
2358
+
2359
+	PKCS11H_DEBUG (
2360
+		PKCS11H_LOG_DEBUG2,
2361
+		"PKCS#11: _pkcs11h_ensureCertificateBlob entry certificate=%p",
2362
+		(void *)certificate
2363
+	);
2364
+
2365
+#if defined(ENABLE_PKCS11H_THREADING)
1496 2366
 	if (
1497 2367
 		rv == CKR_OK &&
1498
-		(pkcs11h_certificate->certificate_id = (unsigned char *)malloc (selected_id_size)) == NULL
2368
+		(rv = _pkcs11h_mutexLock (&certificate->mutexCertificate)) == CKR_OK
1499 2369
 	) {
1500
-		rv = CKR_HOST_MEMORY;
2370
+		fMutexLocked = TRUE;
1501 2371
 	}
2372
+#endif
2373
+
2374
+	if (certificate->id->certificate_blob == NULL) {
2375
+		fOpSuccess = FALSE;
2376
+		fLoginRetry = FALSE;
2377
+		while (rv == CKR_OK && !fOpSuccess) {
2378
+			if (rv == CKR_OK) {
2379
+				rv = _pkcs11h_loadCertificate (certificate);
2380
+			}
1502 2381
 
1503
-	if ( /* should be last on none failure */
2382
+			if (rv == CKR_OK) {
2383
+				fOpSuccess = TRUE;
2384
+			}
2385
+			else {
2386
+				if (!fLoginRetry) {
2387
+					fLoginRetry = TRUE;
2388
+					rv = _pkcs11h_resetCertificateSession (
2389
+						certificate,
2390
+						TRUE,
2391
+						(
2392
+							PKCS11H_PROMPT_MASK_ALLOW_PIN_PROMPT |
2393
+							PKCS11H_PROMPT_MAST_ALLOW_CARD_PROMPT 
2394
+						)
2395
+					);
2396
+				}
2397
+			}
2398
+		}
2399
+	}
2400
+	
2401
+	if (
1504 2402
 		rv == CKR_OK &&
1505
-		(pkcs11h_certificate->certificate = (unsigned char *)malloc (selected_certificate_size)) == NULL
2403
+		certificate->id->certificate_blob == NULL
1506 2404
 	) {
1507
-		rv = CKR_HOST_MEMORY;
2405
+		rv = CKR_FUNCTION_REJECTED;
1508 2406
 	}
1509 2407
 
1510 2408
 	if (rv == CKR_OK) {
1511
-		pkcs11h_certificate->certificate_size = selected_certificate_size;
1512
-		memmove (
1513
-			pkcs11h_certificate->certificate,
1514
-			selected_certificate,
1515
-			selected_certificate_size
1516
-		);
2409
+		_pkcs11h_updateCertificateIdDescription (certificate->id);
2410
+	}
1517 2411
 
1518
-		pkcs11h_certificate->certificate_id_size = selected_id_size;
1519
-		memmove (
1520
-			pkcs11h_certificate->certificate_id,
1521
-			selected_id,
1522
-			selected_id_size
1523
-		);
2412
+#if defined(ENABLE_PKCS11H_THREADING)
2413
+	if (fMutexLocked) {
2414
+		_pkcs11h_mutexRelease (&certificate->mutexCertificate);
2415
+		fMutexLocked = FALSE;
1524 2416
 	}
1525
-	
1526
-	PKCS11DLOG (
1527
-		PKCS11_LOG_DEBUG2,
1528
-		"PKCS#11: _pkcs11h_setCertificateSession_Certificate return rv=%ld-'%s'",
2417
+#endif
2418
+
2419
+	PKCS11H_DEBUG (
2420
+		PKCS11H_LOG_DEBUG2,
2421
+		"PKCS#11: _pkcs11h_ensureCertificateBlob return rv=%ld-'%s'",
1529 2422
 		rv,
1530 2423
 		pkcs11h_getMessage (rv)
1531 2424
 	);
... ...
@@ -1536,101 +4662,132 @@ _pkcs11h_setCertificateSession_Certificate (
1536 1536
 static
1537 1537
 CK_RV
1538 1538
 _pkcs11h_getCertificateKeyAttributes (
1539
-	IN const pkcs11h_certificate_t pkcs11h_certificate
1539
+	IN const pkcs11h_certificate_t certificate
1540 1540
 ) {
1541 1541
 	CK_RV rv = CKR_OK;
1542 1542
 
1543
-	CK_BBOOL key_attrs_sign_recover;
1544
-	CK_BBOOL key_attrs_sign;
1545
-	CK_ATTRIBUTE key_attrs[] = {
1546
-		{CKA_SIGN, &key_attrs_sign_recover, sizeof (key_attrs_sign_recover)},
1547
-		{CKA_SIGN_RECOVER, &key_attrs_sign, sizeof (key_attrs_sign)}
1548
-	};
1549
-
1550
-	bool fOpSuccess = false;
1551
-	bool fLoginRetry = false;
1543
+	PKCS11H_BOOL fOpSuccess = FALSE;
1544
+	PKCS11H_BOOL fLoginRetry = FALSE;
1552 1545
 
1553
-	PKCS11ASSERT (pkcs11h_certificate!=NULL);
1546
+	PKCS11H_ASSERT (certificate!=NULL);
1554 1547
 
1555
-	PKCS11DLOG (
1556
-		PKCS11_LOG_DEBUG2,
1557
-		"PKCS#11: _pkcs11h_getCertificateKeyAttributes entry pkcs11h_certificate=%p",
1558
-		(void *)pkcs11h_certificate
1548
+	PKCS11H_DEBUG (
1549
+		PKCS11H_LOG_DEBUG2,
1550
+		"PKCS#11: _pkcs11h_getCertificateKeyAttributes entry certificate=%p",
1551
+		(void *)certificate
1559 1552
 	);
1560 1553
 
1554
+	certificate->maskSignMode = 0;
1555
+
1561 1556
 	while (rv == CKR_OK && !fOpSuccess) {
1557
+#if defined(ENABLE_PKCS11H_THREADING)
1558
+		PKCS11H_BOOL fMutexLocked = FALSE;
1559
+#endif
1560
+		CK_ATTRIBUTE key_attrs[] = {
1561
+			{CKA_SIGN, NULL, 0},
1562
+			{CKA_SIGN_RECOVER, NULL, 0}
1563
+		};
1564
+
1565
+#if defined(ENABLE_PKCS11H_THREADING)
1566
+		if (
1567
+			rv == CKR_OK &&
1568
+			(rv = _pkcs11h_mutexLock (&certificate->mutexCertificate)) == CKR_OK
1569
+		) {
1570
+			fMutexLocked = TRUE;
1571
+		}
1572
+#endif
1573
+
1574
+		/*
1575
+		 * Don't try invalid object
1576
+		 */
1577
+		if (
1578
+			rv == CKR_OK &&
1579
+			certificate->hKey == PKCS11H_INVALID_OBJECT_HANDLE
1580
+		) {
1581
+			rv = CKR_OBJECT_HANDLE_INVALID;
1582
+		}
1562 1583
 
1563 1584
 		if (rv == CKR_OK) {
1564
-			rv = _pkcs11h_getObjectById (
1565
-				pkcs11h_certificate->session,
1566
-				CKO_PRIVATE_KEY,
1567
-				pkcs11h_certificate->certificate_id,
1568
-				pkcs11h_certificate->certificate_id_size,
1569
-				&pkcs11h_certificate->hKey
1585
+			if (certificate->session->provider->maskSignMode != 0) {
1586
+				certificate->maskSignMode = certificate->session->provider->maskSignMode;
1587
+				fOpSuccess = TRUE;
1588
+				PKCS11H_DEBUG (
1589
+					PKCS11H_LOG_DEBUG1,
1590
+					"PKCS#11: Key attributes enforced by provider (%08x)",
1591
+					certificate->maskSignMode
1592
+				);
1593
+			}
1594
+		}
1595
+
1596
+		if (rv == CKR_OK && !fOpSuccess) {
1597
+			rv = _pkcs11h_getObjectAttributes (
1598
+				certificate->session,
1599
+				certificate->hKey,
1600
+				key_attrs,
1601
+				sizeof (key_attrs) / sizeof (CK_ATTRIBUTE)
1570 1602
 			);
1571 1603
 		}
1572 1604
 
1573
-		if (pkcs11h_certificate->signmode == pkcs11h_signmode_none) {
1574
-			if (!strcmp (pkcs11h_certificate->session->provider->szSignMode, "recover")) {
1575
-				pkcs11h_certificate->signmode = pkcs11h_signmode_recover;
1605
+		if (rv == CKR_OK && !fOpSuccess) {
1606
+			CK_BBOOL *key_attrs_sign = (CK_BBOOL *)key_attrs[0].pValue;
1607
+			CK_BBOOL *key_attrs_sign_recover = (CK_BBOOL *)key_attrs[1].pValue;
1608
+
1609
+			if (key_attrs_sign != NULL && *key_attrs_sign != CK_FALSE) {
1610
+				certificate->maskSignMode |= PKCS11H_SIGNMODE_MASK_SIGN;
1576 1611
 			}
1577
-			else if (!strcmp (pkcs11h_certificate->session->provider->szSignMode, "sign")) {
1578
-				pkcs11h_certificate->signmode = pkcs11h_signmode_sign;
1612
+			if (key_attrs_sign_recover != NULL && *key_attrs_sign_recover != CK_FALSE) {
1613
+				certificate->maskSignMode |= PKCS11H_SIGNMODE_MASK_RECOVER;
1579 1614
 			}
1580
-			else {
1581
-				if (rv == CKR_OK) {
1582
-					rv = pkcs11h_certificate->session->provider->f->C_GetAttributeValue (
1583
-						pkcs11h_certificate->session->hSession,
1584
-						pkcs11h_certificate->hKey,
1585
-						key_attrs,
1586
-						sizeof (key_attrs) / sizeof (CK_ATTRIBUTE)
1587
-					);
1588
-				}
1589
-		
1590
-				if (rv == CKR_OK) {
1591
-					if (key_attrs_sign != CK_FALSE) {
1592
-						pkcs11h_certificate->signmode = pkcs11h_signmode_sign;
1593
-					}
1594
-					else if (key_attrs_sign_recover != CK_FALSE) {
1595
-						pkcs11h_certificate->signmode = pkcs11h_signmode_recover;
1596
-					}
1597
-					else {
1598
-						rv = CKR_KEY_TYPE_INCONSISTENT;
1599
-					}
1600
-
1601
-					PKCS11DLOG (
1602
-						PKCS11_LOG_DEBUG1,
1603
-						"PKCS#11: Signature mode selected: %d",
1604
-						pkcs11h_certificate->signmode
1605
-					);
1606
-				}
1615
+			if (certificate->maskSignMode == 0) {
1616
+				rv = CKR_KEY_TYPE_INCONSISTENT;
1607 1617
 			}
1618
+			PKCS11H_DEBUG (
1619
+				PKCS11H_LOG_DEBUG1,
1620
+				"PKCS#11: Key attributes loaded (%08x)",
1621
+				certificate->maskSignMode
1622
+			);
1608 1623
 		}
1609 1624
 
1625
+		_pkcs11h_freeObjectAttributes (
1626
+			key_attrs,
1627
+			sizeof (key_attrs) / sizeof (CK_ATTRIBUTE)
1628
+		);
1610 1629
 
1630
+#if defined(ENABLE_PKCS11H_THREADING)
1631
+		if (fMutexLocked) {
1632
+			_pkcs11h_mutexRelease (&certificate->mutexCertificate);
1633
+			fMutexLocked = FALSE;
1634
+		}
1635
+#endif
1636
+	
1611 1637
 		if (rv == CKR_OK) {
1612
-			fOpSuccess = true;
1638
+			fOpSuccess = TRUE;
1613 1639
 		}
1614 1640
 		else {
1615 1641
 			if (!fLoginRetry) {
1616
-				PKCS11DLOG (
1617
-					PKCS11_LOG_DEBUG1,
1618
-					"PKCS#11: Get key attributes failed: %ld:'%s'",
1642
+				PKCS11H_DEBUG (
1643
+					PKCS11H_LOG_DEBUG1,
1644
+					"PKCS#11: Get private key attributes failed: %ld:'%s'",
1619 1645
 					rv,
1620 1646
 					pkcs11h_getMessage (rv)
1621 1647
 				);
1622 1648
 
1623
-				rv = _pkcs11h_login (
1624
-					pkcs11h_certificate->session,
1625
-					false
1649
+				rv = _pkcs11h_resetCertificateSession (
1650
+					certificate,
1651
+					FALSE,
1652
+					(
1653
+						PKCS11H_PROMPT_MASK_ALLOW_PIN_PROMPT |
1654
+						PKCS11H_PROMPT_MAST_ALLOW_CARD_PROMPT 
1655
+					)
1626 1656
 				);
1627
-				fLoginRetry = true;
1657
+
1658
+				fLoginRetry = TRUE;
1628 1659
 			}
1629 1660
 		}
1630 1661
 	}
1631
-	
1632
-	PKCS11DLOG (
1633
-		PKCS11_LOG_DEBUG2,
1662
+
1663
+	PKCS11H_DEBUG (
1664
+		PKCS11H_LOG_DEBUG2,
1634 1665
 		"PKCS#11: _pkcs11h_getCertificateKeyAttributes return rv=%ld-'%s'",
1635 1666
 		rv,
1636 1667
 		pkcs11h_getMessage (rv)
... ...
@@ -1639,121 +4796,937 @@ _pkcs11h_getCertificateKeyAttributes (
1639 1639
 	return rv;
1640 1640
 }
1641 1641
 
1642
+static
1642 1643
 CK_RV
1643
-_pkcs11h_resetCertificateSession (
1644
-	IN const pkcs11h_certificate_t pkcs11h_certificate
1644
+_pkcs11h_validateCertificateSession (
1645
+	IN const pkcs11h_certificate_t certificate
1645 1646
 ) {
1646 1647
 	CK_RV rv = CKR_OK;
1647
-	
1648
-	PKCS11DLOG (
1649
-		PKCS11_LOG_DEBUG2,
1650
-		"PKCS#11: pkcs11h_resetCertificateSession entry pkcs11h_certificate=%p",
1651
-		(void *)pkcs11h_certificate
1648
+
1649
+	PKCS11H_ASSERT (certificate!=NULL);
1650
+
1651
+	PKCS11H_DEBUG (
1652
+		PKCS11H_LOG_DEBUG2,
1653
+		"PKCS#11: _pkcs11h_validateCertificateSession entry certificate=%p",
1654
+		(void *)certificate
1652 1655
 	);
1653 1656
 
1654 1657
 	if (rv == CKR_OK) {
1655
-		rv = _pkcs11h_login (
1656
-			pkcs11h_certificate->session,
1657
-			false
1658
-		);
1658
+		rv = _pkcs11h_validateSession (certificate->session);
1659 1659
 	}
1660 1660
 
1661 1661
 	if (rv == CKR_OK) {
1662
-		/*
1663
-		 * Will be performed only once
1664
-		 */
1665
-		rv = _pkcs11h_getCertificateKeyAttributes (pkcs11h_certificate); 
1662
+		if (certificate->hKey == PKCS11H_INVALID_OBJECT_HANDLE) {
1663
+			rv = CKR_OBJECT_HANDLE_INVALID;
1664
+		}
1666 1665
 	}
1667 1666
 
1668
-	PKCS11DLOG (
1669
-		PKCS11_LOG_DEBUG2,
1670
-		"PKCS#11: pkcs11h_freeCertificateSession return"
1667
+	PKCS11H_DEBUG (
1668
+		PKCS11H_LOG_DEBUG2,
1669
+		"PKCS#11: _pkcs11h_validateCertificateSession return rv=%ld-'%s'",
1670
+		rv,
1671
+		pkcs11h_getMessage (rv)
1671 1672
 	);
1672 1673
 
1673
-	return CKR_OK;
1674
+	return rv;
1674 1675
 }
1675 1676
 
1676
-/*=======================================
1677
- * Simplified PKCS#11 functions
1678
- */
1677
+CK_RV
1678
+_pkcs11h_resetCertificateSession (
1679
+	IN const pkcs11h_certificate_t certificate,
1680
+	IN const PKCS11H_BOOL fPublicOnly,
1681
+	IN const unsigned maskPrompt
1682
+) {
1683
+#if defined(ENABLE_PKCS11H_THREADING)
1684
+	PKCS11H_BOOL fMutexLocked = FALSE;
1685
+#endif
1686
+	PKCS11H_BOOL fKeyValid = FALSE;
1687
+	CK_RV rv = CKR_OK;
1688
+
1689
+	PKCS11H_ASSERT (certificate!=NULL);
1690
+	
1691
+	PKCS11H_DEBUG (
1692
+		PKCS11H_LOG_DEBUG2,
1693
+		"PKCS#11: pkcs11h_resetCertificateSession entry certificate=%p, fPublicOnly=%d, maskPrompt=%08x",
1694
+		(void *)certificate,
1695
+		fPublicOnly ? 1 : 0,
1696
+		maskPrompt
1697
+	);
1698
+
1699
+#if defined(ENABLE_PKCS11H_THREADING)
1700
+	if (
1701
+		rv == CKR_OK &&
1702
+		(rv = _pkcs11h_mutexLock (&certificate->mutexCertificate)) == CKR_OK
1703
+	) {
1704
+		fMutexLocked = TRUE;
1705
+	}
1706
+#endif
1707
+
1708
+	if (
1709
+		!fKeyValid &&
1710
+		rv == CKR_OK &&
1711
+		certificate->session == NULL &&
1712
+		(rv = _pkcs11h_getSessionByTokenId (certificate->id->token_id, &certificate->session)) == CKR_OK
1713
+	) {
1714
+		if (certificate->nPINCachePeriod != PKCS11H_PIN_CACHE_INFINITE) {
1715
+			if (certificate->session->nPINCachePeriod != PKCS11H_PIN_CACHE_INFINITE) {
1716
+				if (certificate->session->nPINCachePeriod > certificate->nPINCachePeriod) {
1717
+					certificate->session->timePINExpire = (
1718
+						certificate->session->timePINExpire -
1719
+						(time_t)certificate->session->nPINCachePeriod +
1720
+						(time_t)certificate->nPINCachePeriod
1721
+					);
1722
+					certificate->session->nPINCachePeriod = certificate->nPINCachePeriod;
1723
+				}
1724
+			}
1725
+			else {
1726
+				certificate->session->timePINExpire = (
1727
+					PKCS11H_TIME (NULL) +
1728
+					(time_t)certificate->nPINCachePeriod
1729
+				);
1730
+				certificate->session->nPINCachePeriod = certificate->nPINCachePeriod;
1731
+			}
1732
+		}	
1733
+	}
1734
+
1735
+	/*
1736
+	 * First, if session seems to be valid
1737
+	 * and key handle is invalid (hard-set),
1738
+	 * try to fetch key handle,
1739
+	 * maybe the token is already logged in
1740
+	 */
1741
+	if (rv == CKR_OK) {
1742
+		if (
1743
+			certificate->session->hSession != PKCS11H_INVALID_SESSION_HANDLE && 
1744
+			certificate->hKey == PKCS11H_INVALID_OBJECT_HANDLE &&
1745
+			!fPublicOnly
1746
+		) {
1747
+			if (
1748
+				(rv = _pkcs11h_getObjectById (
1749
+					certificate->session,
1750
+					CKO_PRIVATE_KEY,
1751
+					certificate->id->attrCKA_ID,
1752
+					certificate->id->attrCKA_ID_size,
1753
+					&certificate->hKey
1754
+				)) == CKR_OK
1755
+			) {
1756
+				fKeyValid = TRUE;
1757
+			}
1758
+			else {
1759
+				/*
1760
+				 * Ignore error
1761
+				 */
1762
+				rv = CKR_OK;
1763
+				certificate->hKey = PKCS11H_INVALID_OBJECT_HANDLE;
1764
+			}
1765
+		}
1766
+	}
1767
+
1768
+	if (
1769
+		!fKeyValid &&
1770
+		rv == CKR_OK &&
1771
+		(rv = _pkcs11h_login (
1772
+			certificate->session,
1773
+			fPublicOnly,
1774
+			TRUE,
1775
+			maskPrompt
1776
+		)) == CKR_OK
1777
+	) {
1778
+		rv = _pkcs11h_updateCertificateIdDescription (certificate->id);
1779
+	}
1780
+
1781
+	if (
1782
+		!fKeyValid &&
1783
+		rv == CKR_OK &&
1784
+		!fPublicOnly &&
1785
+		(rv = _pkcs11h_getObjectById (
1786
+			certificate->session,
1787
+			CKO_PRIVATE_KEY,
1788
+			certificate->id->attrCKA_ID,
1789
+			certificate->id->attrCKA_ID_size,
1790
+			&certificate->hKey
1791
+		)) == CKR_OK
1792
+	) {
1793
+		fKeyValid = TRUE;
1794
+	}
1795
+
1796
+	if (
1797
+		rv == CKR_OK &&
1798
+		!fPublicOnly &&
1799
+		!fKeyValid
1800
+	) {
1801
+		rv = CKR_FUNCTION_REJECTED;
1802
+	}
1803
+
1804
+#if defined(ENABLE_PKCS11H_THREADING)
1805
+	if (fMutexLocked) {
1806
+		_pkcs11h_mutexRelease (&certificate->mutexCertificate);
1807
+		fMutexLocked = FALSE;
1808
+	}
1809
+#endif
1810
+
1811
+	PKCS11H_DEBUG (
1812
+		PKCS11H_LOG_DEBUG2,
1813
+		"PKCS#11: _pkcs11h_resetCertificateSession return rv=%ld-'%s'",
1814
+		rv,
1815
+		pkcs11h_getMessage (rv)
1816
+	);
1817
+
1818
+	return rv;
1819
+}
1679 1820
 
1680 1821
 static
1681
-bool
1682
-_pkcs11h_hooks_card_prompt_default (
1683
-	IN const void * pData,
1684
-	IN const char * const szLabel
1822
+CK_RV
1823
+_pkcs11h_certificate_private_op (
1824
+	IN const pkcs11h_certificate_t certificate,
1825
+	IN const enum _pkcs11h_private_op_e op,
1826
+	IN const CK_MECHANISM_TYPE mech_type,
1827
+	IN const unsigned char * const source,
1828
+	IN const size_t source_size,
1829
+	OUT unsigned char * const target,
1830
+	IN OUT size_t * const p_target_size
1685 1831
 ) {
1686
-	PKCS11DLOG (
1687
-		PKCS11_LOG_DEBUG2,
1688
-		"PKCS#11: _pkcs11h_hooks_card_prompt_default pData=%p, szLabel=%s",
1689
-		pData,
1690
-		szLabel
1832
+	CK_MECHANISM mech = {
1833
+		mech_type, NULL, 0
1834
+	};
1835
+	
1836
+	CK_RV rv = CKR_OK;
1837
+	PKCS11H_BOOL fLoginRetry = FALSE;
1838
+	PKCS11H_BOOL fOpSuccess = FALSE;
1839
+
1840
+	PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
1841
+	PKCS11H_ASSERT (s_pkcs11h_data->fInitialized);
1842
+	PKCS11H_ASSERT (certificate!=NULL);
1843
+	PKCS11H_ASSERT (source!=NULL);
1844
+	/*PKCS11H_ASSERT (target); NOT NEEDED*/
1845
+	PKCS11H_ASSERT (p_target_size!=NULL);
1846
+
1847
+	PKCS11H_DEBUG (
1848
+		PKCS11H_LOG_DEBUG2,
1849
+		"PKCS#11: pkcs11h_certificate_private_op entry certificate=%p, op=%d, mech_type=%ld, source=%p, source_size=%u, target=%p, p_target_size=%p",
1850
+		(void *)certificate,
1851
+		op,
1852
+		mech_type,
1853
+		source,
1854
+		source_size,
1855
+		target,
1856
+		(void *)p_target_size
1857
+	);
1858
+
1859
+	if (target == NULL) {
1860
+		*p_target_size = 0;
1861
+	}
1862
+
1863
+	while (rv == CKR_OK && !fOpSuccess) {
1864
+#if defined(ENABLE_PKCS11H_THREADING)
1865
+		PKCS11H_BOOL fMutexLocked = FALSE;
1866
+#endif
1867
+
1868
+		if (rv == CKR_OK && !certificate->fOperationActive) {
1869
+			rv = _pkcs11h_validateCertificateSession (certificate);
1870
+		}
1871
+
1872
+#if defined(ENABLE_PKCS11H_THREADING)
1873
+		if (
1874
+			rv == CKR_OK &&
1875
+			(rv = _pkcs11h_mutexLock (&certificate->session->mutexSession)) == CKR_OK
1876
+		) {
1877
+			fMutexLocked = TRUE;
1878
+		}
1879
+#endif
1880
+
1881
+		if (rv == CKR_OK && !certificate->fOperationActive) {
1882
+			switch (op) {
1883
+				case _pkcs11h_private_op_sign:
1884
+					rv = certificate->session->provider->f->C_SignInit (
1885
+						certificate->session->hSession,
1886
+						&mech,
1887
+						certificate->hKey
1888
+					);
1889
+				break;
1890
+				case _pkcs11h_private_op_sign_recover:
1891
+					rv = certificate->session->provider->f->C_SignRecoverInit (
1892
+						certificate->session->hSession,
1893
+						&mech,
1894
+						certificate->hKey
1895
+					);
1896
+				break;
1897
+				case _pkcs11h_private_op_decrypt:
1898
+					rv = certificate->session->provider->f->C_DecryptInit (
1899
+						certificate->session->hSession,
1900
+						&mech,
1901
+						certificate->hKey
1902
+					);
1903
+				break;
1904
+				default:
1905
+					rv = CKR_ARGUMENTS_BAD;
1906
+				break;
1907
+			}
1908
+		}
1909
+
1910
+		if (rv == CKR_OK) {
1911
+			CK_ULONG size = *p_target_size;
1912
+
1913
+			switch (op) {
1914
+				case _pkcs11h_private_op_sign:
1915
+					rv = certificate->session->provider->f->C_Sign (
1916
+						certificate->session->hSession,
1917
+						(CK_BYTE_PTR)source,
1918
+						source_size,
1919
+						(CK_BYTE_PTR)target,
1920
+						&size
1921
+					);
1922
+				break;
1923
+				case _pkcs11h_private_op_sign_recover:
1924
+					rv = certificate->session->provider->f->C_SignRecover (
1925
+						certificate->session->hSession,
1926
+						(CK_BYTE_PTR)source,
1927
+						source_size,
1928
+						(CK_BYTE_PTR)target,
1929
+						&size
1930
+					);
1931
+				break;
1932
+				case _pkcs11h_private_op_decrypt:
1933
+					rv = certificate->session->provider->f->C_Decrypt (
1934
+						certificate->session->hSession,
1935
+						(CK_BYTE_PTR)source,
1936
+						source_size,
1937
+						(CK_BYTE_PTR)target,
1938
+						&size
1939
+					);
1940
+				break;
1941
+				default:
1942
+					rv = CKR_ARGUMENTS_BAD;
1943
+				break;
1944
+			}
1945
+
1946
+			*p_target_size = size;
1947
+		}
1948
+		
1949
+		if (
1950
+			target == NULL &&
1951
+			(
1952
+				rv == CKR_BUFFER_TOO_SMALL ||
1953
+				rv == CKR_OK
1954
+			)
1955
+		) {
1956
+			certificate->fOperationActive = TRUE;
1957
+			rv = CKR_OK;
1958
+		}
1959
+		else {
1960
+			certificate->fOperationActive = FALSE;
1961
+		}
1962
+
1963
+#if defined(ENABLE_PKCS11H_THREADING)
1964
+		if (fMutexLocked) {
1965
+			_pkcs11h_mutexRelease (&certificate->session->mutexSession);
1966
+			fMutexLocked = FALSE;
1967
+		}
1968
+#endif
1969
+
1970
+		if (rv == CKR_OK) {
1971
+			fOpSuccess = TRUE;
1972
+		}
1973
+		else {
1974
+			if (!fLoginRetry) {
1975
+				PKCS11H_DEBUG (
1976
+					PKCS11H_LOG_DEBUG1,
1977
+					"PKCS#11: Private key operation failed rv=%ld-'%s'",
1978
+					rv,
1979
+					pkcs11h_getMessage (rv)
1980
+				);
1981
+				fLoginRetry = TRUE;
1982
+				rv = _pkcs11h_resetCertificateSession (
1983
+					certificate,
1984
+					FALSE,
1985
+					(
1986
+						PKCS11H_PROMPT_MASK_ALLOW_PIN_PROMPT |
1987
+						PKCS11H_PROMPT_MAST_ALLOW_CARD_PROMPT 
1988
+					)
1989
+				);
1990
+			}
1991
+		}
1992
+	}
1993
+
1994
+	PKCS11H_DEBUG (
1995
+		PKCS11H_LOG_DEBUG2,
1996
+		"PKCS#11: pkcs11h_certificate_private_op return rv=%ld-'%s', *p_target_size=%d",
1997
+		rv,
1998
+		pkcs11h_getMessage (rv),
1999
+		*p_target_size
2000
+	);
2001
+	
2002
+	return rv;
2003
+}
2004
+
2005
+CK_RV
2006
+pkcs11h_freeCertificateId (
2007
+	IN pkcs11h_certificate_id_t certificate_id
2008
+) {
2009
+	PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
2010
+	PKCS11H_ASSERT (s_pkcs11h_data->fInitialized);
2011
+	PKCS11H_ASSERT (certificate_id!=NULL);
2012
+
2013
+	PKCS11H_DEBUG (
2014
+		PKCS11H_LOG_DEBUG2,
2015
+		"PKCS#11: pkcs11h_freeCertificateId entry certificate_id=%p",
2016
+		(void *)certificate_id
1691 2017
 	);
1692 2018
 
1693
-	return false;
2019
+	if (certificate_id->attrCKA_ID != NULL) {
2020
+		_pkcs11h_free ((void *)&certificate_id->attrCKA_ID);
2021
+	}
2022
+	if (certificate_id->certificate_blob != NULL) {
2023
+		_pkcs11h_free ((void *)&certificate_id->certificate_blob);
2024
+	}
2025
+	if (certificate_id->token_id != NULL) {
2026
+		pkcs11h_freeTokenId (certificate_id->token_id);
2027
+		certificate_id->token_id = NULL;
2028
+	}
2029
+	_pkcs11h_free ((void *)&certificate_id);
2030
+
2031
+	PKCS11H_DEBUG (
2032
+		PKCS11H_LOG_DEBUG2,
2033
+		"PKCS#11: pkcs11h_freeCertificateId return"
2034
+	);
2035
+
2036
+	return CKR_OK;
1694 2037
 }
1695 2038
 
1696
-static
1697
-bool
1698
-_pkcs11h_hooks_pin_prompt_default (
1699
-	IN const void * pData,
1700
-	IN const char * const szLabel,
1701
-	OUT char * const szPIN,
1702
-	IN const size_t nMaxPIN
2039
+CK_RV
2040
+pkcs11h_duplicateCertificateId (
2041
+	OUT pkcs11h_certificate_id_t * const to,
2042
+	IN const pkcs11h_certificate_id_t from
1703 2043
 ) {
1704
-	PKCS11DLOG (
1705
-		PKCS11_LOG_DEBUG2,
1706
-		"PKCS#11: _pkcs11h_hooks_pin_prompt_default pData=%p, szLabel=%s",
1707
-		pData,
1708
-		szLabel
2044
+	CK_RV rv = CKR_OK;
2045
+
2046
+	PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
2047
+	PKCS11H_ASSERT (s_pkcs11h_data->fInitialized);
2048
+	PKCS11H_ASSERT (to!=NULL);
2049
+	PKCS11H_ASSERT (from!=NULL);
2050
+
2051
+	PKCS11H_DEBUG (
2052
+		PKCS11H_LOG_DEBUG2,
2053
+		"PKCS#11: pkcs11h_duplicateCertificateId entry to=%p form=%p",
2054
+		(void *)to,
2055
+		(void *)from
2056
+	);
2057
+
2058
+	*to = NULL;
2059
+
2060
+	if (rv == CKR_OK) {
2061
+		rv = _pkcs11h_dupmem (
2062
+			(void*)to,
2063
+			NULL,
2064
+			from,
2065
+			sizeof (struct pkcs11h_certificate_id_s)
2066
+		);
2067
+	}
2068
+
2069
+	if (rv == CKR_OK) {
2070
+		rv = _pkcs11h_dupmem (
2071
+			(void*)&(*to)->token_id,
2072
+			NULL,
2073
+			from->token_id,
2074
+			sizeof (struct pkcs11h_token_id_s)
2075
+		);
2076
+	}
2077
+
2078
+	if (rv == CKR_OK) {
2079
+		rv = _pkcs11h_dupmem (
2080
+			(void*)&(*to)->attrCKA_ID,
2081
+			&(*to)->attrCKA_ID_size,
2082
+			from->attrCKA_ID,
2083
+			from->attrCKA_ID_size
2084
+		);
2085
+	}
2086
+
2087
+	if (rv == CKR_OK) {
2088
+		rv = _pkcs11h_dupmem (
2089
+			(void*)&(*to)->certificate_blob,
2090
+			&(*to)->certificate_blob_size,
2091
+			from->certificate_blob,
2092
+			from->certificate_blob_size
2093
+		);
2094
+	}
2095
+
2096
+	PKCS11H_DEBUG (
2097
+		PKCS11H_LOG_DEBUG2,
2098
+		"PKCS#11: pkcs11h_duplicateCertificateId return rv=%ld-'%s', *to=%p",
2099
+		rv,
2100
+		pkcs11h_getMessage (rv),
2101
+		(void *)*to
1709 2102
 	);
1710 2103
 	
1711
-	return false;
2104
+	return rv;
1712 2105
 }
1713 2106
 
1714 2107
 CK_RV
1715
-pkcs11h_initialize () {
2108
+pkcs11h_freeCertificate (
2109
+	IN pkcs11h_certificate_t certificate
2110
+) {
2111
+	PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
2112
+	PKCS11H_ASSERT (s_pkcs11h_data->fInitialized);
2113
+
2114
+	PKCS11H_DEBUG (
2115
+		PKCS11H_LOG_DEBUG2,
2116
+		"PKCS#11: pkcs11h_freeCertificate entry certificate=%p",
2117
+		(void *)certificate
2118
+	);
2119
+
2120
+	if (certificate != NULL) {
2121
+		if (certificate->session != NULL) {
2122
+			_pkcs11h_releaseSession (certificate->session);
2123
+		}
2124
+		pkcs11h_freeCertificateId (certificate->id);
2125
+		certificate->id = NULL;
2126
+
2127
+#if defined(ENABLE_PKCS11H_THREADING)
2128
+		_pkcs11h_mutexFree (&certificate->mutexCertificate);
2129
+#endif
2130
+
2131
+		_pkcs11h_free ((void *)&certificate);
2132
+	}
2133
+
2134
+	PKCS11H_DEBUG (
2135
+		PKCS11H_LOG_DEBUG2,
2136
+		"PKCS#11: pkcs11h_freeCertificate return"
2137
+	);
1716 2138
 
2139
+	return CKR_OK;
2140
+}
2141
+
2142
+CK_RV
2143
+pkcs11h_certificate_sign (
2144
+	IN const pkcs11h_certificate_t certificate,
2145
+	IN const CK_MECHANISM_TYPE mech_type,
2146
+	IN const unsigned char * const source,
2147
+	IN const size_t source_size,
2148
+	OUT unsigned char * const target,
2149
+	IN OUT size_t * const p_target_size
2150
+) {
1717 2151
 	CK_RV rv = CKR_OK;
1718 2152
 
1719
-	PKCS11DLOG (
1720
-		PKCS11_LOG_DEBUG2,
1721
-		"PKCS#11: pkcs11h_initialize entry"
2153
+	PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
2154
+	PKCS11H_ASSERT (s_pkcs11h_data->fInitialized);
2155
+	PKCS11H_ASSERT (certificate!=NULL);
2156
+	PKCS11H_ASSERT (source!=NULL);
2157
+	/*PKCS11H_ASSERT (target); NOT NEEDED*/
2158
+	PKCS11H_ASSERT (p_target_size!=NULL);
2159
+
2160
+	PKCS11H_DEBUG (
2161
+		PKCS11H_LOG_DEBUG2,
2162
+		"PKCS#11: pkcs11h_certificate_sign entry certificate=%p, mech_type=%ld, source=%p, source_size=%u, target=%p, p_target_size=%p",
2163
+		(void *)certificate,
2164
+		mech_type,
2165
+		source,
2166
+		source_size,
2167
+		target,
2168
+		(void *)p_target_size
1722 2169
 	);
1723 2170
 
1724
-	pkcs11h_terminate ();
2171
+	if (target == NULL) {
2172
+		*p_target_size = 0;
2173
+	}
2174
+
2175
+	if (rv == CKR_OK) {
2176
+		rv = _pkcs11h_certificate_private_op (
2177
+			certificate,
2178
+			_pkcs11h_private_op_sign,
2179
+			mech_type,
2180
+			source,
2181
+			source_size,
2182
+			target,
2183
+			p_target_size
2184
+		);
2185
+	}
2186
+
2187
+	PKCS11H_DEBUG (
2188
+		PKCS11H_LOG_DEBUG2,
2189
+		"PKCS#11: pkcs11h_certificate_sign return rv=%ld-'%s', *p_target_size=%d",
2190
+		rv,
2191
+		pkcs11h_getMessage (rv),
2192
+		*p_target_size
2193
+	);
2194
+	
2195
+	return rv;
2196
+}
2197
+
2198
+CK_RV
2199
+pkcs11h_certificate_signRecover (
2200
+	IN const pkcs11h_certificate_t certificate,
2201
+	IN const CK_MECHANISM_TYPE mech_type,
2202
+	IN const unsigned char * const source,
2203
+	IN const size_t source_size,
2204
+	OUT unsigned char * const target,
2205
+	IN OUT size_t * const p_target_size
2206
+) {
2207
+	CK_RV rv = CKR_OK;
2208
+
2209
+	PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
2210
+	PKCS11H_ASSERT (s_pkcs11h_data->fInitialized);
2211
+	PKCS11H_ASSERT (certificate!=NULL);
2212
+	PKCS11H_ASSERT (source!=NULL);
2213
+	/*PKCS11H_ASSERT (target); NOT NEEDED*/
2214
+	PKCS11H_ASSERT (p_target_size!=NULL);
2215
+
2216
+	PKCS11H_DEBUG (
2217
+		PKCS11H_LOG_DEBUG2,
2218
+		"PKCS#11: pkcs11h_certificate_signRecover entry certificate=%p, mech_type=%ld, source=%p, source_size=%u, target=%p, p_target_size=%p",
2219
+		(void *)certificate,
2220
+		mech_type,
2221
+		source,
2222
+		source_size,
2223
+		target,
2224
+		(void *)p_target_size
2225
+	);
2226
+
2227
+	if (target == NULL) {
2228
+		*p_target_size = 0;
2229
+	}
2230
+
2231
+	if (rv == CKR_OK) {
2232
+		rv = _pkcs11h_certificate_private_op (
2233
+			certificate,
2234
+			_pkcs11h_private_op_sign_recover,
2235
+			mech_type,
2236
+			source,
2237
+			source_size,
2238
+			target,
2239
+			p_target_size
2240
+		);
2241
+	}
2242
+
2243
+	PKCS11H_DEBUG (
2244
+		PKCS11H_LOG_DEBUG2,
2245
+		"PKCS#11: pkcs11h_certificate_signRecover return rv=%ld-'%s', *p_target_size=%d",
2246
+		rv,
2247
+		pkcs11h_getMessage (rv),
2248
+		*p_target_size
2249
+	);
2250
+
2251
+	return rv;
2252
+}
2253
+
2254
+CK_RV
2255
+pkcs11h_certificate_signAny (
2256
+	IN const pkcs11h_certificate_t certificate,
2257
+	IN const CK_MECHANISM_TYPE mech_type,
2258
+	IN const unsigned char * const source,
2259
+	IN const size_t source_size,
2260
+	OUT unsigned char * const target,
2261
+	IN OUT size_t * const p_target_size
2262
+) {
2263
+	CK_RV rv = CKR_OK;
2264
+	PKCS11H_BOOL fSigned = FALSE;
2265
+
2266
+	PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
2267
+	PKCS11H_ASSERT (s_pkcs11h_data->fInitialized);
2268
+	PKCS11H_ASSERT (certificate!=NULL);
2269
+	PKCS11H_ASSERT (source!=NULL);
2270
+	/*PKCS11H_ASSERT (target); NOT NEEDED*/
2271
+	PKCS11H_ASSERT (p_target_size!=NULL);
2272
+
2273
+	PKCS11H_DEBUG (
2274
+		PKCS11H_LOG_DEBUG2,
2275
+		"PKCS#11: pkcs11h_certificate_signAny entry certificate=%p, mech_type=%ld, source=%p, source_size=%u, target=%p, p_target_size=%p",
2276
+		(void *)certificate,
2277
+		mech_type,
2278
+		source,
2279
+		source_size,
2280
+		target,
2281
+		(void *)p_target_size
2282
+	);
1725 2283
 
1726 2284
 	if (
1727 2285
 		rv == CKR_OK &&
1728
-		(pkcs11h_data = (pkcs11h_data_t)malloc (sizeof (struct pkcs11h_data_s))) == NULL
2286
+		certificate->maskSignMode == 0
1729 2287
 	) {
1730
-		rv = CKR_HOST_MEMORY;
2288
+		PKCS11H_DEBUG (
2289
+			PKCS11H_LOG_DEBUG1,
2290
+			"PKCS#11: Getting key attributes"
2291
+		);
2292
+		rv = _pkcs11h_getCertificateKeyAttributes (certificate);
1731 2293
 	}
1732 2294
 
1733
-	if (rv == CKR_OK) {
1734
-		memset (pkcs11h_data, 0, sizeof (struct pkcs11h_data_s));
2295
+	if (
2296
+		rv == CKR_OK &&
2297
+		!fSigned &&
2298
+		(certificate->maskSignMode & PKCS11H_SIGNMODE_MASK_SIGN) != 0
2299
+	) {
2300
+		rv = pkcs11h_certificate_sign (
2301
+			certificate,
2302
+			mech_type,
2303
+			source,
2304
+			source_size,
2305
+			target,
2306
+			p_target_size
2307
+		);
2308
+
2309
+		if (rv == CKR_OK) {
2310
+			fSigned = TRUE;
2311
+		}
2312
+		else if (
2313
+			rv == CKR_FUNCTION_NOT_SUPPORTED ||
2314
+			rv == CKR_KEY_FUNCTION_NOT_PERMITTED
2315
+		) {
2316
+			certificate->maskSignMode &= ~PKCS11H_SIGNMODE_MASK_SIGN;
2317
+			rv = CKR_OK;
2318
+		}
2319
+	}
2320
+	
2321
+	if (
2322
+		rv == CKR_OK &&
2323
+		!fSigned &&
2324
+		(certificate->maskSignMode & PKCS11H_SIGNMODE_MASK_RECOVER) != 0
2325
+	) {
2326
+		rv = pkcs11h_certificate_signRecover (
2327
+			certificate,
2328
+			mech_type,
2329
+			source,
2330
+			source_size,
2331
+			target,
2332
+			p_target_size
2333
+		);
2334
+
2335
+		if (rv == CKR_OK) {
2336
+			fSigned = TRUE;
2337
+		}
2338
+		else if (
2339
+			rv == CKR_FUNCTION_NOT_SUPPORTED ||
2340
+			rv == CKR_KEY_FUNCTION_NOT_PERMITTED
2341
+		) {
2342
+			certificate->maskSignMode &= ~PKCS11H_SIGNMODE_MASK_RECOVER;
2343
+			rv = CKR_OK;
2344
+		}
2345
+	}
2346
+
2347
+	if (!fSigned) {
2348
+		rv = CKR_FUNCTION_FAILED;
1735 2349
 	}
1736 2350
 	
2351
+	PKCS11H_DEBUG (
2352
+		PKCS11H_LOG_DEBUG2,
2353
+		"PKCS#11: pkcs11h_certificate_signAny return rv=%ld-'%s', *p_target_size=%p",
2354
+		rv,
2355
+		pkcs11h_getMessage (rv),
2356
+		(void *)*p_target_size
2357
+	);
2358
+
2359
+	return rv;
2360
+}
2361
+
2362
+CK_RV
2363
+pkcs11h_certificate_decrypt (
2364
+	IN const pkcs11h_certificate_t certificate,
2365
+	IN const CK_MECHANISM_TYPE mech_type,
2366
+	IN const unsigned char * const source,
2367
+	IN const size_t source_size,
2368
+	OUT unsigned char * const target,
2369
+	IN OUT size_t * const p_target_size
2370
+) {
2371
+	CK_RV rv = CKR_OK;
2372
+
2373
+	PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
2374
+	PKCS11H_ASSERT (s_pkcs11h_data->fInitialized);
2375
+	PKCS11H_ASSERT (certificate!=NULL);
2376
+	PKCS11H_ASSERT (source!=NULL);
2377
+	/*PKCS11H_ASSERT (target); NOT NEEDED*/
2378
+	PKCS11H_ASSERT (p_target_size!=NULL);
2379
+
2380
+	PKCS11H_DEBUG (
2381
+		PKCS11H_LOG_DEBUG2,
2382
+		"PKCS#11: pkcs11h_decrypt entry certificate=%p, mech_type=%ld, source=%p, source_size=%u, target=%p, p_target_size=%p",
2383
+		(void *)certificate,
2384
+		mech_type,
2385
+		source,
2386
+		source_size,
2387
+		target,
2388
+		(void *)p_target_size
2389
+	);
2390
+
2391
+	if (target == NULL) {
2392
+		*p_target_size = 0;
2393
+	}
2394
+
2395
+	if (rv == CKR_OK) {
2396
+		rv = _pkcs11h_certificate_private_op (
2397
+			certificate,
2398
+			_pkcs11h_private_op_decrypt,
2399
+			mech_type,
2400
+			source,
2401
+			source_size,
2402
+			target,
2403
+			p_target_size
2404
+		);
2405
+	}
2406
+
2407
+	PKCS11H_DEBUG (
2408
+		PKCS11H_LOG_DEBUG2,
2409
+		"PKCS#11: pkcs11h_decrypt return rv=%ld-'%s', *p_target_size=%d",
2410
+		rv,
2411
+		pkcs11h_getMessage (rv),
2412
+		*p_target_size
2413
+	);
2414
+
2415
+	return rv;
2416
+}
2417
+
2418
+CK_RV
2419
+pkcs11h_certificate_create (
2420
+	IN const pkcs11h_certificate_id_t certificate_id,
2421
+	IN const int nPINCachePeriod,
2422
+	OUT pkcs11h_certificate_t * const p_certificate
2423
+) {
2424
+	pkcs11h_certificate_t certificate = NULL;
2425
+	CK_RV rv = CKR_OK;
2426
+
2427
+	PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
2428
+	PKCS11H_ASSERT (s_pkcs11h_data->fInitialized);
2429
+	PKCS11H_ASSERT (p_certificate!=NULL);
2430
+
2431
+	PKCS11H_DEBUG (
2432
+		PKCS11H_LOG_DEBUG2,
2433
+		"PKCS#11: pkcs11h_certificate_create entry certificate_id=%p, nPINCachePeriod=%d, p_certificate=%p",
2434
+		(void *)certificate_id,
2435
+		nPINCachePeriod,
2436
+		(void *)p_certificate
2437
+	);
2438
+
2439
+	*p_certificate = NULL;
2440
+
1737 2441
 	if (
1738 2442
 		rv == CKR_OK &&
1739
-		(pkcs11h_data->hooks = (pkcs11h_hooks_t)malloc (sizeof (struct pkcs11h_hooks_s))) == NULL
2443
+		(rv = _pkcs11h_malloc ((void*)&certificate, sizeof (struct pkcs11h_certificate_s))) == CKR_OK
1740 2444
 	) {
1741
-		rv = CKR_HOST_MEMORY;
2445
+		certificate->hKey = PKCS11H_INVALID_OBJECT_HANDLE;
2446
+		certificate->nPINCachePeriod = nPINCachePeriod;
2447
+	}
2448
+
2449
+#if defined(ENABLE_PKCS11H_THREADING)
2450
+	if (rv == CKR_OK) {
2451
+		rv = _pkcs11h_mutexInit (&certificate->mutexCertificate);
1742 2452
 	}
2453
+#endif
1743 2454
 
1744 2455
 	if (rv == CKR_OK) {
1745
-		memset (pkcs11h_data->hooks, 0, sizeof (struct pkcs11h_hooks_s));
2456
+		rv = pkcs11h_duplicateCertificateId (&certificate->id, certificate_id);
2457
+	}
2458
+
2459
+	if (rv == CKR_OK) {
2460
+		*p_certificate = certificate;
2461
+		certificate = NULL;
2462
+	}
2463
+
2464
+	if (certificate != NULL) {
2465
+#if defined(ENABLE_PKCS11H_THREADING)
2466
+		_pkcs11h_mutexFree (&certificate->mutexCertificate);
2467
+#endif
2468
+		_pkcs11h_free ((void *)&certificate);
2469
+	}
2470
+
2471
+	PKCS11H_DEBUG (
2472
+		PKCS11H_LOG_DEBUG2,
2473
+		"PKCS#11: pkcs11h_certificate_create return rv=%ld-'%s' *p_certificate=%p",
2474
+		rv,
2475
+		pkcs11h_getMessage (rv),
2476
+		(void *)*p_certificate
2477
+	);
1746 2478
 	
1747
-		pkcs11h_data->fInitialized = true;
1748
-		pkcs11h_data->nPINCachePeriod = PKCS11H_PIN_CACHE_INFINITE;
2479
+	return rv;
2480
+}
2481
+
2482
+CK_RV
2483
+pkcs11h_certificate_getCertificateId (
2484
+	IN const pkcs11h_certificate_t certificate,
2485
+	OUT pkcs11h_certificate_id_t * const p_certificate_id
2486
+) {
2487
+	CK_RV rv = CKR_OK;
2488
+
2489
+	PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
2490
+	PKCS11H_ASSERT (s_pkcs11h_data->fInitialized);
2491
+	PKCS11H_ASSERT (certificate!=NULL);
2492
+	PKCS11H_ASSERT (p_certificate_id!=NULL);
2493
+
2494
+	PKCS11H_DEBUG (
2495
+		PKCS11H_LOG_DEBUG2,
2496
+		"PKCS#11: pkcs11h_certificate_getCertificateId entry certificate=%p, certificate_id=%p",
2497
+		(void *)certificate,
2498
+		(void *)p_certificate_id
2499
+	);
2500
+
2501
+	if (rv == CKR_OK) {
2502
+		rv = pkcs11h_duplicateCertificateId (
2503
+			p_certificate_id,
2504
+			certificate->id
2505
+		);
2506
+	}
2507
+
2508
+	PKCS11H_DEBUG (
2509
+		PKCS11H_LOG_DEBUG2,
2510
+		"PKCS#11: pkcs11h_certificate_getCertificateId return rv=%ld-'%s'",
2511
+		rv,
2512
+		pkcs11h_getMessage (rv)
2513
+	);
2514
+
2515
+	return rv;
2516
+}
2517
+
2518
+CK_RV
2519
+pkcs11h_certificate_getCertificateBlob (
2520
+	IN const pkcs11h_certificate_t certificate,
2521
+	OUT unsigned char * const certificate_blob,
2522
+	IN OUT size_t * const p_certificate_blob_size
2523
+) {
2524
+	size_t certifiate_blob_size_max = 0;
2525
+
2526
+	CK_RV rv = CKR_OK;
1749 2527
 	
1750
-		pkcs11h_setCardPromptHook (_pkcs11h_hooks_card_prompt_default, NULL);
1751
-		pkcs11h_setPINPromptHook (_pkcs11h_hooks_pin_prompt_default, NULL);
2528
+	PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
2529
+	PKCS11H_ASSERT (s_pkcs11h_data->fInitialized);
2530
+	PKCS11H_ASSERT (certificate!=NULL);
2531
+	/*PKCS11H_ASSERT (certificate_blob!=NULL); NOT NEEDED */
2532
+	PKCS11H_ASSERT (p_certificate_blob_size!=NULL);
2533
+
2534
+	PKCS11H_DEBUG (
2535
+		PKCS11H_LOG_DEBUG2,
2536
+		"PKCS#11: pkcs11h_certificate_getCertificateBlob entry certificate=%p, certificate_blob=%p, p_certificate_blob_size=%p",
2537
+		(void *)certificate,
2538
+		certificate_blob,
2539
+		(void *)p_certificate_blob_size
2540
+	);
2541
+
2542
+	certifiate_blob_size_max = *p_certificate_blob_size;
2543
+	*p_certificate_blob_size = 0;
2544
+
2545
+	if (rv == CKR_OK) {
2546
+		rv = _pkcs11h_ensureCertificateBlob (certificate);
1752 2547
 	}
2548
+
2549
+	if (rv == CKR_OK) {
2550
+		*p_certificate_blob_size = certificate->id->certificate_blob_size;
2551
+	}
2552
+
2553
+	if (certificate_blob != NULL) {
2554
+		if (
2555
+			rv == CKR_OK &&
2556
+			certifiate_blob_size_max > certificate->id->certificate_blob_size
2557
+		) {
2558
+			rv = CKR_BUFFER_TOO_SMALL;
2559
+		}
1753 2560
 	
1754
-	PKCS11DLOG (
1755
-		PKCS11_LOG_DEBUG2,
1756
-		"PKCS#11: pkcs11h_initialize return rv=%ld-'%s'",
2561
+		if (rv == CKR_OK) {
2562
+			memmove (
2563
+				certificate_blob,
2564
+				certificate->id->certificate_blob,
2565
+				*p_certificate_blob_size
2566
+			);
2567
+		}
2568
+	}
2569
+
2570
+	PKCS11H_DEBUG (
2571
+		PKCS11H_LOG_DEBUG2,
2572
+		"PKCS#11: pkcs11h_certificate_getCertificateBlob return rv=%ld-'%s'",
1757 2573
 		rv,
1758 2574
 		pkcs11h_getMessage (rv)
1759 2575
 	);
... ...
@@ -1762,262 +5735,863 @@ pkcs11h_initialize () {
1762 1762
 }
1763 1763
 
1764 1764
 CK_RV
1765
-pkcs11h_terminate () {
1765
+pkcs11h_certificate_ensureCertificateAccess (
1766
+	IN const pkcs11h_certificate_t certificate,
1767
+	IN const unsigned maskPrompt
1768
+) {
1769
+	PKCS11H_BOOL fValidCert = FALSE;
1770
+	CK_RV rv = CKR_OK;
1766 1771
 
1767
-	PKCS11DLOG (
1768
-		PKCS11_LOG_DEBUG2,
1769
-		"PKCS#11: pkcs11h_terminate entry"
1772
+	PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
1773
+	PKCS11H_ASSERT (s_pkcs11h_data->fInitialized);
1774
+	PKCS11H_ASSERT (certificate!=NULL);
1775
+
1776
+	PKCS11H_DEBUG (
1777
+		PKCS11H_LOG_DEBUG2,
1778
+		"PKCS#11: pkcs11h_certificate_ensureCertificateAccess entry certificate=%p, maskPrompt=%08x",
1779
+		(void *)certificate,
1780
+		maskPrompt
1770 1781
 	);
1771 1782
 
1772
-	if (pkcs11h_data != NULL) {
1773
-		pkcs11h_provider_t p_last = NULL;
1774
-		pkcs11h_session_t s_last = NULL;
1783
+	if (!fValidCert && rv == CKR_OK) {
1784
+		CK_OBJECT_HANDLE h = PKCS11H_INVALID_OBJECT_HANDLE;
1775 1785
 
1776
-		for (
1777
-			;
1778
-			pkcs11h_data->sessions != NULL;
1779
-			pkcs11h_data->sessions = pkcs11h_data->sessions->next
1786
+		if (
1787
+			(rv = _pkcs11h_getObjectById (
1788
+				certificate->session,
1789
+				CKO_CERTIFICATE,
1790
+				certificate->id->attrCKA_ID,
1791
+				certificate->id->attrCKA_ID_size,
1792
+				&h
1793
+			)) == CKR_OK
1780 1794
 		) {
1781
-			if (s_last != NULL) {
1782
-				if (s_last->nReferenceCount == 0) {
1783
-					free (s_last);
1784
-				}
1785
-			}
1786
-			s_last = pkcs11h_data->sessions;
1787
-			
1788
-			_pkcs11h_logout (s_last);
1789
-			s_last->fValid = false;
1790
-			s_last->provider = NULL;
1795
+			fValidCert = TRUE;
1791 1796
 		}
1792 1797
 
1793
-		if (s_last != NULL) {
1794
-			if (s_last->nReferenceCount == 0) {
1795
-				free (s_last);
1796
-			}
1798
+		if (rv != CKR_OK) {
1799
+			PKCS11H_DEBUG (
1800
+				PKCS11H_LOG_DEBUG1,
1801
+				"PKCS#11: Cannot access existing object rv=%ld-'%s'",
1802
+				rv,
1803
+				pkcs11h_getMessage (rv)
1804
+			);
1805
+
1806
+			/*
1807
+			 * Ignore error
1808
+			 */
1809
+			rv = CKR_OK;
1797 1810
 		}
1811
+	}
1798 1812
 
1799
-		for (
1800
-			;
1801
-			pkcs11h_data->providers != NULL;
1802
-			pkcs11h_data->providers = pkcs11h_data->providers->next
1813
+	if (!fValidCert && rv == CKR_OK) {
1814
+		if (
1815
+			(rv = _pkcs11h_resetCertificateSession (
1816
+				certificate,
1817
+				TRUE,
1818
+				maskPrompt
1819
+			)) == CKR_OK
1803 1820
 		) {
1804
-			if (p_last != NULL) {
1805
-				free (p_last);
1806
-			}
1807
-			p_last = pkcs11h_data->providers;
1808
-		
1809
-			if (p_last->szName != NULL) {
1810
-				free (p_last->szName);
1811
-				p_last->szName = NULL;
1812
-			}
1821
+			fValidCert = TRUE;
1822
+		}
1823
+	}
1813 1824
 
1814
-			if (p_last->szSignMode != NULL) {
1815
-				free (p_last->szSignMode);
1816
-				p_last->szSignMode = NULL;
1817
-			}
1825
+	PKCS11H_DEBUG (
1826
+		PKCS11H_LOG_DEBUG2,
1827
+		"PKCS#11: pkcs11h_certificate_ensureCertificateAccess return rv=%ld-'%s'",
1828
+		rv,
1829
+		pkcs11h_getMessage (rv)
1830
+	);
1818 1831
 	
1819
-			if (p_last->fShouldFinalize) {
1820
-				p_last->f->C_Finalize (NULL);
1821
-				p_last->fShouldFinalize = false;
1822
-			}
1832
+	return rv;
1833
+}
1823 1834
 
1824
-			if (p_last->f != NULL) {
1825
-				p_last->f = NULL;
1826
-			}
1827
-	
1828
-			if (p_last->hLibrary != NULL) {
1829
-#if defined(WIN32)
1830
-				FreeLibrary (p_last->hLibrary);
1831
-#else
1832
-				dlclose (p_last->hLibrary);
1833
-#endif
1834
-				p_last->hLibrary = NULL;
1835
-			}
1836
-		}
1835
+CK_RV
1836
+pkcs11h_certificate_ensureKeyAccess (
1837
+	IN const pkcs11h_certificate_t certificate,
1838
+	IN const unsigned maskPrompt
1839
+) {
1840
+	CK_RV rv = CKR_OK;
1841
+	PKCS11H_BOOL fValidKey = FALSE;
1837 1842
 
1838
-		if (p_last != NULL) {
1839
-			free (p_last);
1843
+	PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
1844
+	PKCS11H_ASSERT (s_pkcs11h_data->fInitialized);
1845
+	PKCS11H_ASSERT (certificate!=NULL);
1846
+
1847
+	PKCS11H_DEBUG (
1848
+		PKCS11H_LOG_DEBUG2,
1849
+		"PKCS#11: pkcs11h_certificate_ensureKeyAccess entry certificate=%p, maskPrompt=%08x",
1850
+		(void *)certificate,
1851
+		maskPrompt
1852
+	);
1853
+
1854
+	if (!fValidKey && rv == CKR_OK) {
1855
+		if (
1856
+			(rv = _pkcs11h_getObjectById (
1857
+				certificate->session,
1858
+				CKO_PRIVATE_KEY,
1859
+				certificate->id->attrCKA_ID,
1860
+				certificate->id->attrCKA_ID_size,
1861
+				&certificate->hKey
1862
+			)) == CKR_OK
1863
+		) {
1864
+			fValidKey = TRUE;
1840 1865
 		}
1841 1866
 
1842
-		if (pkcs11h_data->hooks != NULL) {
1843
-			free (pkcs11h_data->hooks);
1844
-			pkcs11h_data->hooks = NULL;
1867
+		if (rv != CKR_OK) {
1868
+			PKCS11H_DEBUG (
1869
+				PKCS11H_LOG_DEBUG1,
1870
+				"PKCS#11: Cannot access existing object rv=%ld-'%s'",
1871
+				rv,
1872
+				pkcs11h_getMessage (rv)
1873
+			);
1874
+
1875
+			/*
1876
+			 * Ignore error
1877
+			 */
1878
+			rv = CKR_OK;
1879
+			certificate->hKey = PKCS11H_INVALID_OBJECT_HANDLE;
1845 1880
 		}
1881
+	}
1846 1882
 
1847
-		free (pkcs11h_data);
1848
-		pkcs11h_data = NULL;
1883
+	if (!fValidKey && rv == CKR_OK) {
1884
+		if (
1885
+			(rv = _pkcs11h_resetCertificateSession (
1886
+				certificate,
1887
+				FALSE,
1888
+				maskPrompt
1889
+			)) == CKR_OK
1890
+		) {
1891
+			fValidKey = TRUE;
1892
+		}
1849 1893
 	}
1850 1894
 
1851
-	PKCS11DLOG (
1852
-		PKCS11_LOG_DEBUG2,
1853
-		"PKCS#11: pkcs11h_terminate return"
1895
+	PKCS11H_DEBUG (
1896
+		PKCS11H_LOG_DEBUG2,
1897
+		"PKCS#11: pkcs11h_certificate_ensureKeyAccess return rv=%ld-'%s'",
1898
+		rv,
1899
+		pkcs11h_getMessage (rv)
1854 1900
 	);
1855
-
1856
-	return CKR_OK;
1901
+	
1902
+	return rv;
1857 1903
 }
1858 1904
 
1905
+#endif				/* ENABLE_PKCS11H_CERTIFICATE */
1906
+
1907
+#if defined(ENABLE_PKCS11H_LOCATE)
1908
+/*======================================================================*
1909
+ * LOCATE INTERFACE
1910
+ *======================================================================*/
1911
+
1912
+#if defined(ENABLE_PKCS11H_TOKEN) || defined(ENABLE_PKCS11H_CERTIFICATE)
1913
+
1914
+static
1859 1915
 CK_RV
1860
-pkcs11h_setPINPromptHook (
1861
-	IN const pkcs11h_hook_pin_prompt_t hook,
1862
-	IN void * const pData
1916
+_pkcs11h_locate_getTokenIdBySlotId (
1917
+	IN const char * const szSlot,
1918
+	OUT pkcs11h_token_id_t * const p_token_id
1863 1919
 ) {
1864
-	PKCS11ASSERT (pkcs11h_data!=NULL);
1865
-	PKCS11ASSERT (pkcs11h_data->fInitialized);
1920
+	pkcs11h_provider_t current_provider = NULL;
1921
+	char szReferenceName[sizeof (((pkcs11h_provider_t)NULL)->szReferenceName)];
1866 1922
 
1867
-	pkcs11h_data->hooks->pin_prompt = hook;
1868
-	pkcs11h_data->hooks->pin_prompt_data = pData;
1923
+	CK_SLOT_ID selected_slot = PKCS11H_INVALID_SLOT_ID;
1924
+	CK_TOKEN_INFO info;
1925
+	CK_RV rv = CKR_OK;
1869 1926
 
1870
-	return CKR_OK;
1927
+	PKCS11H_ASSERT (szSlot!=NULL);
1928
+	PKCS11H_ASSERT (p_token_id!=NULL);
1929
+
1930
+	PKCS11H_DEBUG (
1931
+		PKCS11H_LOG_DEBUG2,
1932
+		"PKCS#11: _pkcs11h_locate_getTokenIdBySlotId entry szSlot='%s', p_token_id=%p",
1933
+		szSlot,
1934
+		(void *)p_token_id
1935
+	);
1936
+
1937
+	*p_token_id = NULL;
1938
+
1939
+	if (rv == CKR_OK) {
1940
+		if (strchr (szSlot, ':') == NULL) {
1941
+			szReferenceName[0] = '\0';
1942
+			selected_slot = atol (szSlot);
1943
+		}
1944
+		else {
1945
+			char *p;
1946
+
1947
+			strncpy (szReferenceName, szSlot, sizeof (szReferenceName));
1948
+			szReferenceName[sizeof (szReferenceName)-1] = '\0';
1949
+
1950
+			p = strchr (szReferenceName, ':');
1951
+
1952
+			*p = '\0';
1953
+			p++;
1954
+			selected_slot = atol (p);
1955
+		}
1956
+	}
1957
+	
1958
+	if (rv == CKR_OK) {
1959
+		current_provider=s_pkcs11h_data->providers;
1960
+		while (
1961
+			current_provider != NULL &&
1962
+			szReferenceName[0] != '\0' &&		/* So first provider will be selected */
1963
+			strcmp (current_provider->szReferenceName, szReferenceName)
1964
+		) {
1965
+			current_provider = current_provider->next;
1966
+		}
1967
+	
1968
+		if (
1969
+			current_provider == NULL ||
1970
+			(
1971
+				current_provider != NULL &&
1972
+				!current_provider->fEnabled
1973
+			)
1974
+		) {
1975
+			rv = CKR_SLOT_ID_INVALID;
1976
+		}
1977
+	}
1978
+
1979
+	if (
1980
+		rv == CKR_OK &&
1981
+		(rv = current_provider->f->C_GetTokenInfo (selected_slot, &info)) == CKR_OK
1982
+	) {
1983
+		rv = _pkcs11h_getTokenId (
1984
+			&info,
1985
+			p_token_id
1986
+		);
1987
+	}
1988
+
1989
+	PKCS11H_DEBUG (
1990
+		PKCS11H_LOG_DEBUG2,
1991
+		"PKCS#11: _pkcs11h_locate_getTokenIdBySlotId return rv=%ld-'%s', *p_token_id=%p",
1992
+		rv,
1993
+		pkcs11h_getMessage (rv),
1994
+		(void *)*p_token_id
1995
+	);
1996
+
1997
+	return rv;
1871 1998
 }
1872 1999
 
2000
+static
1873 2001
 CK_RV
1874
-pkcs11h_setCardPromptHook (
1875
-	IN const pkcs11h_hook_card_prompt_t hook,
1876
-	IN void * const pData
2002
+_pkcs11h_locate_getTokenIdBySlotName (
2003
+	IN const char * const szName,
2004
+	OUT pkcs11h_token_id_t * const p_token_id
1877 2005
 ) {
1878
-	PKCS11ASSERT (pkcs11h_data!=NULL);
1879
-	PKCS11ASSERT (pkcs11h_data->fInitialized);
2006
+	pkcs11h_provider_t current_provider = NULL;
2007
+
2008
+	CK_SLOT_ID selected_slot = PKCS11H_INVALID_SLOT_ID;
2009
+	CK_TOKEN_INFO info;
2010
+	CK_RV rv = CKR_OK;
1880 2011
 
1881
-	pkcs11h_data->hooks->card_prompt = hook;
1882
-	pkcs11h_data->hooks->card_prompt_data = pData;
2012
+	PKCS11H_BOOL fFound = FALSE;
1883 2013
 
1884
-	return CKR_OK;
2014
+	PKCS11H_ASSERT (szName!=NULL);
2015
+	PKCS11H_ASSERT (p_token_id!=NULL);
2016
+
2017
+	PKCS11H_DEBUG (
2018
+		PKCS11H_LOG_DEBUG2,
2019
+		"PKCS#11: _pkcs11h_locate_getTokenIdBySlotName entry szName='%s', p_token_id=%p",
2020
+		szName,
2021
+		(void *)p_token_id
2022
+	);
2023
+
2024
+	*p_token_id = NULL;
2025
+
2026
+	current_provider = s_pkcs11h_data->providers;
2027
+	while (
2028
+		current_provider != NULL &&
2029
+		rv == CKR_OK &&
2030
+		!fFound
2031
+	) {
2032
+		CK_SLOT_ID_PTR slots = NULL;
2033
+		CK_ULONG slotnum;
2034
+		CK_SLOT_ID slot_index;
2035
+
2036
+		if (!current_provider->fEnabled) {
2037
+			continue;
2038
+		}
2039
+
2040
+		if (rv == CKR_OK) {
2041
+			rv = _pkcs11h_getSlotList (
2042
+				current_provider,
2043
+				CK_TRUE,
2044
+				&slots,
2045
+				&slotnum
2046
+			);
2047
+		}
2048
+
2049
+		for (
2050
+			slot_index=0;
2051
+			(
2052
+				slot_index < slotnum &&
2053
+				rv == CKR_OK &&
2054
+				!fFound
2055
+			);
2056
+			slot_index++
2057
+		) {
2058
+			CK_SLOT_INFO info;
2059
+
2060
+			if (
2061
+				(rv = current_provider->f->C_GetSlotInfo (
2062
+					slots[slot_index],
2063
+					&info
2064
+				)) == CKR_OK
2065
+			) {
2066
+				char szCurrentName[sizeof (info.slotDescription)+1];
2067
+
2068
+				_pkcs11h_fixupFixedString (
2069
+					szCurrentName,
2070
+					(char *)info.slotDescription,
2071
+					sizeof (info.slotDescription)
2072
+				);
2073
+
2074
+				if (!strcmp (szCurrentName, szName)) {
2075
+					fFound = TRUE;
2076
+					selected_slot = slots[slot_index];
2077
+				}
2078
+			}
2079
+
2080
+			if (rv != CKR_OK) {
2081
+				PKCS11H_DEBUG (
2082
+					PKCS11H_LOG_DEBUG1,
2083
+					"PKCS#11: Cannot get slot information for provider '%s' slot %ld rv=%ld-'%s'",
2084
+					current_provider->manufacturerID,
2085
+					slots[slot_index],
2086
+					rv,
2087
+					pkcs11h_getMessage (rv)
2088
+				);
2089
+
2090
+				/*
2091
+				 * Ignore error
2092
+				 */
2093
+				rv = CKR_OK;
2094
+			}
2095
+		}
2096
+
2097
+		if (rv != CKR_OK) {
2098
+			PKCS11H_DEBUG (
2099
+				PKCS11H_LOG_DEBUG1,
2100
+				"PKCS#11: Cannot get slot list for provider '%s' rv=%ld-'%s'",
2101
+				current_provider->manufacturerID,
2102
+				rv,
2103
+				pkcs11h_getMessage (rv)
2104
+			);
2105
+
2106
+			/*
2107
+			 * Ignore error
2108
+			 */
2109
+			rv = CKR_OK;
2110
+		}
2111
+
2112
+		if (slots != NULL) {
2113
+			_pkcs11h_free ((void *)&slots);
2114
+			slots = NULL;
2115
+		}
2116
+
2117
+		if (!fFound) {
2118
+			current_provider = current_provider->next;
2119
+		}
2120
+	}
2121
+
2122
+	if (rv == CKR_OK && !fFound) {
2123
+		rv = CKR_SLOT_ID_INVALID;
2124
+	}
2125
+
2126
+	if (
2127
+		rv == CKR_OK &&
2128
+		(rv = current_provider->f->C_GetTokenInfo (selected_slot, &info)) == CKR_OK
2129
+	) {
2130
+		rv = _pkcs11h_getTokenId (
2131
+			&info,
2132
+			p_token_id
2133
+		);
2134
+	}
2135
+
2136
+	PKCS11H_DEBUG (
2137
+		PKCS11H_LOG_DEBUG2,
2138
+		"PKCS#11: _pkcs11h_locate_getTokenIdBySlotName return rv=%ld-'%s' *p_token_id=%p",
2139
+		rv,
2140
+		pkcs11h_getMessage (rv),
2141
+		(void *)*p_token_id
2142
+	);
2143
+
2144
+	return rv; 
1885 2145
 }
1886 2146
 
2147
+static
1887 2148
 CK_RV
1888
-pkcs11h_setPINCachePeriod (
1889
-	IN const int nPINCachePeriod
2149
+_pkcs11h_locate_getTokenIdByLabel (
2150
+	IN const char * const szLabel,
2151
+	OUT pkcs11h_token_id_t * const p_token_id
1890 2152
 ) {
1891
-	PKCS11ASSERT (pkcs11h_data!=NULL);
1892
-	PKCS11ASSERT (pkcs11h_data->fInitialized);
2153
+	pkcs11h_provider_t current_provider = NULL;
1893 2154
 
1894
-	pkcs11h_data->nPINCachePeriod = nPINCachePeriod;
2155
+	CK_SLOT_ID selected_slot = PKCS11H_INVALID_SLOT_ID;
2156
+	CK_TOKEN_INFO info;
2157
+	CK_RV rv = CKR_OK;
1895 2158
 
1896
-	return CKR_OK;
2159
+	PKCS11H_BOOL fFound = FALSE;
2160
+
2161
+	PKCS11H_ASSERT (szLabel!=NULL);
2162
+	PKCS11H_ASSERT (p_token_id!=NULL);
2163
+
2164
+	PKCS11H_DEBUG (
2165
+		PKCS11H_LOG_DEBUG2,
2166
+		"PKCS#11: _pkcs11h_locate_getTokenIdByLabel entry szLabel='%s', p_token_id=%p",
2167
+		szLabel,
2168
+		(void *)p_token_id
2169
+	);
2170
+
2171
+	*p_token_id = NULL;
2172
+
2173
+	current_provider = s_pkcs11h_data->providers;
2174
+	while (
2175
+		current_provider != NULL &&
2176
+		rv == CKR_OK &&
2177
+		!fFound
2178
+	) {
2179
+		CK_SLOT_ID_PTR slots = NULL;
2180
+		CK_ULONG slotnum;
2181
+		CK_SLOT_ID slot_index;
2182
+
2183
+		if (!current_provider->fEnabled) {
2184
+			continue;
2185
+		}
2186
+
2187
+		if (rv == CKR_OK) {
2188
+			rv = _pkcs11h_getSlotList (
2189
+				current_provider,
2190
+				CK_TRUE,
2191
+				&slots,
2192
+				&slotnum
2193
+			);
2194
+		}
2195
+
2196
+		for (
2197
+			slot_index=0;
2198
+			(
2199
+				slot_index < slotnum &&
2200
+				rv == CKR_OK &&
2201
+				!fFound
2202
+			);
2203
+			slot_index++
2204
+		) {
2205
+			CK_TOKEN_INFO info;
2206
+
2207
+			if (rv == CKR_OK) {
2208
+				rv = current_provider->f->C_GetTokenInfo (
2209
+					slots[slot_index],
2210
+					&info
2211
+				);
2212
+			}
2213
+
2214
+			if (rv == CKR_OK) {
2215
+				char szCurrentLabel[sizeof (info.label)+1];
2216
+		
2217
+				_pkcs11h_fixupFixedString (
2218
+					szCurrentLabel,
2219
+					(char *)info.label,
2220
+					sizeof (info.label)
2221
+				);
2222
+
2223
+				if (!strcmp (szCurrentLabel, szLabel)) {
2224
+					fFound = TRUE;
2225
+					selected_slot = slots[slot_index];
2226
+				}
2227
+			}
2228
+
2229
+			if (rv != CKR_OK) {
2230
+				PKCS11H_DEBUG (
2231
+					PKCS11H_LOG_DEBUG1,
2232
+					"PKCS#11: Cannot get token information for provider '%s' slot %ld rv=%ld-'%s'",
2233
+					current_provider->manufacturerID,
2234
+					slots[slot_index],
2235
+					rv,
2236
+					pkcs11h_getMessage (rv)
2237
+				);
2238
+
2239
+				/*
2240
+				 * Ignore error
2241
+				 */
2242
+				rv = CKR_OK;
2243
+			}
2244
+		}
2245
+
2246
+		if (rv != CKR_OK) {
2247
+			PKCS11H_DEBUG (
2248
+				PKCS11H_LOG_DEBUG1,
2249
+				"PKCS#11: Cannot get slot list for provider '%s' rv=%ld-'%s'",
2250
+				current_provider->manufacturerID,
2251
+				rv,
2252
+				pkcs11h_getMessage (rv)
2253
+			);
2254
+
2255
+			/*
2256
+			 * Ignore error
2257
+			 */
2258
+			rv = CKR_OK;
2259
+		}
2260
+
2261
+		if (slots != NULL) {
2262
+			_pkcs11h_free ((void *)&slots);
2263
+			slots = NULL;
2264
+		}
2265
+
2266
+		if (!fFound) {
2267
+			current_provider = current_provider->next;
2268
+		}
2269
+	}
2270
+
2271
+	if (rv == CKR_OK && !fFound) {
2272
+		rv = CKR_SLOT_ID_INVALID;
2273
+	}
2274
+
2275
+	if (
2276
+		rv == CKR_OK &&
2277
+		(rv = current_provider->f->C_GetTokenInfo (selected_slot, &info)) == CKR_OK
2278
+	) {
2279
+		rv = _pkcs11h_getTokenId (
2280
+			&info,
2281
+			p_token_id
2282
+		);
2283
+	}
2284
+
2285
+	PKCS11H_DEBUG (
2286
+		PKCS11H_LOG_DEBUG2,
2287
+		"PKCS#11: _pkcs11h_locate_getTokenIdByLabel return rv=%ld-'%s', *p_token_id=%p",
2288
+		rv,
2289
+		pkcs11h_getMessage (rv),
2290
+		(void *)*p_token_id
2291
+	);
2292
+
2293
+	return rv;
1897 2294
 }
1898 2295
 
1899 2296
 CK_RV
1900
-pkcs11h_addProvider (
1901
-	IN const char * const szProvider,
1902
-	IN const char * const szSignMode
2297
+pkcs11h_locate_token (
2298
+	IN const char * const szSlotType,
2299
+	IN const char * const szSlot,
2300
+	OUT pkcs11h_token_id_t * const p_token_id
1903 2301
 ) {
1904
-	pkcs11h_provider_t provider = NULL;
1905
-	CK_C_GetFunctionList gfl = NULL;
1906
-#if defined(WIN32)
1907
-	int mypid = 0;
1908
-#else
1909
-	pid_t mypid = getpid ();
2302
+#if defined(ENABLE_PKCS11H_THREADING)
2303
+	PKCS11H_BOOL fMutexLocked = FALSE;
1910 2304
 #endif
2305
+
2306
+	pkcs11h_token_id_t dummy_token_id = NULL;
2307
+	pkcs11h_token_id_t token_id = NULL;
2308
+	PKCS11H_BOOL fFound = FALSE;
2309
+	
1911 2310
 	CK_RV rv = CKR_OK;
1912 2311
 
1913
-	PKCS11ASSERT (pkcs11h_data!=NULL);
1914
-	PKCS11ASSERT (pkcs11h_data->fInitialized);
1915
-	PKCS11ASSERT (szProvider!=NULL);
2312
+	PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
2313
+	PKCS11H_ASSERT (s_pkcs11h_data->fInitialized);
2314
+	PKCS11H_ASSERT (szSlotType!=NULL);
2315
+	PKCS11H_ASSERT (szSlot!=NULL);
2316
+	PKCS11H_ASSERT (p_token_id!=NULL);
1916 2317
 
1917
-	PKCS11DLOG (
1918
-		PKCS11_LOG_DEBUG2,
1919
-		"PKCS#11: pkcs11h_addProvider entry pid=%d, szProvider=%s, szSignMode=%s",
1920
-		mypid,
1921
-		szProvider,
1922
-		szSignMode
2318
+	PKCS11H_DEBUG (
2319
+		PKCS11H_LOG_DEBUG2,
2320
+		"PKCS#11: pkcs11h_locate_token entry szSlotType='%s', szSlot='%s', p_token_id=%p",
2321
+		szSlotType,
2322
+		szSlot,
2323
+		(void *)p_token_id
1923 2324
 	);
1924 2325
 
2326
+	*p_token_id = NULL;
2327
+
2328
+#if defined(ENABLE_PKCS11H_THREADING)
1925 2329
 	if (
1926 2330
 		rv == CKR_OK &&
1927
-		(provider = (pkcs11h_provider_t)malloc (sizeof (struct pkcs11h_provider_s))) == NULL
2331
+		(rv = _pkcs11h_mutexLock (&s_pkcs11h_data->mutexGlobal)) == CKR_OK
1928 2332
 	) {
1929
-		rv = CKR_HOST_MEMORY;
2333
+		fMutexLocked = TRUE;
1930 2334
 	}
2335
+#endif
1931 2336
 
1932
-	if (rv == CKR_OK) {
1933
-		memset (provider, 0, sizeof (struct pkcs11h_provider_s));
1934
-		provider->szName = strdup (szProvider);
1935
-		
1936
-		if (szSignMode == NULL) {
1937
-			provider->szSignMode = strdup ("auto");
2337
+	if (
2338
+		rv == CKR_OK &&
2339
+		(rv = _pkcs11h_newTokenId (&dummy_token_id)) == CKR_OK
2340
+	) {
2341
+		/*
2342
+		 * Temperary slot id
2343
+		 */
2344
+		strcpy (dummy_token_id->label, "SLOT(");
2345
+		strncat (dummy_token_id->label, szSlotType, sizeof (dummy_token_id->label)-1-strlen (dummy_token_id->label));
2346
+		strncat (dummy_token_id->label, "=", sizeof (dummy_token_id->label)-1-strlen (dummy_token_id->label));
2347
+		strncat (dummy_token_id->label, szSlot, sizeof (dummy_token_id->label)-1-strlen (dummy_token_id->label));
2348
+		strncat (dummy_token_id->label, ")", sizeof (dummy_token_id->label)-1-strlen (dummy_token_id->label));
2349
+		dummy_token_id->label[sizeof (dummy_token_id->label)-1] = 0;
2350
+	}
2351
+
2352
+	while (rv == CKR_OK && !fFound) {
2353
+		if (!strcmp (szSlotType, "id")) {
2354
+			rv = _pkcs11h_locate_getTokenIdBySlotId (
2355
+				szSlot,
2356
+				&token_id
2357
+			);
2358
+		}
2359
+		else if (!strcmp (szSlotType, "name")) {
2360
+			rv = _pkcs11h_locate_getTokenIdBySlotName (
2361
+				szSlot,
2362
+				&token_id
2363
+			);
2364
+		}
2365
+		else if (!strcmp (szSlotType, "label")) {
2366
+			rv = _pkcs11h_locate_getTokenIdByLabel (
2367
+				szSlot,
2368
+				&token_id
2369
+			);
1938 2370
 		}
1939 2371
 		else {
1940
-			provider->szSignMode = strdup (szSignMode);
2372
+			rv = CKR_ARGUMENTS_BAD;
1941 2373
 		}
1942
-		if (provider->szSignMode == NULL) {
1943
-			rv = CKR_HOST_MEMORY;
2374
+
2375
+		if (rv == CKR_OK) {
2376
+			fFound = TRUE;
1944 2377
 		}
1945
-	}
1946
-		
1947
-	if (rv == CKR_OK) {
1948
-#if defined(WIN32)
1949
-		provider->hLibrary = LoadLibrary (szProvider);
1950
-#else
1951
-		provider->hLibrary = dlopen (szProvider, RTLD_NOW);
1952
-#endif
1953
-		if (provider->hLibrary == NULL) {
1954
-			rv = CKR_FUNCTION_FAILED;
2378
+
2379
+		if (!fFound && rv != CKR_ARGUMENTS_BAD) {
2380
+
2381
+			PKCS11H_DEBUG (
2382
+				PKCS11H_LOG_DEBUG1,
2383
+				"PKCS#11: pkcs11h_locate_token failed rv=%ld-'%s'",
2384
+				rv,
2385
+				pkcs11h_getMessage (rv)
2386
+			);
2387
+
2388
+			/*
2389
+			 * Ignore error
2390
+			 */
2391
+			rv = CKR_OK;
2392
+
2393
+			PKCS11H_DEBUG (
2394
+				PKCS11H_LOG_DEBUG1,
2395
+				"PKCS#11: Calling token_prompt hook for '%s'",
2396
+				dummy_token_id->label
2397
+			);
2398
+	
2399
+			if (
2400
+				!s_pkcs11h_data->hooks.token_prompt (
2401
+					s_pkcs11h_data->hooks.token_prompt_data,
2402
+					dummy_token_id
2403
+				)
2404
+			) {
2405
+				rv = CKR_CANCEL;
2406
+			}
2407
+
2408
+			PKCS11H_DEBUG (
2409
+				PKCS11H_LOG_DEBUG1,
2410
+				"PKCS#11: token_prompt returned %ld",
2411
+				rv
2412
+			);
1955 2413
 		}
1956 2414
 	}
1957 2415
 
1958
-	if (rv == CKR_OK) {
1959
-#if defined(WIN32)
1960
-		gfl = (CK_C_GetFunctionList)GetProcAddress (
1961
-			provider->hLibrary,
1962
-			"C_GetFunctionList"
1963
-		);
1964
-#else
1965
-		/*
1966
-		 * Make compiler happy!
1967
-		 */
1968
-		void *p = dlsym (
1969
-			provider->hLibrary,
1970
-			"C_GetFunctionList"
1971
-		);
1972
-		memmove (
1973
-			&gfl, 
1974
-			&p,
1975
-			sizeof (void *)
1976
-		);
1977
-#endif
1978
-		if (gfl == NULL) {
1979
-			rv = CKR_FUNCTION_FAILED;
1980
-		}
2416
+	if (rv == CKR_OK && !fFound) {
2417
+		rv = CKR_SLOT_ID_INVALID;
1981 2418
 	}
1982 2419
 
1983 2420
 	if (rv == CKR_OK) {
1984
-		rv = gfl (&provider->f);
2421
+		*p_token_id = token_id;
2422
+		token_id = NULL;
1985 2423
 	}
1986 2424
 
1987
-	if (rv == CKR_OK) {
1988
-		if ((rv = provider->f->C_Initialize (NULL)) != CKR_OK) {
1989
-			if (rv == CKR_CRYPTOKI_ALREADY_INITIALIZED) {
1990
-				rv = CKR_OK;
2425
+	if (dummy_token_id != NULL) {
2426
+		pkcs11h_freeTokenId (dummy_token_id);
2427
+		dummy_token_id = NULL;
2428
+	}
2429
+
2430
+#if defined(ENABLE_PKCS11H_THREADING)
2431
+	if (fMutexLocked) {
2432
+		_pkcs11h_mutexRelease (&s_pkcs11h_data->mutexGlobal);
2433
+		fMutexLocked = FALSE;
2434
+	}
2435
+#endif
2436
+
2437
+	PKCS11H_DEBUG (
2438
+		PKCS11H_LOG_DEBUG2,
2439
+		"PKCS#11: pkcs11h_locate_token return rv=%ld-'%s', *p_token_id=%p",
2440
+		rv,
2441
+		pkcs11h_getMessage (rv),
2442
+		(void *)*p_token_id
2443
+	);
2444
+
2445
+	return rv;
2446
+}
2447
+
2448
+#endif				/* ENABLE_PKCS11H_TOKEN || ENABLE_PKCS11H_CERTIFICATE */
2449
+
2450
+#if defined(ENABLE_PKCS11H_CERTIFICATE)
2451
+
2452
+static
2453
+void
2454
+_pkcs11h_locate_hexToBinary (
2455
+	OUT unsigned char * const target,
2456
+	IN const char * const szSource,
2457
+	IN OUT size_t * const p_target_size
2458
+) {
2459
+	size_t target_max_size;
2460
+	const char *p;
2461
+	char buf[3] = {'\0', '\0', '\0'};
2462
+	int i = 0;
2463
+
2464
+	PKCS11H_ASSERT (szSource!=NULL);
2465
+	PKCS11H_ASSERT (target!=NULL);
2466
+	PKCS11H_ASSERT (p_target_size!=NULL);
2467
+
2468
+	target_max_size = *p_target_size;
2469
+	p = szSource;
2470
+	*p_target_size = 0;
2471
+
2472
+	while (*p != '\0' && *p_target_size < target_max_size) {
2473
+		if (isxdigit (*p)) {
2474
+			buf[i%2] = *p;
2475
+
2476
+			if ((i%2) == 1) {
2477
+				unsigned v;
2478
+				if (sscanf (buf, "%x", &v) != 1) {
2479
+					v = 0;
2480
+				}
2481
+				target[*p_target_size] = v & 0xff;
2482
+				(*p_target_size)++;
1991 2483
 			}
2484
+
2485
+			i++;
1992 2486
 		}
1993
-		else {
1994
-			provider->fShouldFinalize = true;
1995
-		}
2487
+		p++;
1996 2488
 	}
2489
+}
2490
+
2491
+static
2492
+CK_RV
2493
+_pkcs11h_locate_getCertificateIdByLabel (
2494
+	IN const pkcs11h_session_t session,
2495
+	IN OUT const pkcs11h_certificate_id_t certificate_id,
2496
+	IN const char * const szLabel
2497
+) {
2498
+	CK_OBJECT_CLASS cert_filter_class = CKO_CERTIFICATE;
2499
+	CK_ATTRIBUTE cert_filter[] = {
2500
+		{CKA_CLASS, &cert_filter_class, sizeof (cert_filter_class)},
2501
+		{CKA_LABEL, (CK_BYTE_PTR)szLabel, strlen (szLabel)}
2502
+	};
2503
+
2504
+	CK_OBJECT_HANDLE *objects = NULL;
2505
+	CK_ULONG objects_found = 0;
2506
+	CK_RV rv = CKR_OK;
2507
+
2508
+	CK_ULONG i;
2509
+
2510
+	PKCS11H_ASSERT (session!=NULL);
2511
+	PKCS11H_ASSERT (certificate_id!=NULL);
2512
+	PKCS11H_ASSERT (szLabel!=NULL);
2513
+
2514
+	PKCS11H_DEBUG (
2515
+		PKCS11H_LOG_DEBUG2,
2516
+		"PKCS#11: _pkcs11h_locate_getCertificateIdByLabel entry session=%p, certificate_id=%p, szLabel='%s'",
2517
+		(void *)session,
2518
+		(void *)certificate_id,
2519
+		szLabel
2520
+	);
1997 2521
 
1998 2522
 	if (rv == CKR_OK) {
1999
-		provider->fEnabled = true;
2523
+		rv = _pkcs11h_validateSession (session);
2000 2524
 	}
2001 2525
 
2002
-	if (provider != NULL) {
2003
-		if (pkcs11h_data->providers == NULL) {
2004
-			pkcs11h_data->providers = provider;
2526
+	if (rv == CKR_OK) {
2527
+		rv = _pkcs11h_findObjects (
2528
+			session,
2529
+			cert_filter,
2530
+			sizeof (cert_filter) / sizeof (CK_ATTRIBUTE),
2531
+			&objects,
2532
+			&objects_found
2533
+		);
2534
+	}
2535
+
2536
+	for (i=0;rv == CKR_OK && i < objects_found;i++) {
2537
+		CK_ATTRIBUTE attrs[] = {
2538
+			{CKA_ID, NULL, 0},
2539
+			{CKA_VALUE, NULL, 0}
2540
+		};
2541
+
2542
+		if (rv == CKR_OK) {
2543
+			rv = _pkcs11h_getObjectAttributes (
2544
+				session,
2545
+				objects[i],
2546
+				attrs,
2547
+				sizeof (attrs) / sizeof (CK_ATTRIBUTE)
2548
+			);
2005 2549
 		}
2006
-		else {
2007
-			pkcs11h_provider_t last = NULL;
2008
-	
2009
-			for (
2010
-				last = pkcs11h_data->providers;
2011
-				last->next != NULL;
2012
-				last = last->next
2550
+
2551
+		if (
2552
+			rv == CKR_OK &&
2553
+			_pkcs11h_isBetterCertificate (
2554
+				certificate_id->certificate_blob,
2555
+				certificate_id->certificate_blob_size,
2556
+				attrs[1].pValue,
2557
+				attrs[1].ulValueLen
2558
+			)
2559
+		) {
2560
+			if (certificate_id->attrCKA_ID != NULL) {
2561
+				_pkcs11h_free ((void *)&certificate_id->attrCKA_ID);
2562
+			}
2563
+			if (certificate_id->certificate_blob != NULL) {
2564
+				_pkcs11h_free ((void *)&certificate_id->certificate_blob);
2565
+			}
2566
+			rv = _pkcs11h_dupmem (
2567
+				(void *)&certificate_id->attrCKA_ID,
2568
+				&certificate_id->attrCKA_ID_size,
2569
+				attrs[0].pValue,
2570
+				attrs[0].ulValueLen
2013 2571
 			);
2014
-			last->next = provider;
2572
+			rv = _pkcs11h_dupmem (
2573
+				(void *)&certificate_id->certificate_blob,
2574
+				&certificate_id->certificate_blob_size,
2575
+				attrs[1].pValue,
2576
+				attrs[1].ulValueLen
2577
+			);
2578
+		}
2579
+
2580
+		if (rv != CKR_OK) {
2581
+			PKCS11H_DEBUG (
2582
+				PKCS11H_LOG_DEBUG1,
2583
+				"PKCS#11: Cannot get object attribute for provider '%s' object %ld rv=%ld-'%s'",
2584
+				session->provider->manufacturerID,
2585
+				objects[i],
2586
+				rv,
2587
+				pkcs11h_getMessage (rv)
2588
+			);
2589
+
2590
+			/*
2591
+			 * Ignore error
2592
+			 */
2593
+			rv = CKR_OK;
2015 2594
 		}
2595
+
2596
+		_pkcs11h_freeObjectAttributes (
2597
+			attrs,
2598
+			sizeof (attrs) / sizeof (CK_ATTRIBUTE)
2599
+		);
2600
+	}
2601
+	
2602
+	if (
2603
+		rv == CKR_OK &&
2604
+		certificate_id->certificate_blob == NULL
2605
+	) {
2606
+		rv = CKR_ATTRIBUTE_VALUE_INVALID;
2016 2607
 	}
2017 2608
 
2018
-	PKCS11DLOG (
2019
-		PKCS11_LOG_DEBUG2,
2020
-		"PKCS#11: pkcs11h_addProvider return rv=%ld-'%s'",
2609
+	if (objects != NULL) {
2610
+		_pkcs11h_free ((void *)&objects);
2611
+	}
2612
+
2613
+	/*
2614
+	 * No need to free allocated objects
2615
+	 * on error, since the certificate_id
2616
+	 * should be free by caller.
2617
+	 */
2618
+
2619
+	PKCS11H_DEBUG (
2620
+		PKCS11H_LOG_DEBUG2,
2621
+		"PKCS#11: _pkcs11h_locate_getCertificateIdByLabel return rv=%ld-'%s'",
2021 2622
 		rv,
2022 2623
 		pkcs11h_getMessage (rv)
2023 2624
 	);
... ...
@@ -2025,371 +6599,1001 @@ pkcs11h_addProvider (
2025 2025
 	return rv;
2026 2026
 }
2027 2027
 
2028
+static
2028 2029
 CK_RV
2029
-pkcs11h_forkFixup () {
2030
-#if defined(WIN32)
2031
-	int mypid = 0;
2032
-#else
2033
-	pid_t mypid = getpid ();
2034
-#endif
2030
+_pkcs11h_locate_getCertificateIdBySubject (
2031
+	IN const pkcs11h_session_t session,
2032
+	IN OUT const pkcs11h_certificate_id_t certificate_id,
2033
+	IN const char * const szSubject
2034
+) {
2035
+	CK_OBJECT_CLASS cert_filter_class = CKO_CERTIFICATE;
2036
+	CK_ATTRIBUTE cert_filter[] = {
2037
+		{CKA_CLASS, &cert_filter_class, sizeof (cert_filter_class)}
2038
+	};
2035 2039
 
2036
-	PKCS11DLOG (
2037
-		PKCS11_LOG_DEBUG2,
2038
-		"PKCS#11: pkcs11h_forkFixup entry pid=%d",
2039
-		mypid
2040
+	CK_OBJECT_HANDLE *objects = NULL;
2041
+	CK_ULONG objects_found = 0;
2042
+	CK_RV rv = CKR_OK;
2043
+
2044
+	CK_ULONG i;
2045
+
2046
+	PKCS11H_ASSERT (session!=NULL);
2047
+	PKCS11H_ASSERT (certificate_id!=NULL);
2048
+	PKCS11H_ASSERT (szSubject!=NULL);
2049
+
2050
+	PKCS11H_DEBUG (
2051
+		PKCS11H_LOG_DEBUG2,
2052
+		"PKCS#11: _pkcs11h_locate_getCertificateIdBySubject entry session=%p, certificate_id=%p, szSubject=%s",
2053
+		(void *)session,
2054
+		(void *)certificate_id,
2055
+		szSubject
2040 2056
 	);
2041 2057
 
2042
-	if (pkcs11h_data != NULL && pkcs11h_data->fInitialized) {
2058
+	if (rv == CKR_OK) {
2059
+		rv = _pkcs11h_validateSession (session);
2060
+	}
2061
+
2062
+	if (rv == CKR_OK) {
2063
+		rv = _pkcs11h_findObjects (
2064
+			session,
2065
+			cert_filter,
2066
+			sizeof (cert_filter) / sizeof (CK_ATTRIBUTE),
2067
+			&objects,
2068
+			&objects_found
2069
+		);
2070
+	}
2043 2071
 
2044
-		pkcs11h_provider_t current;
2072
+	for (i=0;rv == CKR_OK && i < objects_found;i++) {
2073
+		CK_ATTRIBUTE attrs[] = {
2074
+			{CKA_ID, NULL, 0},
2075
+			{CKA_VALUE, NULL, 0}
2076
+		};
2077
+		char szCurrentSubject[1024];
2078
+		szCurrentSubject[0] = '\0';
2045 2079
 
2046
-		for (
2047
-			current = pkcs11h_data->providers;
2048
-			current != NULL;
2049
-			current = current->next
2080
+		if (rv == CKR_OK) {
2081
+			rv = _pkcs11h_getObjectAttributes (
2082
+				session,
2083
+				objects[i],
2084
+				attrs,
2085
+				sizeof (attrs) / sizeof (CK_ATTRIBUTE)
2086
+			);
2087
+		}
2088
+
2089
+		if (rv == CKR_OK) {
2090
+			X509 *x509 = NULL;
2091
+			pkcs11_openssl_d2i_t d2i1;
2092
+
2093
+			x509 = X509_new ();
2094
+
2095
+			d2i1 = (pkcs11_openssl_d2i_t)attrs[1].pValue;
2096
+			if (d2i_X509 (&x509, &d2i1, attrs[1].ulValueLen)) {
2097
+				X509_NAME_oneline (
2098
+					X509_get_subject_name (x509),
2099
+					szCurrentSubject,
2100
+					sizeof (szCurrentSubject)
2101
+				);
2102
+				szCurrentSubject[sizeof (szCurrentSubject) - 1] = '\0';
2103
+			}
2104
+
2105
+			if (x509 != NULL) {
2106
+				X509_free (x509);
2107
+				x509 = NULL;
2108
+			}
2109
+		}
2110
+
2111
+		if (
2112
+			rv == CKR_OK &&
2113
+			!strcmp (szSubject, szCurrentSubject) &&
2114
+			_pkcs11h_isBetterCertificate (
2115
+				certificate_id->certificate_blob,
2116
+				certificate_id->certificate_blob_size,
2117
+				attrs[1].pValue,
2118
+				attrs[1].ulValueLen
2119
+			)
2050 2120
 		) {
2051
-			if (current->fEnabled) {
2052
-				current->f->C_Initialize (NULL);
2121
+			if (certificate_id->attrCKA_ID != NULL) {
2122
+				_pkcs11h_free ((void *)&certificate_id->attrCKA_ID);
2123
+			}
2124
+			if (certificate_id->certificate_blob != NULL) {
2125
+				_pkcs11h_free ((void *)&certificate_id->certificate_blob);
2053 2126
 			}
2127
+			rv = _pkcs11h_dupmem (
2128
+				(void *)&certificate_id->attrCKA_ID,
2129
+				&certificate_id->attrCKA_ID_size,
2130
+				attrs[0].pValue,
2131
+				attrs[0].ulValueLen
2132
+			);
2133
+			rv = _pkcs11h_dupmem (
2134
+				(void *)&certificate_id->certificate_blob,
2135
+				&certificate_id->certificate_blob_size,
2136
+				attrs[1].pValue,
2137
+				attrs[1].ulValueLen
2138
+			);
2139
+		}
2140
+
2141
+		if (rv != CKR_OK) {
2142
+			PKCS11H_DEBUG (
2143
+				PKCS11H_LOG_DEBUG1,
2144
+				"PKCS#11: Cannot get object attribute for provider '%s' object %ld rv=%ld-'%s'",
2145
+				session->provider->manufacturerID,
2146
+				objects[i],
2147
+				rv,
2148
+				pkcs11h_getMessage (rv)
2149
+			);
2150
+
2151
+			/*
2152
+			 * Ignore error
2153
+			 */
2154
+			rv = CKR_OK;
2054 2155
 		}
2156
+
2157
+		_pkcs11h_freeObjectAttributes (
2158
+			attrs,
2159
+			sizeof (attrs) / sizeof (CK_ATTRIBUTE)
2160
+		);
2161
+	}
2162
+	
2163
+	if (
2164
+		rv == CKR_OK &&
2165
+		certificate_id->certificate_blob == NULL
2166
+	) {
2167
+		rv = CKR_ATTRIBUTE_VALUE_INVALID;
2055 2168
 	}
2056 2169
 
2057
-	PKCS11DLOG (
2058
-		PKCS11_LOG_DEBUG2,
2059
-		"PKCS#11: pkcs11h_forkFixup return"
2170
+	if (objects != NULL) {
2171
+		_pkcs11h_free ((void *)&objects);
2172
+	}
2173
+
2174
+	/*
2175
+	 * No need to free allocated objects
2176
+	 * on error, since the certificate_id
2177
+	 * should be free by caller.
2178
+	 */
2179
+
2180
+	PKCS11H_DEBUG (
2181
+		PKCS11H_LOG_DEBUG2,
2182
+		"PKCS#11: _pkcs11h_locate_getCertificateIdBySubject return rv=%ld-'%s'",
2183
+		rv,
2184
+		pkcs11h_getMessage (rv)
2060 2185
 	);
2061 2186
 
2062
-	return CKR_OK;
2187
+	return rv;
2063 2188
 }
2064 2189
 
2065 2190
 CK_RV
2066
-pkcs11h_createCertificateSession (
2191
+pkcs11h_locate_certificate (
2067 2192
 	IN const char * const szSlotType,
2068 2193
 	IN const char * const szSlot,
2069 2194
 	IN const char * const szIdType,
2070 2195
 	IN const char * const szId,
2071
-	IN const bool fProtectedAuthentication,
2072
-	IN const bool fCertPrivate,
2073
-	IN const int nPINCachePeriod,
2074
-	OUT pkcs11h_certificate_t * const p_pkcs11h_certificate
2196
+	OUT pkcs11h_certificate_id_t * const p_certificate_id
2075 2197
 ) {
2076
-	pkcs11h_certificate_t pkcs11h_certificate = NULL;
2198
+	pkcs11h_certificate_id_t certificate_id = NULL;
2199
+	pkcs11h_session_t session = NULL;
2200
+	PKCS11H_BOOL fOpSuccess = FALSE;
2201
+	PKCS11H_BOOL fLoginRetry = FALSE;
2202
+	
2077 2203
 	CK_RV rv = CKR_OK;
2078 2204
 
2079
-	bool fOpSuccess = false;
2080
-	bool fLogonRetry = false;
2081
-
2082
-	PKCS11ASSERT (pkcs11h_data!=NULL);
2083
-	PKCS11ASSERT (pkcs11h_data->fInitialized);
2084
-	PKCS11ASSERT (szSlotType!=NULL);
2085
-	PKCS11ASSERT (szSlot!=NULL);
2086
-	PKCS11ASSERT (szIdType!=NULL);
2087
-	PKCS11ASSERT (szId!=NULL);
2088
-	PKCS11ASSERT (p_pkcs11h_certificate!=NULL);
2089
-
2090
-	PKCS11DLOG (
2091
-		PKCS11_LOG_DEBUG2,
2092
-		"PKCS#11: pkcs11h_createSession entry szSlotType=%s, szSlot=%s, szIdType=%s, szId=%s, fProtectedAuthentication=%d, fCertPrivate=%d, nPINCachePeriod=%d, p_pkcs11h_certificate=%p",
2205
+	PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
2206
+	PKCS11H_ASSERT (s_pkcs11h_data->fInitialized);
2207
+	PKCS11H_ASSERT (szSlotType!=NULL);
2208
+	PKCS11H_ASSERT (szSlot!=NULL);
2209
+	PKCS11H_ASSERT (szIdType!=NULL);
2210
+	PKCS11H_ASSERT (szId!=NULL);
2211
+	PKCS11H_ASSERT (p_certificate_id!=NULL);
2212
+
2213
+	PKCS11H_DEBUG (
2214
+		PKCS11H_LOG_DEBUG2,
2215
+		"PKCS#11: pkcs11h_locateCertificate entry szSlotType='%s', szSlot='%s', szIdType='%s', szId='%s', p_certificate_id=%p",
2093 2216
 		szSlotType,
2094 2217
 		szSlot,
2095 2218
 		szIdType,
2096 2219
 		szId,
2097
-		fProtectedAuthentication ? 1 : 0,
2098
-		fCertPrivate ? 1 : 0,
2099
-		nPINCachePeriod,
2100
-		(void *)p_pkcs11h_certificate
2220
+		(void *)p_certificate_id
2101 2221
 	);
2102 2222
 
2103
-	if (
2104
-		rv == CKR_OK &&
2105
-		(pkcs11h_certificate = (pkcs11h_certificate_t)malloc (sizeof (struct pkcs11h_certificate_s))) == NULL
2106
-	) {
2107
-		rv = CKR_HOST_MEMORY;
2108
-	}
2223
+	*p_certificate_id = NULL;
2109 2224
 
2110 2225
 	if (rv == CKR_OK) {
2111
-		*p_pkcs11h_certificate = pkcs11h_certificate;
2112
-		memset (pkcs11h_certificate, 0, sizeof (struct pkcs11h_certificate_s));
2113
-	}
2114
-	
2115
-	if (rv == CKR_OK) {
2116
-		pkcs11h_certificate->hKey = PKCS11H_INVALID_OBJECT_HANDLE;
2117
-		pkcs11h_certificate->fCertPrivate = fCertPrivate;
2226
+		rv = _pkcs11h_newCertificateId (&certificate_id);
2118 2227
 	}
2119 2228
 
2120 2229
 	if (rv == CKR_OK) {
2121
-		rv = _pkcs11h_getSession (
2230
+		rv = pkcs11h_locate_token (
2122 2231
 			szSlotType,
2123 2232
 			szSlot,
2124
-			fProtectedAuthentication,
2125
-			nPINCachePeriod,
2126
-			&pkcs11h_certificate->session
2233
+			&certificate_id->token_id
2234
+		);
2235
+	}
2236
+
2237
+	if (rv == CKR_OK) {
2238
+		rv = _pkcs11h_getSessionByTokenId (
2239
+			certificate_id->token_id,
2240
+			&session
2127 2241
 		);
2128 2242
 	}
2129 2243
 
2130
-	fOpSuccess = false;
2131
-	fLogonRetry = false;
2132 2244
 	while (rv == CKR_OK && !fOpSuccess) {
2133
-		if (rv == CKR_OK) {
2134
-			/*
2135
-			 * Don't repeat this if succeeded in
2136
-			 * unauthenticated session
2137
-			 */
2138
-			if (pkcs11h_certificate->certificate == NULL) {
2139
-				rv = _pkcs11h_setCertificateSession_Certificate (
2140
-					pkcs11h_certificate,
2141
-					szIdType,
2142
-					szId
2245
+#if defined(ENABLE_PKCS11H_THREADING)
2246
+		PKCS11H_BOOL fMutexLocked = FALSE;
2247
+#endif
2248
+
2249
+#if defined(ENABLE_PKCS11H_THREADING)
2250
+		if (
2251
+			rv == CKR_OK &&
2252
+			(rv = _pkcs11h_mutexLock (&s_pkcs11h_data->mutexGlobal)) == CKR_OK
2253
+		) {
2254
+			fMutexLocked = TRUE;
2255
+		}
2256
+#endif
2257
+
2258
+		if (!strcmp (szIdType, "id")) {
2259
+			certificate_id->attrCKA_ID_size = strlen (szId)/2;
2260
+
2261
+			if (
2262
+				rv == CKR_OK &&
2263
+				(rv = _pkcs11h_malloc (
2264
+					(void*)&certificate_id->attrCKA_ID,
2265
+					certificate_id->attrCKA_ID_size
2266
+				)) == CKR_OK
2267
+			) {
2268
+				_pkcs11h_locate_hexToBinary (
2269
+					certificate_id->attrCKA_ID,
2270
+					szId,
2271
+					&certificate_id->attrCKA_ID_size
2143 2272
 				);
2144 2273
 			}
2145 2274
 		}
2275
+		else if (!strcmp (szIdType, "label")) {
2276
+			rv = _pkcs11h_locate_getCertificateIdByLabel (
2277
+				session,
2278
+				certificate_id,
2279
+				szId
2280
+			);
2281
+		}
2282
+		else if (!strcmp (szIdType, "subject")) {
2283
+			rv = _pkcs11h_locate_getCertificateIdBySubject (
2284
+				session,
2285
+				certificate_id,
2286
+				szId
2287
+			);
2288
+		}
2289
+		else {
2290
+			rv = CKR_ARGUMENTS_BAD;
2291
+		}
2292
+
2293
+#if defined(ENABLE_PKCS11H_THREADING)
2294
+		if (fMutexLocked) {
2295
+			_pkcs11h_mutexRelease (&s_pkcs11h_data->mutexGlobal);
2296
+			fMutexLocked = FALSE;
2297
+		}
2298
+#endif
2146 2299
 
2147 2300
 		if (rv == CKR_OK) {
2148
-			fOpSuccess = true;
2301
+			fOpSuccess = TRUE;
2149 2302
 		}
2150 2303
 		else {
2151
-			if (!fLogonRetry) {
2152
-				fLogonRetry = true;
2304
+			if (!fLoginRetry) {
2305
+				PKCS11H_DEBUG (
2306
+					PKCS11H_LOG_DEBUG1,
2307
+					"PKCS#11: Get certificate failed: %ld:'%s'",
2308
+					rv,
2309
+					pkcs11h_getMessage (rv)
2310
+				);
2311
+
2153 2312
 				rv = _pkcs11h_login (
2154
-					pkcs11h_certificate->session,
2155
-					!pkcs11h_certificate->fCertPrivate
2313
+					session,
2314
+					TRUE,
2315
+					TRUE,
2316
+					(
2317
+						PKCS11H_PROMPT_MASK_ALLOW_PIN_PROMPT |
2318
+						PKCS11H_PROMPT_MAST_ALLOW_CARD_PROMPT 
2319
+					)
2156 2320
 				);
2321
+
2322
+				fLoginRetry = TRUE;
2157 2323
 			}
2158 2324
 		}
2159 2325
 	}
2160 2326
 
2161
-	PKCS11DLOG (
2162
-		PKCS11_LOG_DEBUG2,
2163
-		"PKCS#11: pkcs11h_createSession return rv=%ld-'%s'",
2327
+	if (rv == CKR_OK) {
2328
+		*p_certificate_id = certificate_id;
2329
+		certificate_id = NULL;
2330
+	}
2331
+
2332
+	if (certificate_id != NULL) {
2333
+		pkcs11h_freeCertificateId (certificate_id);
2334
+		certificate_id = NULL;
2335
+	}
2336
+
2337
+	if (session != NULL) {
2338
+		_pkcs11h_releaseSession (session);
2339
+		session = NULL;
2340
+	}
2341
+
2342
+	PKCS11H_DEBUG (
2343
+		PKCS11H_LOG_DEBUG2,
2344
+		"PKCS#11: pkcs11h_locateCertificate return rv=%ld-'%s' *p_certificate_id=%p",
2164 2345
 		rv,
2165
-		pkcs11h_getMessage (rv)
2346
+		pkcs11h_getMessage (rv),
2347
+		(void *)*p_certificate_id
2166 2348
 	);
2167 2349
 	
2168 2350
 	return rv;
2169 2351
 }
2170 2352
 
2353
+#endif				/* ENABLE_PKCS11H_CERTIFICATE */
2354
+
2355
+#endif				/* ENABLE_PKCS11H_LOCATE */
2356
+
2357
+#if defined(ENABLE_PKCS11H_ENUM)
2358
+/*======================================================================*
2359
+ * ENUM INTERFACE
2360
+ *======================================================================*/
2361
+
2362
+#if defined(ENABLE_PKCS11H_TOKEN)
2363
+
2364
+CK_RV
2365
+pkcs11h_freeTokenIdList (
2366
+	IN const pkcs11h_token_id_list_t token_id_list
2367
+) {
2368
+	pkcs11h_token_id_list_t _id = token_id_list;
2369
+
2370
+	PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
2371
+	PKCS11H_ASSERT (s_pkcs11h_data->fInitialized);
2372
+	/*PKCS11H_ASSERT (token_id_list!=NULL); NOT NEEDED*/
2373
+
2374
+	PKCS11H_DEBUG (
2375
+		PKCS11H_LOG_DEBUG2,
2376
+		"PKCS#11: pkcs11h_freeTokenIdList entry token_id_list=%p",
2377
+		(void *)token_id_list
2378
+	);
2379
+
2380
+	while (_id != NULL) {
2381
+		pkcs11h_token_id_list_t x = _id;
2382
+		_id = _id->next;
2383
+		if (x->token_id != NULL) {
2384
+			pkcs11h_freeTokenId (x->token_id);
2385
+		}
2386
+		x->next = NULL;
2387
+		_pkcs11h_free ((void *)&x);
2388
+	}
2389
+
2390
+	PKCS11H_DEBUG (
2391
+		PKCS11H_LOG_DEBUG2,
2392
+		"PKCS#11: pkcs11h_freeTokenIdList return"
2393
+	);
2394
+
2395
+	return CKR_OK;
2396
+}
2397
+
2171 2398
 CK_RV
2172
-pkcs11h_freeCertificateSession (
2173
-	IN const pkcs11h_certificate_t pkcs11h_certificate
2399
+pkcs11h_enum_getTokenIds (
2400
+	IN const int method,
2401
+	OUT pkcs11h_token_id_list_t * const p_token_id_list
2174 2402
 ) {
2175
-	PKCS11DLOG (
2176
-		PKCS11_LOG_DEBUG2,
2177
-		"PKCS#11: pkcs11h_freeCertificateSession entry pkcs11h_certificate=%p",
2178
-		(void *)pkcs11h_certificate
2403
+#if defined(ENABLE_PKCS11H_THREADING)
2404
+	PKCS11H_BOOL fMutexLocked = FALSE;
2405
+#endif
2406
+
2407
+	pkcs11h_token_id_list_t token_id_list = NULL;
2408
+	pkcs11h_provider_t current_provider;
2409
+	CK_RV rv = CKR_OK;
2410
+
2411
+	PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
2412
+	PKCS11H_ASSERT (s_pkcs11h_data->fInitialized);
2413
+	PKCS11H_ASSERT (p_token_id_list!=NULL);
2414
+
2415
+	PKCS11H_DEBUG (
2416
+		PKCS11H_LOG_DEBUG2,
2417
+		"PKCS#11: pkcs11h_enum_getTokenIds entry p_token_id_list=%p",
2418
+		(void *)p_token_id_list
2179 2419
 	);
2180 2420
 
2181
-	if (pkcs11h_certificate != NULL) {
2182
-		if (pkcs11h_certificate->session != NULL) {
2183
-			_pkcs11h_releaseSession (pkcs11h_certificate->session);
2421
+	*p_token_id_list = NULL;
2422
+
2423
+#if defined(ENABLE_PKCS11H_THREADING)
2424
+	if (
2425
+		rv == CKR_OK &&
2426
+		(rv = _pkcs11h_mutexLock (&s_pkcs11h_data->mutexGlobal)) == CKR_OK
2427
+	) {
2428
+		fMutexLocked = TRUE;
2429
+	}
2430
+#endif
2431
+
2432
+	for (
2433
+		current_provider = s_pkcs11h_data->providers;
2434
+		(
2435
+			current_provider != NULL &&
2436
+			rv == CKR_OK
2437
+		);
2438
+		current_provider = current_provider->next
2439
+	) {
2440
+		CK_SLOT_ID_PTR slots = NULL;
2441
+		CK_ULONG slotnum;
2442
+		CK_SLOT_ID slot_index;
2443
+
2444
+		if (!current_provider->fEnabled) {
2445
+			continue;
2184 2446
 		}
2185
-		if (pkcs11h_certificate->certificate != NULL) {
2186
-			free (pkcs11h_certificate->certificate);
2447
+
2448
+		if (rv == CKR_OK) {
2449
+			rv = _pkcs11h_getSlotList (
2450
+				current_provider,
2451
+				CK_TRUE,
2452
+				&slots,
2453
+				&slotnum
2454
+			);
2187 2455
 		}
2188
-		if (pkcs11h_certificate->certificate_id != NULL) {
2189
-			free (pkcs11h_certificate->certificate_id);
2456
+
2457
+		for (
2458
+			slot_index=0;
2459
+			(
2460
+				slot_index < slotnum &&
2461
+				rv == CKR_OK
2462
+			);
2463
+			slot_index++
2464
+		) {
2465
+			pkcs11h_token_id_list_t entry = NULL;
2466
+			CK_TOKEN_INFO info;
2467
+
2468
+			if (rv == CKR_OK) {
2469
+				rv = _pkcs11h_malloc ((void *)&entry, sizeof (struct pkcs11h_token_id_list_s));
2470
+			}
2471
+
2472
+			if (rv == CKR_OK) {
2473
+				rv = current_provider->f->C_GetTokenInfo (
2474
+					slots[slot_index],
2475
+					&info
2476
+				);
2477
+			}
2478
+
2479
+			if (rv == CKR_OK) {
2480
+				rv = _pkcs11h_getTokenId (
2481
+					&info,
2482
+					&entry->token_id
2483
+				);
2484
+			}
2485
+
2486
+			if (rv == CKR_OK) {
2487
+				entry->next = token_id_list;
2488
+				token_id_list = entry;
2489
+				entry = NULL;
2490
+			}
2491
+
2492
+			if (entry != NULL) {
2493
+				pkcs11h_freeTokenIdList (entry);
2494
+				entry = NULL;
2495
+			}
2496
+		}
2497
+
2498
+		if (rv != CKR_OK) {
2499
+			PKCS11H_DEBUG (
2500
+				PKCS11H_LOG_DEBUG1,
2501
+				"PKCS#11: Cannot get slot list for provider '%s' rv=%ld-'%s'",
2502
+				current_provider->manufacturerID,
2503
+				rv,
2504
+				pkcs11h_getMessage (rv)
2505
+			);
2506
+
2507
+			/*
2508
+			 * Ignore error
2509
+			 */
2510
+			rv = CKR_OK;
2511
+		}
2512
+
2513
+		if (slots != NULL) {
2514
+			_pkcs11h_free ((void *)&slots);
2515
+			slots = NULL;
2516
+		}
2517
+	}
2518
+
2519
+	if (rv == CKR_OK && method == PKCS11H_ENUM_METHOD_CACHE) {
2520
+		pkcs11h_session_t session = NULL;
2521
+
2522
+		for (
2523
+			session = s_pkcs11h_data->sessions;
2524
+			session != NULL && rv == CKR_OK;
2525
+			session = session->next
2526
+		) {
2527
+			pkcs11h_token_id_list_t entry = NULL;
2528
+			PKCS11H_BOOL fFound = FALSE;
2529
+
2530
+			for (
2531
+				entry = token_id_list;
2532
+				entry != NULL && !fFound;
2533
+				entry = entry->next
2534
+			) {
2535
+				if (
2536
+					pkcs11h_sameTokenId (
2537
+						session->token_id,
2538
+						entry->token_id
2539
+					)
2540
+				) {
2541
+					fFound = TRUE;
2542
+				}
2543
+			}
2544
+
2545
+			if (!fFound) {
2546
+				entry = NULL;
2547
+
2548
+				if (rv == CKR_OK) {
2549
+					rv = _pkcs11h_malloc (
2550
+						(void *)&entry,
2551
+						sizeof (struct pkcs11h_token_id_list_s)
2552
+					);
2553
+				}
2554
+
2555
+				if (rv == CKR_OK) {
2556
+					rv = pkcs11h_duplicateTokenId (
2557
+						&entry->token_id,
2558
+						session->token_id
2559
+					);
2560
+				}
2561
+
2562
+				if (rv == CKR_OK) {
2563
+					entry->next = token_id_list;
2564
+					token_id_list = entry;
2565
+					entry = NULL;
2566
+				}
2567
+
2568
+				if (entry != NULL) {
2569
+					if (entry->token_id != NULL) {
2570
+						pkcs11h_freeTokenId (entry->token_id);
2571
+					}
2572
+					_pkcs11h_free ((void *)&entry);
2573
+				}
2574
+			}
2190 2575
 		}
2576
+	}
2191 2577
 
2192
-		free (pkcs11h_certificate);
2578
+	if (rv == CKR_OK) {
2579
+		*p_token_id_list = token_id_list;
2580
+		token_id_list = NULL;
2581
+	}
2582
+
2583
+	if (token_id_list != NULL) {
2584
+		pkcs11h_freeTokenIdList (token_id_list);
2585
+		token_id_list = NULL;
2193 2586
 	}
2194 2587
 
2195
-	PKCS11DLOG (
2196
-		PKCS11_LOG_DEBUG2,
2197
-		"PKCS#11: pkcs11h_freeCertificateSession return"
2588
+#if defined(ENABLE_PKCS11H_THREADING)
2589
+	if (fMutexLocked) {
2590
+		rv = _pkcs11h_mutexRelease (&s_pkcs11h_data->mutexGlobal);
2591
+		fMutexLocked = FALSE;
2592
+	}
2593
+#endif
2594
+
2595
+	PKCS11H_DEBUG (
2596
+		PKCS11H_LOG_DEBUG2,
2597
+		"PKCS#11: pkcs11h_enum_getTokenIds return rv=%ld-'%s', *p_token_id_list=%p",
2598
+		rv,
2599
+		pkcs11h_getMessage (rv),
2600
+		(void *)p_token_id_list
2601
+	);
2602
+	
2603
+	return rv;
2604
+}
2605
+
2606
+#endif
2607
+
2608
+#if defined(ENABLE_PKCS11H_DATA)
2609
+
2610
+CK_RV
2611
+pkcs11h_freeDataIdList (
2612
+	IN const pkcs11h_data_id_list_t data_id_list
2613
+) {
2614
+	pkcs11h_data_id_list_t _id = data_id_list;
2615
+
2616
+	PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
2617
+	PKCS11H_ASSERT (s_pkcs11h_data->fInitialized);
2618
+	/*PKCS11H_ASSERT (data_id_list!=NULL); NOT NEEDED*/
2619
+
2620
+	PKCS11H_DEBUG (
2621
+		PKCS11H_LOG_DEBUG2,
2622
+		"PKCS#11: pkcs11h_freeDataIdList entry token_id_list=%p",
2623
+		(void *)data_id_list
2624
+	);
2625
+
2626
+	while (_id != NULL) {
2627
+		pkcs11h_data_id_list_t x = _id;
2628
+		_id = _id->next;
2629
+
2630
+		if (x->application != NULL) {
2631
+			_pkcs11h_free ((void *)&x->application);
2632
+		}
2633
+		if (x->label != NULL) {
2634
+			_pkcs11h_free ((void *)&x->label);
2635
+		}
2636
+		_pkcs11h_free ((void *)&x);
2637
+	}
2638
+
2639
+	PKCS11H_DEBUG (
2640
+		PKCS11H_LOG_DEBUG2,
2641
+		"PKCS#11: pkcs11h_freeDataIdList return"
2198 2642
 	);
2199 2643
 
2200 2644
 	return CKR_OK;
2201 2645
 }
2202 2646
 
2203 2647
 CK_RV
2204
-pkcs11h_sign (
2205
-	IN const pkcs11h_certificate_t pkcs11h_certificate,
2206
-	IN const CK_MECHANISM_TYPE mech_type,
2207
-	IN const unsigned char * const source,
2208
-	IN const size_t source_size,
2209
-	OUT unsigned char * const target,
2210
-	IN OUT size_t * const target_size
2648
+pkcs11h_enumDataObjects (
2649
+	IN const pkcs11h_token_id_t token_id,
2650
+	IN const PKCS11H_BOOL fPublic,
2651
+	OUT pkcs11h_data_id_list_t * const p_data_id_list
2211 2652
 ) {
2212
-	CK_MECHANISM mech = {
2213
-		mech_type, NULL, 0
2214
-	};
2215
-	
2653
+	pkcs11h_session_t session = NULL;
2654
+	pkcs11h_data_id_list_t data_id_list = NULL;
2216 2655
 	CK_RV rv = CKR_OK;
2217
-	bool fLogonRetry = false;
2218
-	bool fOpSuccess = false;
2219 2656
 
2220
-	PKCS11ASSERT (pkcs11h_data!=NULL);
2221
-	PKCS11ASSERT (pkcs11h_data->fInitialized);
2222
-	PKCS11ASSERT (pkcs11h_certificate!=NULL);
2223
-	PKCS11ASSERT (source!=NULL);
2224
-	PKCS11ASSERT (target_size!=NULL);
2657
+	PKCS11H_BOOL fOpSuccess = FALSE;
2658
+	PKCS11H_BOOL fLoginRetry = FALSE;
2225 2659
 
2226
-	PKCS11DLOG (
2227
-		PKCS11_LOG_DEBUG2,
2228
-		"PKCS#11: pkcs11h_sign entry pkcs11h_certificate=%p, mech_type=%ld, source=%p, source_size=%u, target=%p, target_size=%p",
2229
-		(void *)pkcs11h_certificate,
2230
-		mech_type,
2231
-		source,
2232
-		source_size,
2233
-		target,
2234
-		(void *)target_size
2660
+	PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
2661
+	PKCS11H_ASSERT (s_pkcs11h_data->fInitialized);
2662
+	PKCS11H_ASSERT (p_data_id_list!=NULL);
2663
+
2664
+	PKCS11H_DEBUG (
2665
+		PKCS11H_LOG_DEBUG2,
2666
+		"PKCS#11: pkcs11h_enumDataObjects entry p_data_id_list=%p",
2667
+		(void *)p_data_id_list
2235 2668
 	);
2236 2669
 
2670
+	*p_data_id_list = NULL;
2671
+
2237 2672
 	if (rv == CKR_OK) {
2238
-		rv = _pkcs11h_validateSession (pkcs11h_certificate->session);
2673
+		rv = _pkcs11h_getSessionByTokenId (
2674
+			token_id,
2675
+			&session
2676
+		);
2239 2677
 	}
2240 2678
 
2241 2679
 	while (rv == CKR_OK && !fOpSuccess) {
2680
+#if defined(ENABLE_PKCS11H_THREADING)
2681
+		PKCS11H_BOOL fMutexLocked = FALSE;
2682
+#endif
2242 2683
 
2243
-		/*
2244
-		 * Don't try invalid object
2245
-		 */
2684
+		CK_OBJECT_CLASS class = CKO_DATA;
2685
+		CK_ATTRIBUTE filter[] = {
2686
+			{CKA_CLASS, (void *)&class, sizeof (class)}
2687
+		};
2688
+		CK_OBJECT_HANDLE *objects = NULL;
2689
+		CK_ULONG objects_found = 0;
2690
+
2691
+		CK_ULONG i;
2692
+
2693
+		if (rv == CKR_OK) {
2694
+			rv = _pkcs11h_validateSession (session);
2695
+		}
2696
+
2697
+#if defined(ENABLE_PKCS11H_THREADING)
2246 2698
 		if (
2247 2699
 			rv == CKR_OK &&
2248
-			pkcs11h_certificate->hKey == PKCS11H_INVALID_OBJECT_HANDLE
2700
+			(rv = _pkcs11h_mutexLock (&session->mutexSession)) == CKR_OK
2249 2701
 		) {
2250
-			rv = CKR_OBJECT_HANDLE_INVALID;
2702
+			fMutexLocked = TRUE;
2251 2703
 		}
2704
+#endif
2252 2705
 
2253 2706
 		if (rv == CKR_OK) {
2254
-			rv = pkcs11h_certificate->session->provider->f->C_SignInit (
2255
-				pkcs11h_certificate->session->hSession,
2256
-				&mech,
2257
-				pkcs11h_certificate->hKey
2707
+			rv = _pkcs11h_findObjects (
2708
+				session,
2709
+				filter,
2710
+				sizeof (filter) / sizeof (CK_ATTRIBUTE),
2711
+				&objects,
2712
+				&objects_found
2258 2713
 			);
2259 2714
 		}
2260 2715
 
2261
-		if (rv == CKR_OK) {
2262
-			CK_ULONG size = *target_size;
2263
-			rv = pkcs11h_certificate->session->provider->f->C_Sign (
2264
-				pkcs11h_certificate->session->hSession,
2265
-				(CK_BYTE_PTR)source,
2266
-				source_size,
2267
-				(CK_BYTE_PTR)target,
2268
-				&size
2716
+		for (i = 0;rv == CKR_OK && i < objects_found;i++) {
2717
+			pkcs11h_data_id_list_t entry = NULL;
2718
+
2719
+			CK_ATTRIBUTE attrs[] = {
2720
+				{CKA_APPLICATION, NULL, 0},
2721
+				{CKA_LABEL, NULL, 0}
2722
+			};
2723
+
2724
+			if (rv == CKR_OK) {
2725
+				rv = _pkcs11h_getObjectAttributes (
2726
+					session,
2727
+					objects[i],
2728
+					attrs,
2729
+					sizeof (attrs) / sizeof (CK_ATTRIBUTE)
2730
+				);
2731
+			}
2732
+			
2733
+			if (rv == CKR_OK) {
2734
+				rv = _pkcs11h_malloc (
2735
+					(void *)&entry,
2736
+					sizeof (struct pkcs11h_data_id_list_s)
2737
+				);
2738
+			}
2739
+
2740
+			if (
2741
+				rv == CKR_OK &&
2742
+				(rv = _pkcs11h_malloc (
2743
+					(void *)&entry->application,
2744
+					attrs[0].ulValueLen+1
2745
+				)) == CKR_OK
2746
+			) {
2747
+				memmove (entry->application, attrs[0].pValue, attrs[0].ulValueLen);
2748
+				entry->application[attrs[0].ulValueLen] = '\0';
2749
+			}
2750
+
2751
+			if (
2752
+				rv == CKR_OK &&
2753
+				(rv = _pkcs11h_malloc (
2754
+					(void *)&entry->label,
2755
+					attrs[1].ulValueLen+1
2756
+				)) == CKR_OK
2757
+			) {
2758
+				memmove (entry->label, attrs[1].pValue, attrs[1].ulValueLen);
2759
+				entry->label[attrs[1].ulValueLen] = '\0';
2760
+			}
2761
+
2762
+			if (rv == CKR_OK) {
2763
+				entry->next = data_id_list;
2764
+				data_id_list = entry;
2765
+				entry = NULL;
2766
+			}
2767
+
2768
+			_pkcs11h_freeObjectAttributes (
2769
+				attrs,
2770
+				sizeof (attrs) / sizeof (CK_ATTRIBUTE)
2269 2771
 			);
2270 2772
 
2271
-			*target_size = (int)size;
2773
+			if (entry != NULL) {
2774
+				if (entry->application != NULL) {
2775
+					_pkcs11h_free ((void *)&entry->application);
2776
+				}
2777
+				if (entry->label != NULL) {
2778
+					_pkcs11h_free ((void *)&entry->label);
2779
+				}
2780
+				_pkcs11h_free ((void *)&entry);
2781
+			}
2782
+		}
2783
+
2784
+		if (objects != NULL) {
2785
+			_pkcs11h_free ((void *)&objects);
2272 2786
 		}
2273 2787
 
2788
+#if defined(ENABLE_PKCS11H_THREADING)
2789
+		if (fMutexLocked) {
2790
+			_pkcs11h_mutexRelease (&session->mutexSession);
2791
+			fMutexLocked = FALSE;
2792
+		}
2793
+#endif
2274 2794
 
2275 2795
 		if (rv == CKR_OK) {
2276
-			fOpSuccess = true;
2796
+			fOpSuccess = TRUE;
2277 2797
 		}
2278 2798
 		else {
2279
-			if (!fLogonRetry) {
2280
-				PKCS11DLOG (
2281
-					PKCS11_LOG_DEBUG1,
2282
-					"PKCS#11: Private key operation failed rv=%ld-'%s'",
2799
+			if (!fLoginRetry) {
2800
+				PKCS11H_DEBUG (
2801
+					PKCS11H_LOG_DEBUG1,
2802
+					"PKCS#11: Enumerate data objects failed rv=%ld-'%s'",
2283 2803
 					rv,
2284 2804
 					pkcs11h_getMessage (rv)
2285 2805
 				);
2286
-				fLogonRetry = true;
2287
-				rv = _pkcs11h_resetCertificateSession (pkcs11h_certificate);
2806
+				fLoginRetry = TRUE;
2807
+				rv = _pkcs11h_login (
2808
+					session,
2809
+					fPublic,
2810
+					TRUE,
2811
+					(
2812
+						PKCS11H_PROMPT_MASK_ALLOW_PIN_PROMPT |
2813
+						PKCS11H_PROMPT_MAST_ALLOW_CARD_PROMPT 
2814
+					)
2815
+				);
2288 2816
 			}
2289 2817
 		}
2290 2818
 	}
2291 2819
 
2292
-	PKCS11DLOG (
2293
-		PKCS11_LOG_DEBUG2,
2294
-		"PKCS#11: pkcs11h_sign return rv=%ld-'%s'",
2820
+	if (rv == CKR_OK) {
2821
+		*p_data_id_list = data_id_list;
2822
+		data_id_list = NULL;
2823
+	}
2824
+
2825
+	if (session != NULL) {
2826
+		_pkcs11h_releaseSession (session);
2827
+		session = NULL;
2828
+	}
2829
+
2830
+	if (data_id_list != NULL) {
2831
+		pkcs11h_freeDataIdList (data_id_list);
2832
+		data_id_list = NULL;
2833
+	}
2834
+
2835
+	PKCS11H_DEBUG (
2836
+		PKCS11H_LOG_DEBUG2,
2837
+		"PKCS#11: pkcs11h_data_id_list_t return rv=%ld-'%s', *p_data_id_list=%p",
2295 2838
 		rv,
2296
-		pkcs11h_getMessage (rv)
2839
+		pkcs11h_getMessage (rv),
2840
+		(void *)*p_data_id_list
2297 2841
 	);
2298 2842
 	
2299 2843
 	return rv;
2300 2844
 }
2301 2845
 
2846
+#endif				/* ENABLE_PKCS11H_DATA */
2847
+
2848
+#if defined(ENABLE_PKCS11H_CERTIFICATE)
2849
+
2850
+static
2302 2851
 CK_RV
2303
-pkcs11h_signRecover (
2304
-	IN const pkcs11h_certificate_t pkcs11h_certificate,
2305
-	IN const CK_MECHANISM_TYPE mech_type,
2306
-	IN const unsigned char * const source,
2307
-	IN const size_t source_size,
2308
-	OUT unsigned char * const target,
2309
-	IN OUT size_t * const target_size
2852
+_pkcs11h_enum_getSessionCertificates (
2853
+	IN const pkcs11h_session_t session
2310 2854
 ) {
2311
-	CK_MECHANISM mech = {
2312
-		mech_type, NULL, 0
2313
-	};
2855
+	PKCS11H_BOOL fOpSuccess = FALSE;
2856
+	PKCS11H_BOOL fLoginRetry = FALSE;
2857
+
2314 2858
 	CK_RV rv = CKR_OK;
2315
-	bool fLogonRetry = false;
2316
-	bool fOpSuccess = false;
2317 2859
 
2318
-	PKCS11ASSERT (pkcs11h_data!=NULL);
2319
-	PKCS11ASSERT (pkcs11h_data->fInitialized);
2320
-	PKCS11ASSERT (pkcs11h_certificate!=NULL);
2321
-	PKCS11ASSERT (source!=NULL);
2322
-	PKCS11ASSERT (target_size!=NULL);
2860
+	PKCS11H_ASSERT (session!=NULL);
2323 2861
 
2324
-	PKCS11DLOG (
2325
-		PKCS11_LOG_DEBUG2,
2326
-		"PKCS#11: pkcs11h_signRecover entry pkcs11h_certificate=%p, mech_type=%ld, source=%p, source_size=%u, target=%p, target_size=%p",
2327
-		(void *)pkcs11h_certificate,
2328
-		mech_type,
2329
-		source,
2330
-		source_size,
2331
-		target,
2332
-		(void *)target_size
2862
+	PKCS11H_DEBUG (
2863
+		PKCS11H_LOG_DEBUG2,
2864
+		"PKCS#11: _pkcs11h_enum_getSessionCertificates entry session=%p",
2865
+		(void *)session
2333 2866
 	);
2334
-
2335
-	if (rv == CKR_OK) {
2336
-		rv = _pkcs11h_validateSession (pkcs11h_certificate->session);
2337
-	}
2867
+	
2868
+	/* THREADS: NO NEED TO LOCK, GLOBAL CACHE IS LOCKED */
2338 2869
 
2339 2870
 	while (rv == CKR_OK && !fOpSuccess) {
2871
+		CK_OBJECT_CLASS cert_filter_class = CKO_CERTIFICATE;
2872
+		CK_ATTRIBUTE cert_filter[] = {
2873
+			{CKA_CLASS, &cert_filter_class, sizeof (cert_filter_class)}
2874
+		};
2340 2875
 
2341
-		/*
2342
-		 * Don't try invalid object
2343
-		 */
2344
-		if (
2345
-			rv == CKR_OK &&
2346
-			pkcs11h_certificate->hKey == PKCS11H_INVALID_OBJECT_HANDLE
2347
-		) {
2348
-			rv = CKR_OBJECT_HANDLE_INVALID;
2876
+		CK_OBJECT_HANDLE *objects = NULL;
2877
+		CK_ULONG objects_found = 0;
2878
+
2879
+		CK_ULONG i;
2880
+
2881
+		if (rv == CKR_OK) {
2882
+			rv = _pkcs11h_validateSession (session);
2349 2883
 		}
2350 2884
 
2351 2885
 		if (rv == CKR_OK) {
2352
-			rv = pkcs11h_certificate->session->provider->f->C_SignRecoverInit (
2353
-				pkcs11h_certificate->session->hSession,
2354
-				&mech,
2355
-				pkcs11h_certificate->hKey
2886
+			rv = _pkcs11h_findObjects (
2887
+				session,
2888
+				cert_filter,
2889
+				sizeof (cert_filter) / sizeof (CK_ATTRIBUTE),
2890
+				&objects,
2891
+				&objects_found
2356 2892
 			);
2357 2893
 		}
2894
+			
2895
+		for (i=0;rv == CKR_OK && i < objects_found;i++) {
2896
+			pkcs11h_certificate_id_t certificate_id = NULL;
2897
+			pkcs11h_certificate_id_list_t new_element = NULL;
2898
+			
2899
+			CK_ATTRIBUTE attrs[] = {
2900
+				{CKA_ID, NULL, 0},
2901
+				{CKA_VALUE, NULL, 0}
2902
+			};
2358 2903
 
2359
-		if (rv == CKR_OK) {
2360
-			CK_ULONG size = *target_size;
2361
-			rv = pkcs11h_certificate->session->provider->f->C_SignRecover (
2362
-				pkcs11h_certificate->session->hSession,
2363
-				(CK_BYTE_PTR)source,
2364
-				source_size,
2365
-				(CK_BYTE_PTR)target,
2366
-				&size
2904
+			if (rv == CKR_OK) {
2905
+				rv = _pkcs11h_getObjectAttributes (
2906
+					session,
2907
+					objects[i],
2908
+					attrs,
2909
+					sizeof (attrs) / sizeof (CK_ATTRIBUTE)
2910
+				);
2911
+			}
2912
+
2913
+			if (
2914
+				rv == CKR_OK &&
2915
+				(rv = _pkcs11h_newCertificateId (&certificate_id)) == CKR_OK
2916
+			) {
2917
+				rv = pkcs11h_duplicateTokenId (
2918
+					&certificate_id->token_id,
2919
+					session->token_id
2920
+				);
2921
+			}
2922
+
2923
+			if (rv == CKR_OK) {
2924
+				rv = _pkcs11h_dupmem (
2925
+					(void*)&certificate_id->attrCKA_ID,
2926
+					&certificate_id->attrCKA_ID_size,
2927
+					attrs[0].pValue,
2928
+					attrs[0].ulValueLen
2929
+				);
2930
+			}
2931
+
2932
+			if (rv == CKR_OK) {
2933
+				rv = _pkcs11h_dupmem (
2934
+					(void*)&certificate_id->certificate_blob,
2935
+					&certificate_id->certificate_blob_size,
2936
+					attrs[1].pValue,
2937
+					attrs[1].ulValueLen
2938
+				);
2939
+			}
2940
+
2941
+			if (rv == CKR_OK) {
2942
+				rv = _pkcs11h_updateCertificateIdDescription (certificate_id);
2943
+			}
2944
+
2945
+			if (
2946
+				rv == CKR_OK &&
2947
+				(rv = _pkcs11h_malloc (
2948
+					(void *)&new_element,
2949
+					sizeof (struct pkcs11h_certificate_id_list_s)
2950
+				)) == CKR_OK
2951
+			) {
2952
+				new_element->next = session->cached_certs;
2953
+				new_element->certificate_id = certificate_id;
2954
+				certificate_id = NULL;
2955
+
2956
+				session->cached_certs = new_element;
2957
+				new_element = NULL;
2958
+			}
2959
+
2960
+			if (certificate_id != NULL) {
2961
+				pkcs11h_freeCertificateId (certificate_id);
2962
+				certificate_id = NULL;
2963
+			}
2964
+
2965
+			if (new_element != NULL) {
2966
+				_pkcs11h_free ((void *)&new_element);
2967
+				new_element = NULL;
2968
+			}
2969
+
2970
+			_pkcs11h_freeObjectAttributes (
2971
+				attrs,
2972
+				sizeof (attrs) / sizeof (CK_ATTRIBUTE)
2367 2973
 			);
2368 2974
 
2369
-			*target_size = (int)size;
2975
+			if (rv != CKR_OK) {
2976
+				PKCS11H_DEBUG (
2977
+					PKCS11H_LOG_DEBUG1,
2978
+					"PKCS#11: Cannot get object attribute for provider '%s' object %ld rv=%ld-'%s'",
2979
+					session->provider->manufacturerID,
2980
+					objects[i],
2981
+					rv,
2982
+					pkcs11h_getMessage (rv)
2983
+				);
2984
+
2985
+				/*
2986
+				 * Ignore error
2987
+				 */
2988
+				rv = CKR_OK;
2989
+			}
2370 2990
 		}
2371 2991
 
2992
+		if (objects != NULL) {
2993
+			_pkcs11h_free ((void *)&objects);
2994
+		}
2372 2995
 
2373 2996
 		if (rv == CKR_OK) {
2374
-			fOpSuccess = true;
2997
+			fOpSuccess = TRUE;
2375 2998
 		}
2376 2999
 		else {
2377
-			if (!fLogonRetry) {
2378
-				PKCS11DLOG (
2379
-					PKCS11_LOG_DEBUG1,
2380
-					"PKCS#11: Private key operation failed rv=%ld-'%s'",
3000
+			if (!fLoginRetry) {
3001
+				PKCS11H_DEBUG (
3002
+					PKCS11H_LOG_DEBUG1,
3003
+					"PKCS#11: Get certificate attributes failed: %ld:'%s'",
2381 3004
 					rv,
2382 3005
 					pkcs11h_getMessage (rv)
2383 3006
 				);
2384
-				fLogonRetry = true;
2385
-				rv = _pkcs11h_resetCertificateSession (pkcs11h_certificate);
3007
+
3008
+				rv = _pkcs11h_login (
3009
+					session,
3010
+					TRUE,
3011
+					TRUE,
3012
+					PKCS11H_PROMPT_MASK_ALLOW_PIN_PROMPT
3013
+				);
3014
+
3015
+				fLoginRetry = TRUE;
2386 3016
 			}
2387 3017
 		}
2388 3018
 	}
2389 3019
 
2390
-	PKCS11DLOG (
2391
-		PKCS11_LOG_DEBUG2,
2392
-		"PKCS#11: pkcs11h_signRecover return rv=%ld-'%s'",
3020
+	PKCS11H_DEBUG (
3021
+		PKCS11H_LOG_DEBUG2,
3022
+		"PKCS#11: _pkcs11h_enum_getSessionCertificates return rv=%ld-'%s'",
2393 3023
 		rv,
2394 3024
 		pkcs11h_getMessage (rv)
2395 3025
 	);
... ...
@@ -2397,97 +7601,205 @@ pkcs11h_signRecover (
2397 2397
 	return rv;
2398 2398
 }
2399 2399
 
2400
+static
2400 2401
 CK_RV
2401
-pkcs11h_decrypt (
2402
-	IN const pkcs11h_certificate_t pkcs11h_certificate,
2403
-	IN const CK_MECHANISM_TYPE mech_type,
2404
-	IN const unsigned char * const source,
2405
-	IN const size_t source_size,
2406
-	OUT unsigned char * const target,
2407
-	IN OUT size_t * const target_size
2402
+_pkcs11h_enum_splitCertificateIdList (
2403
+	IN const pkcs11h_certificate_id_list_t cert_id_all,
2404
+	OUT pkcs11h_certificate_id_list_t * const p_cert_id_issuers_list,
2405
+	OUT pkcs11h_certificate_id_list_t * const p_cert_id_end_list
2408 2406
 ) {
2409
-	CK_MECHANISM mech = {
2410
-		mech_type, NULL, 0
2411
-	};
2412
-	CK_ULONG size;
2407
+	typedef struct info_s {
2408
+		struct info_s *next;
2409
+		pkcs11h_certificate_id_t e;
2410
+		X509 *x509;
2411
+		PKCS11H_BOOL fIsIssuer;
2412
+	} *info_t;
2413
+
2414
+	pkcs11h_certificate_id_list_t cert_id_issuers_list = NULL;
2415
+	pkcs11h_certificate_id_list_t cert_id_end_list = NULL;
2416
+
2417
+	info_t head = NULL;
2418
+	info_t info = NULL;
2419
+
2413 2420
 	CK_RV rv = CKR_OK;
2414
-	bool fLogonRetry = false;
2415
-	bool fOpSuccess = false;
2416 2421
 
2417
-	PKCS11ASSERT (pkcs11h_data!=NULL);
2418
-	PKCS11ASSERT (pkcs11h_data->fInitialized);
2419
-	PKCS11ASSERT (pkcs11h_certificate!=NULL);
2420
-	PKCS11ASSERT (source!=NULL);
2421
-	PKCS11ASSERT (target_size!=NULL);
2422
+	/*PKCS11H_ASSERT (cert_id_all!=NULL); NOT NEEDED */
2423
+	/*PKCS11H_ASSERT (p_cert_id_issuers_list!=NULL); NOT NEEDED*/
2424
+	PKCS11H_ASSERT (p_cert_id_end_list!=NULL);
2422 2425
 
2423
-	PKCS11DLOG (
2424
-		PKCS11_LOG_DEBUG2,
2425
-		"PKCS#11: pkcs11h_decrypt entry pkcs11h_certificate=%p, mech_type=%ld, source=%p, source_size=%u, target=%p, target_size=%p",
2426
-		(void *)pkcs11h_certificate,
2427
-		mech_type,
2428
-		source,
2429
-		source_size,
2430
-		target,
2431
-		(void *)target_size
2426
+	PKCS11H_DEBUG (
2427
+		PKCS11H_LOG_DEBUG2,
2428
+		"PKCS#11: pkcs11h_splitCertificateIdList entry cert_id_all=%p, p_cert_id_issuers_list=%p, p_cert_id_end_list=%p",
2429
+		(void *)cert_id_all,
2430
+		(void *)p_cert_id_issuers_list,
2431
+		(void *)p_cert_id_end_list
2432 2432
 	);
2433 2433
 
2434
-	if (rv != CKR_OK) {
2435
-		rv = _pkcs11h_validateSession (pkcs11h_certificate->session);
2434
+	if (p_cert_id_issuers_list != NULL) {
2435
+		*p_cert_id_issuers_list = NULL;
2436 2436
 	}
2437
+	*p_cert_id_end_list = NULL;
2437 2438
 
2438
-	while (rv == CKR_OK && !fOpSuccess) {
2439
+	OpenSSL_add_all_digests ();
2439 2440
 
2440
-		/*
2441
-		 * Don't try invalid object
2442
-		 */
2443
-		if (
2444
-			rv == CKR_OK &&
2445
-			pkcs11h_certificate->hKey == PKCS11H_INVALID_OBJECT_HANDLE
2441
+	if (rv == CKR_OK) {
2442
+		pkcs11h_certificate_id_list_t entry = NULL;
2443
+
2444
+		for (
2445
+			entry = cert_id_all;
2446
+			entry != NULL && rv == CKR_OK;
2447
+			entry = entry->next
2446 2448
 		) {
2447
-			rv = CKR_OBJECT_HANDLE_INVALID;
2448
-		}
2449
+			info_t new_info = NULL;
2449 2450
 
2450
-		if (rv == CKR_OK) {
2451
-			rv = pkcs11h_certificate->session->provider->f->C_DecryptInit (
2452
-				pkcs11h_certificate->session->hSession,
2453
-				&mech,
2454
-				pkcs11h_certificate->hKey
2455
-			);
2451
+			if (
2452
+				rv == CKR_OK &&
2453
+				(rv = _pkcs11h_malloc ((void *)&new_info, sizeof (struct info_s))) == CKR_OK &&
2454
+				entry->certificate_id->certificate_blob != NULL
2455
+			) {
2456
+				pkcs11_openssl_d2i_t d2i = (pkcs11_openssl_d2i_t)entry->certificate_id->certificate_blob;
2457
+				new_info->next = head;
2458
+				new_info->e = entry->certificate_id;
2459
+				new_info->x509 = X509_new ();
2460
+				if (
2461
+					new_info->x509 != NULL &&
2462
+					!d2i_X509 (
2463
+						&new_info->x509,
2464
+						&d2i,
2465
+						entry->certificate_id->certificate_blob_size
2466
+					)
2467
+				) {
2468
+					X509_free (new_info->x509);
2469
+					new_info->x509 = NULL;
2470
+				}
2471
+				head = new_info;
2472
+				new_info = NULL;
2473
+			}
2456 2474
 		}
2457 2475
 
2458
-		if (rv == CKR_OK) {
2459
-			size = *target_size;
2460
-			rv = pkcs11h_certificate->session->provider->f->C_Decrypt (
2461
-				pkcs11h_certificate->session->hSession,
2462
-				(CK_BYTE_PTR)source,
2463
-				source_size,
2464
-				(CK_BYTE_PTR)target,
2465
-				&size
2466
-			);
2476
+	}
2467 2477
 
2468
-			*target_size = (int)size;
2469
-		}
2478
+	if (rv == CKR_OK) {
2479
+		for (
2480
+			info = head;
2481
+			info != NULL;
2482
+			info = info->next
2483
+		) {
2484
+			info_t info2 = NULL;
2485
+			for (
2486
+				info2 = head;
2487
+				info2 != NULL && !info->fIsIssuer;
2488
+				info2 = info2->next
2489
+			) {
2490
+				EVP_PKEY *pub = NULL;
2470 2491
 
2471
-		if (rv == CKR_OK) {
2472
-			fOpSuccess = true;
2492
+				pub = X509_get_pubkey (info->x509);
2493
+
2494
+				if (
2495
+					info != info2 &&
2496
+					info->x509 != NULL &&
2497
+					info2->x509 != NULL &&
2498
+/* Some people get this wrong		!X509_NAME_cmp (
2499
+						X509_get_subject_name (info->x509),
2500
+						X509_get_issuer_name (info2->x509)
2501
+					) && */
2502
+					X509_verify (info2->x509, pub) == 1
2503
+				) {
2504
+					info->fIsIssuer = TRUE;
2505
+				}
2506
+
2507
+				if (pub != NULL) {
2508
+					EVP_PKEY_free (pub);
2509
+					pub = NULL;
2510
+				}
2511
+			}
2473 2512
 		}
2474
-		else {
2475
-			if (!fLogonRetry) {
2476
-				PKCS11DLOG (
2477
-					PKCS11_LOG_DEBUG1,
2478
-					"PKCS#11: Private key operation failed rv=%ld-'%s'",
2479
-					rv,
2480
-					pkcs11h_getMessage (rv)
2513
+	}
2514
+
2515
+	if (rv == CKR_OK) {
2516
+		for (
2517
+			info = head;
2518
+			info != NULL && rv == CKR_OK;
2519
+			info = info->next
2520
+		) {
2521
+			pkcs11h_certificate_id_list_t new_entry = NULL;
2522
+
2523
+			if (rv == CKR_OK) {
2524
+				rv = _pkcs11h_malloc (
2525
+					(void *)&new_entry,
2526
+					sizeof (struct pkcs11h_certificate_id_list_s)
2481 2527
 				);
2482
-				fLogonRetry = true;
2483
-				rv = _pkcs11h_resetCertificateSession (pkcs11h_certificate);
2484 2528
 			}
2529
+
2530
+			if (
2531
+				rv == CKR_OK &&
2532
+				(rv = pkcs11h_duplicateCertificateId (
2533
+					&new_entry->certificate_id,
2534
+					info->e
2535
+				)) == CKR_OK
2536
+			) {
2537
+				/*
2538
+				 * Should not free base list
2539
+				 */
2540
+				info->e = NULL;
2541
+			}
2542
+
2543
+			if (rv == CKR_OK) {
2544
+				if (info->fIsIssuer) {
2545
+					new_entry->next = cert_id_issuers_list;
2546
+					cert_id_issuers_list = new_entry;
2547
+					new_entry = NULL;
2548
+				}
2549
+				else {
2550
+					new_entry->next = cert_id_end_list;
2551
+					cert_id_end_list = new_entry;
2552
+					new_entry = NULL;
2553
+				}
2554
+			}
2555
+
2556
+			if (new_entry != NULL) {
2557
+				if (new_entry->certificate_id != NULL) {
2558
+					pkcs11h_freeCertificateId (new_entry->certificate_id);
2559
+				}
2560
+				_pkcs11h_free ((void *)&new_entry);
2561
+			}
2562
+		}
2563
+	}
2564
+
2565
+	if (rv == CKR_OK) {
2566
+		while (head != NULL) {
2567
+			info_t entry = head;
2568
+			head = head->next;
2569
+
2570
+			if (entry->x509 != NULL) {
2571
+				X509_free (entry->x509);
2572
+				entry->x509 = NULL;
2573
+			}
2574
+			_pkcs11h_free ((void *)&entry);
2485 2575
 		}
2486 2576
 	}
2487 2577
 
2488
-	PKCS11DLOG (
2489
-		PKCS11_LOG_DEBUG2,
2490
-		"PKCS#11: pkcs11h_decrypt return rv=%ld-'%s'",
2578
+	if (rv == CKR_OK && p_cert_id_issuers_list != NULL ) {
2579
+		*p_cert_id_issuers_list = cert_id_issuers_list;
2580
+		cert_id_issuers_list = NULL;
2581
+	}
2582
+
2583
+	if (rv == CKR_OK) {
2584
+		*p_cert_id_end_list = cert_id_end_list;
2585
+		cert_id_end_list = NULL;
2586
+	}
2587
+
2588
+	if (cert_id_issuers_list != NULL) {
2589
+		pkcs11h_freeCertificateIdList (cert_id_issuers_list);
2590
+	}
2591
+
2592
+	if (cert_id_end_list != NULL) {
2593
+		pkcs11h_freeCertificateIdList (cert_id_end_list);
2594
+	}
2595
+
2596
+	PKCS11H_DEBUG (
2597
+		PKCS11H_LOG_DEBUG2,
2598
+		"PKCS#11: pkcs11h_splitCertificateIdList return rv=%ld-'%s'",
2491 2599
 		rv,
2492 2600
 		pkcs11h_getMessage (rv)
2493 2601
 	);
... ...
@@ -2496,172 +7808,802 @@ pkcs11h_decrypt (
2496 2496
 }
2497 2497
 
2498 2498
 CK_RV
2499
-pkcs11h_getCertificate (
2500
-	IN const pkcs11h_certificate_t pkcs11h_certificate,
2501
-	OUT unsigned char * const certificate,
2502
-	IN OUT size_t * const certificate_size
2499
+pkcs11h_freeCertificateIdList (
2500
+	IN const pkcs11h_certificate_id_list_t cert_id_list
2501
+) {
2502
+	pkcs11h_certificate_id_list_t _id = cert_id_list;
2503
+
2504
+	PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
2505
+	PKCS11H_ASSERT (s_pkcs11h_data->fInitialized);
2506
+	/*PKCS11H_ASSERT (cert_id_list!=NULL); NOT NEEDED*/
2507
+
2508
+	PKCS11H_DEBUG (
2509
+		PKCS11H_LOG_DEBUG2,
2510
+		"PKCS#11: pkcs11h_freeCertificateIdList entry cert_id_list=%p",
2511
+		(void *)cert_id_list
2512
+	);
2513
+
2514
+	while (_id != NULL) {
2515
+		pkcs11h_certificate_id_list_t x = _id;
2516
+		_id = _id->next;
2517
+		if (x->certificate_id != NULL) {
2518
+			pkcs11h_freeCertificateId (x->certificate_id);
2519
+		}
2520
+		x->next = NULL;
2521
+		_pkcs11h_free ((void *)&x);
2522
+	}
2523
+
2524
+	PKCS11H_DEBUG (
2525
+		PKCS11H_LOG_DEBUG2,
2526
+		"PKCS#11: pkcs11h_freeCertificateIdList return"
2527
+	);
2528
+
2529
+	return CKR_OK;
2530
+}
2531
+
2532
+CK_RV
2533
+pkcs11h_enum_getTokenCertificateIds (
2534
+	IN const pkcs11h_token_id_t token_id,
2535
+	IN const int method,
2536
+	OUT pkcs11h_certificate_id_list_t * const p_cert_id_issuers_list,
2537
+	OUT pkcs11h_certificate_id_list_t * const p_cert_id_end_list
2503 2538
 ) {
2539
+#if defined(ENABLE_PKCS11H_THREADING)
2540
+	PKCS11H_BOOL fMutexLocked = FALSE;
2541
+#endif
2542
+	pkcs11h_session_t session = NULL;
2504 2543
 	CK_RV rv = CKR_OK;
2544
+
2545
+	PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
2546
+	PKCS11H_ASSERT (s_pkcs11h_data->fInitialized);
2547
+	PKCS11H_ASSERT (token_id!=NULL);
2548
+	/*PKCS11H_ASSERT (p_cert_id_issuers_list!=NULL); NOT NEEDED*/
2549
+	PKCS11H_ASSERT (p_cert_id_end_list!=NULL);
2550
+
2551
+	PKCS11H_DEBUG (
2552
+		PKCS11H_LOG_DEBUG2,
2553
+		"PKCS#11: pkcs11h_enum_getTokenCertificateIds entry token_id=%p, method=%d, p_cert_id_issuers_list=%p, p_cert_id_end_list=%p",
2554
+		(void *)token_id,
2555
+		method,
2556
+		(void *)p_cert_id_issuers_list,
2557
+		(void *)p_cert_id_end_list
2558
+	);
2559
+
2560
+	if (p_cert_id_issuers_list != NULL) {
2561
+		*p_cert_id_issuers_list = NULL;
2562
+	}
2563
+	*p_cert_id_end_list = NULL;
2564
+
2565
+#if defined(ENABLE_PKCS11H_THREADING)
2566
+	if (
2567
+		rv == CKR_OK &&
2568
+		(rv = _pkcs11h_mutexLock (&s_pkcs11h_data->mutexCache)) == CKR_OK
2569
+	) {
2570
+		fMutexLocked = TRUE;
2571
+	}
2572
+#endif
2573
+
2574
+	if (
2575
+		rv == CKR_OK &&
2576
+		(rv = _pkcs11h_getSessionByTokenId (
2577
+			token_id,
2578
+			&session
2579
+		)) == CKR_OK
2580
+	) {
2581
+		if (method == PKCS11H_ENUM_METHOD_RELOAD) {
2582
+			pkcs11h_freeCertificateIdList (session->cached_certs);
2583
+			session->cached_certs = NULL;
2584
+		}
2585
+
2586
+		if (session->cached_certs == NULL) {
2587
+			rv = _pkcs11h_enum_getSessionCertificates (session);
2588
+		}
2589
+	}
2590
+
2591
+	if (rv == CKR_OK) {
2592
+		rv = _pkcs11h_enum_splitCertificateIdList (
2593
+			session->cached_certs,
2594
+			p_cert_id_issuers_list,
2595
+			p_cert_id_end_list
2596
+		);
2597
+	}
2598
+
2599
+	if (session != NULL) {
2600
+		_pkcs11h_releaseSession (session);
2601
+	}
2602
+
2603
+#if defined(ENABLE_PKCS11H_THREADING)
2604
+	if (fMutexLocked) {
2605
+		_pkcs11h_mutexRelease (&s_pkcs11h_data->mutexCache);
2606
+		fMutexLocked = FALSE;
2607
+	}
2608
+#endif
2609
+
2610
+	PKCS11H_DEBUG (
2611
+		PKCS11H_LOG_DEBUG2,
2612
+		"PKCS#11: pkcs11h_enum_getTokenCertificateIds return rv=%ld-'%s'",
2613
+		rv,
2614
+		pkcs11h_getMessage (rv)
2615
+	);
2505 2616
 	
2506
-	PKCS11ASSERT (pkcs11h_data!=NULL);
2507
-	PKCS11ASSERT (pkcs11h_data->fInitialized);
2508
-	PKCS11ASSERT (certificate_size!=NULL);
2617
+	return rv;
2618
+}
2509 2619
 
2510
-	PKCS11DLOG (
2511
-		PKCS11_LOG_DEBUG2,
2512
-		"PKCS#11: pkcs11h_getCertificate entry pkcs11h_certificate=%p, certificate=%p, certificate_size=%p",
2513
-		(void *)pkcs11h_certificate,
2514
-		certificate,
2515
-		(void *)certificate_size
2620
+CK_RV
2621
+pkcs11h_enum_getCertificateIds (
2622
+	IN const int method,
2623
+	OUT pkcs11h_certificate_id_list_t * const p_cert_id_issuers_list,
2624
+	OUT pkcs11h_certificate_id_list_t * const p_cert_id_end_list
2625
+) {
2626
+#if defined(ENABLE_PKCS11H_THREADING)
2627
+	PKCS11H_BOOL fMutexLocked = FALSE;
2628
+#endif
2629
+	pkcs11h_certificate_id_list_t cert_id_list = NULL;
2630
+	pkcs11h_provider_t current_provider;
2631
+	pkcs11h_session_t current_session;
2632
+	CK_RV rv = CKR_OK;
2633
+
2634
+	PKCS11H_ASSERT (s_pkcs11h_data!=NULL);
2635
+	PKCS11H_ASSERT (s_pkcs11h_data->fInitialized);
2636
+	/*PKCS11H_ASSERT (p_cert_id_issuers_list!=NULL); NOT NEEDED*/
2637
+	PKCS11H_ASSERT (p_cert_id_end_list!=NULL);
2638
+
2639
+	PKCS11H_DEBUG (
2640
+		PKCS11H_LOG_DEBUG2,
2641
+		"PKCS#11: pkcs11h_enum_getCertificateIds entry method=%d, p_cert_id_issuers_list=%p, p_cert_id_end_list=%p",
2642
+		method,
2643
+		(void *)p_cert_id_issuers_list,
2644
+		(void *)p_cert_id_end_list
2516 2645
 	);
2517 2646
 
2647
+	if (p_cert_id_issuers_list != NULL) {
2648
+		*p_cert_id_issuers_list = NULL;
2649
+	}
2650
+	*p_cert_id_end_list = NULL;
2651
+
2652
+#if defined(ENABLE_PKCS11H_THREADING)
2518 2653
 	if (
2519 2654
 		rv == CKR_OK &&
2520
-		pkcs11h_certificate->certificate == NULL
2655
+		(rv = _pkcs11h_mutexLock (&s_pkcs11h_data->mutexCache)) == CKR_OK
2521 2656
 	) {
2522
-		rv = CKR_FUNCTION_REJECTED;
2657
+		fMutexLocked = TRUE;
2658
+	}
2659
+#endif
2660
+
2661
+	for (
2662
+		current_session = s_pkcs11h_data->sessions;
2663
+		current_session != NULL;
2664
+		current_session = current_session->next
2665
+	) {
2666
+		current_session->fTouch = FALSE;
2667
+		if (method == PKCS11H_ENUM_METHOD_RELOAD) {
2668
+			pkcs11h_freeCertificateIdList (current_session->cached_certs);
2669
+			current_session->cached_certs = NULL;
2670
+		}
2671
+	}
2672
+
2673
+	for (
2674
+		current_provider = s_pkcs11h_data->providers;
2675
+		(
2676
+			current_provider != NULL &&
2677
+			rv == CKR_OK
2678
+		);
2679
+		current_provider = current_provider->next
2680
+	) {
2681
+		CK_SLOT_ID_PTR slots = NULL;
2682
+		CK_ULONG slotnum;
2683
+		CK_SLOT_ID slot_index;
2684
+
2685
+		if (!current_provider->fEnabled) {
2686
+			continue;
2687
+		}
2688
+
2689
+		if (rv == CKR_OK) {
2690
+			rv = _pkcs11h_getSlotList (
2691
+				current_provider,
2692
+				CK_TRUE,
2693
+				&slots,
2694
+				&slotnum
2695
+			);
2696
+		}
2697
+
2698
+		for (
2699
+			slot_index=0;
2700
+			(
2701
+				slot_index < slotnum &&
2702
+				rv == CKR_OK
2703
+			);
2704
+			slot_index++
2705
+		) {
2706
+			pkcs11h_session_t session = NULL;
2707
+			pkcs11h_token_id_t token_id = NULL;
2708
+			CK_TOKEN_INFO info;
2709
+
2710
+			if (rv == CKR_OK) {
2711
+				rv = current_provider->f->C_GetTokenInfo (
2712
+					slots[slot_index],
2713
+					&info
2714
+				);
2715
+			}
2716
+
2717
+			if (
2718
+				rv == CKR_OK &&
2719
+				(rv = _pkcs11h_getTokenId (
2720
+					&info,
2721
+					&token_id
2722
+				)) == CKR_OK &&
2723
+				(rv = _pkcs11h_getSessionByTokenId (
2724
+					token_id,
2725
+					&session
2726
+				)) == CKR_OK
2727
+			) {
2728
+				session->fTouch = TRUE;
2729
+
2730
+				if (session->cached_certs == NULL) {
2731
+					rv = _pkcs11h_enum_getSessionCertificates (session);
2732
+				}
2733
+			}
2734
+
2735
+			if (rv != CKR_OK) {
2736
+				PKCS11H_DEBUG (
2737
+					PKCS11H_LOG_DEBUG1,
2738
+					"PKCS#11: Cannot get token information for provider '%s' slot %ld rv=%ld-'%s'",
2739
+					current_provider->manufacturerID,
2740
+					slots[slot_index],
2741
+					rv,
2742
+					pkcs11h_getMessage (rv)
2743
+				);
2744
+
2745
+				/*
2746
+				 * Ignore error
2747
+				 */
2748
+				rv = CKR_OK;
2749
+			}
2750
+
2751
+			if (session != NULL) {
2752
+				_pkcs11h_releaseSession (session);
2753
+				session = NULL;
2754
+			}
2755
+
2756
+			if (token_id != NULL) {
2757
+				pkcs11h_freeTokenId (token_id);
2758
+				token_id = NULL;
2759
+			}
2760
+		}
2761
+
2762
+		if (rv != CKR_OK) {
2763
+			PKCS11H_DEBUG (
2764
+				PKCS11H_LOG_DEBUG1,
2765
+				"PKCS#11: Cannot get slot list for provider '%s' rv=%ld-'%s'",
2766
+				current_provider->manufacturerID,
2767
+				rv,
2768
+				pkcs11h_getMessage (rv)
2769
+			);
2770
+
2771
+			/*
2772
+			 * Ignore error
2773
+			 */
2774
+			rv = CKR_OK;
2775
+		}
2776
+
2777
+		if (slots != NULL) {
2778
+			_pkcs11h_free ((void *)&slots);
2779
+			slots = NULL;
2780
+		}
2781
+	}
2782
+
2783
+	for (
2784
+		current_session = s_pkcs11h_data->sessions;
2785
+		(
2786
+			current_session != NULL &&
2787
+			rv == CKR_OK
2788
+		);
2789
+		current_session = current_session->next
2790
+	) {
2791
+		if (
2792
+			method == PKCS11H_ENUM_METHOD_CACHE ||
2793
+			(
2794
+				(
2795
+					method == PKCS11H_ENUM_METHOD_RELOAD ||
2796
+					method == PKCS11H_ENUM_METHOD_CACHE_EXIST
2797
+				) &&
2798
+				current_session->fTouch
2799
+			)
2800
+		) {
2801
+			pkcs11h_certificate_id_list_t entry = NULL;
2802
+
2803
+			for (
2804
+				entry = current_session->cached_certs;
2805
+				(
2806
+					entry != NULL &&
2807
+					rv == CKR_OK
2808
+				);
2809
+				entry = entry->next
2810
+			) {
2811
+				pkcs11h_certificate_id_list_t new_entry = NULL;
2812
+
2813
+				if (
2814
+					rv == CKR_OK &&
2815
+					(rv = _pkcs11h_malloc (
2816
+						(void *)&new_entry,
2817
+						sizeof (struct pkcs11h_certificate_id_list_s)
2818
+					)) == CKR_OK &&
2819
+					(rv = pkcs11h_duplicateCertificateId (
2820
+						&new_entry->certificate_id,
2821
+						entry->certificate_id
2822
+					)) == CKR_OK
2823
+				) {
2824
+					new_entry->next = cert_id_list;
2825
+					cert_id_list = new_entry;
2826
+					new_entry = NULL;
2827
+				}
2828
+
2829
+				if (new_entry != NULL) {
2830
+					new_entry->next = NULL;
2831
+					pkcs11h_freeCertificateIdList (new_entry);
2832
+					new_entry = NULL;
2833
+				}
2834
+			}
2835
+		}
2523 2836
 	}
2524 2837
 
2525 2838
 	if (rv == CKR_OK) {
2526
-		*certificate_size = pkcs11h_certificate->certificate_size;
2839
+		rv = _pkcs11h_enum_splitCertificateIdList (
2840
+			cert_id_list,
2841
+			p_cert_id_issuers_list,
2842
+			p_cert_id_end_list
2843
+		);
2527 2844
 	}
2528 2845
 
2529
-	if (certificate != NULL) {
2846
+	if (cert_id_list != NULL) {
2847
+		pkcs11h_freeCertificateIdList (cert_id_list);
2848
+		cert_id_list = NULL;
2849
+	}
2850
+
2851
+
2852
+#if defined(ENABLE_PKCS11H_THREADING)
2853
+	if (fMutexLocked) {
2854
+		_pkcs11h_mutexRelease (&s_pkcs11h_data->mutexCache);
2855
+		fMutexLocked = FALSE;
2856
+	}
2857
+#endif
2858
+
2859
+	PKCS11H_DEBUG (
2860
+		PKCS11H_LOG_DEBUG2,
2861
+		"PKCS#11: pkcs11h_enum_getCertificateIds return rv=%ld-'%s'",
2862
+		rv,
2863
+		pkcs11h_getMessage (rv)
2864
+	);
2865
+	
2866
+	return rv;
2867
+}
2868
+
2869
+#endif				/* ENABLE_PKCS11H_CERTIFICATE */
2870
+
2871
+#endif				/* ENABLE_PKCS11H_ENUM */
2872
+
2873
+#if defined(ENABLE_PKCS11H_SLOTEVENT)
2874
+/*======================================================================*
2875
+ * SLOTEVENT INTERFACE
2876
+ *======================================================================*/
2877
+
2878
+static
2879
+unsigned long
2880
+_pkcs11h_slotevent_checksum (
2881
+	IN const unsigned char * const p,
2882
+	IN const size_t s
2883
+) {
2884
+	unsigned long r = 0;
2885
+	size_t i;
2886
+	for (i=0;i<s;i++) {
2887
+		r += p[i];
2888
+	}
2889
+	return r;
2890
+}
2891
+
2892
+static
2893
+void *
2894
+_pkcs11h_slotevent_provider (
2895
+	IN void *p
2896
+) {
2897
+	pkcs11h_provider_t provider = (pkcs11h_provider_t)p;
2898
+	CK_SLOT_ID slot;
2899
+	CK_RV rv = CKR_OK;
2900
+
2901
+	PKCS11H_DEBUG (
2902
+		PKCS11H_LOG_DEBUG2,
2903
+		"PKCS#11: _pkcs11h_slotevent_provider provider='%s' entry",
2904
+		provider->manufacturerID
2905
+	);
2906
+
2907
+	if (rv == CKR_OK && !provider->fEnabled) {
2908
+		rv = CKR_OPERATION_NOT_INITIALIZED;
2909
+	}
2910
+
2911
+	if (rv == CKR_OK) {
2912
+
2913
+		if (provider->nSlotEventPollInterval == 0) {
2914
+			provider->nSlotEventPollInterval = PKCS11H_DEFAULT_SLOTEVENT_POLL;
2915
+		}
2916
+
2917
+		/*
2918
+		 * If we cannot finalize, we cannot cause
2919
+		 * WaitForSlotEvent to terminate
2920
+		 */
2921
+		if (!provider->fShouldFinalize) {
2922
+			PKCS11H_DEBUG (
2923
+				PKCS11H_LOG_DEBUG1,
2924
+				"PKCS#11: Setup slotevent provider='%s' mode hardset to poll",
2925
+				provider->manufacturerID
2926
+			);
2927
+			provider->nSlotEventMethod = PKCS11H_SLOTEVENT_METHOD_POLL;
2928
+		}
2929
+
2530 2930
 		if (
2931
+			provider->nSlotEventMethod == PKCS11H_SLOTEVENT_METHOD_AUTO ||
2932
+			provider->nSlotEventMethod == PKCS11H_SLOTEVENT_METHOD_TRIGGER
2933
+		) { 
2934
+			if (
2935
+				provider->f->C_WaitForSlotEvent (
2936
+					CKF_DONT_BLOCK,
2937
+					&slot,
2938
+					NULL_PTR
2939
+				) == CKR_FUNCTION_NOT_SUPPORTED
2940
+			) {
2941
+				PKCS11H_DEBUG (
2942
+					PKCS11H_LOG_DEBUG1,
2943
+					"PKCS#11: Setup slotevent provider='%s' mode is poll",
2944
+					provider->manufacturerID
2945
+				);
2946
+
2947
+				provider->nSlotEventMethod = PKCS11H_SLOTEVENT_METHOD_POLL;
2948
+			}
2949
+			else {
2950
+				PKCS11H_DEBUG (
2951
+					PKCS11H_LOG_DEBUG1,
2952
+					"PKCS#11: Setup slotevent provider='%s' mode is trigger",
2953
+					provider->manufacturerID
2954
+				);
2955
+
2956
+				provider->nSlotEventMethod = PKCS11H_SLOTEVENT_METHOD_TRIGGER;
2957
+			}
2958
+		}
2959
+	}
2960
+
2961
+	if (provider->nSlotEventMethod == PKCS11H_SLOTEVENT_METHOD_TRIGGER) {
2962
+		while (
2963
+			!s_pkcs11h_data->fSlotEventShouldTerminate &&
2964
+			provider->fEnabled &&
2531 2965
 			rv == CKR_OK &&
2532
-			*certificate_size > pkcs11h_certificate->certificate_size
2966
+			(rv = provider->f->C_WaitForSlotEvent (
2967
+				0,
2968
+				&slot,
2969
+				NULL_PTR
2970
+			)) == CKR_OK
2533 2971
 		) {
2534
-			rv = CKR_BUFFER_TOO_SMALL;
2972
+			PKCS11H_DEBUG (
2973
+				PKCS11H_LOG_DEBUG1,
2974
+				"PKCS#11: Slotevent provider='%s' event",
2975
+				provider->manufacturerID
2976
+			);
2977
+
2978
+			_pkcs11h_condSignal (&s_pkcs11h_data->condSlotEvent);
2535 2979
 		}
2536
-	
2980
+	}
2981
+	else {
2982
+		unsigned long ulLastChecksum = 0;
2983
+		PKCS11H_BOOL fFirstTime = TRUE;
2984
+
2985
+		while (
2986
+			!s_pkcs11h_data->fSlotEventShouldTerminate &&
2987
+			provider->fEnabled &&
2988
+			rv == CKR_OK
2989
+		) {
2990
+			unsigned long ulCurrentChecksum = 0;
2991
+
2992
+			CK_SLOT_ID_PTR slots = NULL;
2993
+			CK_ULONG slotnum;
2994
+
2995
+			PKCS11H_DEBUG (
2996
+				PKCS11H_LOG_DEBUG1,
2997
+				"PKCS#11: Slotevent provider='%s' poll",
2998
+				provider->manufacturerID
2999
+			);
3000
+
3001
+			if (
3002
+				rv == CKR_OK &&
3003
+				(rv = _pkcs11h_getSlotList (
3004
+					provider,
3005
+					TRUE,
3006
+					&slots,
3007
+					&slotnum
3008
+				)) == CKR_OK
3009
+			) {
3010
+				CK_ULONG i;
3011
+				
3012
+				for (i=0;i<slotnum;i++) {
3013
+					CK_TOKEN_INFO info;
3014
+
3015
+					if (provider->f->C_GetTokenInfo (slots[i], &info) == CKR_OK) {
3016
+						ulCurrentChecksum += (
3017
+							_pkcs11h_slotevent_checksum (
3018
+								info.label,
3019
+								sizeof (info.label)
3020
+							) +
3021
+							_pkcs11h_slotevent_checksum (
3022
+								info.manufacturerID,
3023
+								sizeof (info.manufacturerID)
3024
+							) +
3025
+							_pkcs11h_slotevent_checksum (
3026
+								info.model,
3027
+								sizeof (info.model)
3028
+							) +
3029
+							_pkcs11h_slotevent_checksum (
3030
+								info.serialNumber,
3031
+								sizeof (info.serialNumber)
3032
+							)
3033
+						);
3034
+					}
3035
+				}
3036
+			}
3037
+			
3038
+			if (rv == CKR_OK) {
3039
+				if (fFirstTime) {
3040
+					fFirstTime = FALSE;
3041
+				}
3042
+				else {
3043
+					if (ulLastChecksum != ulCurrentChecksum) {
3044
+						PKCS11H_DEBUG (
3045
+							PKCS11H_LOG_DEBUG1,
3046
+							"PKCS#11: Slotevent provider='%s' event",
3047
+							provider->manufacturerID
3048
+						);
3049
+
3050
+						_pkcs11h_condSignal (&s_pkcs11h_data->condSlotEvent);
3051
+					}
3052
+				}
3053
+				ulLastChecksum = ulCurrentChecksum;
3054
+			}
3055
+
3056
+			if (slots != NULL) {
3057
+				_pkcs11h_free ((void *)&slots);
3058
+			}
3059
+			
3060
+			if (!s_pkcs11h_data->fSlotEventShouldTerminate) {
3061
+				_pkcs11h_sleep (provider->nSlotEventPollInterval);
3062
+			}
3063
+		}
3064
+	}
3065
+
3066
+	PKCS11H_DEBUG (
3067
+		PKCS11H_LOG_DEBUG2,
3068
+		"PKCS#11: _pkcs11h_slotevent_provider provider='%s' return",
3069
+		provider->manufacturerID
3070
+	);
3071
+
3072
+	return NULL;
3073
+}
3074
+
3075
+static
3076
+void *
3077
+_pkcs11h_slotevent_manager (
3078
+	IN void *p
3079
+) {
3080
+	PKCS11H_BOOL fFirst = TRUE;
3081
+
3082
+	(void)p;
3083
+
3084
+	PKCS11H_DEBUG (
3085
+		PKCS11H_LOG_DEBUG2,
3086
+		"PKCS#11: _pkcs11h_slotevent_manager entry"
3087
+	);
3088
+
3089
+	/*
3090
+	 * Trigger hook, so application may
3091
+	 * depend on initial slot change
3092
+	 */
3093
+	PKCS11H_DEBUG (
3094
+		PKCS11H_LOG_DEBUG1,
3095
+		"PKCS#11: Calling slotevent hook"
3096
+	);
3097
+	s_pkcs11h_data->hooks.slotevent (s_pkcs11h_data->hooks.slotevent_data);
3098
+
3099
+	while (
3100
+		fFirst ||	/* Must enter wait or mutex will never be free */
3101
+		!s_pkcs11h_data->fSlotEventShouldTerminate
3102
+	) {
3103
+		pkcs11h_provider_t current_provider;
3104
+
3105
+		fFirst = FALSE;
3106
+
3107
+		/*
3108
+		 * Start each provider thread
3109
+		 * if not already started.
3110
+		 * This is required in order to allow
3111
+		 * adding new providers.
3112
+		 */
3113
+		for (
3114
+			current_provider = s_pkcs11h_data->providers;
3115
+			current_provider != NULL;
3116
+			current_provider = current_provider->next
3117
+		) {
3118
+			if (!current_provider->fEnabled) {
3119
+				if (current_provider->threadSlotEvent == PKCS11H_THREAD_NULL) {
3120
+					_pkcs11h_threadStart (
3121
+						&current_provider->threadSlotEvent,
3122
+						_pkcs11h_slotevent_provider,
3123
+						current_provider
3124
+					);
3125
+				}
3126
+			}
3127
+			else {
3128
+				if (current_provider->threadSlotEvent != PKCS11H_THREAD_NULL) {
3129
+					_pkcs11h_threadJoin (&current_provider->threadSlotEvent);
3130
+				}
3131
+			}
3132
+		}
3133
+
3134
+		PKCS11H_DEBUG (
3135
+			PKCS11H_LOG_DEBUG2,
3136
+			"PKCS#11: _pkcs11h_slotevent_manager waiting for slotevent"
3137
+		);
3138
+		_pkcs11h_condWait (&s_pkcs11h_data->condSlotEvent, PKCS11H_COND_INFINITE);
3139
+
3140
+		if (s_pkcs11h_data->fSlotEventSkipEvent) {
3141
+			PKCS11H_DEBUG (
3142
+				PKCS11H_LOG_DEBUG1,
3143
+				"PKCS#11: Slotevent skipping event"
3144
+			);
3145
+			s_pkcs11h_data->fSlotEventSkipEvent = FALSE;
3146
+		}
3147
+		else {
3148
+			PKCS11H_DEBUG (
3149
+				PKCS11H_LOG_DEBUG1,
3150
+				"PKCS#11: Calling slotevent hook"
3151
+			);
3152
+			s_pkcs11h_data->hooks.slotevent (s_pkcs11h_data->hooks.slotevent_data);
3153
+		}
3154
+	}
3155
+
3156
+	{
3157
+		pkcs11h_provider_t current_provider;
3158
+
3159
+		PKCS11H_DEBUG (
3160
+			PKCS11H_LOG_DEBUG2,
3161
+			"PKCS#11: _pkcs11h_slotevent_manager joining threads"
3162
+		);
3163
+
3164
+
3165
+		for (
3166
+			current_provider = s_pkcs11h_data->providers;
3167
+			current_provider != NULL;
3168
+			current_provider = current_provider->next
3169
+		) {
3170
+			if (current_provider->threadSlotEvent != PKCS11H_THREAD_NULL) {
3171
+				_pkcs11h_threadJoin (&current_provider->threadSlotEvent);
3172
+			}
3173
+		}
3174
+	}
3175
+
3176
+	PKCS11H_DEBUG (
3177
+		PKCS11H_LOG_DEBUG2,
3178
+		"PKCS#11: _pkcs11h_slotevent_manager return"
3179
+	);
3180
+
3181
+	return NULL;
3182
+}
3183
+
3184
+static
3185
+CK_RV
3186
+_pkcs11h_slotevent_init () {
3187
+	CK_RV rv = CKR_OK;
3188
+
3189
+	PKCS11H_DEBUG (
3190
+		PKCS11H_LOG_DEBUG2,
3191
+		"PKCS#11: _pkcs11h_slotevent_init entry"
3192
+	);
3193
+
3194
+	if (!s_pkcs11h_data->fSlotEventInitialized) {
2537 3195
 		if (rv == CKR_OK) {
2538
-			memmove (certificate, pkcs11h_certificate->certificate, *certificate_size);	
3196
+			rv = _pkcs11h_condInit (&s_pkcs11h_data->condSlotEvent);
3197
+		}
3198
+		
3199
+		if (rv == CKR_OK) {
3200
+			rv = _pkcs11h_threadStart (
3201
+				&s_pkcs11h_data->threadSlotEvent,
3202
+				_pkcs11h_slotevent_manager,
3203
+				NULL
3204
+			);
3205
+		}
3206
+		
3207
+		if (rv == CKR_OK) {
3208
+			s_pkcs11h_data->fSlotEventInitialized = TRUE;
2539 3209
 		}
2540 3210
 	}
2541 3211
 
2542
-	PKCS11DLOG (
2543
-		PKCS11_LOG_DEBUG2,
2544
-		"PKCS#11: pkcs11h_getCertificate return rv=%ld-'%s'",
3212
+	PKCS11H_DEBUG (
3213
+		PKCS11H_LOG_DEBUG2,
3214
+		"PKCS#11: _pkcs11h_slotevent_init return rv=%ld-'%s'",
2545 3215
 		rv,
2546 3216
 		pkcs11h_getMessage (rv)
2547 3217
 	);
2548 3218
 
3219
+	return rv;
3220
+}
3221
+
3222
+static
3223
+CK_RV
3224
+_pkcs11h_slotevent_notify () {
3225
+	
3226
+	PKCS11H_DEBUG (
3227
+		PKCS11H_LOG_DEBUG2,
3228
+		"PKCS#11: _pkcs11h_slotevent_notify entry"
3229
+	);
3230
+
3231
+	if (s_pkcs11h_data->fSlotEventInitialized) {
3232
+		s_pkcs11h_data->fSlotEventSkipEvent = TRUE;
3233
+		_pkcs11h_condSignal (&s_pkcs11h_data->condSlotEvent);
3234
+	}
3235
+
3236
+	PKCS11H_DEBUG (
3237
+		PKCS11H_LOG_DEBUG2,
3238
+		"PKCS#11: _pkcs11h_slotevent_notify return"
3239
+	);
3240
+
2549 3241
 	return CKR_OK;
2550 3242
 }
2551 3243
 
2552
-char *
2553
-pkcs11h_getMessage (
2554
-	IN const int rv
2555
-) {
2556
-	switch (rv) {
2557
-		case CKR_OK: return "CKR_OK";
2558
-		case CKR_CANCEL: return "CKR_CANCEL";
2559
-		case CKR_HOST_MEMORY: return "CKR_HOST_MEMORY";
2560
-		case CKR_SLOT_ID_INVALID: return "CKR_SLOT_ID_INVALID";
2561
-		case CKR_GENERAL_ERROR: return "CKR_GENERAL_ERROR";
2562
-		case CKR_FUNCTION_FAILED: return "CKR_FUNCTION_FAILED";
2563
-		case CKR_ARGUMENTS_BAD: return "CKR_ARGUMENTS_BAD";
2564
-		case CKR_NO_EVENT: return "CKR_NO_EVENT";
2565
-		case CKR_NEED_TO_CREATE_THREADS: return "CKR_NEED_TO_CREATE_THREADS";
2566
-		case CKR_CANT_LOCK: return "CKR_CANT_LOCK";
2567
-		case CKR_ATTRIBUTE_READ_ONLY: return "CKR_ATTRIBUTE_READ_ONLY";
2568
-		case CKR_ATTRIBUTE_SENSITIVE: return "CKR_ATTRIBUTE_SENSITIVE";
2569
-		case CKR_ATTRIBUTE_TYPE_INVALID: return "CKR_ATTRIBUTE_TYPE_INVALID";
2570
-		case CKR_ATTRIBUTE_VALUE_INVALID: return "CKR_ATTRIBUTE_VALUE_INVALID";
2571
-		case CKR_DATA_INVALID: return "CKR_DATA_INVALID";
2572
-		case CKR_DATA_LEN_RANGE: return "CKR_DATA_LEN_RANGE";
2573
-		case CKR_DEVICE_ERROR: return "CKR_DEVICE_ERROR";
2574
-		case CKR_DEVICE_MEMORY: return "CKR_DEVICE_MEMORY";
2575
-		case CKR_DEVICE_REMOVED: return "CKR_DEVICE_REMOVED";
2576
-		case CKR_ENCRYPTED_DATA_INVALID: return "CKR_ENCRYPTED_DATA_INVALID";
2577
-		case CKR_ENCRYPTED_DATA_LEN_RANGE: return "CKR_ENCRYPTED_DATA_LEN_RANGE";
2578
-		case CKR_FUNCTION_CANCELED: return "CKR_FUNCTION_CANCELED";
2579
-		case CKR_FUNCTION_NOT_PARALLEL: return "CKR_FUNCTION_NOT_PARALLEL";
2580
-		case CKR_FUNCTION_NOT_SUPPORTED: return "CKR_FUNCTION_NOT_SUPPORTED";
2581
-		case CKR_KEY_HANDLE_INVALID: return "CKR_KEY_HANDLE_INVALID";
2582
-		case CKR_KEY_SIZE_RANGE: return "CKR_KEY_SIZE_RANGE";
2583
-		case CKR_KEY_TYPE_INCONSISTENT: return "CKR_KEY_TYPE_INCONSISTENT";
2584
-		case CKR_KEY_NOT_NEEDED: return "CKR_KEY_NOT_NEEDED";
2585
-		case CKR_KEY_CHANGED: return "CKR_KEY_CHANGED";
2586
-		case CKR_KEY_NEEDED: return "CKR_KEY_NEEDED";
2587
-		case CKR_KEY_INDIGESTIBLE: return "CKR_KEY_INDIGESTIBLE";
2588
-		case CKR_KEY_FUNCTION_NOT_PERMITTED: return "CKR_KEY_FUNCTION_NOT_PERMITTED";
2589
-		case CKR_KEY_NOT_WRAPPABLE: return "CKR_KEY_NOT_WRAPPABLE";
2590
-		case CKR_KEY_UNEXTRACTABLE: return "CKR_KEY_UNEXTRACTABLE";
2591
-		case CKR_MECHANISM_INVALID: return "CKR_MECHANISM_INVALID";
2592
-		case CKR_MECHANISM_PARAM_INVALID: return "CKR_MECHANISM_PARAM_INVALID";
2593
-		case CKR_OBJECT_HANDLE_INVALID: return "CKR_OBJECT_HANDLE_INVALID";
2594
-		case CKR_OPERATION_ACTIVE: return "CKR_OPERATION_ACTIVE";
2595
-		case CKR_OPERATION_NOT_INITIALIZED: return "CKR_OPERATION_NOT_INITIALIZED";
2596
-		case CKR_PIN_INCORRECT: return "CKR_PIN_INCORRECT";
2597
-		case CKR_PIN_INVALID: return "CKR_PIN_INVALID";
2598
-		case CKR_PIN_LEN_RANGE: return "CKR_PIN_LEN_RANGE";
2599
-		case CKR_PIN_EXPIRED: return "CKR_PIN_EXPIRED";
2600
-		case CKR_PIN_LOCKED: return "CKR_PIN_LOCKED";
2601
-		case CKR_SESSION_CLOSED: return "CKR_SESSION_CLOSED";
2602
-		case CKR_SESSION_COUNT: return "CKR_SESSION_COUNT";
2603
-		case CKR_SESSION_HANDLE_INVALID: return "CKR_SESSION_HANDLE_INVALID";
2604
-		case CKR_SESSION_PARALLEL_NOT_SUPPORTED: return "CKR_SESSION_PARALLEL_NOT_SUPPORTED";
2605
-		case CKR_SESSION_READ_ONLY: return "CKR_SESSION_READ_ONLY";
2606
-		case CKR_SESSION_EXISTS: return "CKR_SESSION_EXISTS";
2607
-		case CKR_SESSION_READ_ONLY_EXISTS: return "CKR_SESSION_READ_ONLY_EXISTS";
2608
-		case CKR_SESSION_READ_WRITE_SO_EXISTS: return "CKR_SESSION_READ_WRITE_SO_EXISTS";
2609
-		case CKR_SIGNATURE_INVALID: return "CKR_SIGNATURE_INVALID";
2610
-		case CKR_SIGNATURE_LEN_RANGE: return "CKR_SIGNATURE_LEN_RANGE";
2611
-		case CKR_TEMPLATE_INCOMPLETE: return "CKR_TEMPLATE_INCOMPLETE";
2612
-		case CKR_TEMPLATE_INCONSISTENT: return "CKR_TEMPLATE_INCONSISTENT";
2613
-		case CKR_TOKEN_NOT_PRESENT: return "CKR_TOKEN_NOT_PRESENT";
2614
-		case CKR_TOKEN_NOT_RECOGNIZED: return "CKR_TOKEN_NOT_RECOGNIZED";
2615
-		case CKR_TOKEN_WRITE_PROTECTED: return "CKR_TOKEN_WRITE_PROTECTED";
2616
-		case CKR_UNWRAPPING_KEY_HANDLE_INVALID: return "CKR_UNWRAPPING_KEY_HANDLE_INVALID";
2617
-		case CKR_UNWRAPPING_KEY_SIZE_RANGE: return "CKR_UNWRAPPING_KEY_SIZE_RANGE";
2618
-		case CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT: return "CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT";
2619
-		case CKR_USER_ALREADY_LOGGED_IN: return "CKR_USER_ALREADY_LOGGED_IN";
2620
-		case CKR_USER_NOT_LOGGED_IN: return "CKR_USER_NOT_LOGGED_IN";
2621
-		case CKR_USER_PIN_NOT_INITIALIZED: return "CKR_USER_PIN_NOT_INITIALIZED";
2622
-		case CKR_USER_TYPE_INVALID: return "CKR_USER_TYPE_INVALID";
2623
-		case CKR_USER_ANOTHER_ALREADY_LOGGED_IN: return "CKR_USER_ANOTHER_ALREADY_LOGGED_IN";
2624
-		case CKR_USER_TOO_MANY_TYPES: return "CKR_USER_TOO_MANY_TYPES";
2625
-		case CKR_WRAPPED_KEY_INVALID: return "CKR_WRAPPED_KEY_INVALID";
2626
-		case CKR_WRAPPED_KEY_LEN_RANGE: return "CKR_WRAPPED_KEY_LEN_RANGE";
2627
-		case CKR_WRAPPING_KEY_HANDLE_INVALID: return "CKR_WRAPPING_KEY_HANDLE_INVALID";
2628
-		case CKR_WRAPPING_KEY_SIZE_RANGE: return "CKR_WRAPPING_KEY_SIZE_RANGE";
2629
-		case CKR_WRAPPING_KEY_TYPE_INCONSISTENT: return "CKR_WRAPPING_KEY_TYPE_INCONSISTENT";
2630
-		case CKR_RANDOM_SEED_NOT_SUPPORTED: return "CKR_RANDOM_SEED_NOT_SUPPORTED";
2631
-		case CKR_RANDOM_NO_RNG: return "CKR_RANDOM_NO_RNG";
2632
-		case CKR_DOMAIN_PARAMS_INVALID: return "CKR_DOMAIN_PARAMS_INVALID";
2633
-		case CKR_BUFFER_TOO_SMALL: return "CKR_BUFFER_TOO_SMALL";
2634
-		case CKR_SAVED_STATE_INVALID: return "CKR_SAVED_STATE_INVALID";
2635
-		case CKR_INFORMATION_SENSITIVE: return "CKR_INFORMATION_SENSITIVE";
2636
-		case CKR_STATE_UNSAVEABLE: return "CKR_STATE_UNSAVEABLE";
2637
-		case CKR_CRYPTOKI_NOT_INITIALIZED: return "CKR_CRYPTOKI_NOT_INITIALIZED";
2638
-		case CKR_CRYPTOKI_ALREADY_INITIALIZED: return "CKR_CRYPTOKI_ALREADY_INITIALIZED";
2639
-		case CKR_MUTEX_BAD: return "CKR_MUTEX_BAD";
2640
-		case CKR_MUTEX_NOT_LOCKED: return "CKR_MUTEX_NOT_LOCKED";
2641
-		case CKR_FUNCTION_REJECTED: return "CKR_FUNCTION_REJECTED";
2642
-		case CKR_VENDOR_DEFINED: return "CKR_VENDOR_DEFINED";
2643
-		default: return "Unknown PKCS#11 error";
3244
+static
3245
+CK_RV
3246
+_pkcs11h_slotevent_terminate () {
3247
+	
3248
+	PKCS11H_DEBUG (
3249
+		PKCS11H_LOG_DEBUG2,
3250
+		"PKCS#11: _pkcs11h_slotevent_terminate entry"
3251
+	);
3252
+
3253
+	if (s_pkcs11h_data->fSlotEventInitialized) {
3254
+		s_pkcs11h_data->fSlotEventShouldTerminate = TRUE;
3255
+
3256
+		_pkcs11h_slotevent_notify ();
3257
+
3258
+		if (s_pkcs11h_data->threadSlotEvent != PKCS11H_THREAD_NULL) {
3259
+			_pkcs11h_threadJoin (&s_pkcs11h_data->threadSlotEvent);
3260
+		}
3261
+
3262
+		_pkcs11h_condFree (&s_pkcs11h_data->condSlotEvent);
3263
+		s_pkcs11h_data->fSlotEventInitialized = FALSE;
2644 3264
 	}
3265
+
3266
+	PKCS11H_DEBUG (
3267
+		PKCS11H_LOG_DEBUG2,
3268
+		"PKCS#11: _pkcs11h_slotevent_terminate return"
3269
+	);
3270
+
3271
+	return CKR_OK;
2645 3272
 }
2646 3273
 
2647
-/*==========================================
2648
- * openssl interface
2649
- */
3274
+#endif
3275
+
3276
+#if defined(ENABLE_PKCS11H_OPENSSL)
3277
+/*======================================================================*
3278
+ * OPENSSL INTERFACE
3279
+ *======================================================================*/
2650 3280
 
2651 3281
 static
2652 3282
 pkcs11h_openssl_session_t
2653
-_pkcs11h_openssl_get_pkcs11h_openssl_session (
3283
+_pkcs11h_openssl_get_openssl_session (
2654 3284
 	IN OUT const RSA *rsa
2655 3285
 ) {
2656 3286
 	pkcs11h_openssl_session_t session;
2657 3287
 		
2658
-	PKCS11ASSERT (rsa!=NULL);
3288
+	PKCS11H_ASSERT (rsa!=NULL);
2659 3289
 #if OPENSSL_VERSION_NUMBER < 0x00907000L
2660 3290
 	session = (pkcs11h_openssl_session_t)RSA_get_app_data ((RSA *)rsa);
2661 3291
 #else
2662 3292
 	session = (pkcs11h_openssl_session_t)RSA_get_app_data (rsa);
2663 3293
 #endif
2664
-	PKCS11ASSERT (session!=NULL);
3294
+	PKCS11H_ASSERT (session!=NULL);
2665 3295
 
2666 3296
 	return session;
2667 3297
 }
... ...
@@ -2671,12 +8613,10 @@ pkcs11h_certificate_t
2671 2671
 _pkcs11h_openssl_get_pkcs11h_certificate (
2672 2672
 	IN OUT const RSA *rsa
2673 2673
 ) {
2674
-	pkcs11h_openssl_session_t session = _pkcs11h_openssl_get_pkcs11h_openssl_session (rsa);
2674
+	pkcs11h_openssl_session_t session = _pkcs11h_openssl_get_openssl_session (rsa);
2675 2675
 	
2676
-	PKCS11ASSERT (session!=NULL);
2677
-	PKCS11ASSERT (session->certificate!=NULL);
2678
-	PKCS11ASSERT (session->certificate->session!=NULL);
2679
-	PKCS11ASSERT (session->certificate->session->fValid);
2676
+	PKCS11H_ASSERT (session!=NULL);
2677
+	PKCS11H_ASSERT (session->certificate!=NULL);
2680 2678
 
2681 2679
 	return session->certificate;
2682 2680
 }
... ...
@@ -2702,12 +8642,12 @@ _pkcs11h_openssl_dec (
2702 2702
 	IN int padding
2703 2703
 ) {
2704 2704
 #endif
2705
-	PKCS11ASSERT (from!=NULL);
2706
-	PKCS11ASSERT (to!=NULL);
2707
-	PKCS11ASSERT (rsa!=NULL);
2705
+	PKCS11H_ASSERT (from!=NULL);
2706
+	PKCS11H_ASSERT (to!=NULL);
2707
+	PKCS11H_ASSERT (rsa!=NULL);
2708 2708
 
2709
-	PKCS11DLOG (
2710
-		PKCS11_LOG_DEBUG2,
2709
+	PKCS11H_DEBUG (
2710
+		PKCS11H_LOG_DEBUG2,
2711 2711
 		"PKCS#11: _pkcs11h_openssl_dec entered - flen=%d, from=%p, to=%p, rsa=%p, padding=%d",
2712 2712
 		flen,
2713 2713
 		from,
... ...
@@ -2716,13 +8656,13 @@ _pkcs11h_openssl_dec (
2716 2716
 		padding
2717 2717
 	);
2718 2718
 
2719
-	PKCS11LOG (
2720
-		PKCS11_LOG_ERROR,
2719
+	PKCS11H_LOG (
2720
+		PKCS11H_LOG_ERROR,
2721 2721
 		"PKCS#11: Private key decryption is not supported"
2722 2722
 	);
2723 2723
 
2724
-	PKCS11DLOG (
2725
-		PKCS11_LOG_DEBUG2,
2724
+	PKCS11H_DEBUG (
2725
+		PKCS11H_LOG_DEBUG2,
2726 2726
 		"PKCS#11: _pkcs11h_openssl_dec return"
2727 2727
 	);
2728 2728
 
... ...
@@ -2752,7 +8692,7 @@ _pkcs11h_openssl_sign (
2752 2752
 	IN OUT const RSA *rsa
2753 2753
 ) {
2754 2754
 #endif
2755
-	pkcs11h_certificate_t pkcs11h_certificate = _pkcs11h_openssl_get_pkcs11h_certificate (rsa);
2755
+	pkcs11h_certificate_t certificate = _pkcs11h_openssl_get_pkcs11h_certificate (rsa);
2756 2756
 	CK_RV rv = CKR_OK;
2757 2757
 
2758 2758
 	int myrsa_size = 0;
... ...
@@ -2761,12 +8701,12 @@ _pkcs11h_openssl_sign (
2761 2761
 	unsigned char *enc = NULL;
2762 2762
 	int enc_len = 0;
2763 2763
 
2764
-	PKCS11ASSERT (m!=NULL);
2765
-	PKCS11ASSERT (sigret!=NULL);
2766
-	PKCS11ASSERT (siglen!=NULL);
2764
+	PKCS11H_ASSERT (m!=NULL);
2765
+	PKCS11H_ASSERT (sigret!=NULL);
2766
+	PKCS11H_ASSERT (siglen!=NULL);
2767 2767
 
2768
-	PKCS11DLOG (
2769
-		PKCS11_LOG_DEBUG2,
2768
+	PKCS11H_DEBUG (
2769
+		PKCS11H_LOG_DEBUG2,
2770 2770
 		"PKCS#11: _pkcs11h_openssl_sign entered - type=%d, m=%p, m_len=%u, signret=%p, signlen=%p, rsa=%p",
2771 2771
 		type,
2772 2772
 		m,
... ...
@@ -2794,18 +8734,18 @@ _pkcs11h_openssl_sign (
2794 2794
 
2795 2795
 		if (
2796 2796
 			rv == CKR_OK &&
2797
-			(enc=enc_alloc=(unsigned char *)malloc ((unsigned int)myrsa_size+1)) == NULL
2797
+			(rv = _pkcs11h_malloc ((void*)&enc, myrsa_size+1)) == CKR_OK
2798 2798
 		) {
2799
-			rv = CKR_HOST_MEMORY;
2799
+			enc_alloc = enc;
2800 2800
 		}
2801 2801
 		
2802 2802
 		if (rv == CKR_OK) {
2803
-			sig.algor= &algor;
2803
+			sig.algor = &algor;
2804 2804
 		}
2805 2805
 
2806 2806
 		if (
2807 2807
 			rv == CKR_OK &&
2808
-			(sig.algor->algorithm=OBJ_nid2obj(type)) == NULL
2808
+			(sig.algor->algorithm = OBJ_nid2obj (type)) == NULL
2809 2809
 		) {
2810 2810
 			rv = CKR_FUNCTION_FAILED;
2811 2811
 		}
... ...
@@ -2818,26 +8758,26 @@ _pkcs11h_openssl_sign (
2818 2818
 		}
2819 2819
 	
2820 2820
 		if (rv == CKR_OK) {
2821
-			parameter.type=V_ASN1_NULL;
2822
-			parameter.value.ptr=NULL;
2821
+			parameter.type = V_ASN1_NULL;
2822
+			parameter.value.ptr = NULL;
2823 2823
 	
2824
-			sig.algor->parameter= &parameter;
2824
+			sig.algor->parameter = &parameter;
2825 2825
 
2826
-			sig.digest=&digest;
2827
-			sig.digest->data=(unsigned char *)m;
2828
-			sig.digest->length=m_len;
2826
+			sig.digest = &digest;
2827
+			sig.digest->data = (unsigned char *)m;
2828
+			sig.digest->length = m_len;
2829 2829
 		}
2830 2830
 	
2831 2831
 		if (
2832 2832
 			rv == CKR_OK &&
2833
-			(enc_len=i2d_X509_SIG(&sig,NULL)) < 0
2833
+			(enc_len=i2d_X509_SIG (&sig, NULL)) < 0
2834 2834
 		) {
2835 2835
 			rv = CKR_FUNCTION_FAILED;
2836 2836
 		}
2837 2837
 	
2838 2838
 		if (rv == CKR_OK) {
2839
-			unsigned char *p=enc;
2840
-			i2d_X509_SIG(&sig,&p);
2839
+			unsigned char *p = enc;
2840
+			i2d_X509_SIG (&sig, &p);
2841 2841
 		}
2842 2842
 	}
2843 2843
 
... ...
@@ -2848,65 +8788,34 @@ _pkcs11h_openssl_sign (
2848 2848
 		rv = CKR_KEY_SIZE_RANGE;
2849 2849
 	}
2850 2850
 
2851
-	/*
2852
-	 * Get key attributes
2853
-	 * so signature mode will
2854
-	 * be available
2855
-	 */
2856
-	if (rv == CKR_OK) {
2857
-		rv = _pkcs11h_getCertificateKeyAttributes (pkcs11h_certificate);
2858
-	}
2859
-
2860 2851
 	if (rv == CKR_OK) {
2861
-		PKCS11DLOG (
2862
-			PKCS11_LOG_DEBUG1,
2852
+		PKCS11H_DEBUG (
2853
+			PKCS11H_LOG_DEBUG1,
2863 2854
 			"PKCS#11: Performing signature"
2864 2855
 		);
2865 2856
 
2866 2857
 		*siglen = myrsa_size;
2867 2858
 
2868
-		switch (pkcs11h_certificate->signmode) {
2869
-			case pkcs11h_signmode_sign:
2870
-				if (
2871
-					(rv = pkcs11h_sign (
2872
-						pkcs11h_certificate,
2873
-						CKM_RSA_PKCS,
2874
-						enc,
2875
-						enc_len,
2876
-						sigret,
2877
-						siglen
2878
-					)) != CKR_OK
2879
-				) {
2880
-					PKCS11LOG (PKCS11_LOG_WARN, "PKCS#11: Cannot perform signature %ld:'%s'", rv, pkcs11h_getMessage (rv));
2881
-				}
2882
-			break;
2883
-			case pkcs11h_signmode_recover:
2884
-				if (
2885
-					(rv = pkcs11h_signRecover (
2886
-						pkcs11h_certificate,
2887
-						CKM_RSA_PKCS,
2888
-						enc,
2889
-						enc_len,
2890
-						sigret,
2891
-						siglen
2892
-					)) != CKR_OK
2893
-				) {
2894
-					PKCS11LOG (PKCS11_LOG_WARN, "PKCS#11: Cannot perform signature-recover %ld:'%s'", rv, pkcs11h_getMessage (rv));
2895
-				}
2896
-			break;
2897
-			default:
2898
-				rv = CKR_FUNCTION_REJECTED;
2899
-				PKCS11LOG (PKCS11_LOG_WARN, "PKCS#11: Invalid signature mode");
2900
-			break;
2859
+		if (
2860
+			(rv = pkcs11h_certificate_signAny (
2861
+				certificate,
2862
+				CKM_RSA_PKCS,
2863
+				enc,
2864
+				enc_len,
2865
+				sigret,
2866
+				siglen
2867
+			)) != CKR_OK
2868
+		) {
2869
+			PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Cannot perform signature %ld:'%s'", rv, pkcs11h_getMessage (rv));
2901 2870
 		}
2902 2871
 	}
2903 2872
 
2904 2873
 	if (enc_alloc != NULL) {
2905
-		free (enc_alloc);
2874
+		_pkcs11h_free ((void *)&enc_alloc);
2906 2875
 	}
2907 2876
 	
2908
-	PKCS11DLOG (
2909
-		PKCS11_LOG_DEBUG2,
2877
+	PKCS11H_DEBUG (
2878
+		PKCS11H_LOG_DEBUG2,
2910 2879
 		"PKCS#11: _pkcs11h_openssl_sign - return rv=%ld-'%s'",
2911 2880
 		rv,
2912 2881
 		pkcs11h_getMessage (rv)
... ...
@@ -2920,18 +8829,18 @@ int
2920 2920
 _pkcs11h_openssl_finish (
2921 2921
 	IN OUT RSA *rsa
2922 2922
 ) {
2923
-	pkcs11h_openssl_session_t pkcs11h_openssl_session = _pkcs11h_openssl_get_pkcs11h_openssl_session (rsa);
2923
+	pkcs11h_openssl_session_t openssl_session = _pkcs11h_openssl_get_openssl_session (rsa);
2924 2924
 
2925
-	PKCS11DLOG (
2926
-		PKCS11_LOG_DEBUG2,
2925
+	PKCS11H_DEBUG (
2926
+		PKCS11H_LOG_DEBUG2,
2927 2927
 		"PKCS#11: _pkcs11h_openssl_finish - entered rsa=%p",
2928 2928
 		(void *)rsa
2929 2929
 	);
2930 2930
 
2931 2931
 	RSA_set_app_data (rsa, NULL);
2932 2932
 	
2933
-	if (pkcs11h_openssl_session->orig_finish != NULL) {
2934
-		pkcs11h_openssl_session->orig_finish (rsa);
2933
+	if (openssl_session->orig_finish != NULL) {
2934
+		openssl_session->orig_finish (rsa);
2935 2935
 
2936 2936
 #ifdef BROKEN_OPENSSL_ENGINE
2937 2937
 		{
... ...
@@ -2950,10 +8859,10 @@ _pkcs11h_openssl_finish (
2950 2950
 #endif
2951 2951
 	}
2952 2952
 
2953
-	pkcs11h_openssl_freeSession (pkcs11h_openssl_session);
2953
+	pkcs11h_openssl_freeSession (openssl_session);
2954 2954
 
2955
-	PKCS11DLOG (
2956
-		PKCS11_LOG_DEBUG2,
2955
+	PKCS11H_DEBUG (
2956
+		PKCS11H_LOG_DEBUG2,
2957 2957
 		"PKCS#11: _pkcs11h_openssl_finish - return"
2958 2958
 	);
2959 2959
 	
... ...
@@ -2961,192 +8870,187 @@ _pkcs11h_openssl_finish (
2961 2961
 }
2962 2962
 
2963 2963
 pkcs11h_openssl_session_t
2964
-pkcs11h_openssl_createSession () {
2965
-	pkcs11h_openssl_session_t pkcs11h_openssl_session = NULL;
2966
-	bool fOK = true;
2964
+pkcs11h_openssl_createSession (
2965
+	IN const pkcs11h_certificate_t certificate
2966
+) {
2967
+	pkcs11h_openssl_session_t openssl_session = NULL;
2968
+	PKCS11H_BOOL fOK = TRUE;
2967 2969
 
2968
-	PKCS11DLOG (
2969
-		PKCS11_LOG_DEBUG2,
2970
+	PKCS11H_DEBUG (
2971
+		PKCS11H_LOG_DEBUG2,
2970 2972
 		"PKCS#11: pkcs11h_openssl_createSession - entry"
2971 2973
 	);
2972 2974
 
2973 2975
 	if (
2974 2976
 		fOK &&
2975
-		(pkcs11h_openssl_session = (pkcs11h_openssl_session_t)malloc (sizeof (struct pkcs11h_openssl_session_s))) == NULL
2977
+		_pkcs11h_malloc (
2978
+			(void*)&openssl_session,
2979
+			sizeof (struct pkcs11h_openssl_session_s)) != CKR_OK
2976 2980
 	) {
2977
-		fOK = false;
2978
-		PKCS11LOG (PKCS11_LOG_WARN, "PKCS#11: Cannot allocate memory");
2981
+		fOK = FALSE;
2982
+		PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Cannot allocate memory");
2979 2983
 	}
2980 2984
 
2981 2985
 	if (fOK) {
2982
-		memset (pkcs11h_openssl_session, 0, sizeof (struct pkcs11h_openssl_session_s));
2983
-	}
2986
+		const RSA_METHOD *def = RSA_get_default_method();
2984 2987
 
2985
-	if (fOK) {
2986
-		pkcs11h_openssl_session->nReferenceCount = 1;
2988
+		memmove (&openssl_session->smart_rsa, def, sizeof(RSA_METHOD));
2989
+
2990
+		openssl_session->orig_finish = def->finish;
2991
+
2992
+		openssl_session->smart_rsa.name = "pkcs11";
2993
+		openssl_session->smart_rsa.rsa_priv_dec = _pkcs11h_openssl_dec;
2994
+		openssl_session->smart_rsa.rsa_sign = _pkcs11h_openssl_sign;
2995
+		openssl_session->smart_rsa.finish = _pkcs11h_openssl_finish;
2996
+		openssl_session->smart_rsa.flags  = RSA_METHOD_FLAG_NO_CHECK | RSA_FLAG_EXT_PKEY;
2997
+		openssl_session->certificate = certificate;
2998
+		openssl_session->nReferenceCount = 1;
2987 2999
 	}
2988 3000
 
2989 3001
 	if (!fOK) {
2990
-		free (pkcs11h_openssl_session);
2991
-		pkcs11h_openssl_session = NULL;
3002
+		_pkcs11h_free ((void *)&openssl_session);
2992 3003
 	}
2993 3004
 	
2994
-	PKCS11DLOG (
2995
-		PKCS11_LOG_DEBUG2,
2996
-		"PKCS#11: pkcs11h_openssl_createSession - return pkcs11h_openssl_session=%p",
2997
-		(void *)pkcs11h_openssl_session
3005
+	PKCS11H_DEBUG (
3006
+		PKCS11H_LOG_DEBUG2,
3007
+		"PKCS#11: pkcs11h_openssl_createSession - return openssl_session=%p",
3008
+		(void *)openssl_session
2998 3009
 	);
2999 3010
 
3000
-	return pkcs11h_openssl_session;
3011
+	return openssl_session;
3001 3012
 }
3002 3013
 
3003 3014
 void
3004 3015
 pkcs11h_openssl_freeSession (
3005
-	IN const pkcs11h_openssl_session_t pkcs11h_openssl_session
3016
+	IN const pkcs11h_openssl_session_t openssl_session
3006 3017
 ) {
3007
-	PKCS11ASSERT (pkcs11h_openssl_session!=NULL);
3008
-	PKCS11ASSERT (pkcs11h_openssl_session->nReferenceCount>0);
3018
+	PKCS11H_ASSERT (openssl_session!=NULL);
3019
+	PKCS11H_ASSERT (openssl_session->nReferenceCount>0);
3009 3020
 	
3010
-	PKCS11DLOG (
3011
-		PKCS11_LOG_DEBUG2,
3012
-		"PKCS#11: pkcs11h_openssl_freeSession - entry pkcs11h_openssl_session=%p, count=%d",
3013
-		(void *)pkcs11h_openssl_session,
3014
-		pkcs11h_openssl_session->nReferenceCount
3021
+	PKCS11H_DEBUG (
3022
+		PKCS11H_LOG_DEBUG2,
3023
+		"PKCS#11: pkcs11h_openssl_freeSession - entry openssl_session=%p, count=%d",
3024
+		(void *)openssl_session,
3025
+		openssl_session->nReferenceCount
3015 3026
 	);
3016 3027
 
3017
-	pkcs11h_openssl_session->nReferenceCount--;
3028
+	openssl_session->nReferenceCount--;
3018 3029
 	
3019
-	if (pkcs11h_openssl_session->nReferenceCount == 0) {
3020
-		if (pkcs11h_openssl_session->x509) {
3021
-			X509_free (pkcs11h_openssl_session->x509);
3022
-			pkcs11h_openssl_session->x509 = NULL;
3030
+	if (openssl_session->nReferenceCount == 0) {
3031
+		if (openssl_session->x509 != NULL) {
3032
+			X509_free (openssl_session->x509);
3033
+			openssl_session->x509 = NULL;
3023 3034
 		}
3024
-		if (pkcs11h_openssl_session->certificate != NULL) {
3025
-			pkcs11h_freeCertificateSession (pkcs11h_openssl_session->certificate);
3026
-			pkcs11h_openssl_session->certificate = NULL;
3035
+		if (openssl_session->certificate != NULL) {
3036
+			pkcs11h_freeCertificate (openssl_session->certificate);
3037
+			openssl_session->certificate = NULL;
3027 3038
 		}
3028 3039
 		
3029
-		free (pkcs11h_openssl_session);
3040
+		_pkcs11h_free ((void *)&openssl_session);
3030 3041
 	}
3031 3042
 
3032
-	PKCS11DLOG (
3033
-		PKCS11_LOG_DEBUG2,
3043
+	PKCS11H_DEBUG (
3044
+		PKCS11H_LOG_DEBUG2,
3034 3045
 		"PKCS#11: pkcs11h_openssl_freeSession - return"
3035 3046
 	);
3036 3047
 }
3037 3048
 
3038 3049
 RSA *
3039 3050
 pkcs11h_openssl_getRSA (
3040
-	IN const pkcs11h_openssl_session_t pkcs11h_openssl_session
3051
+	IN const pkcs11h_openssl_session_t openssl_session
3041 3052
 ) {
3042 3053
 	X509 *x509 = NULL;
3043 3054
 	RSA *rsa = NULL;
3044 3055
 	EVP_PKEY *pubkey = NULL;
3045 3056
 	CK_RV rv = CKR_OK;
3046 3057
 
3047
-	unsigned char certificate[10*1024];
3048
-	size_t certificate_size;
3049 3058
 	pkcs11_openssl_d2i_t d2i1 = NULL;
3050
-	bool fOK = true;
3059
+	PKCS11H_BOOL fOK = TRUE;
3051 3060
 
3052
-	PKCS11ASSERT (pkcs11h_openssl_session!=NULL);
3053
-	PKCS11ASSERT (!pkcs11h_openssl_session->fInitialized);
3061
+	PKCS11H_ASSERT (openssl_session!=NULL);
3062
+	PKCS11H_ASSERT (!openssl_session->fInitialized);
3063
+	PKCS11H_ASSERT (openssl_session!=NULL);
3054 3064
 
3055
-	PKCS11DLOG (
3056
-		PKCS11_LOG_DEBUG2,
3057
-		"PKCS#11: pkcs11h_openssl_getRSA - entry pkcs11h_openssl_session=%p",
3058
-		(void *)pkcs11h_openssl_session
3065
+	PKCS11H_DEBUG (
3066
+		PKCS11H_LOG_DEBUG2,
3067
+		"PKCS#11: pkcs11h_openssl_getRSA - entry openssl_session=%p",
3068
+		(void *)openssl_session
3059 3069
 	);
3060 3070
 
3061 3071
 	if (
3062 3072
 		fOK &&
3063 3073
 		(x509 = X509_new ()) == NULL
3064 3074
 	) {
3065
-		fOK = false;
3066
-		PKCS11LOG (PKCS11_LOG_WARN, "PKCS#11: Unable to allocate certificate object");
3075
+		fOK = FALSE;
3076
+		PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Unable to allocate certificate object");
3067 3077
 	}
3068 3078
 
3069
-	certificate_size = sizeof (certificate);
3070 3079
 	if (
3071 3080
 		fOK &&
3072
-		(rv = pkcs11h_getCertificate (
3073
-			pkcs11h_openssl_session->certificate,
3074
-			certificate,
3075
-			&certificate_size
3076
-		)) != CKR_OK
3077
-	) { 
3078
-		fOK = false;
3079
-		PKCS11LOG (PKCS11_LOG_WARN, "PKCS#11: Cannot read X.509 certificate from token %ld-'%s'", rv, pkcs11h_getMessage (rv));
3081
+		(rv = _pkcs11h_ensureCertificateBlob (openssl_session->certificate)) != CKR_OK
3082
+	) {
3083
+		fOK = FALSE;
3084
+		PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Cannot read X.509 certificate from token %ld-'%s'", rv, pkcs11h_getMessage (rv));
3080 3085
 	}
3081 3086
 
3082
-	d2i1 = (pkcs11_openssl_d2i_t)certificate;
3087
+	d2i1 = (pkcs11_openssl_d2i_t)openssl_session->certificate->id->certificate_blob;
3083 3088
 	if (
3084 3089
 		fOK &&
3085
-		!d2i_X509 (&x509, &d2i1, certificate_size)
3090
+		!d2i_X509 (&x509, &d2i1, openssl_session->certificate->id->certificate_blob_size)
3086 3091
 	) {
3087
-		fOK = false;
3088
-		PKCS11LOG (PKCS11_LOG_WARN, "PKCS#11: Unable to parse X.509 certificate");
3092
+		fOK = FALSE;
3093
+		PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Unable to parse X.509 certificate");
3089 3094
 	}
3090 3095
 
3091 3096
 	if (
3092 3097
 		fOK &&
3093 3098
 		(pubkey = X509_get_pubkey (x509)) == NULL
3094 3099
 	) {
3095
-		fOK = false;
3096
-		PKCS11LOG (PKCS11_LOG_WARN, "PKCS#11: Cannot get public key");
3100
+		fOK = FALSE;
3101
+		PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Cannot get public key");
3097 3102
 	}
3098 3103
 	
3099 3104
 	if (
3100 3105
 		fOK &&
3101 3106
 		pubkey->type != EVP_PKEY_RSA
3102 3107
 	) {
3103
-		fOK = false;
3104
-		PKCS11LOG (PKCS11_LOG_WARN, "PKCS#11: Invalid public key algorithm");
3108
+		fOK = FALSE;
3109
+		PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Invalid public key algorithm");
3105 3110
 	}
3106 3111
 
3107 3112
 	if (
3108 3113
 		fOK &&
3109 3114
 		(rsa = EVP_PKEY_get1_RSA (pubkey)) == NULL
3110 3115
 	) {
3111
-		fOK = false;
3112
-		PKCS11LOG (PKCS11_LOG_WARN, "PKCS#11: Cannot get RSA key");
3116
+		fOK = FALSE;
3117
+		PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: Cannot get RSA key");
3113 3118
 	}
3114 3119
 
3115
- 	if (fOK) {
3116
-		const RSA_METHOD *def = RSA_get_default_method();
3117
-
3118
-		memmove (&pkcs11h_openssl_session->smart_rsa, def, sizeof(RSA_METHOD));
3119
-
3120
-		pkcs11h_openssl_session->orig_finish = def->finish;
3121
-
3122
-		pkcs11h_openssl_session->smart_rsa.name = "pkcs11";
3123
-		pkcs11h_openssl_session->smart_rsa.rsa_priv_dec = _pkcs11h_openssl_dec;
3124
-		pkcs11h_openssl_session->smart_rsa.rsa_sign = _pkcs11h_openssl_sign;
3125
-		pkcs11h_openssl_session->smart_rsa.finish = _pkcs11h_openssl_finish;
3126
-		pkcs11h_openssl_session->smart_rsa.flags  = RSA_METHOD_FLAG_NO_CHECK | RSA_FLAG_EXT_PKEY;
3120
+	if (fOK) {
3127 3121
 
3128
-		RSA_set_method (rsa, &pkcs11h_openssl_session->smart_rsa);
3129
-		RSA_set_app_data (rsa, pkcs11h_openssl_session);
3130
-		pkcs11h_openssl_session->nReferenceCount++;
3122
+		RSA_set_method (rsa, &openssl_session->smart_rsa);
3123
+		RSA_set_app_data (rsa, openssl_session);
3124
+		openssl_session->nReferenceCount++;
3131 3125
 	}
3132 3126
 	
3133 3127
 #ifdef BROKEN_OPENSSL_ENGINE
3134 3128
 	if (fOK) {
3135
-		if (!rsa->engine)
3129
+		if (!rsa->engine) {
3136 3130
 			rsa->engine = ENGINE_get_default_RSA();
3131
+		}
3137 3132
 
3138
-		ENGINE_set_RSA(ENGINE_get_default_RSA(), &pkcs11h_openssl_session->smart_rsa);
3139
-		PKCS11LOG (PKCS11_LOG_WARN, "PKCS#11: OpenSSL engine support is broken! Workaround enabled");
3133
+		ENGINE_set_RSA(ENGINE_get_default_RSA(), &openssl_session->smart_rsa);
3134
+		PKCS11H_LOG (PKCS11H_LOG_WARN, "PKCS#11: OpenSSL engine support is broken! Workaround enabled");
3140 3135
 	}
3141 3136
 #endif
3142 3137
 		
3143 3138
 	if (fOK) {
3144 3139
 		/*
3145
-			So that it won't hold RSA
3146
-		*/
3147
-		pkcs11h_openssl_session->x509 = X509_dup (x509);
3140
+		 * dup x509 so that it won't hold RSA
3141
+		 */
3142
+		openssl_session->x509 = X509_dup (x509);
3148 3143
 		rsa->flags |= RSA_FLAG_SIGN_VER;
3149
-		pkcs11h_openssl_session->fInitialized = true;
3144
+		openssl_session->fInitialized = TRUE;
3150 3145
 	}
3151 3146
 	else {
3152 3147
 		if (rsa != NULL) {
... ...
@@ -3169,8 +9073,8 @@ pkcs11h_openssl_getRSA (
3169 3169
 		x509 = NULL;
3170 3170
 	}
3171 3171
 	
3172
-	PKCS11DLOG (
3173
-		PKCS11_LOG_DEBUG2,
3172
+	PKCS11H_DEBUG (
3173
+		PKCS11H_LOG_DEBUG2,
3174 3174
 		"PKCS#11: pkcs11h_openssl_getRSA - return rsa=%p",
3175 3175
 		(void *)rsa
3176 3176
 	);
... ...
@@ -3180,24 +9084,24 @@ pkcs11h_openssl_getRSA (
3180 3180
 
3181 3181
 X509 *
3182 3182
 pkcs11h_openssl_getX509 (
3183
-	IN const pkcs11h_openssl_session_t pkcs11h_openssl_session
3183
+	IN const pkcs11h_openssl_session_t openssl_session
3184 3184
 ) {
3185 3185
 	X509 *x509 = NULL;
3186 3186
 	
3187
-	PKCS11ASSERT (pkcs11h_openssl_session!=NULL);
3187
+	PKCS11H_ASSERT (openssl_session!=NULL);
3188 3188
 
3189
-	PKCS11DLOG (
3190
-		PKCS11_LOG_DEBUG2,
3191
-		"PKCS#11: pkcs11h_openssl_getX509 - entry pkcs11h_openssl_session=%p",
3192
-		(void *)pkcs11h_openssl_session
3189
+	PKCS11H_DEBUG (
3190
+		PKCS11H_LOG_DEBUG2,
3191
+		"PKCS#11: pkcs11h_openssl_getX509 - entry openssl_session=%p",
3192
+		(void *)openssl_session
3193 3193
 	);
3194 3194
 
3195
-	if (pkcs11h_openssl_session->x509 != NULL) {
3196
-		x509 = X509_dup (pkcs11h_openssl_session->x509);
3195
+	if (openssl_session->x509 != NULL) {
3196
+		x509 = X509_dup (openssl_session->x509);
3197 3197
 	}
3198 3198
 	
3199
-	PKCS11DLOG (
3200
-		PKCS11_LOG_DEBUG2,
3199
+	PKCS11H_DEBUG (
3200
+		PKCS11H_LOG_DEBUG2,
3201 3201
 		"PKCS#11: pkcs11h_openssl_getX509 - return x509=%p",
3202 3202
 		(void *)x509
3203 3203
 	);
... ...
@@ -3205,6 +9109,12 @@ pkcs11h_openssl_getX509 (
3205 3205
 	return x509;
3206 3206
 }
3207 3207
 
3208
+#endif				/* ENABLE_PKCS11H_OPENSSL */
3209
+
3210
+#if defined(ENABLE_PKCS11H_STANDALONE)
3211
+/*======================================================================*
3212
+ * STANDALONE INTERFACE
3213
+ *======================================================================*/
3208 3214
 
3209 3215
 void
3210 3216
 pkcs11h_standalone_dump_slots (
... ...
@@ -3216,7 +9126,9 @@ pkcs11h_standalone_dump_slots (
3216 3216
 
3217 3217
 	pkcs11h_provider_t pkcs11h_provider;
3218 3218
 
3219
-	PKCS11ASSERT (provider!=NULL);
3219
+	PKCS11H_ASSERT (my_output!=NULL);
3220
+	/*PKCS11H_ASSERT (pData) NOT NEEDED */
3221
+	PKCS11H_ASSERT (provider!=NULL);
3220 3222
 
3221 3223
 	if (
3222 3224
 		rv == CKR_OK &&
... ...
@@ -3227,7 +9139,18 @@ pkcs11h_standalone_dump_slots (
3227 3227
 
3228 3228
 	if (
3229 3229
 		rv == CKR_OK &&
3230
-		(rv = pkcs11h_addProvider (provider, NULL)) != CKR_OK
3230
+		(rv = pkcs11h_addProvider (
3231
+			provider,
3232
+			provider,
3233
+			FALSE,
3234
+			(
3235
+				PKCS11H_SIGNMODE_MASK_SIGN |
3236
+				PKCS11H_SIGNMODE_MASK_RECOVER
3237
+			),
3238
+			PKCS11H_SLOTEVENT_METHOD_AUTO,
3239
+			0,
3240
+			FALSE
3241
+		)) != CKR_OK
3231 3242
 	) {
3232 3243
 		my_output (pData, "PKCS#11: Cannot initialize provider %ld-'%s'\n", rv, pkcs11h_getMessage (rv));
3233 3244
 	}
... ...
@@ -3236,7 +9159,7 @@ pkcs11h_standalone_dump_slots (
3236 3236
 	 * our provider is head
3237 3237
 	 */
3238 3238
 	if (rv == CKR_OK) {
3239
-		pkcs11h_provider = pkcs11h_data->providers;
3239
+		pkcs11h_provider = s_pkcs11h_data->providers;
3240 3240
 		if (pkcs11h_provider == NULL || !pkcs11h_provider->fEnabled) {
3241 3241
 			my_output (pData, "PKCS#11: Cannot get provider %ld-'%s'\n", rv, pkcs11h_getMessage (rv));
3242 3242
 			rv = CKR_GENERAL_ERROR;
... ...
@@ -3254,8 +9177,8 @@ pkcs11h_standalone_dump_slots (
3254 3254
 			char szManufacturerID[sizeof (info.manufacturerID)+1];
3255 3255
 	
3256 3256
 			_pkcs11h_fixupFixedString (
3257
-				(char *)info.manufacturerID,
3258 3257
 				szManufacturerID,
3258
+				(char *)info.manufacturerID,
3259 3259
 				sizeof (info.manufacturerID)
3260 3260
 			);
3261 3261
 	
... ...
@@ -3277,17 +9200,17 @@ pkcs11h_standalone_dump_slots (
3277 3277
 	}
3278 3278
 	
3279 3279
 	if (rv == CKR_OK) {
3280
-		CK_SLOT_ID slots[1024];
3280
+		CK_SLOT_ID_PTR slots = NULL;
3281 3281
 		CK_ULONG slotnum;
3282
-		CK_SLOT_ID s;
3282
+		CK_SLOT_ID slot_index;
3283 3283
 		
3284
-		slotnum = sizeof (slots) / sizeof (CK_SLOT_ID);
3285 3284
 		if (
3286
-			(rv = pkcs11h_provider->f->C_GetSlotList (
3287
-				FALSE,
3288
-				slots,
3285
+			 _pkcs11h_getSlotList (
3286
+				pkcs11h_provider,
3287
+				CK_FALSE,
3288
+				&slots,
3289 3289
 				&slotnum
3290
-			)) != CKR_OK
3290
+			) != CKR_OK
3291 3291
 		) {
3292 3292
 			my_output (pData, "PKCS#11: Cannot get slot list %ld-'%s'\n", rv, pkcs11h_getMessage (rv));
3293 3293
 		}
... ...
@@ -3301,48 +9224,93 @@ pkcs11h_standalone_dump_slots (
3301 3301
 					"\n"
3302 3302
 					"Slots: (id - name)\n"
3303 3303
 				),
3304
-				PKCS11_PRM_SLOT_TYPE,
3305
-				PKCS11_PRM_SLOT_ID
3304
+				PKCS11H_PRM_SLOT_TYPE,
3305
+				PKCS11H_PRM_SLOT_ID
3306 3306
 			);
3307
-			for (s=0;s<slotnum;s++) {
3307
+			for (slot_index=0;slot_index < slotnum;slot_index++) {
3308 3308
 				CK_SLOT_INFO info;
3309 3309
 	
3310 3310
 				if (
3311 3311
 					(rv = pkcs11h_provider->f->C_GetSlotInfo (
3312
-						slots[s],
3312
+						slots[slot_index],
3313 3313
 						&info
3314 3314
 					)) == CKR_OK
3315 3315
 				) {
3316 3316
 					char szCurrentName[sizeof (info.slotDescription)+1];
3317 3317
 				
3318 3318
 					_pkcs11h_fixupFixedString (
3319
-						(char *)info.slotDescription,
3320 3319
 						szCurrentName,
3320
+						(char *)info.slotDescription,
3321 3321
 						sizeof (info.slotDescription)
3322 3322
 					);
3323 3323
 	
3324
-					my_output (pData, "\t%lu - %s\n", slots[s], szCurrentName);
3324
+					my_output (pData, "\t%lu - %s\n", slots[slot_index], szCurrentName);
3325 3325
 				}
3326 3326
 			}
3327 3327
 		}
3328
+
3329
+		if (slots != NULL) {
3330
+			_pkcs11h_free ((void *)&slots);
3331
+		}
3328 3332
 	}
3329 3333
 	
3330 3334
 	pkcs11h_terminate ();
3331 3335
 }
3332 3336
 
3333 3337
 static
3334
-bool
3338
+PKCS11H_BOOL
3335 3339
 _pkcs11h_standalone_dump_objects_pin_prompt (
3336 3340
 	IN const void *pData,
3337
-	IN const char * const szLabel,
3341
+	IN const pkcs11h_token_id_t token,
3338 3342
 	OUT char * const szPIN,
3339 3343
 	IN const size_t nMaxPIN
3340 3344
 ) {
3341 3345
 	strncpy (szPIN, (char *)pData, nMaxPIN);
3342
-	return true;
3346
+	return TRUE;
3343 3347
 }
3344 3348
 
3345 3349
 void
3350
+_pkcs11h_standalone_dump_objects_hex (
3351
+	IN const unsigned char * const p,
3352
+	IN const size_t p_size,
3353
+	OUT char * const sz,
3354
+	IN const size_t max,
3355
+	IN const char * const szLinePrefix
3356
+) {
3357
+	size_t j;
3358
+
3359
+	sz[0] = '\0';
3360
+
3361
+	for (j=0;j<p_size;j+=16) {
3362
+		char szLine[3*16+1];
3363
+		size_t k;
3364
+
3365
+		szLine[0] = '\0';
3366
+		for (k=0;k<16 && j+k<p_size;k++) {
3367
+			sprintf (szLine+strlen (szLine), "%02x ", p[j+k]);
3368
+		}
3369
+
3370
+		strncat (
3371
+			sz,
3372
+			szLinePrefix,
3373
+			max-1-strlen (sz)
3374
+		);
3375
+		strncat (
3376
+			sz,
3377
+			szLine,
3378
+			max-1-strlen (sz)
3379
+		);
3380
+		strncat (
3381
+			sz,
3382
+			"\n",
3383
+			max-1-strlen (sz)
3384
+		);
3385
+	}
3386
+
3387
+	sz[max-1] = '\0';
3388
+}
3389
+	
3390
+void
3346 3391
 pkcs11h_standalone_dump_objects (
3347 3392
 	IN const pkcs11h_output_print_t my_output,
3348 3393
 	IN const void *pData,
... ...
@@ -3353,11 +9321,15 @@ pkcs11h_standalone_dump_objects (
3353 3353
 	CK_SLOT_ID s;
3354 3354
 	CK_RV rv = CKR_OK;
3355 3355
 
3356
-	pkcs11h_provider_t pkcs11h_provider;
3356
+	pkcs11h_provider_t pkcs11h_provider = NULL;
3357
+	pkcs11h_token_id_t token_id = NULL;
3358
+	pkcs11h_session_t session = NULL;
3357 3359
 
3358
-	PKCS11ASSERT (provider!=NULL);
3359
-	PKCS11ASSERT (slot!=NULL);
3360
-	PKCS11ASSERT (pin!=NULL);
3360
+	PKCS11H_ASSERT (my_output!=NULL);
3361
+	/*PKCS11H_ASSERT (pData) NOT NEEDED */
3362
+	PKCS11H_ASSERT (provider!=NULL);
3363
+	PKCS11H_ASSERT (slot!=NULL);
3364
+	PKCS11H_ASSERT (pin!=NULL);
3361 3365
 
3362 3366
 	s = atoi (slot);
3363 3367
 
... ...
@@ -3377,16 +9349,27 @@ pkcs11h_standalone_dump_objects (
3377 3377
 
3378 3378
 	if (
3379 3379
 		rv == CKR_OK &&
3380
-		(rv = pkcs11h_addProvider (provider, NULL)) != CKR_OK
3380
+		(rv = pkcs11h_addProvider (
3381
+			provider,
3382
+			provider,
3383
+			FALSE,
3384
+			(
3385
+				PKCS11H_SIGNMODE_MASK_SIGN |
3386
+				PKCS11H_SIGNMODE_MASK_RECOVER
3387
+			),
3388
+			PKCS11H_SLOTEVENT_METHOD_AUTO,
3389
+			0,
3390
+			FALSE
3391
+		)) != CKR_OK
3381 3392
 	) {
3382 3393
 		my_output (pData, "PKCS#11: Cannot initialize provider %ld-'%s'\n", rv, pkcs11h_getMessage (rv));
3383 3394
 	}
3384 3395
 
3385
-  	/*
3396
+	/*
3386 3397
 	 * our provider is head
3387 3398
 	 */
3388 3399
 	if (rv == CKR_OK) {
3389
-		pkcs11h_provider = pkcs11h_data->providers;
3400
+		pkcs11h_provider = s_pkcs11h_data->providers;
3390 3401
 		if (pkcs11h_provider == NULL || !pkcs11h_provider->fEnabled) {
3391 3402
 			my_output (pData, "PKCS#11: Cannot get provider %ld-'%s'\n", rv, pkcs11h_getMessage (rv));
3392 3403
 			rv = CKR_GENERAL_ERROR;
... ...
@@ -3403,6 +9386,7 @@ pkcs11h_standalone_dump_objects (
3403 3403
 			)) != CKR_OK
3404 3404
 		) {
3405 3405
 			my_output (pData, "PKCS#11: Cannot get token information for slot %ld %ld-'%s'\n", s, rv, pkcs11h_getMessage (rv));
3406
+			/* Ignore this error */
3406 3407
 			rv = CKR_OK;
3407 3408
 		}
3408 3409
 		else {
... ...
@@ -3412,23 +9396,23 @@ pkcs11h_standalone_dump_objects (
3412 3412
 			char szSerialNumber[sizeof (info.serialNumber)+1];
3413 3413
 			
3414 3414
 			_pkcs11h_fixupFixedString (
3415
-				(char *)info.label,
3416 3415
 				szLabel,
3416
+				(char *)info.label,
3417 3417
 				sizeof (info.label)
3418 3418
 			);
3419 3419
 			_pkcs11h_fixupFixedString (
3420
-				(char *)info.manufacturerID,
3421 3420
 				szManufacturerID,
3421
+				(char *)info.manufacturerID,
3422 3422
 				sizeof (info.manufacturerID)
3423 3423
 			);
3424 3424
 			_pkcs11h_fixupFixedString (
3425
-				(char *)info.model,
3426 3425
 				szModel,
3426
+				(char *)info.model,
3427 3427
 				sizeof (info.model)
3428 3428
 			);
3429 3429
 			_pkcs11h_fixupFixedString (
3430
-				(char *)info.serialNumber,
3431 3430
 				szSerialNumber,
3431
+				(char *)info.serialNumber,
3432 3432
 				sizeof (info.serialNumber)
3433 3433
 			);
3434 3434
 	
... ...
@@ -3451,256 +9435,449 @@ pkcs11h_standalone_dump_objects (
3451 3451
 				szModel,
3452 3452
 				szSerialNumber,
3453 3453
 				(unsigned)info.flags,
3454
-				PKCS11_PRM_SLOT_TYPE,
3455
-				PKCS11_PRM_SLOT_ID,
3454
+				PKCS11H_PRM_SLOT_TYPE,
3455
+				PKCS11H_PRM_SLOT_ID,
3456 3456
 				szLabel
3457 3457
 			);
3458
+
3459
+			if (
3460
+				rv == CKR_OK &&
3461
+				(rv = _pkcs11h_getTokenId (
3462
+					&info,
3463
+					&token_id
3464
+				)) != CKR_OK
3465
+			) {
3466
+				my_output (pData, "PKCS#11: Cannot get token id for slot %ld %ld-'%s'\n", s, rv, pkcs11h_getMessage (rv));		
3467
+				rv = CKR_OK;
3468
+			}
3458 3469
 		}
3459 3470
 	}
3460 3471
 
3461
-	if (rv == CKR_OK) {
3462
-		CK_SESSION_HANDLE session;
3463
-		
3472
+	if (token_id != NULL) {
3464 3473
 		if (
3465
-			(rv = pkcs11h_provider->f->C_OpenSession (
3466
-				s,
3467
-				CKF_SERIAL_SESSION,
3468
-				NULL_PTR,
3469
-				NULL_PTR,
3474
+			(rv = _pkcs11h_getSessionByTokenId (
3475
+				token_id,
3470 3476
 				&session
3471 3477
 			)) != CKR_OK
3472 3478
 		) {
3473
-			my_output (pData, "PKCS#11: Cannot open session to slot %ld %ld-'%s'\n", s, rv, pkcs11h_getMessage (rv));
3479
+			my_output (pData, "PKCS#11: Cannot session for token '%s' %ld-'%s'\n", token_id->label, rv, pkcs11h_getMessage (rv));		
3474 3480
 			rv = CKR_OK;
3475 3481
 		}
3476
-		else {
3477
-			CK_OBJECT_HANDLE objects[10];
3478
-			CK_ULONG objects_found;
3482
+	}
3483
+
3484
+	if (session != NULL) {
3485
+		CK_OBJECT_HANDLE *objects = NULL;
3486
+		CK_ULONG objects_found = 0;
3487
+		CK_ULONG i;
3488
+
3489
+		if (
3490
+			(rv = _pkcs11h_login (
3491
+				session,
3492
+				FALSE,
3493
+				TRUE,
3494
+				PKCS11H_PROMPT_MASK_ALLOW_PIN_PROMPT
3495
+			)) != CKR_OK
3496
+		) {
3497
+			my_output (pData, "PKCS#11: Cannot open session to token '%s' %ld-'%s'\n", session->token_id->label, rv, pkcs11h_getMessage (rv));
3498
+		}
3479 3499
 	
3500
+		my_output (
3501
+			pData,
3502
+			(
3503
+				"The following objects are available for use with this token.\n"
3504
+				"Each object shown below may be used as a parameter to\n"
3505
+				"%s and %s options.\n"
3506
+				"\n"
3507
+			),
3508
+			PKCS11H_PRM_OBJ_TYPE,
3509
+			PKCS11H_PRM_OBJ_ID
3510
+		);
3511
+
3512
+		if (
3513
+			rv == CKR_OK &&
3514
+			(rv = _pkcs11h_findObjects (
3515
+				session,
3516
+				NULL,
3517
+				0,
3518
+				&objects,
3519
+				&objects_found
3520
+			)) != CKR_OK
3521
+		) {
3522
+			my_output (pData, "PKCS#11: Cannot query objects for token '%s' %ld-'%s'\n", session->token_id->label, rv, pkcs11h_getMessage (rv));
3523
+		}
3524
+	
3525
+		for (i=0;rv == CKR_OK && i < objects_found;i++) {
3526
+			CK_OBJECT_CLASS attrs_class = 0;
3527
+			CK_ATTRIBUTE attrs[] = {
3528
+				{CKA_CLASS, &attrs_class, sizeof (attrs_class)}
3529
+			};
3530
+
3480 3531
 			if (
3481
-				(rv = pkcs11h_provider->f->C_Login (
3482
-					session,
3483
-					CKU_USER,
3484
-					(CK_CHAR_PTR)pin,
3485
-					(CK_ULONG)strlen (pin)
3486
-				)) != CKR_OK &&
3487
-				rv != CKR_USER_ALREADY_LOGGED_IN
3488
-			) {
3489
-				my_output (pData, "PKCS#11: Cannot login to token on slot %ld %ld-'%s'\n", s, rv, pkcs11h_getMessage (rv));
3490
-			}
3491
-		
3492
-			if (
3493
-				(rv = pkcs11h_provider->f->C_FindObjectsInit (
3532
+				_pkcs11h_getObjectAttributes (
3494 3533
 					session,
3495
-					NULL,
3496
-					0
3497
-				)) != CKR_OK
3534
+					objects[i],
3535
+					attrs,
3536
+					sizeof (attrs) / sizeof (CK_ATTRIBUTE)
3537
+				) == CKR_OK
3498 3538
 			) {
3499
-				my_output (pData, "PKCS#11: Cannot query objects for token on slot %ld %ld-'%s'\n", s, rv, pkcs11h_getMessage (rv));
3500
-			}
3501
-		
3502
-			my_output (
3503
-				pData,
3504
-				(
3505
-					"The following objects are available for use with this token.\n"
3506
-					"Each object shown below may be used as a parameter to\n"
3507
-					"%s and %s options.\n"
3508
-					"\n"
3509
-				),
3510
-				PKCS11_PRM_OBJ_TYPE,
3511
-				PKCS11_PRM_OBJ_ID
3512
-			);
3513
-		
3514
-			while (
3515
-				(rv = pkcs11h_provider->f->C_FindObjects (
3516
-					session,
3517
-					objects,
3518
-					sizeof (objects) / sizeof (CK_OBJECT_HANDLE),
3519
-					&objects_found
3520
-				)) == CKR_OK &&
3521
-				objects_found > 0
3522
-			) { 
3523
-				CK_ULONG i;
3524
-				
3525
-				for (i=0;i<objects_found;i++) {
3526
-					CK_OBJECT_CLASS attrs_class;
3527
-					unsigned char attrs_id[PKCS11H_MAX_ATTRIBUTE_SIZE];
3528
-					unsigned char attrs_label[PKCS11H_MAX_ATTRIBUTE_SIZE];
3529
-					CK_ATTRIBUTE attrs[] = {
3530
-						{CKA_CLASS, &attrs_class, sizeof (attrs_class)},
3531
-						{CKA_ID, attrs_id, sizeof (attrs_id)},
3532
-						{CKA_LABEL, attrs_label, sizeof (attrs_label)-1}
3539
+				if (attrs_class == CKO_CERTIFICATE) {
3540
+					CK_ATTRIBUTE attrs_cert[] = {
3541
+						{CKA_ID, NULL, 0},
3542
+						{CKA_LABEL, NULL, 0},
3543
+						{CKA_VALUE, NULL, 0}
3533 3544
 					};
3534
-			
3545
+					unsigned char *attrs_id = NULL;
3546
+					int attrs_id_size = 0;
3547
+					unsigned char *attrs_value = NULL;
3548
+					int attrs_value_size = 0;
3549
+					char *attrs_label = NULL;
3550
+					char szHexId[1024];
3551
+					char szSubject[1024];
3552
+					char szSerial[1024];
3553
+					char szNotBefore[1024];
3554
+
3555
+					szSubject[0] = '\0';
3556
+					szSerial[0] = '\0';
3557
+					szNotBefore[0] = '\0';
3558
+
3559
+
3535 3560
 					if (
3536
-						pkcs11h_provider->f->C_GetAttributeValue (
3561
+						_pkcs11h_getObjectAttributes (
3537 3562
 							session,
3538 3563
 							objects[i],
3539
-							attrs,
3540
-							sizeof (attrs) / sizeof (CK_ATTRIBUTE)
3564
+							attrs_cert,
3565
+							sizeof (attrs_cert) / sizeof (CK_ATTRIBUTE)
3566
+						) == CKR_OK &&
3567
+						_pkcs11h_malloc (
3568
+							(void *)&attrs_label,
3569
+							attrs_cert[1].ulValueLen+1
3541 3570
 						) == CKR_OK
3542 3571
 					) {
3543
-						int id_len = attrs[1].ulValueLen;
3544
-						int j;
3545
-							
3546
-						attrs_label[attrs[2].ulValueLen] = 0;
3547
-		
3548
-						my_output (
3549
-							pData,
3550
-							(
3551
-								"Object\n"
3552
-								"\tLabel:\t\t%s\n"
3553
-								"\tId:\n"
3554
-							),
3555
-							attrs_label
3572
+						attrs_id = (unsigned char *)attrs_cert[0].pValue;
3573
+						attrs_id_size = attrs_cert[0].ulValueLen;
3574
+						attrs_value = (unsigned char *)attrs_cert[2].pValue;
3575
+						attrs_value_size = attrs_cert[2].ulValueLen;
3576
+
3577
+						memset (attrs_label, 0, attrs_cert[1].ulValueLen+1);
3578
+						memmove (attrs_label, attrs_cert[1].pValue, attrs_cert[1].ulValueLen);
3579
+						_pkcs11h_standalone_dump_objects_hex (
3580
+							attrs_id,
3581
+							attrs_id_size,
3582
+							szHexId,
3583
+							sizeof (szHexId),
3584
+							"\t\t"
3556 3585
 						);
3557
-		
3558
-							
3559
-						for (j=0;j<id_len;j+=16) {
3560
-							char szLine[3*16+1];
3561
-							int k;
3562
-		
3563
-							szLine[0] = '\0';
3564
-							for (k=0;k<16 && j+k<id_len;k++) {
3565
-								sprintf (szLine+strlen (szLine), "%02x ", attrs_id[j+k]);
3566
-							}
3567
-		
3568
-							my_output (pData, "\t\t%s\n", szLine);
3586
+					}
3587
+
3588
+					if (attrs_value != NULL) {
3589
+						X509 *x509 = NULL;
3590
+						BIO *bioSerial = NULL;
3591
+
3592
+						if ((x509 = X509_new ()) == NULL) {
3593
+							my_output (pData, "Cannot create x509 context\n");
3569 3594
 						}
3570
-		
3571
-						if (attrs_class == CKO_CERTIFICATE) {
3572
-							unsigned char certificate[PKCS11H_MAX_ATTRIBUTE_SIZE];
3573
-							CK_ATTRIBUTE attrs_cert[] = {
3574
-								{CKA_VALUE, certificate, sizeof (certificate)}
3575
-							};
3576
-		
3577
-							my_output (pData, "\tType:\t\tCertificate\n");
3578
-		
3579
-							if (
3580
-								pkcs11h_provider->f->C_GetAttributeValue (
3581
-									session,
3582
-									objects[i],
3583
-									attrs_cert,
3584
-									sizeof (attrs_cert) / sizeof (CK_ATTRIBUTE)
3585
-								) == CKR_OK
3586
-							) {
3587
-								X509 *x509 = NULL;
3588
-								BIO *bioSerial = NULL;
3589
-		
3590
-								char szSubject[1024];
3591
-								char szSerial[1024];
3592
-								char szNotBefore[1024];
3593
-		
3594
-								szSubject[0] = '\0';
3595
-								szSerial[0] = '\0';
3596
-								szNotBefore[0] = '\0';
3597
-		
3598
-								if ((x509 = X509_new ()) == NULL) {
3599
-									my_output (pData, "Cannot create x509 context\n");
3600
-								}
3601
-								else {
3602
-									pkcs11_openssl_d2i_t d2i1 = (pkcs11_openssl_d2i_t)certificate;
3603
-									if (d2i_X509 (&x509, &d2i1, attrs_cert[0].ulValueLen)) {
3604
-		
3605
-										ASN1_TIME *notBefore = X509_get_notBefore (x509);
3606
-										if (notBefore != NULL && notBefore->length < (int) sizeof (szNotBefore) - 1) {
3607
-											memmove (szNotBefore, notBefore->data, notBefore->length);
3608
-											szNotBefore[notBefore->length] = '\0';
3609
-										}
3610
-		
3611
-										X509_NAME_oneline (
3612
-											X509_get_subject_name (x509),
3613
-											szSubject,
3614
-											sizeof (szSubject)
3615
-										);
3616
-										szSubject[sizeof (szSubject) - 1] = '\0';
3617
-									}
3618
-								}
3619
-		
3620
-								if ((bioSerial = BIO_new (BIO_s_mem ())) == NULL) {
3621
-									my_output (pData, "Cannot create BIO context\n");
3622
-								}
3623
-								else {
3624
-									int n;
3625
-		
3626
-									i2a_ASN1_INTEGER(bioSerial, X509_get_serialNumber (x509));
3627
-									n = BIO_read (bioSerial, szSerial, sizeof (szSerial)-1);
3628
-									if (n<0) {
3629
-										szSerial[0] = '\0';
3630
-									}
3631
-									else {
3632
-										szSerial[n] = '\0';
3633
-									}
3634
-								}
3635
-		
3636
-		
3637
-								if (x509 != NULL) {
3638
-									X509_free (x509);
3639
-									x509 = NULL;
3640
-								}
3641
-								if (bioSerial != NULL) {
3642
-									BIO_free_all (bioSerial);
3643
-									bioSerial = NULL;
3595
+						else {
3596
+							pkcs11_openssl_d2i_t d2i1 = (pkcs11_openssl_d2i_t)attrs_value;
3597
+							if (d2i_X509 (&x509, &d2i1, attrs_value_size)) {
3598
+
3599
+								ASN1_TIME *notBefore = X509_get_notBefore (x509);
3600
+								if (notBefore != NULL && notBefore->length < (int) sizeof (szNotBefore) - 1) {
3601
+									memmove (szNotBefore, notBefore->data, notBefore->length);
3602
+									szNotBefore[notBefore->length] = '\0';
3644 3603
 								}
3645
-		
3646
-								my_output (
3647
-									pData,
3648
-									(
3649
-										"\tsubject:\t%s\n"
3650
-										"\tserialNumber:\t%s\n"
3651
-										"\tnotBefore:\t%s\n"
3652
-									),
3604
+
3605
+								X509_NAME_oneline (
3606
+									X509_get_subject_name (x509),
3653 3607
 									szSubject,
3654
-									szSerial,
3655
-									szNotBefore
3608
+									sizeof (szSubject)
3656 3609
 								);
3610
+								szSubject[sizeof (szSubject) - 1] = '\0';
3657 3611
 							}
3658 3612
 						}
3659
-						else if (attrs_class == CKO_PRIVATE_KEY) {
3660
-							CK_BBOOL sign_recover;
3661
-							CK_BBOOL sign;
3662
-							CK_ATTRIBUTE attrs_key[] = {
3663
-								{CKA_SIGN, &sign_recover, sizeof (sign_recover)},
3664
-								{CKA_SIGN_RECOVER, &sign, sizeof (sign)}
3665
-							};
3666
-		
3667
-							my_output (pData, "\tType:\t\tPrivate Key\n");
3668
-		
3669
-							if (
3670
-								pkcs11h_provider->f->C_GetAttributeValue (
3671
-									session,
3672
-									objects[i],
3673
-									attrs_key,
3674
-									sizeof (attrs_key) / sizeof (CK_ATTRIBUTE)
3675
-								) == CKR_OK
3676
-							) {
3677
-								my_output (
3678
-									pData,
3679
-									(
3680
-										"\tSign:\t\t%s\n"
3681
-										"\tSign Recover:\t%s\n"
3682
-									),
3683
-									sign ? "TRUE" : "FALSE",
3684
-									sign_recover ? "TRUE" : "FALSE"
3685
-								);
3686
-							}
3613
+
3614
+						if ((bioSerial = BIO_new (BIO_s_mem ())) == NULL) {
3615
+							my_output (pData, "Cannot create BIO context\n");
3687 3616
 						}
3688 3617
 						else {
3689
-							my_output (pData, "\tType:\t\tUnsupported\n");
3618
+							int n;
3619
+
3620
+							i2a_ASN1_INTEGER(bioSerial, X509_get_serialNumber (x509));
3621
+							n = BIO_read (bioSerial, szSerial, sizeof (szSerial)-1);
3622
+							if (n<0) {
3623
+								szSerial[0] = '\0';
3624
+							}
3625
+							else {
3626
+								szSerial[n] = '\0';
3627
+							}
3628
+						}
3629
+
3630
+						if (x509 != NULL) {
3631
+							X509_free (x509);
3632
+							x509 = NULL;
3633
+						}
3634
+						if (bioSerial != NULL) {
3635
+							BIO_free_all (bioSerial);
3636
+							bioSerial = NULL;
3690 3637
 						}
3691 3638
 					}
3639
+
3640
+					my_output (
3641
+						pData,
3642
+						(
3643
+							"Object\n"
3644
+							"\tType:\t\t\tCertificate\n"
3645
+							"\tCKA_ID:\n"
3646
+							"%s"
3647
+							"\tCKA_LABEL:\t\t%s\n"
3648
+							"\tsubject:\t\t%s\n"
3649
+							"\tserialNumber:\t\t%s\n"
3650
+							"\tnotBefore:\t\t%s\n"
3651
+						),
3652
+						szHexId,
3653
+						attrs_label,
3654
+						szSubject,
3655
+						szSerial,
3656
+						szNotBefore
3657
+					);
3658
+
3659
+					_pkcs11h_free ((void *)&attrs_label);
3660
+
3661
+					_pkcs11h_freeObjectAttributes (
3662
+						attrs_cert,
3663
+						sizeof (attrs_cert) / sizeof (CK_ATTRIBUTE)
3664
+					);
3665
+				}
3666
+				else if (attrs_class == CKO_PRIVATE_KEY) {
3667
+					CK_BBOOL sign_recover = CK_FALSE;
3668
+					CK_BBOOL sign = CK_FALSE;
3669
+					CK_ATTRIBUTE attrs_key[] = {
3670
+						{CKA_SIGN, &sign_recover, sizeof (sign_recover)},
3671
+						{CKA_SIGN_RECOVER, &sign, sizeof (sign)}
3672
+					};
3673
+					CK_ATTRIBUTE attrs_key_common[] = {
3674
+						{CKA_ID, NULL, 0},
3675
+						{CKA_LABEL, NULL, 0}
3676
+					};
3677
+					unsigned char *attrs_id = NULL;
3678
+					int attrs_id_size = 0;
3679
+					char *attrs_label = NULL;
3680
+					char szHexId[1024];
3681
+
3682
+					pkcs11h_provider->f->C_GetAttributeValue (
3683
+						session->hSession,
3684
+						objects[i],
3685
+						attrs_key,
3686
+						sizeof (attrs_key) / sizeof (CK_ATTRIBUTE)
3687
+					);
3688
+
3689
+					if (
3690
+						_pkcs11h_getObjectAttributes (
3691
+							session,
3692
+							objects[i],
3693
+							attrs_key_common,
3694
+							sizeof (attrs_key_common) / sizeof (CK_ATTRIBUTE)
3695
+						) == CKR_OK &&
3696
+						_pkcs11h_malloc (
3697
+							(void *)&attrs_label,
3698
+							attrs_key_common[1].ulValueLen+1
3699
+						) == CKR_OK
3700
+					) {
3701
+						attrs_id = (unsigned char *)attrs_key_common[0].pValue;
3702
+						attrs_id_size = attrs_key_common[0].ulValueLen;
3703
+
3704
+						memset (attrs_label, 0, attrs_key_common[1].ulValueLen+1);
3705
+						memmove (attrs_label, attrs_key_common[1].pValue, attrs_key_common[1].ulValueLen);
3706
+
3707
+						_pkcs11h_standalone_dump_objects_hex (
3708
+							attrs_id,
3709
+							attrs_id_size,
3710
+							szHexId,
3711
+							sizeof (szHexId),
3712
+							"\t\t"
3713
+						);
3714
+							
3715
+					}
3716
+
3717
+					my_output (
3718
+						pData,
3719
+						(
3720
+							"Object\n"
3721
+							"\tType:\t\t\tPrivate Key\n"
3722
+							"\tCKA_ID:\n"
3723
+							"%s"
3724
+							"\tCKA_LABEL:\t\t%s\n"
3725
+							"\tCKA_SIGN:\t\t%s\n"
3726
+							"\tCKA_SIGN_RECOVER:\t%s\n"
3727
+						),
3728
+						szHexId,
3729
+						attrs_label,
3730
+						sign ? "TRUE" : "FALSE",
3731
+						sign_recover ? "TRUE" : "FALSE"
3732
+					);
3733
+
3734
+					_pkcs11h_free ((void *)&attrs_label);
3735
+
3736
+					_pkcs11h_freeObjectAttributes (
3737
+						attrs_key_common,
3738
+						sizeof (attrs_key_common) / sizeof (CK_ATTRIBUTE)
3739
+					);
3740
+				}
3741
+				else if (attrs_class == CKO_PUBLIC_KEY) {
3742
+					CK_ATTRIBUTE attrs_key_common[] = {
3743
+						{CKA_ID, NULL, 0},
3744
+						{CKA_LABEL, NULL, 0}
3745
+					};
3746
+					unsigned char *attrs_id = NULL;
3747
+					int attrs_id_size = 0;
3748
+					char *attrs_label = NULL;
3749
+					char szHexId[1024];
3750
+
3751
+					if (
3752
+						_pkcs11h_getObjectAttributes (
3753
+							session,
3754
+							objects[i],
3755
+							attrs_key_common,
3756
+							sizeof (attrs_key_common) / sizeof (CK_ATTRIBUTE)
3757
+						) == CKR_OK &&
3758
+						_pkcs11h_malloc (
3759
+							(void *)&attrs_label,
3760
+							attrs_key_common[1].ulValueLen+1
3761
+						) == CKR_OK
3762
+					) {
3763
+						attrs_id = (unsigned char *)attrs_key_common[0].pValue;
3764
+						attrs_id_size = attrs_key_common[0].ulValueLen;
3765
+
3766
+						memset (attrs_label, 0, attrs_key_common[1].ulValueLen+1);
3767
+						memmove (attrs_label, attrs_key_common[1].pValue, attrs_key_common[1].ulValueLen);
3768
+
3769
+						_pkcs11h_standalone_dump_objects_hex (
3770
+							attrs_id,
3771
+							attrs_id_size,
3772
+							szHexId,
3773
+							sizeof (szHexId),
3774
+							"\t\t"
3775
+						);
3776
+							
3777
+					}
3778
+
3779
+					my_output (
3780
+						pData,
3781
+						(
3782
+							"Object\n"
3783
+							"\tType:\t\t\tPublic Key\n"
3784
+							"\tCKA_ID:\n"
3785
+							"%s"
3786
+							"\tCKA_LABEL:\t\t%s\n"
3787
+						),
3788
+						szHexId,
3789
+						attrs_label
3790
+					);
3791
+
3792
+					_pkcs11h_free ((void *)&attrs_label);
3793
+
3794
+					_pkcs11h_freeObjectAttributes (
3795
+						attrs_key_common,
3796
+						sizeof (attrs_key_common) / sizeof (CK_ATTRIBUTE)
3797
+					);
3798
+				}
3799
+				else if (attrs_class == CKO_DATA) {
3800
+					CK_ATTRIBUTE attrs_key_common[] = {
3801
+						{CKA_APPLICATION, NULL, 0},
3802
+						{CKA_LABEL, NULL, 0}
3803
+					};
3804
+					char *attrs_application = NULL;
3805
+					char *attrs_label = NULL;
3806
+
3807
+					if (
3808
+						_pkcs11h_getObjectAttributes (
3809
+							session,
3810
+							objects[i],
3811
+							attrs_key_common,
3812
+							sizeof (attrs_key_common) / sizeof (CK_ATTRIBUTE)
3813
+						) == CKR_OK &&
3814
+						_pkcs11h_malloc (
3815
+							(void *)&attrs_application,
3816
+							attrs_key_common[0].ulValueLen+1
3817
+						) == CKR_OK &&
3818
+						_pkcs11h_malloc (
3819
+							(void *)&attrs_label,
3820
+							attrs_key_common[1].ulValueLen+1
3821
+						) == CKR_OK
3822
+					) {
3823
+						memset (attrs_application, 0, attrs_key_common[0].ulValueLen+1);
3824
+						memmove (attrs_application, attrs_key_common[0].pValue, attrs_key_common[0].ulValueLen);
3825
+						memset (attrs_label, 0, attrs_key_common[1].ulValueLen+1);
3826
+						memmove (attrs_label, attrs_key_common[1].pValue, attrs_key_common[1].ulValueLen);
3827
+					}
3828
+
3829
+					my_output (
3830
+						pData,
3831
+						(
3832
+							"Object\n"
3833
+							"\tType:\t\t\tData\n"
3834
+							"\tCKA_APPLICATION\t\t%s\n"
3835
+							"\tCKA_LABEL:\t\t%s\n"
3836
+						),
3837
+						attrs_application,
3838
+						attrs_label
3839
+					);
3840
+
3841
+					_pkcs11h_free ((void *)&attrs_application);
3842
+					_pkcs11h_free ((void *)&attrs_label);
3843
+
3844
+					_pkcs11h_freeObjectAttributes (
3845
+						attrs_key_common,
3846
+						sizeof (attrs_key_common) / sizeof (CK_ATTRIBUTE)
3847
+					);
3848
+				}
3849
+				else {
3850
+					my_output (
3851
+						pData,
3852
+						(
3853
+							"Object\n"
3854
+							"\tType:\t\t\tUnsupported\n"
3855
+						)
3856
+					);
3692 3857
 				}
3693
-			
3694
-				pkcs11h_provider->f->C_FindObjectsFinal (session);
3695
-				pkcs11h_provider->f->C_Logout (session);
3696
-				pkcs11h_provider->f->C_CloseSession (session);
3697 3858
 			}
3859
+
3860
+			_pkcs11h_freeObjectAttributes (
3861
+				attrs,
3862
+				sizeof (attrs) / sizeof (CK_ATTRIBUTE)
3863
+			);
3864
+
3865
+			/*
3866
+			 * Ignore any error and
3867
+			 * perform next iteration
3868
+			 */
3869
+			rv = CKR_OK;
3698 3870
 		}
3871
+	
3872
+		if (objects != NULL) {
3873
+			_pkcs11h_free ((void *)&objects);
3874
+		}
3875
+
3876
+		/*
3877
+		 * Ignore this error
3878
+		 */
3879
+		rv = CKR_OK;
3880
+	}
3881
+
3882
+	if (session != NULL) {
3883
+		_pkcs11h_releaseSession (session);
3884
+		session = NULL;
3885
+	}
3886
+
3887
+	if (token_id != NULL) {
3888
+		pkcs11h_freeTokenId (token_id);
3889
+		token_id = NULL;
3699 3890
 	}
3700 3891
 	
3701 3892
 	pkcs11h_terminate ();
3702 3893
 }
3703 3894
 
3895
+#endif				/* ENABLE_PKCS11H_STANDALONE */
3896
+
3704 3897
 #ifdef BROKEN_OPENSSL_ENGINE
3705 3898
 static void broken_openssl_init() __attribute__ ((constructor));
3706 3899
 static void  broken_openssl_init()
... ...
@@ -3713,4 +9890,5 @@ static void  broken_openssl_init()
3713 3713
 
3714 3714
 #else
3715 3715
 static void dummy (void) {}
3716
-#endif /* PKCS11_HELPER_ENABLE */
3716
+#endif				/* PKCS11H_HELPER_ENABLE */
3717
+
... ...
@@ -1,5 +1,5 @@
1 1
 /*
2
- * Copyright (c) 2005 Alon Bar-Lev <alon.barlev@gmail.com>
2
+ * Copyright (c) 2005-2006 Alon Bar-Lev <alon.barlev@gmail.com>
3 3
  * All rights reserved.
4 4
  *
5 5
  * Redistribution and use in source and binary forms, with or without modifi-
... ...
@@ -34,225 +34,895 @@
34 34
  *
35 35
  */
36 36
 
37
-#ifndef __PKCS11_HELPER_H
38
-#define __PKCS11_HELPER_H
37
+#ifndef __PKCS11H_HELPER_H
38
+#define __PKCS11H_HELPER_H
39
+
40
+#if defined(__cplusplus)
41
+extern "C" {
42
+#endif
39 43
 
40 44
 #include "pkcs11-helper-config.h"
41 45
 
42
-#define PKCS11H_MAX_ATTRIBUTE_SIZE	(10*1024)
46
+#if defined(ENABLE_PKCS11H_SLOTEVENT) && !defined(ENABLE_PKCS11H_THREADING)
47
+#error PKCS#11: ENABLE_PKCS11H_SLOTEVENT requires ENABLE_PKCS11H_THREADING
48
+#endif
49
+#if defined(ENABLE_PKCS11H_OPENSSL) && !defined(ENABLE_PKCS11H_CERTIFICATE)
50
+#error PKCS#11: ENABLE_PKCS11H_OPENSSL requires ENABLE_PKCS11H_CERTIFICATE
51
+#endif
52
+
53
+#define PKCS11H_LOG_DEBUG2	5
54
+#define PKCS11H_LOG_DEBUG1	4
55
+#define PKCS11H_LOG_INFO	3
56
+#define PKCS11H_LOG_WARN	2
57
+#define PKCS11H_LOG_ERROR	1
58
+#define PKCS11H_LOG_QUITE	0
59
+
43 60
 #define PKCS11H_PIN_CACHE_INFINITE	-1
44 61
 
62
+#define PKCS11H_SIGNMODE_MASK_SIGN	(1<<0)
63
+#define PKCS11H_SIGNMODE_MASK_RECOVER	(1<<1)
64
+
65
+#define PKCS11H_PROMPT_MASK_ALLOW_PIN_PROMPT	(1<<0)
66
+#define PKCS11H_PROMPT_MAST_ALLOW_CARD_PROMPT	(1<<1)
67
+
68
+#define PKCS11H_SLOTEVENT_METHOD_AUTO		0
69
+#define PKCS11H_SLOTEVENT_METHOD_TRIGGER	1
70
+#define PKCS11H_SLOTEVENT_METHOD_POLL		2
71
+
72
+#define PKCS11H_ENUM_METHOD_CACHE		0
73
+#define PKCS11H_ENUM_METHOD_CACHE_EXIST	1
74
+#define PKCS11H_ENUM_METHOD_RELOAD		2
75
+
45 76
 typedef void (*pkcs11h_output_print_t)(
46 77
 	IN const void *pData,
47 78
 	IN const char * const szFormat,
48 79
 	IN ...
80
+)
81
+#ifdef __GNUC__
82
+    __attribute__ ((format (printf, 2, 3)))
83
+#endif
84
+ ;
85
+
86
+struct pkcs11h_token_id_s;
87
+typedef struct pkcs11h_token_id_s *pkcs11h_token_id_t;
88
+
89
+#if defined(ENABLE_PKCS11H_CERTIFICATE)
90
+
91
+struct pkcs11h_certificate_id_s;
92
+struct pkcs11h_certificate_s;
93
+typedef struct pkcs11h_certificate_id_s *pkcs11h_certificate_id_t;
94
+typedef struct pkcs11h_certificate_s *pkcs11h_certificate_t;
95
+
96
+#endif				/* ENABLE_PKCS11H_CERTIFICATE */
97
+
98
+#if defined(ENABLE_PKCS11H_ENUM)
99
+
100
+struct pkcs11h_token_id_list_s;
101
+typedef struct pkcs11h_token_id_list_s *pkcs11h_token_id_list_t;
102
+
103
+#if defined(ENABLE_PKCS11H_DATA)
104
+
105
+struct pkcs11h_data_id_list_s;
106
+typedef struct pkcs11h_data_id_list_s *pkcs11h_data_id_list_t;
107
+
108
+#endif				/* ENABLE_PKCS11H_DATA */
109
+
110
+#if defined(ENABLE_PKCS11H_CERTIFICATE)
111
+
112
+struct pkcs11h_certificate_id_list_s;
113
+typedef struct pkcs11h_certificate_id_list_s *pkcs11h_certificate_id_list_t;
114
+
115
+#endif				/* ENABLE_PKCS11H_CERTIFICATE */
116
+
117
+#endif				/* ENABLE_PKCS11H_ENUM */
118
+
119
+typedef void (*pkcs11h_hook_log_t)(
120
+	IN const void *pData,
121
+	IN const unsigned flags,
122
+	IN const char * const szFormat,
123
+	IN va_list args
49 124
 );
50 125
 
51
-typedef bool (*pkcs11h_hook_card_prompt_t)(
126
+typedef void (*pkcs11h_hook_slotevent_t)(
127
+	IN const void *pData
128
+);
129
+
130
+typedef PKCS11H_BOOL (*pkcs11h_hook_token_prompt_t)(
52 131
 	IN const void *pData,
53
-	IN const char * const szLabel
132
+	IN const pkcs11h_token_id_t token
54 133
 );
55 134
 
56
-typedef bool (*pkcs11h_hook_pin_prompt_t)(
135
+typedef PKCS11H_BOOL (*pkcs11h_hook_pin_prompt_t)(
57 136
 	IN const void *pData,
58
-	IN const char * const szLabel,
137
+	IN const pkcs11h_token_id_t token,
59 138
 	OUT char * const szPIN,
60 139
 	IN const size_t nMaxPIN
61 140
 );
62 141
 
142
+struct pkcs11h_token_id_s {
143
+	char label[1024];
144
+	char manufacturerID[sizeof (((CK_TOKEN_INFO *)NULL)->manufacturerID)+1];
145
+	char model[sizeof (((CK_TOKEN_INFO *)NULL)->model)+1];
146
+	char serialNumber[sizeof (((CK_TOKEN_INFO *)NULL)->serialNumber)+1];
147
+};
148
+
149
+#if defined(ENABLE_PKCS11H_CERTIFICATE)
150
+
151
+struct pkcs11h_certificate_id_s {
152
+	pkcs11h_token_id_t token_id;
63 153
 
64
-typedef struct pkcs11h_hooks_s {
65
-	void *card_prompt_data;
66
-	void *pin_prompt_data;
67
-	pkcs11h_hook_card_prompt_t card_prompt;
68
-	pkcs11h_hook_pin_prompt_t pin_prompt;
69
-} *pkcs11h_hooks_t;
154
+	char displayName[1024];
155
+	CK_BYTE_PTR attrCKA_ID;
156
+	size_t attrCKA_ID_size;
70 157
 
71
-typedef struct pkcs11h_provider_s {
72
-	struct pkcs11h_provider_s *next;
158
+	unsigned char *certificate_blob;
159
+	size_t certificate_blob_size;
160
+};
73 161
 
74
-	bool fEnabled;
75
-	char *szName;
76
-	
77
-#if defined(WIN32)
78
-	HANDLE hLibrary;
79
-#else
80
-	void *hLibrary;
81 162
 #endif
82
-	CK_FUNCTION_LIST_PTR f;
83
-	bool fShouldFinalize;
84
-	char *szSignMode;
85 163
 
86
-} *pkcs11h_provider_t;
164
+#if defined(ENABLE_PKCS11H_ENUM)
87 165
 
88
-typedef struct pkcs11h_session_s {
89
-	struct pkcs11h_session_s *next;
166
+struct pkcs11h_token_id_list_s {
167
+	pkcs11h_token_id_list_t next;
168
+	pkcs11h_token_id_t token_id;
169
+};
90 170
 
91
-	int nReferenceCount;
92
-	bool fValid;
171
+#if defined(ENABLE_PKCS11H_DATA)
93 172
 
94
-	pkcs11h_provider_t provider;
173
+struct pkcs11h_data_id_list_s {
174
+	pkcs11h_data_id_list_t next;
95 175
 
96
-	bool fProtectedAuthentication;
176
+	char *application;
177
+	char *label;
178
+};
97 179
 
98
-	char szLabel[sizeof (((CK_TOKEN_INFO *)NULL)->label)+1];
99
-	CK_CHAR serialNumber[sizeof (((CK_TOKEN_INFO *)NULL)->serialNumber)];
180
+#endif				/* ENABLE_PKCS11H_DATA */
100 181
 
101
-	CK_SESSION_HANDLE hSession;
182
+#if defined(ENABLE_PKCS11H_CERTIFICATE)
102 183
 
103
-	int nPINCachePeriod;
104
-	time_t timePINExpire;
105
-} *pkcs11h_session_t;
184
+struct pkcs11h_certificate_id_list_s {
185
+	pkcs11h_certificate_id_list_t next;
186
+	pkcs11h_certificate_id_t certificate_id;
187
+};
106 188
 
107
-typedef struct pkcs11h_certificate_s {
189
+#endif				/* ENABLE_PKCS11H_CERTIFICATE */
108 190
 
109
-	pkcs11h_session_t session;
191
+#endif				/* ENABLE_PKCS11H_CERTIFICATE */
110 192
 
111
-	unsigned char *certificate;
112
-	size_t certificate_size;
113
-	unsigned char *certificate_id;
114
-	size_t certificate_id_size;
193
+#if defined(ENABLE_PKCS11H_OPENSSL)
115 194
 
116
-	enum {
117
-		pkcs11h_signmode_none = 0,
118
-		pkcs11h_signmode_sign,
119
-		pkcs11h_signmode_recover
120
-	} signmode;
195
+struct pkcs11h_openssl_session_s;
196
+typedef struct pkcs11h_openssl_session_s *pkcs11h_openssl_session_t;
121 197
 
122
-	CK_OBJECT_HANDLE hKey;
198
+#endif				/* ENABLE_PKCS11H_OPENSSL */
123 199
 
124
-	bool fCertPrivate;
125
-} *pkcs11h_certificate_t;
200
+/*
201
+ * pkcs11h_getMessage - Get message by return value.
202
+ *
203
+ * Parameters:
204
+ * 	rv	- Return value.
205
+ */
206
+char *
207
+pkcs11h_getMessage (
208
+	IN const int rv
209
+);
126 210
 
127
-typedef struct pkcs11h_data_s {
128
-	bool fInitialized;
129
-	int nPINCachePeriod;
211
+/*
212
+ * pkcs11h_initialize - Inititalize helper interface.
213
+ *
214
+ * Must be called once, from main thread.
215
+ * Defaults:
216
+ * 	Protected authentication enabled.
217
+ * 	PIN cached is infinite.
218
+ */
219
+CK_RV
220
+pkcs11h_initialize ();
130 221
 
131
-	pkcs11h_provider_t providers;
132
-	pkcs11h_session_t sessions;
133
-	pkcs11h_hooks_t hooks;
222
+/*
223
+ * pkcs11h_terminate - Terminate helper interface.
224
+ *
225
+ * Must be called once, from main thread, after all
226
+ * related resources freed.
227
+ */
228
+CK_RV
229
+pkcs11h_terminate ();
134 230
 
135
-	CK_SESSION_HANDLE session;
136
-} *pkcs11h_data_t;
231
+/*
232
+ * pkcs11h_setLogLevel - Set current log level of the helper.
233
+ *
234
+ * Parameters:
235
+ * 	flags	- current log level.
236
+ *
237
+ * The log level can be set to maximum, but setting it to lower
238
+ * level will improve performance.
239
+ */
240
+void
241
+pkcs11h_setLogLevel (
242
+	IN const unsigned flags
243
+);
137 244
 
138
-typedef struct pkcs11h_openssl_session_s {
139
-	int nReferenceCount;
140
-	bool fInitialized;
141
-	X509 *x509;
142
-	RSA_METHOD smart_rsa;
143
-	int (*orig_finish)(RSA *rsa);
144
-	pkcs11h_certificate_t certificate;
145
-} *pkcs11h_openssl_session_t;
245
+/*
246
+ * pkcs11h_getLogLevel - Get current log level.
247
+ */
248
+unsigned
249
+pkcs11h_getLogLevel ();
146 250
 
251
+/*
252
+ * pkcs11h_setLogHook - Set a log callback.
253
+ *
254
+ * Parameters:
255
+ * 	hook	- Callback.
256
+ * 	pData	- Data to send to callback.
257
+ */
147 258
 CK_RV
148
-pkcs11h_initialize ();
259
+pkcs11h_setLogHook (
260
+	IN const pkcs11h_hook_log_t hook,
261
+	IN void * const pData
262
+);
149 263
 
264
+/*
265
+ * pkcs11h_setSlotEventHook - Set a slot event callback.
266
+ *
267
+ * Parameters:
268
+ * 	hook	- Callback.
269
+ * 	pData	- Data to send to callback.
270
+ *
271
+ * Calling this function initialize slot event notifications, these
272
+ * notifications can be started, but never terminate due to PKCS#11 limitation.
273
+ *
274
+ * In order to use slot events you must have threading enabled.
275
+ */
150 276
 CK_RV
151
-pkcs11h_terminate ();
277
+pkcs11h_setSlotEventHook (
278
+	IN const pkcs11h_hook_slotevent_t hook,
279
+	IN void * const pData
280
+);
152 281
 
282
+/*
283
+ * pkcs11h_setTokenPromptHook - Set a token prompt callback.
284
+ *
285
+ * Parameters:
286
+ * 	hook	- Callback.
287
+ * 	pData	- Data to send to callback.
288
+ */
153 289
 CK_RV
154
-pkcs11h_setCardPromptHook (
155
-	IN const pkcs11h_hook_card_prompt_t hook,
290
+pkcs11h_setTokenPromptHook (
291
+	IN const pkcs11h_hook_token_prompt_t hook,
156 292
 	IN void * const pData
157 293
 );
158 294
 
295
+/*
296
+ * pkcs11h_setPINPromptHook - Set a pin prompt callback.
297
+ *
298
+ * Parameters:
299
+ * 	hook	- Callback.
300
+ * 	pData	- Data to send to callback.
301
+ */
159 302
 CK_RV
160 303
 pkcs11h_setPINPromptHook (
161 304
 	IN const pkcs11h_hook_pin_prompt_t hook,
162 305
 	IN void * const pData
163 306
 );
164 307
 
308
+/*
309
+ * pkcs11h_setProtectedAuthentication - Set global protected authentication mode.
310
+ *
311
+ * Parameters:
312
+ * 	fProtectedAuthentication	- Allow protected authentication if enabled by token.
313
+ */
314
+CK_RV
315
+pkcs11h_setProtectedAuthentication (
316
+	IN const PKCS11H_BOOL fProtectedAuthentication
317
+);
318
+
319
+/*
320
+ * pkcs11h_setPINCachePeriod - Set global PIN cache timeout.
321
+ *
322
+ * Parameters:
323
+ * 	nPINCachePeriod	- Cache period in seconds, or PKCS11H_PIN_CACHE_INFINITE.
324
+ */
165 325
 CK_RV
166 326
 pkcs11h_setPINCachePeriod (
167 327
 	IN const int nPINCachePeriod
168 328
 );
169 329
 
330
+/*
331
+ * pkcs11h_setMaxLoginRetries - Set global login retries attempts.
332
+ *
333
+ * Parameters:
334
+ * 	nMaxLoginRetries	- Login retries handled by the helper.
335
+ */
336
+CK_RV
337
+pkcs11h_setMaxLoginRetries (
338
+	IN const int nMaxLoginRetries
339
+);
340
+
341
+/*
342
+ * pkcs11h_addProvider - Add a PKCS#11 provider.
343
+ *
344
+ * Parameters:
345
+ * 	szReferenceName		- Reference name for this provider.
346
+ * 	szProvider		- Provider library location.
347
+ * 	fProtectedAuthentication	- Allow this provider to use protected authentication.
348
+ * 	maskSignMode		- Provider signmode override.
349
+ * 	nSlotEventMethod	- Provider slot event method.
350
+ * 	nSlotEventPollInterval	- Slot event poll interval (If in polling mode).
351
+ * 	fCertIsPrivate		- Provider's certificate access should be done after login.
352
+ *
353
+ * This function must be called from the main thread.
354
+ *
355
+ * The global fProtectedAuthentication must be enabled in order to allow provider specific.
356
+ * The maskSignMode can be 0 in order to automatically detect key sign mode.
357
+ */
170 358
 CK_RV
171 359
 pkcs11h_addProvider (
360
+	IN const char * const szReferenceName,
172 361
 	IN const char * const szProvider,
173
-	IN const char * const szSignMode
362
+	IN const PKCS11H_BOOL fProtectedAuthentication,
363
+	IN const unsigned maskSignMode,
364
+	IN const int nSlotEventMethod,
365
+	IN const int nSlotEventPollInterval,
366
+	IN const PKCS11H_BOOL fCertIsPrivate
174 367
 );
175 368
 
369
+/*
370
+ * pkcs11h_delProvider - Delete a PKCS#11 provider.
371
+ *
372
+ * Parameters:
373
+ * 	szReferenceName		- Reference name for this provider.
374
+ *
375
+ * This function must be called from the main thread.
376
+ */
377
+CK_RV
378
+pkcs11h_removeProvider (
379
+	IN const char * const szReferenceName
380
+);
381
+
382
+/*
383
+ * pkcs11h_forkFixup - Handle special case of Unix fork()
384
+ *
385
+ * This function should be called after fork is called. This is required
386
+ * due to a limitation of the PKCS#11 standard.
387
+ *
388
+ * This function must be called from the main thread.
389
+ *
390
+ * The helper library handles fork automatically if ENABLE_PKCS11H_THREADING
391
+ * is set on configuration file, by use of pthread_atfork.
392
+ */
176 393
 CK_RV
177 394
 pkcs11h_forkFixup ();
178 395
 
396
+/*
397
+ * pkcs11h_plugAndPlay - Handle slot rescan.
398
+ *
399
+ * This function must be called from the main thread.
400
+ *
401
+ * PKCS#11 providers do not allow plug&play, plug&play can be established by
402
+ * finalizing all providers and initializing them again.
403
+ *
404
+ * The cost of this process is invalidating all sessions, and require user
405
+ * login at the next access.
406
+ */
179 407
 CK_RV
180
-pkcs11h_createCertificateSession (
181
-	IN const char * const szSlotType,
182
-	IN const char * const szSlot,
183
-	IN const char * const szIdType,
184
-	IN const char * const szId,
185
-	IN const bool fProtectedAuthentication,
186
-	IN const bool fCertPrivate,
408
+pkcs11h_plugAndPlay ();
409
+
410
+/*
411
+ * pkcs11h_freeTokenId - Free token_id object.
412
+ */
413
+CK_RV
414
+pkcs11h_freeTokenId (
415
+	IN pkcs11h_token_id_t certificate_id
416
+);
417
+
418
+/*
419
+ * pkcs11h_duplicateTokenId - Duplicate token_id object.
420
+ */
421
+CK_RV
422
+pkcs11h_duplicateTokenId (
423
+	OUT pkcs11h_token_id_t * const to,
424
+	IN const pkcs11h_token_id_t from
425
+);
426
+
427
+/*
428
+ * pkcs11h_sameTokenId - Returns TRUE if same token id
429
+ */
430
+PKCS11H_BOOL
431
+pkcs11h_sameTokenId (
432
+	IN const pkcs11h_token_id_t a,
433
+	IN const pkcs11h_token_id_t b
434
+);
435
+
436
+#if defined(ENABLE_PKCS11H_TOKEN)
437
+
438
+/*
439
+ * pkcs11h_token_ensureAccess - Ensure token is accessible.
440
+ *
441
+ * Parameters:
442
+ * 	token_id	- Token id object.
443
+ * 	maskPrompt	- Allow prompt.
444
+ */
445
+CK_RV
446
+pkcs11h_token_ensureAccess (
447
+	IN const pkcs11h_token_id_t token_id,
448
+	IN const unsigned maskPrompt
449
+);
450
+
451
+#endif				/* ENABLE_PKCS11H_TOKEN */
452
+
453
+#if defined(ENABLE_PKCS11H_DATA)
454
+
455
+CK_RV
456
+pkcs11h_data_get (
457
+	IN const pkcs11h_token_id_t token_id,
458
+	IN const PKCS11H_BOOL fPublic,
459
+	IN const char * const szApplication,
460
+	IN const char * const szLabel,
461
+	OUT char * const blob,
462
+	IN OUT size_t * const p_blob_size
463
+);
464
+
465
+CK_RV
466
+pkcs11h_data_put (
467
+	IN const pkcs11h_token_id_t token_id,
468
+	IN const PKCS11H_BOOL fPublic,
469
+	IN const char * const szApplication,
470
+	IN const char * const szLabel,
471
+	OUT char * const blob,
472
+	IN const size_t blob_size
473
+);
474
+
475
+CK_RV
476
+pkcs11h_data_del (
477
+	IN const pkcs11h_token_id_t token_id,
478
+	IN const PKCS11H_BOOL fPublic,
479
+	IN const char * const szApplication,
480
+	IN const char * const szLabel
481
+);
482
+
483
+#endif				/* ENABLE_PKCS11H_DATA */
484
+
485
+#if defined(ENABLE_PKCS11H_CERTIFICATE)
486
+/*======================================================================*
487
+ * CERTIFICATE INTERFACE
488
+ *======================================================================*/
489
+
490
+/*
491
+ * pkcs11h_freeCertificateId - Free certificate_id object.
492
+ */
493
+CK_RV
494
+pkcs11h_freeCertificateId (
495
+	IN pkcs11h_certificate_id_t certificate_id
496
+);
497
+
498
+/*
499
+ * pkcs11h_duplicateCertificateId - Duplicate certificate_id object.
500
+ */
501
+CK_RV
502
+pkcs11h_duplicateCertificateId (
503
+	OUT pkcs11h_certificate_id_t * const to,
504
+	IN const pkcs11h_certificate_id_t from
505
+);
506
+
507
+/*
508
+ * pkcs11h_freeCertificate - Free certificate object.
509
+ */
510
+CK_RV
511
+pkcs11h_freeCertificate (
512
+	IN pkcs11h_certificate_t certificate
513
+);
514
+
515
+/*
516
+ * pkcs11h_certificate_create - Create a certificate object out of certificate_id.
517
+ *
518
+ * Parameters:
519
+ *	certificate_id	- Certificate id object to be based on.
520
+ *	nPINCachePeriod	- Session specific cache period.
521
+ *	p_certificate	- Receives certificate object.
522
+ *
523
+ * The certificate id object may not specify the full certificate.
524
+ * The certificate object must be freed by caller.
525
+ */	
526
+CK_RV
527
+pkcs11h_certificate_create (
528
+	IN const pkcs11h_certificate_id_t certificate_id,
187 529
 	IN const int nPINCachePeriod,
188
-	OUT pkcs11h_certificate_t * const pkcs11h_certificate
530
+	OUT pkcs11h_certificate_t * const p_certificate
531
+);
532
+
533
+/*
534
+ * pkcs11h_certificate_getCertificateId - Get certifiate id object out of a certifiate
535
+ *
536
+ * Parameters:
537
+ * 	certificate		- Certificate object.
538
+ * 	p_certificate_id	- Certificate id object pointer.
539
+ *
540
+ * The certificate id must be freed by caller.
541
+ */
542
+CK_RV
543
+pkcs11h_certificate_getCertificateId (
544
+	IN const pkcs11h_certificate_t certificate,
545
+	OUT pkcs11h_certificate_id_t * const p_certificate_id
546
+);
547
+
548
+/*
549
+ * pkcs11h_certificate_getCertificateBlob - Get the certificate blob out of the certificate object.
550
+ *
551
+ * ParametersL
552
+ * 	certificate		- Certificate object.
553
+ * 	certificate_blob	- Buffer.
554
+ * 	certificate_blob_size	- Buffer size.
555
+ *
556
+ * Buffer may be NULL in order to get size.
557
+ */
558
+CK_RV
559
+pkcs11h_certificate_getCertificateBlob (
560
+	IN const pkcs11h_certificate_t certificate,
561
+	OUT unsigned char * const certificate_blob,
562
+	IN OUT size_t * const p_certificate_blob_size
189 563
 );
190 564
 
565
+/*
566
+ * pkcs11h_certificate_ensureCertificateAccess - Ensure certificate is accessible.
567
+ *
568
+ * Parameters:
569
+ * 	certificate	- Certificate object.
570
+ * 	maskPrompt	- Allow prompt.
571
+ */
191 572
 CK_RV
192
-pkcs11h_freeCertificateSession (
193
-	IN const pkcs11h_certificate_t pkcs11h_certificate
573
+pkcs11h_certificate_ensureCertificateAccess (
574
+	IN const pkcs11h_certificate_t certificate,
575
+	IN const unsigned maskPrompt
194 576
 );
195 577
 
578
+/*
579
+ * pkcs11h_certificate_ensureKeyAccess - Ensure key is accessible.
580
+ *
581
+ * Parameters:
582
+ * 	certificate	- Certificate object.
583
+ * 	maskPrompt	- Allow prompt.
584
+ */
196 585
 CK_RV
197
-pkcs11h_sign (
198
-	IN const pkcs11h_certificate_t pkcs11h_certificate,
586
+pkcs11h_certificate_ensureKeyAccess (
587
+	IN const pkcs11h_certificate_t certificate,
588
+	IN const unsigned maskPrompt
589
+);
590
+
591
+/*
592
+ * pkcs11h_certificate_sign - Sign data.
593
+ *
594
+ * Parameters:
595
+ * 	certificate	- Certificate object.
596
+ * 	mech_type	- PKCS#11 mechanism.
597
+ *	source		- Buffer to sign.
598
+ *	source_size	- Buffer size.
599
+ *	target		- Target buffer, can be NULL to get size.
600
+ *	target_size	- Target buffer size.
601
+ */
602
+CK_RV
603
+pkcs11h_certificate_sign (
604
+	IN const pkcs11h_certificate_t certificate,
199 605
 	IN const CK_MECHANISM_TYPE mech_type,
200 606
 	IN const unsigned char * const source,
201 607
 	IN const size_t source_size,
202 608
 	OUT unsigned char * const target,
203
-	IN OUT size_t * const target_size
609
+	IN OUT size_t * const p_target_size
204 610
 );
205 611
 
612
+/*
613
+ * pkcs11h_certificate_signRecover - Sign data.
614
+ *
615
+ * Parameters:
616
+ * 	certificate	- Certificate object.
617
+ * 	mech_type	- PKCS#11 mechanism.
618
+ *	source		- Buffer to sign.
619
+ *	source_size	- Buffer size.
620
+ *	target		- Target buffer, can be NULL to get size.
621
+ *	target_size	- Target buffer size.
622
+ */
206 623
 CK_RV
207
-pkcs11h_signRecover (
208
-	IN const pkcs11h_certificate_t pkcs11h_certificate,
624
+pkcs11h_certificate_signRecover (
625
+	IN const pkcs11h_certificate_t certificate,
209 626
 	IN const CK_MECHANISM_TYPE mech_type,
210 627
 	IN const unsigned char * const source,
211 628
 	IN const size_t source_size,
212 629
 	OUT unsigned char * const target,
213
-	IN OUT size_t * const target_size
630
+	IN OUT size_t * const p_target_size
214 631
 );
215 632
 
633
+/*
634
+ * pkcs11h_certificate_signAny - Sign data mechanism determined by key attributes.
635
+ *
636
+ * Parameters:
637
+ * 	certificate	- Certificate object.
638
+ * 	mech_type	- PKCS#11 mechanism.
639
+ *	source		- Buffer to sign.
640
+ *	source_size	- Buffer size.
641
+ *	target		- Target buffer, can be NULL to get size.
642
+ *	target_size	- Target buffer size.
643
+ */
216 644
 CK_RV
217
-pkcs11h_decrypt (
218
-	IN const pkcs11h_certificate_t pkcs11h_certificate,
645
+pkcs11h_certificate_signAny (
646
+	IN const pkcs11h_certificate_t certificate,
219 647
 	IN const CK_MECHANISM_TYPE mech_type,
220 648
 	IN const unsigned char * const source,
221 649
 	IN const size_t source_size,
222 650
 	OUT unsigned char * const target,
223
-	IN OUT size_t * const target_size
651
+	IN OUT size_t * const p_target_size
224 652
 );
225 653
 
654
+/*
655
+ * pkcs11h_certificate_decrypt - Decrypt data.
656
+ *
657
+ * Parameters:
658
+ * 	certificate	- Certificate object.
659
+ * 	mech_type	- PKCS#11 mechanism.
660
+ *	source		- Buffer to sign.
661
+ *	source_size	- Buffer size.
662
+ *	target		- Target buffer, can be NULL to get size.
663
+ *	target_size	- Target buffer size.
664
+ */
226 665
 CK_RV
227
-pkcs11h_getCertificate (
228
-	IN const pkcs11h_certificate_t pkcs11h_certificate,
229
-	OUT unsigned char * const certificate,
230
-	IN OUT size_t * const certificate_size
666
+pkcs11h_certificate_decrypt (
667
+	IN const pkcs11h_certificate_t certificate,
668
+	IN const CK_MECHANISM_TYPE mech_type,
669
+	IN const unsigned char * const source,
670
+	IN const size_t source_size,
671
+	OUT unsigned char * const target,
672
+	IN OUT size_t * const p_target_size
231 673
 );
232 674
 
233
-char *
234
-pkcs11h_getMessage (
235
-	IN const int rv
675
+#endif				/* ENABLE_PKCS11H_CERTIFICATE */
676
+
677
+#if defined(ENABLE_PKCS11H_LOCATE)
678
+/*======================================================================*
679
+ * LOCATE INTERFACE
680
+ *======================================================================*/
681
+
682
+#if defined(ENABLE_PKCS11H_TOKEN) || defined(ENABLE_PKCS11H_CERTIFICATE)
683
+
684
+/*
685
+ * pkcs11h_locate_token - Locate token based on atributes.
686
+ *
687
+ * Parameters:
688
+ * 	szSlotType	- How to locate slot.
689
+ * 	szSlot		- Slot name.
690
+ * 	p_token_id	- Token object.
691
+ *
692
+ * Slot:
693
+ * 	id	- Slot number.
694
+ * 	name	- Slot name.
695
+ * 	label	- Available token label.
696
+ *
697
+ * Caller must free token id.
698
+ */
699
+CK_RV
700
+pkcs11h_locate_token (
701
+	IN const char * const szSlotType,
702
+	IN const char * const szSlot,
703
+	OUT pkcs11h_token_id_t * const p_token_id
236 704
 );
237 705
 
706
+#endif				/* ENABLE_PKCS11H_TOKEN || ENABLE_PKCS11H_CERTIFICATE */
707
+
708
+#if defined(ENABLE_PKCS11H_CERTIFICATE)
709
+
710
+/*
711
+ * pkcs11h_locate_certificate - Locate certificate based on atributes.
712
+ *
713
+ * Parameters:
714
+ * 	szSlotType	- How to locate slot.
715
+ * 	szSlot		- Slot name.
716
+ * 	szIdType	- How to locate object.
717
+ * 	szId		- Object name.
718
+ * 	p_certificate_id	- Certificate object.
719
+ *
720
+ * Slot:
721
+ * Same as pkcs11h_locate_token.
722
+ *
723
+ * Object:
724
+ * 	id	- Certificate CKA_ID (hex string) (Fastest).
725
+ * 	label	- Certificate CKA_LABEL (string).
726
+ * 	subject	- Certificate subject (OpenSSL DN).
727
+ *
728
+ * Caller must free certificate id.
729
+ */
730
+CK_RV
731
+pkcs11h_locate_certificate (
732
+	IN const char * const szSlotType,
733
+	IN const char * const szSlot,
734
+	IN const char * const szIdType,
735
+	IN const char * const szId,
736
+	OUT pkcs11h_certificate_id_t * const p_certificate_id
737
+);
738
+
739
+#endif				/* ENABLE_PKCS11H_CERTIFICATE */
740
+
741
+#endif				/* ENABLE_PKCS11H_LOCATE */
742
+
743
+#if defined(ENABLE_PKCS11H_ENUM)
744
+/*======================================================================*
745
+ * ENUM INTERFACE
746
+ *======================================================================*/
747
+
748
+#if defined(ENABLE_PKCS11H_TOKEN)
749
+
750
+/*
751
+ * pkcs11h_freeCertificateIdList - Free certificate_id list.
752
+ */
753
+CK_RV
754
+pkcs11h_freeTokenIdList (
755
+	IN const pkcs11h_token_id_list_t token_id_list
756
+);
757
+
758
+/*
759
+ * pkcs11h_enum_getTokenIds - Enumerate available tokens
760
+ *
761
+ * Parameters:
762
+ * 	p_token_id_list		- A list of token ids.
763
+ * 	
764
+ * Caller must free the list.
765
+ */
766
+CK_RV
767
+pkcs11h_enum_getTokenIds (
768
+	IN const int method,
769
+	OUT pkcs11h_token_id_list_t * const p_token_id_list
770
+);
771
+
772
+#endif				/* ENABLE_PKCS11H_TOKEN */
773
+
774
+#if defined(ENABLE_PKCS11H_DATA)
775
+
776
+CK_RV
777
+pkcs11h_freeDataIdList (
778
+	IN const pkcs11h_data_id_list_t data_id_list
779
+);
780
+
781
+CK_RV
782
+pkcs11h_enumDataObjects (
783
+	IN const pkcs11h_token_id_t token_id,
784
+	IN const PKCS11H_BOOL fPublic,
785
+	OUT pkcs11h_data_id_list_t * const p_data_id_list
786
+);
787
+
788
+#endif				/* ENABLE_PKCS11H_DATA */
789
+
790
+#if defined(ENABLE_PKCS11H_CERTIFICATE)
791
+
792
+/*
793
+ * pkcs11h_freeCertificateIdList - Free certificate_id list.
794
+ */
795
+CK_RV
796
+pkcs11h_freeCertificateIdList (
797
+	IN const pkcs11h_certificate_id_list_t cert_id_list
798
+);
799
+
800
+/*
801
+ * pkcs11h_enum_getTokenCertificateIds - Enumerate available certificates on specific token
802
+ *
803
+ * Parameters:
804
+ * 	token_id		- Token id to enum.
805
+ * 	method			- How to fetch certificates.
806
+ * 	p_cert_id_issuers_list	- Receives issues list, can be NULL.
807
+ * 	p_cert_id_end_list	- Receives end certificates list.
808
+ *
809
+ * This function will likely take long time.
810
+ *
811
+ * Method can be one of the following:
812
+ *	PKCS11H_ENUM_METHOD_CACHE
813
+ *		Return available certificates, even if token was once detected and
814
+ *		was removed.
815
+ *	PKCS11H_ENUM_METHOD_CACHE_EXIST
816
+ *		Return available certificates for available tokens only, don't
817
+ *		read the contents of the token if already read, even if this token
818
+ *		removed and inserted.
819
+ *	PKCS11H_ENUM_METHOD_RELOAD
820
+ *		Clear all caches and then enum.
821
+ *
822
+ * Caller must free the lists.
823
+ */
824
+CK_RV
825
+pkcs11h_enum_getTokenCertificateIds (
826
+	IN const pkcs11h_token_id_t token_id,
827
+	IN const int method,
828
+	OUT pkcs11h_certificate_id_list_t * const p_cert_id_issuers_list,
829
+	OUT pkcs11h_certificate_id_list_t * const p_cert_id_end_list
830
+);
831
+
832
+/*
833
+ * pkcs11h_enum_getCertificateIds - Enumerate available certificates.
834
+ *
835
+ * Parameters:
836
+ * 	method			- How to fetch certificates.
837
+ * 	p_cert_id_issuers_list	- Receives issues list, can be NULL.
838
+ * 	p_cert_id_end_list	- Receives end certificates list.
839
+ *
840
+ * This function will likely take long time.
841
+ *
842
+ * Method can be one of the following:
843
+ *	PKCS11H_ENUM_METHOD_CACHE
844
+ *		Return available certificates, even if token was once detected and
845
+ *		was removed.
846
+ *	PKCS11H_ENUM_METHOD_CACHE_EXIST
847
+ *		Return available certificates for available tokens only, don't
848
+ *		read the contents of the token if already read, even if this token
849
+ *		removed and inserted.
850
+ *	PKCS11H_ENUM_METHOD_RELOAD
851
+ *		Clear all caches and then enum.
852
+ *
853
+ * Caller must free lists.
854
+ */
855
+CK_RV
856
+pkcs11h_enum_getCertificateIds (
857
+	IN const int method,
858
+	OUT pkcs11h_certificate_id_list_t * const p_cert_id_issuers_list,
859
+	OUT pkcs11h_certificate_id_list_t * const p_cert_id_end_list
860
+);
861
+
862
+#endif				/* ENABLE_PKCS11H_CERTIFICATE */
863
+
864
+#endif				/* ENABLE_PKCS11H_ENUM */
865
+
866
+#if defined(ENABLE_PKCS11H_OPENSSL)
867
+/*======================================================================*
868
+ * OPENSSL INTERFACE
869
+ *======================================================================*/
870
+
871
+/*
872
+ * pkcs11h_openssl_createSession - Create OpenSSL session based on a certificate object.
873
+ *
874
+ * Parameters:
875
+ * 	certificate	- Certificate object.
876
+ *
877
+ * The certificate object will be freed by the OpenSSL interface on session end.
878
+ */
238 879
 pkcs11h_openssl_session_t
239
-pkcs11h_openssl_createSession ();
880
+pkcs11h_openssl_createSession (
881
+	IN const pkcs11h_certificate_t certificate
882
+);
240 883
 
884
+/*
885
+ * pkcs11h_openssl_freeSession - Free OpenSSL session.
886
+ *
887
+ * Parameters:
888
+ * 	openssl_session	- Session to free.
889
+ *
890
+ * The openssl_session object has a reference count just like other OpenSSL objects.
891
+ */
241 892
 void
242 893
 pkcs11h_openssl_freeSession (
243
-	IN const pkcs11h_openssl_session_t pkcs11h_openssl_session
894
+	IN const pkcs11h_openssl_session_t openssl_session
244 895
 );
245 896
 
897
+/*
898
+ * pkcs11h_openssl_getRSA - Returns an RSA object out of the openssl_session object.
899
+ *
900
+ * Parameters:
901
+ * 	openssl_session	- Session.
902
+ */
246 903
 RSA *
247 904
 pkcs11h_openssl_getRSA (
248
-	IN const pkcs11h_openssl_session_t pkcs11h_openssl_session
905
+	IN const pkcs11h_openssl_session_t openssl_session
249 906
 );
250 907
 
908
+/*
909
+ * pkcs11h_openssl_getX509 - Returns an X509 object out of the openssl_session object.
910
+ *
911
+ * Parameters:
912
+ * 	openssl_session	- Session.
913
+ */
251 914
 X509 *
252 915
 pkcs11h_openssl_getX509 (
253
-	IN const pkcs11h_openssl_session_t pkcs11h_openssl_session
916
+	IN const pkcs11h_openssl_session_t openssl_session
254 917
 );
255 918
 
919
+#endif				/* ENABLE_PKCS11H_OPENSSL */
920
+
921
+#if defined(ENABLE_PKCS11H_STANDALONE)
922
+/*======================================================================*
923
+ * STANDALONE INTERFACE
924
+ *======================================================================*/
925
+
256 926
 void
257 927
 pkcs11h_standalone_dump_slots (
258 928
 	IN const pkcs11h_output_print_t my_output,
... ...
@@ -269,4 +939,10 @@ pkcs11h_standalone_dump_objects (
269 269
 	IN const char * const pin
270 270
 );
271 271
 
272
+#endif				/* ENABLE_PKCS11H_STANDALONE */
273
+
274
+#ifdef __cplusplus
275
+}
272 276
 #endif
277
+
278
+#endif				/* __PKCS11H_HELPER_H */
... ...
@@ -44,6 +44,74 @@
44 44
 #include "pkcs11.h"
45 45
 
46 46
 static
47
+unsigned
48
+_pkcs11_msg_pkcs112openvpn (
49
+	IN const unsigned flags
50
+) {
51
+	unsigned openvpn_flags;
52
+
53
+	switch (flags) {
54
+		case PKCS11H_LOG_DEBUG2:
55
+			openvpn_flags = D_PKCS11_DEBUG;
56
+		break;
57
+		case PKCS11H_LOG_DEBUG1:
58
+			openvpn_flags = D_SHOW_PKCS11;
59
+		break;
60
+		case PKCS11H_LOG_INFO:
61
+			openvpn_flags = M_INFO;
62
+		break;
63
+		case PKCS11H_LOG_WARN:
64
+			openvpn_flags = M_WARN;
65
+		break;
66
+		case PKCS11H_LOG_ERROR:
67
+			openvpn_flags = M_FATAL;
68
+		break;
69
+		default:
70
+			openvpn_flags = M_FATAL;
71
+		break;
72
+	}
73
+
74
+#if defined(ENABLE_PKCS11_FORCE_DEBUG)
75
+	openvpn_flags=M_INFO;
76
+#endif
77
+
78
+	return openvpn_flags;
79
+}
80
+
81
+static
82
+unsigned
83
+_pkcs11_msg_openvpn2pkcs11 (
84
+	IN const unsigned flags
85
+) {
86
+	unsigned pkcs11_flags;
87
+
88
+	if ((flags & D_PKCS11_DEBUG) != 0) {
89
+		pkcs11_flags = PKCS11H_LOG_DEBUG2;
90
+	}
91
+	else if ((flags & D_SHOW_PKCS11) != 0) {
92
+		pkcs11_flags = PKCS11H_LOG_DEBUG1;
93
+	}
94
+	else if ((flags & M_INFO) != 0) {
95
+		pkcs11_flags = PKCS11H_LOG_INFO;
96
+	}
97
+	else if ((flags & M_WARN) != 0) {
98
+		pkcs11_flags = PKCS11H_LOG_WARN;
99
+	}
100
+	else if ((flags & M_FATAL) != 0) {
101
+		pkcs11_flags = PKCS11H_LOG_ERROR;
102
+	}
103
+	else {
104
+		pkcs11_flags = PKCS11H_LOG_ERROR;
105
+	}
106
+
107
+#if defined(ENABLE_PKCS11_FORCE_DEBUG)
108
+	pkcs11_flags = PKCS11H_LOG_DEBUG2;
109
+#endif
110
+
111
+	return pkcs11_flags;
112
+}
113
+
114
+static
47 115
 void
48 116
 _pkcs11_openvpn_print (
49 117
 	IN const void *pData,
... ...
@@ -62,20 +130,46 @@ _pkcs11_openvpn_print (
62 62
 }
63 63
 
64 64
 static
65
+void
66
+_pkcs11_openvpn_log (
67
+	IN const void *pData,
68
+	IN unsigned flags,
69
+	IN const char * const szFormat,
70
+	IN va_list args
71
+) {
72
+	char Buffer[10*1024];
73
+	
74
+	vsnprintf (Buffer, sizeof (Buffer), szFormat, args);
75
+	Buffer[sizeof (Buffer)-1] = 0;
76
+
77
+	msg (_pkcs11_msg_pkcs112openvpn (flags), "%s", Buffer);
78
+}
79
+
80
+static
65 81
 bool
66
-_pkcs11_openvpn_card_prompt (
82
+_pkcs11_openvpn_token_prompt (
67 83
 	IN const void *pData,
68
-	IN const char * const szLabel
84
+	IN const pkcs11h_token_id_t token
69 85
 ) {
70 86
 	static struct user_pass token_resp;
71 87
 
72
-	ASSERT (szLabel!=NULL);
88
+	ASSERT (token!=NULL);
73 89
 
74 90
 	CLEAR (token_resp);
75 91
 	token_resp.defined = false;
76 92
 	token_resp.nocache = true;
77
-	openvpn_snprintf (token_resp.username, sizeof (token_resp.username), "Please insert %s token", szLabel);
78
-	get_user_pass (&token_resp, NULL, "token-insertion-request", GET_USER_PASS_MANAGEMENT|GET_USER_PASS_NEED_OK);
93
+	openvpn_snprintf (
94
+		token_resp.username,
95
+		sizeof (token_resp.username),
96
+		"Please insert %s token",
97
+		token->label
98
+	);
99
+	get_user_pass (
100
+		&token_resp,
101
+		NULL,
102
+		"token-insertion-request",
103
+		GET_USER_PASS_MANAGEMENT|GET_USER_PASS_NEED_OK
104
+	);
79 105
 
80 106
 	return strcmp (token_resp.password, "ok") == 0;
81 107
 }
... ...
@@ -84,16 +178,16 @@ static
84 84
 bool
85 85
 _pkcs11_openvpn_pin_prompt (
86 86
 	IN const void *pData,
87
-	IN const char * const szLabel,
87
+	IN const pkcs11h_token_id_t token,
88 88
 	OUT char * const szPIN,
89 89
 	IN const size_t nMaxPIN
90 90
 ) {
91 91
 	static struct user_pass token_pass;
92 92
 	char szPrompt[1024];
93 93
 
94
-	ASSERT (szLabel!=NULL);
94
+	ASSERT (token!=NULL);
95 95
 
96
-	openvpn_snprintf (szPrompt, sizeof (szPrompt), "%s token", szLabel);
96
+	openvpn_snprintf (szPrompt, sizeof (szPrompt), "%s token", token->label);
97 97
 
98 98
 	token_pass.defined = false;
99 99
 	token_pass.nocache = true;
... ...
@@ -111,12 +205,13 @@ _pkcs11_openvpn_pin_prompt (
111 111
 
112 112
 bool
113 113
 pkcs11_initialize (
114
-	const int nPINCachePeriod
114
+	IN const bool fProtectedAuthentication,
115
+	IN const int nPINCachePeriod
115 116
 ) {
116 117
 	CK_RV rv = CKR_OK;
117 118
 
118
-	PKCS11LOG (
119
-		PKCS11_LOG_DEBUG2,
119
+	dmsg (
120
+		D_PKCS11_DEBUG,
120 121
 		"PKCS#11: pkcs11_initialize - entered"
121 122
 	);
122 123
 
... ...
@@ -124,32 +219,50 @@ pkcs11_initialize (
124 124
 		rv == CKR_OK &&
125 125
 		(rv = pkcs11h_initialize ()) != CKR_OK
126 126
 	) {
127
-		PKCS11LOG (PKCS11_LOG_ERROR, "PKCS#11: Cannot initialize %ld-'%s'", rv, pkcs11h_getMessage (rv));
127
+		msg (M_FATAL, "PKCS#11: Cannot initialize %ld-'%s'", rv, pkcs11h_getMessage (rv));
128 128
 	}
129 129
 
130 130
 	if (
131 131
 		rv == CKR_OK &&
132
-		(rv = pkcs11h_setCardPromptHook (_pkcs11_openvpn_card_prompt, NULL)) != CKR_OK
132
+		(rv = pkcs11h_setLogHook (_pkcs11_openvpn_log, NULL)) != CKR_OK
133 133
 	) {
134
-		PKCS11LOG (PKCS11_LOG_ERROR, "PKCS#11: Cannot set hooks %ld-'%s'", rv, pkcs11h_getMessage (rv));
134
+		msg (M_FATAL, "PKCS#11: Cannot set hooks %ld-'%s'", rv, pkcs11h_getMessage (rv));
135
+	}
136
+
137
+	if (rv == CKR_OK) {
138
+		pkcs11h_setLogLevel (_pkcs11_msg_openvpn2pkcs11 (get_debug_level ()));
139
+	}
140
+
141
+	if (
142
+		rv == CKR_OK &&
143
+		(rv = pkcs11h_setTokenPromptHook (_pkcs11_openvpn_token_prompt, NULL)) != CKR_OK
144
+	) {
145
+		msg (M_FATAL, "PKCS#11: Cannot set hooks %ld-'%s'", rv, pkcs11h_getMessage (rv));
135 146
 	}
136 147
 
137 148
 	if (
138 149
 		rv == CKR_OK &&
139 150
 		(rv = pkcs11h_setPINPromptHook (_pkcs11_openvpn_pin_prompt, NULL)) != CKR_OK
140 151
 	) {
141
-		PKCS11LOG (PKCS11_LOG_ERROR, "PKCS#11: Cannot set hooks %ld-'%s'", rv, pkcs11h_getMessage (rv));
152
+		msg (M_FATAL, "PKCS#11: Cannot set hooks %ld-'%s'", rv, pkcs11h_getMessage (rv));
153
+	}
154
+
155
+	if (
156
+		rv == CKR_OK &&
157
+		(rv = pkcs11h_setProtectedAuthentication (fProtectedAuthentication)) != CKR_OK
158
+	) {
159
+		msg (M_FATAL, "PKCS#11: Cannot set protected authentication mode %ld-'%s'", rv, pkcs11h_getMessage (rv));
142 160
 	}
143 161
 
144 162
 	if (
145 163
 		rv == CKR_OK &&
146 164
 		(rv = pkcs11h_setPINCachePeriod (nPINCachePeriod)) != CKR_OK
147 165
 	) {
148
-		PKCS11LOG (PKCS11_LOG_ERROR, "PKCS#11: Cannot set PIN cache period %ld-'%s'", rv, pkcs11h_getMessage (rv));
166
+		msg (M_FATAL, "PKCS#11: Cannot set PIN cache period %ld-'%s'", rv, pkcs11h_getMessage (rv));
149 167
 	}
150 168
 
151
-	PKCS11LOG (
152
-		PKCS11_LOG_DEBUG2,
169
+	dmsg (
170
+		D_PKCS11_DEBUG,
153 171
 		"PKCS#11: pkcs11_initialize - return %ld-'%s'",
154 172
 		rv,
155 173
 		pkcs11h_getMessage (rv)
... ...
@@ -160,15 +273,15 @@ pkcs11_initialize (
160 160
 
161 161
 void
162 162
 pkcs11_terminate () {
163
-	PKCS11LOG (
164
-		PKCS11_LOG_DEBUG2,
163
+	dmsg (
164
+		D_PKCS11_DEBUG,
165 165
 		"PKCS#11: pkcs11_terminate - entered"
166 166
 	);
167 167
 
168 168
 	pkcs11h_terminate ();
169 169
 
170
-	PKCS11LOG (
171
-		PKCS11_LOG_DEBUG2,
170
+	dmsg (
171
+		D_PKCS11_DEBUG,
172 172
 		"PKCS#11: pkcs11_terminate - return"
173 173
 	);
174 174
 }
... ...
@@ -181,32 +294,69 @@ pkcs11_forkFixup () {
181 181
 bool
182 182
 pkcs11_addProvider (
183 183
 	IN const char * const provider,
184
-	IN const char * const sign_mode
184
+	IN const bool fProtectedAuthentication,
185
+	IN const char * const sign_mode,
186
+	IN const bool fCertIsPrivate
185 187
 ) {
188
+	unsigned maskSignMode = 0;
189
+
186 190
 	CK_RV rv = CKR_OK;
187 191
 
188
-	PKCS11LOG (
189
-		PKCS11_LOG_DEBUG2,
192
+	ASSERT (provider!=NULL);
193
+	/*ASSERT (sign_mode!=NULL); NULL is default */
194
+
195
+	dmsg (
196
+		D_PKCS11_DEBUG,
190 197
 		"PKCS#11: pkcs11_addProvider - entered - provider='%s', sign_mode='%s'",
191 198
 		provider,
192 199
 		sign_mode == NULL ? "default" : sign_mode
193 200
 	);
194 201
 
195
-	PKCS11LOG (
196
-		PKCS11_LOG_INFO,
202
+	msg (
203
+		M_INFO,
197 204
 		"PKCS#11: Adding PKCS#11 provider '%s'",
198 205
 		provider
199 206
 	);
200 207
 
208
+	if (rv == CKR_OK) {
209
+		if (sign_mode == NULL || !strcmp (sign_mode, "auto")) {
210
+			maskSignMode = 0;
211
+		}
212
+		else if (!strcmp (sign_mode, "sign")) {
213
+			maskSignMode = PKCS11H_SIGNMODE_MASK_SIGN;
214
+		}
215
+		else if (!strcmp (sign_mode, "recover")) {
216
+			maskSignMode = PKCS11H_SIGNMODE_MASK_RECOVER;
217
+		}
218
+		else if (!strcmp (sign_mode, "any")) {
219
+			maskSignMode = (
220
+				PKCS11H_SIGNMODE_MASK_SIGN |
221
+				PKCS11H_SIGNMODE_MASK_RECOVER
222
+			);
223
+		}
224
+		else {
225
+			msg (M_FATAL, "PKCS#11: Invalid sign mode '%s'", sign_mode);
226
+			rv = CKR_ARGUMENTS_BAD;
227
+		}
228
+	}
229
+
201 230
 	if (
202 231
 		rv == CKR_OK &&
203
-		(rv = pkcs11h_addProvider (provider, sign_mode)) != CKR_OK
232
+		(rv = pkcs11h_addProvider (
233
+			provider,
234
+			provider,
235
+			fProtectedAuthentication,
236
+			maskSignMode,
237
+			PKCS11H_SLOTEVENT_METHOD_AUTO,
238
+			0,
239
+			fCertIsPrivate
240
+		)) != CKR_OK
204 241
 	) {
205
-		PKCS11LOG (PKCS11_LOG_WARN, "PKCS#11: Cannot initialize provider '%s' %ld-'%s'", provider, rv, pkcs11h_getMessage (rv));
242
+		msg (M_WARN, "PKCS#11: Cannot initialize provider '%s' %ld-'%s'", provider, rv, pkcs11h_getMessage (rv));
206 243
 	}
207 244
 
208
-	PKCS11LOG (
209
-		PKCS11_LOG_DEBUG2,
245
+	dmsg (
246
+		D_PKCS11_DEBUG,
210 247
 		"PKCS#11: pkcs11_addProvider - return rv=%ld-'%s'",
211 248
 		rv,
212 249
 		pkcs11h_getMessage (rv)
... ...
@@ -221,73 +371,94 @@ SSL_CTX_use_pkcs11 (
221 221
 	IN const char * const pkcs11_slot_type,
222 222
 	IN const char * const pkcs11_slot,
223 223
 	IN const char * const pkcs11_id_type,
224
-	IN const char * const pkcs11_id,
225
-	IN const bool pkcs11_protected_authentication,
226
-	IN const bool pkcs11_cert_private
224
+	IN const char * const pkcs11_id
227 225
 ) {
228 226
 	X509 *x509 = NULL;
229 227
 	RSA *rsa = NULL;
230
-	pkcs11h_openssl_session_t pkcs11h_openssl_session = NULL;
228
+	pkcs11h_certificate_id_t certificate_id = NULL;
229
+	pkcs11h_certificate_t certificate = NULL;
230
+	pkcs11h_openssl_session_t openssl_session = NULL;
231 231
 	CK_RV rv = CKR_OK;
232 232
 
233 233
 	bool fOK = true;
234 234
 
235
-	PKCS11LOG (
236
-		PKCS11_LOG_DEBUG2,
237
-		"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",
235
+	ASSERT (ssl_ctx!=NULL);
236
+	ASSERT (pkcs11_slot_type!=NULL);
237
+	ASSERT (pkcs11_slot!=NULL);
238
+	ASSERT (pkcs11_id_type!=NULL);
239
+	ASSERT (pkcs11_id!=NULL);
240
+
241
+	dmsg (
242
+		D_PKCS11_DEBUG,
243
+		"PKCS#11: SSL_CTX_use_pkcs11 - entered - ssl_ctx=%p, pkcs11_slot_type='%s', pkcs11_slot='%s', pkcs11_id_type='%s', pkcs11_id='%s'",
238 244
 		(void *)ssl_ctx,
239 245
 		pkcs11_slot_type,
240 246
 		pkcs11_slot,
241 247
 		pkcs11_id_type,
242
-		pkcs11_id,
243
-		pkcs11_protected_authentication ? 1 : 0
248
+		pkcs11_id
244 249
 	);
245 250
 
246
-	PKCS11ASSERT (ssl_ctx!=NULL);
247
-	PKCS11ASSERT (pkcs11_slot_type!=NULL);
248
-	PKCS11ASSERT (pkcs11_slot!=NULL);
249
-	PKCS11ASSERT (pkcs11_id_type!=NULL);
250
-	PKCS11ASSERT (pkcs11_id!=NULL);
251
+	ASSERT (ssl_ctx!=NULL);
252
+	ASSERT (pkcs11_slot_type!=NULL);
253
+	ASSERT (pkcs11_slot!=NULL);
254
+	ASSERT (pkcs11_id_type!=NULL);
255
+	ASSERT (pkcs11_id!=NULL);
251 256
 
252 257
 	if (
253 258
 		fOK &&
254
-		(pkcs11h_openssl_session = pkcs11h_openssl_createSession ()) == NULL
259
+		(rv = pkcs11h_locate_certificate (
260
+			pkcs11_slot_type,
261
+			pkcs11_slot,
262
+			pkcs11_id_type,
263
+			pkcs11_id,
264
+			&certificate_id
265
+		)) != CKR_OK
255 266
 	) {
256 267
 		fOK = false;
257
-		PKCS11LOG (PKCS11_LOG_WARN, "PKCS#11: Cannot initialize openssh session");
268
+		msg (M_WARN, "PKCS#11: Cannot set parameters %ld-'%s'", rv, pkcs11h_getMessage (rv));
258 269
 	}
259 270
 
260 271
 	if (
261 272
 		fOK &&
262
-		(rv = pkcs11h_createCertificateSession (
263
-			pkcs11_slot_type,
264
-			pkcs11_slot,
265
-			pkcs11_id_type,
266
-			pkcs11_id,
267
-			pkcs11_protected_authentication,
268
-			pkcs11_cert_private,
273
+		(rv = pkcs11h_certificate_create (
274
+			certificate_id,
269 275
 			PKCS11H_PIN_CACHE_INFINITE,
270
-			&pkcs11h_openssl_session->certificate
276
+			&certificate
271 277
 		)) != CKR_OK
272 278
 	) {
273 279
 		fOK = false;
274
-		PKCS11LOG (PKCS11_LOG_WARN, "PKCS#11: Cannot set parameters %ld-'%s'", rv, pkcs11h_getMessage (rv));
280
+		msg (M_WARN, "PKCS#11: Cannot get certificate %ld-'%s'", rv, pkcs11h_getMessage (rv));
275 281
 	}
276 282
 
277 283
 	if (
278 284
 		fOK &&
279
-		(rsa = pkcs11h_openssl_getRSA (pkcs11h_openssl_session)) == NULL
285
+		(openssl_session = pkcs11h_openssl_createSession (certificate)) == NULL
280 286
 	) {
281 287
 		fOK = false;
282
-		PKCS11LOG (PKCS11_LOG_WARN, "PKCS#11: Unable get rsa object");
288
+		msg (M_WARN, "PKCS#11: Cannot initialize openssl session");
289
+	}
290
+
291
+	if (fOK) {
292
+		/*
293
+		 * Will be released by openssl_session
294
+		 */
295
+		certificate = NULL;
283 296
 	}
284 297
 
285 298
 	if (
286 299
 		fOK &&
287
-		(x509 = pkcs11h_openssl_getX509 (pkcs11h_openssl_session)) == NULL
300
+		(rsa = pkcs11h_openssl_getRSA (openssl_session)) == NULL
288 301
 	) {
289 302
 		fOK = false;
290
-		PKCS11LOG (PKCS11_LOG_WARN, "PKCS#11: Unable get certificate object");
303
+		msg (M_WARN, "PKCS#11: Unable get rsa object");
304
+	}
305
+
306
+	if (
307
+		fOK &&
308
+		(x509 = pkcs11h_openssl_getX509 (openssl_session)) == NULL
309
+	) {
310
+		fOK = false;
311
+		msg (M_WARN, "PKCS#11: Unable get certificate object");
291 312
 	}
292 313
 
293 314
 	if (
... ...
@@ -295,7 +466,7 @@ SSL_CTX_use_pkcs11 (
295 295
 		!SSL_CTX_use_RSAPrivateKey (ssl_ctx, rsa)
296 296
 	) {
297 297
 		fOK = false;
298
-		PKCS11LOG (PKCS11_LOG_WARN, "PKCS#11: Cannot set private key for openssl");
298
+		msg (M_WARN, "PKCS#11: Cannot set private key for openssl");
299 299
 	}
300 300
 
301 301
 	if (
... ...
@@ -303,7 +474,7 @@ SSL_CTX_use_pkcs11 (
303 303
 		!SSL_CTX_use_certificate (ssl_ctx, x509)
304 304
 	) {
305 305
 		fOK = false;
306
-		PKCS11LOG (PKCS11_LOG_WARN, "PKCS#11: Cannot set certificate for openssl");
306
+		msg (M_WARN, "PKCS#11: Cannot set certificate for openssl");
307 307
 	}
308 308
 
309 309
 	/*
... ...
@@ -320,14 +491,24 @@ SSL_CTX_use_pkcs11 (
320 320
 		RSA_free (rsa);
321 321
 		rsa = NULL;
322 322
 	}
323
+
324
+	if (certificate != NULL) {
325
+		pkcs11h_freeCertificate (certificate);
326
+		certificate = NULL;
327
+	}
328
+
329
+	if (certificate_id != NULL) {
330
+		pkcs11h_freeCertificateId (certificate_id);
331
+		certificate_id = NULL;
332
+	}
323 333
 	
324
-	if (pkcs11h_openssl_session != NULL) {
325
-		pkcs11h_openssl_freeSession (pkcs11h_openssl_session);
326
-		pkcs11h_openssl_session = NULL;
334
+	if (openssl_session != NULL) {
335
+		pkcs11h_openssl_freeSession (openssl_session);
336
+		openssl_session = NULL;
327 337
 	}
328 338
 
329
-	PKCS11LOG (
330
-		PKCS11_LOG_DEBUG2,
339
+	dmsg (
340
+		D_PKCS11_DEBUG,
331 341
 		"PKCS#11: SSL_CTX_use_pkcs11 - return fOK=%d, rv=%ld",
332 342
 		fOK ? 1 : 0,
333 343
 		rv
... ...
@@ -31,6 +31,7 @@
31 31
 
32 32
 bool
33 33
 pkcs11_initialize (
34
+	const bool fProtectedAuthentication,
34 35
 	const int nPINCachePeriod
35 36
 );
36 37
 
... ...
@@ -43,7 +44,9 @@ pkcs11_forkFixup ();
43 43
 bool
44 44
 pkcs11_addProvider (
45 45
 	const char * const provider,
46
-	const char * const sign_mode
46
+	const bool fProtectedAuthentication,
47
+	const char * const sign_mode,
48
+	const bool fCertIsPrivate
47 49
 );
48 50
 
49 51
 int
... ...
@@ -52,9 +55,7 @@ SSL_CTX_use_pkcs11 (
52 52
 	const char * const pkcs11_slot_type,
53 53
 	const char * const pkcs11_slot,
54 54
 	const char * const pkcs11_id_type,
55
-	const char * const pkcs11_id,
56
-	const bool pkcs11_protected_authentication,
57
-	const bool pkcs11_cert_private
55
+	const char * const pkcs11_id
58 56
 );
59 57
 
60 58
 void
... ...
@@ -71,4 +72,4 @@ show_pkcs11_objects (
71 71
 
72 72
 #endif			/* ENABLE_PKCS11 */
73 73
 
74
-#endif			/* OPENVPN_PKCS11_H */
74
+#endif			/* OPENVPN_PKCS11H_H */
... ...
@@ -1145,7 +1145,7 @@ init_ssl (const struct options *options)
1145 1145
       if (options->pkcs11_providers[0])
1146 1146
        {
1147 1147
         /* Load Certificate and Private Key */
1148
-	if (!SSL_CTX_use_pkcs11 (ctx, options->pkcs11_slot_type, options->pkcs11_slot, options->pkcs11_id_type, options->pkcs11_id, options->pkcs11_protected_authentication, options->pkcs11_cert_private))
1148
+	if (!SSL_CTX_use_pkcs11 (ctx, options->pkcs11_slot_type, options->pkcs11_slot, options->pkcs11_id_type, options->pkcs11_id))
1149 1149
 	  msg (M_SSLERR, "Cannot load certificate \"%s:%s\" from slot \"%s:%s\" using PKCS#11 interface",
1150 1150
                options->pkcs11_id_type, options->pkcs11_id, options->pkcs11_slot_type, options->pkcs11_slot);
1151 1151
        }