Browse code

Merged with Alon's r688.

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

james authored on 2005/10/20 14:58:08
Showing 18 changed files
... ...
@@ -67,7 +67,7 @@ openvpn_SOURCES = \
67 67
 	multi.c multi.h \
68 68
         ntlm.c ntlm.h \
69 69
 	occ.c occ.h occ-inline.h \
70
-	pkcs11.c pkcs11.h cryptoki.h \
70
+	pkcs11.c pkcs11.h pkcs11-helper.c pkcs11-helper.h pkcs11-helper-config.h cryptoki.h \
71 71
 	openvpn.c openvpn.h \
72 72
 	openvpn-plugin.h \
73 73
 	options.c options.h \
... ...
@@ -300,26 +300,29 @@ void x_msg (const unsigned int flags, const char *format, ...)
300 300
 
301 301
 	  if ((flags & M_NOPREFIX) || suppress_timestamps)
302 302
 	    {
303
-	      fprintf (fp, "%s%s%s\n",
303
+	      fprintf (fp, "%s%s%s%s",
304 304
 		       prefix,
305 305
 		       prefix_sep,
306
-		       m1);
306
+		       m1,
307
+		       (flags&M_NOLF) ? "" : "\n");
307 308
 	    }
308 309
 	  else
309 310
 	    {
310 311
 #ifdef USE_PTHREAD
311
-	      fprintf (fp, "%s [%d] %s%s%s\n",
312
+	      fprintf (fp, "%s [%d] %s%s%s%s",
312 313
 		       time_string (0, 0, show_usec, &gc),
313 314
 		       (int) openvpn_thread_self (),
314 315
 		       prefix,
315 316
 		       prefix_sep,
316
-		       m1);
317
+		       m1,
318
+		       (flags&M_NOLF) ? "" : "\n");
317 319
 #else
318
-	      fprintf (fp, "%s %s%s%s\n",
320
+	      fprintf (fp, "%s %s%s%s%s",
319 321
 		       time_string (0, 0, show_usec, &gc),
320 322
 		       prefix,
321 323
 		       prefix_sep,
322
-		       m1);
324
+		       m1,
325
+		       (flags&M_NOLF) ? "" : "\n");
323 326
 #endif
324 327
 	    }
325 328
 	  fflush(fp);
... ...
@@ -97,6 +97,7 @@ extern int x_msg_line_num;
97 97
 #define M_USAGE_SMALL     (1<<13)        /* fatal options error, call usage_small */
98 98
 #define M_MSG_VIRT_OUT    (1<<14)        /* output message through msg_status_output callback */
99 99
 #define M_OPTERR          (1<<15)        /* print "Options error:" prefix */
100
+#define M_NOLF            (1<<16)        /* don't print new line */
100 101
 
101 102
 /* flag combinations which are frequently used */
102 103
 #define M_ERR     (M_FATAL | M_ERRNO)
... ...
@@ -116,12 +116,12 @@ context_init_1 (struct context *c)
116 116
 #if defined(ENABLE_PKCS11)
117 117
   {
118 118
     int i;
119
-    init_pkcs11 (c->options.pkcs11_pin_cache_period);
119
+    pkcs11_initialize (c->options.pkcs11_pin_cache_period);
120 120
     for (i=0;i<MAX_PARMS && c->options.pkcs11_providers[i] != NULL;i++)
121
-     add_pkcs11 (c->options.pkcs11_providers[i], c->options.pkcs11_sign_mode[i]);
121
+     pkcs11_addProvider (c->options.pkcs11_providers[i], c->options.pkcs11_sign_mode[i]);
122 122
   }
123 123
 #endif
124
-  
124
+
125 125
 #if P2MP
126 126
   /* Auth user/pass input */
127 127
   if (c->options.auth_user_pass_file)
... ...
@@ -236,7 +236,7 @@ uninit_static (void)
236 236
 #endif
237 237
 
238 238
 #ifdef ENABLE_PKCS11
239
-  free_pkcs11 ();
239
+  pkcs11_terminate ();
240 240
 #endif
241 241
 
242 242
 #if defined(MEASURE_TLS_HANDSHAKE_STATS) && defined(USE_CRYPTO) && defined(USE_SSL)
... ...
@@ -376,7 +376,7 @@ possibly_become_daemon (const struct options *options, const bool first_time)
376 376
 	set_std_files_to_null (true);
377 377
 
378 378
 #if defined(ENABLE_PKCS11)
379
-      fork_fix_pkcs11 ();
379
+      pkcs11_forkFixup ();
380 380
 #endif
381 381
 
382 382
       ret = true;
... ...
@@ -96,7 +96,7 @@ HEADERS = \
96 96
 	ntlm.h \
97 97
 	occ-inline.h \
98 98
 	occ.h \
99
-	pkcs11.h \
99
+	pkcs11.h pkcs11-helper.h cryptoki.h \
100 100
         openvpn.h \
101 101
 	openvpn-plugin.h \
102 102
 	options.h \
... ...
@@ -151,7 +151,7 @@ OBJS =  base64.o \
151 151
 	multi.o \
152 152
 	ntlm.o \
153 153
 	occ.o \
154
-	pkcs11.o \
154
+	pkcs11.o pkcs11-helper.o \
155 155
         openvpn.o \
156 156
 	options.o \
157 157
 	otime.o \
... ...
@@ -81,7 +81,7 @@ HEADERS = \
81 81
 	ntlm.h \
82 82
 	occ-inline.h \
83 83
 	occ.h \
84
-	pkcs11.h \
84
+	pkcs11.h pkcs11-helper.h cryptoki.h \
85 85
         openvpn.h \
86 86
 	openvpn-plugin.h \
87 87
 	options.h \
... ...
@@ -136,7 +136,7 @@ OBJS =  base64.obj \
136 136
 	multi.obj \
137 137
 	ntlm.obj \
138 138
 	occ.obj \
139
-	pkcs11.obj \
139
+	pkcs11.obj pkcs11-helper.obj \
140 140
         openvpn.obj \
141 141
 	options.obj \
142 142
 	otime.obj \
... ...
@@ -39,6 +39,7 @@
39 39
 #include "event.h"
40 40
 #include "otime.h"
41 41
 #include "integer.h"
42
+#include "misc.h"
42 43
 #include "manage.h"
43 44
 
44 45
 #include "memdbg.h"
... ...
@@ -74,6 +75,7 @@ man_help ()
74 74
   msg (M_CLIENT, "                         + show last N lines or 'all' for entire history.");
75 75
   msg (M_CLIENT, "mute [n]               : Set log mute level to n, or show level if n is absent.");
76 76
   msg (M_CLIENT, "net                    : (Windows only) Show network info and routing table.");
77
+  msg (M_CLIENT, "ok type                : Enter confirmation for NEED-OK request.");
77 78
   msg (M_CLIENT, "password type p        : Enter password p for a queried OpenVPN password.");
78 79
   msg (M_CLIENT, "signal s               : Send signal s to daemon,");
79 80
   msg (M_CLIENT, "                         s = SIGHUP|SIGTERM|SIGUSR1|SIGUSR2.");
... ...
@@ -467,6 +469,10 @@ man_up_finalize (struct management *man)
467 467
       if (strlen (man->connection.up_query.password))
468 468
 	man->connection.up_query.defined = true;
469 469
       break;
470
+    case UP_QUERY_NEED_OK:
471
+      if (strlen (man->connection.up_query.password))
472
+	man->connection.up_query.defined = true;
473
+      break;
470 474
     default:
471 475
       ASSERT (0);
472 476
     }
... ...
@@ -521,6 +527,13 @@ man_query_password (struct management *man, const char *type, const char *string
521 521
 }
522 522
 
523 523
 static void
524
+man_query_need_ok (struct management *man, const char *type)
525
+{
526
+  const bool needed = ((man->connection.up_query_mode == UP_QUERY_NEED_OK) && man->connection.up_query_type);
527
+  man_query_user_pass (man, type, "ok", needed, "ok-confirmation", man->connection.up_query.password, USER_PASS_LEN);
528
+}
529
+
530
+static void
524 531
 man_net (struct management *man)
525 532
 {
526 533
   if (man->persist.callback.show_net)
... ...
@@ -708,6 +721,11 @@ man_dispatch_command (struct management *man, struct status_output *so, const ch
708 708
       if (man_need (man, p, 2, 0))
709 709
 	man_query_password (man, p[1], p[2]);
710 710
     }
711
+  else if (streq (p[0], "ok"))
712
+    {
713
+      if (man_need (man, p, 1, 0))
714
+	man_query_need_ok (man, p[1]);
715
+    }
711 716
   else if (streq (p[0], "net"))
712 717
     {
713 718
       man_net (man);
... ...
@@ -1130,7 +1148,7 @@ man_settings_init (struct man_settings *ms,
1130 1130
        * Get username/password
1131 1131
        */
1132 1132
       if (pass_file)
1133
-	get_user_pass (&ms->up, pass_file, true, "Management", 0);
1133
+	get_user_pass (&ms->up, pass_file, "Management", GET_USER_PASS_PASSWORD_ONLY);
1134 1134
 
1135 1135
       /*
1136 1136
        * Should OpenVPN query the management layer for
... ...
@@ -1728,7 +1746,7 @@ bool
1728 1728
 management_query_user_pass (struct management *man,
1729 1729
 			    struct user_pass *up,
1730 1730
 			    const char *type,
1731
-			    const bool password_only)
1731
+			    const unsigned int flags)
1732 1732
 {
1733 1733
   struct gc_arena gc = gc_new ();
1734 1734
   bool ret = false;
... ...
@@ -1738,6 +1756,9 @@ management_query_user_pass (struct management *man,
1738 1738
       volatile int signal_received = 0;
1739 1739
       const bool standalone_disabled_save = man->persist.standalone_disabled;
1740 1740
       struct buffer alert_msg = alloc_buf_gc (128, &gc);
1741
+      const char *alert_type = NULL;
1742
+      const char *prefix = NULL;
1743
+      unsigned int up_query_mode = 0;
1741 1744
 
1742 1745
       ret = true;
1743 1746
       man->persist.standalone_disabled = false; /* This is so M_CLIENT messages will be correctly passed through msg() */
... ...
@@ -1745,9 +1766,28 @@ management_query_user_pass (struct management *man,
1745 1745
 
1746 1746
       CLEAR (man->connection.up_query);
1747 1747
 
1748
-      buf_printf (&alert_msg, ">PASSWORD:Need '%s' %s",
1748
+      if (flags & GET_USER_PASS_NEED_OK)
1749
+	{
1750
+	  up_query_mode = UP_QUERY_NEED_OK;
1751
+	  prefix= "NEED-OK";
1752
+	  alert_type = "confirmation";
1753
+	}
1754
+      else if (flags & GET_USER_PASS_PASSWORD_ONLY)
1755
+	{
1756
+	  up_query_mode = UP_QUERY_PASS;
1757
+	  prefix = "PASSWORD";
1758
+	  alert_type = "password";
1759
+	}
1760
+      else
1761
+	{
1762
+	  up_query_mode = UP_QUERY_USER_PASS;
1763
+	  prefix = "PASSWORD";
1764
+	  alert_type = "username/password";
1765
+	}
1766
+      buf_printf (&alert_msg, ">%s:Need '%s' %s",
1767
+		  prefix,
1749 1768
 		  type,
1750
-		  password_only ? "password" : "username/password");
1769
+		  alert_type);
1751 1770
 
1752 1771
       man_wait_for_client_connection (man, &signal_received, 0, MWCC_PASSWORD_WAIT);
1753 1772
       if (signal_received)
... ...
@@ -1759,7 +1799,7 @@ management_query_user_pass (struct management *man,
1759 1759
 	  msg (M_CLIENT, "%s", man->persist.special_state_msg);
1760 1760
 
1761 1761
 	  /* tell command line parser which info we need */
1762
-	  man->connection.up_query_mode = password_only ? UP_QUERY_PASS : UP_QUERY_USER_PASS;
1762
+	  man->connection.up_query_mode = up_query_mode;
1763 1763
 	  man->connection.up_query_type = type;
1764 1764
 
1765 1765
 	  /* run command processing event loop until we get our username/password */
... ...
@@ -203,6 +203,7 @@ struct man_settings {
203 203
 #define UP_QUERY_DISABLED  0
204 204
 #define UP_QUERY_USER_PASS 1
205 205
 #define UP_QUERY_PASS      2
206
+#define UP_QUERY_NEED_OK   3
206 207
 
207 208
 /* states */
208 209
 #define MS_INITIAL          0  /* all sockets are closed */
... ...
@@ -282,7 +283,7 @@ void management_set_callback (struct management *man,
282 282
 
283 283
 void management_clear_callback (struct management *man);
284 284
 
285
-bool management_query_user_pass (struct management *man, struct user_pass *up, const char *type, const bool password_only);
285
+bool management_query_user_pass (struct management *man, struct user_pass *up, const char *type, const unsigned int flags);
286 286
 
287 287
 bool management_would_hold (struct management *man);
288 288
 bool management_hold (struct management *man);
... ...
@@ -1155,7 +1155,6 @@ get_console_input (const char *prompt, const bool echo, char *input, const int c
1155 1155
 void
1156 1156
 get_user_pass (struct user_pass *up,
1157 1157
 	       const char *auth_file,
1158
-	       const bool password_only,
1159 1158
 	       const char *prefix,
1160 1159
 	       const unsigned int flags)
1161 1160
 {
... ...
@@ -1173,32 +1172,44 @@ get_user_pass (struct user_pass *up,
1173 1173
 	  && ((auth_file && streq (auth_file, "management")) || (from_stdin && (flags & GET_USER_PASS_MANAGEMENT)))
1174 1174
 	  && management_query_user_pass_enabled (management))
1175 1175
 	{
1176
-	  if (!management_query_user_pass (management, up, prefix, password_only))
1177
-	    msg (M_FATAL, "ERROR: could not read %s username/password from management interface", prefix);
1176
+	  if (!management_query_user_pass (management, up, prefix, flags))
1177
+	    msg (M_FATAL, "ERROR: could not read %s username/password/ok from management interface", prefix);
1178 1178
 	}
1179 1179
       else
1180 1180
 #endif
1181 1181
       /*
1182 1182
        * Get username/password from standard input?
1183 1183
        */
1184
-      if (from_stdin)
1184
+      if (from_stdin || (flags & GET_USER_PASS_NEED_OK))
1185 1185
 	{
1186 1186
 	  struct buffer user_prompt = alloc_buf_gc (128, &gc);
1187 1187
 	  struct buffer pass_prompt = alloc_buf_gc (128, &gc);
1188 1188
 
1189
-	  buf_printf (&user_prompt, "Enter %s Username:", prefix);
1190
-	  buf_printf (&pass_prompt, "Enter %s Password:", prefix);
1191
-
1192
-	  if (!password_only)
1189
+	  if (flags & GET_USER_PASS_NEED_OK)
1193 1190
 	    {
1194
-	      if (!get_console_input (BSTR (&user_prompt), true, up->username, USER_PASS_LEN))
1195
-		msg (M_FATAL, "ERROR: could not read %s username from stdin", prefix);
1196
-	      if (strlen (up->username) == 0)
1197
-		msg (M_FATAL, "ERROR: %s username is empty", prefix);
1191
+	      buf_printf (&pass_prompt, "NEED-OK:%s:", prefix);
1192
+	    }
1193
+	  else
1194
+	    {
1195
+	      buf_printf (&user_prompt, "Enter %s Username:", prefix);
1196
+	      buf_printf (&pass_prompt, "Enter %s Password:", prefix);
1197
+
1198
+	      if (!(flags & GET_USER_PASS_PASSWORD_ONLY))
1199
+		{
1200
+		  if (!get_console_input (BSTR (&user_prompt), true, up->username, USER_PASS_LEN))
1201
+		    msg (M_FATAL, "ERROR: could not read %s username from stdin", prefix);
1202
+		  if (strlen (up->username) == 0)
1203
+		    msg (M_FATAL, "ERROR: %s username is empty", prefix);
1204
+		}
1198 1205
 	    }
1199 1206
 
1200 1207
 	  if (!get_console_input (BSTR (&pass_prompt), false, up->password, USER_PASS_LEN))
1201
-	    msg (M_FATAL, "ERROR: could not not read %s password from stdin", prefix);
1208
+	    msg (M_FATAL, "ERROR: could not not read %s %s from stdin",
1209
+		 prefix,
1210
+		 (flags & GET_USER_PASS_NEED_OK) ? "ok-confirmation" : "password");
1211
+
1212
+	  if (flags & GET_USER_PASS_NEED_OK)
1213
+	    strcpy (up->password, "ok");
1202 1214
 	}
1203 1215
       else
1204 1216
 	{
... ...
@@ -1222,7 +1233,7 @@ get_user_pass (struct user_pass *up,
1222 1222
 	  if (!fp)
1223 1223
 	    msg (M_ERR, "Error opening '%s' auth file: %s", prefix, auth_file);
1224 1224
 
1225
-	  if (password_only)
1225
+	  if (flags & GET_USER_PASS_PASSWORD_ONLY)
1226 1226
 	    {
1227 1227
 	      if (fgets (up->password, USER_PASS_LEN, fp) == NULL)
1228 1228
 		msg (M_FATAL, "Error reading password from %s authfile: %s",
... ...
@@ -1243,7 +1254,7 @@ get_user_pass (struct user_pass *up,
1243 1243
 	  chomp (up->username);
1244 1244
 	  chomp (up->password);
1245 1245
       
1246
-	  if (!password_only && strlen (up->username) == 0)
1246
+	  if (!(flags & GET_USER_PASS_PASSWORD_ONLY) && strlen (up->username) == 0)
1247 1247
 	    msg (M_FATAL, "ERROR: username from %s authfile '%s' is empty", prefix, auth_file);
1248 1248
 	}
1249 1249
 
... ...
@@ -229,12 +229,16 @@ struct user_pass
229 229
 
230 230
 bool get_console_input (const char *prompt, const bool echo, char *input, const int capacity);
231 231
 
232
-#define GET_USER_PASS_MANAGEMENT  (1<<0)
233
-#define GET_USER_PASS_SENSITIVE   (1<<1)
232
+/*
233
+ * Flags for get_user_pass and management_query_user_pass
234
+ */
235
+#define GET_USER_PASS_MANAGEMENT    (1<<0)
236
+#define GET_USER_PASS_SENSITIVE     (1<<1)
237
+#define GET_USER_PASS_PASSWORD_ONLY (1<<2)
238
+#define GET_USER_PASS_NEED_OK       (1<<3)
234 239
 
235 240
 void get_user_pass (struct user_pass *up,
236 241
 		    const char *auth_file,
237
-		    const bool password_only,
238 242
 		    const char *prefix,
239 243
 		    const unsigned int flags);
240 244
 
... ...
@@ -4896,7 +4896,7 @@ add_option (struct options *options,
4896 4896
     {
4897 4897
       char *module =  p[i++];
4898 4898
       VERIFY_PERMISSION (OPT_P_GENERAL);
4899
-      show_pkcs11_slots (M_INFO|M_NOPREFIX, M_WARN|M_NOPREFIX, module);
4899
+      show_pkcs11_slots (module);
4900 4900
       openvpn_exit (OPENVPN_EXIT_STATUS_GOOD); /* exit point */
4901 4901
     }
4902 4902
   else if (streq (p[0], "show-pkcs11-objects") && p[1] && p[2])
... ...
@@ -4916,7 +4916,7 @@ add_option (struct options *options,
4916 4916
       
4917 4917
       gc_free (&gc);
4918 4918
       
4919
-      show_pkcs11_objects (M_INFO|M_NOPREFIX, M_WARN|M_NOPREFIX, provider, slot, pin);
4919
+      show_pkcs11_objects (provider, slot, pin);
4920 4920
       openvpn_exit (OPENVPN_EXIT_STATUS_GOOD); /* exit point */
4921 4921
     }
4922 4922
   else if (streq (p[0], "pkcs11-providers") && p[1])
4923 4923
new file mode 100644
... ...
@@ -0,0 +1,84 @@
0
+/*
1
+*  OpenVPN -- An application to securely tunnel IP networks
2
+*             over a single TCP/UDP port, with support for SSL/TLS-based
3
+*             session authentication and key exchange,
4
+*             packet encryption, packet authentication, and
5
+*             packet compression.
6
+*
7
+*  Copyright (C) 2002-2005 OpenVPN Solutions LLC <info@openvpn.net>
8
+*
9
+*  This program is free software; you can redistribute it and/or modify
10
+*  it under the terms of the GNU General Public License version 2
11
+*  as published by the Free Software Foundation.
12
+*
13
+*  This program is distributed in the hope that it will be useful,
14
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
+*  GNU General Public License for more details.
17
+*
18
+*  You should have received a copy of the GNU General Public License
19
+*  along with this program (see the file COPYING included with this
20
+*  distribution); if not, write to the Free Software Foundation, Inc.,
21
+*  59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
22
+*/
23
+
24
+#ifndef __PKCS11_HELPER_CONFIG_H
25
+#define __PKCS11_HELPER_CONFIG_H
26
+
27
+#if!defined(PKCS11H_NO_NEED_INCLUDE_CONFIG)
28
+
29
+#if defined(WIN32)
30
+#include "config-win32.h"
31
+#else
32
+#include "config.h"
33
+#endif
34
+
35
+#include "syshead.h"
36
+
37
+#endif /* PKCS11H_NO_NEED_INCLUDE_CONFIG */
38
+
39
+#ifdef ENABLE_PKCS11
40
+#define PKCS11H_ENABLE_HELPER
41
+#endif
42
+
43
+#ifdef PKCS11H_ENABLE_HELPER
44
+
45
+#if defined(WIN32)
46
+#include "cryptoki-win32.h"
47
+#else
48
+#include "cryptoki.h"
49
+#endif
50
+
51
+#include "error.h"
52
+#include "misc.h"
53
+#include "ssl.h"
54
+
55
+#define PKCS11ASSERT		ASSERT
56
+#define PKCS11LOG		msg
57
+#define PKCS11_LOG_DEBUG2	D_PKCS11_DEBUG
58
+#define PKCS11_LOG_DEBUG1	D_SHOW_PKCS11
59
+#define PKCS11_LOG_INFO		M_INFO
60
+#define PKCS11_LOG_WARN		M_WARN
61
+#define PKCS11_LOG_ERROR	M_FATAL
62
+
63
+#if !defined(false)
64
+#define false 0
65
+#endif
66
+#if !defined(true)
67
+#define true (!false)
68
+#endif
69
+
70
+#if !defined(IN)
71
+#define IN
72
+#endif
73
+#if !defined(OUT)
74
+#define OUT
75
+#endif
76
+
77
+#define PKCS11_PRM_SLOT_TYPE	"--pkcs11-slot-type"
78
+#define PKCS11_PRM_SLOT_ID	"--pkcs11-slot"
79
+#define PKCS11_PRM_OBJ_TYPE	"--pkcs11-id-type"
80
+#define PKCS11_PRM_OBJ_ID	"--pkcs11-id"
81
+
82
+#endif		/* PKCS11H_ENABLE_HELPER */
83
+#endif		/* __PKCS11_HELPER_CONFIG_H */
0 84
new file mode 100644
... ...
@@ -0,0 +1,3239 @@
0
+/*
1
+ * Copyright (c) 2005 Alon Bar-Lev <alon.barlev@gmail.com>
2
+ * All rights reserved.
3
+ *
4
+ * Redistribution and use in source and binary forms, with or without modifi-
5
+ * cation, are permitted provided that the following conditions are met:
6
+ *
7
+ *   o  Redistributions of source code must retain the above copyright notice,
8
+ *      this list of conditions and the following disclaimer.
9
+ *
10
+ *   o  Redistributions in binary form must reproduce the above copyright no-
11
+ *      tice, this list of conditions and the following disclaimer in the do-
12
+ *      cumentation and/or other materials provided with the distribution.
13
+ *
14
+ *   o  The names of the contributors may not be used to endorse or promote
15
+ *      products derived from this software without specific prior written
16
+ *      permission.
17
+ *
18
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
20
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
21
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LI-
22
+ * ABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUEN-
23
+ * TIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEV-
25
+ * ER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABI-
26
+ * LITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
27
+ * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
+ */
29
+
30
+/*
31
+ * The routines in this file deal with providing private key cryptography
32
+ * using RSA Security Inc. PKCS #11 Cryptographic Token Interface (Cryptoki).
33
+ *
34
+ */
35
+
36
+#include "pkcs11-helper-config.h"
37
+
38
+#if defined(PKCS11H_ENABLE_HELPER)
39
+
40
+#if defined(WIN32)
41
+#include "cryptoki-win32.h"
42
+#else
43
+#include "cryptoki.h"
44
+#endif
45
+
46
+#include "pkcs11-helper.h"
47
+
48
+/*===========================================
49
+ * Constants
50
+ */
51
+
52
+#if OPENSSL_VERSION_NUMBER < 0x00907000L && defined(CRYPTO_LOCK_ENGINE)
53
+# define RSA_get_default_method RSA_get_default_openssl_method
54
+#else
55
+# ifdef HAVE_ENGINE_GET_DEFAULT_RSA
56
+#  include <openssl/engine.h>
57
+#  if OPENSSL_VERSION_NUMBER < 0x0090704fL
58
+#   define BROKEN_OPENSSL_ENGINE
59
+#  endif
60
+# endif
61
+#endif
62
+
63
+
64
+/*===========================================
65
+ * Low level prototypes
66
+ */
67
+
68
+static
69
+void
70
+_pkcs11h_fixupFixedString (
71
+	IN const char * const szSource,
72
+	OUT char * const szTarget,			/* MUST BE >= nLength+1 */
73
+	IN const size_t nLength				/* FIXED STRING LENGTH */
74
+);
75
+static
76
+void
77
+_hexToBinary (
78
+	IN const char * const szSource,
79
+	OUT unsigned char * const target,
80
+	IN OUT size_t * const target_size
81
+);
82
+static
83
+CK_RV
84
+_pkcs11h_getSlotById (
85
+	IN const pkcs11h_session_t pkcs11h_session,
86
+	IN const char * const szSlot
87
+);
88
+static
89
+CK_RV
90
+_pkcs11h_getSlotByName (
91
+	IN const pkcs11h_session_t pkcs11h_session,
92
+	IN const char * const szName
93
+);
94
+static
95
+CK_RV
96
+_pkcs11h_getSlotByLabel (
97
+	IN const pkcs11h_session_t pkcs11h_session,
98
+	IN const char * const szLabel
99
+);
100
+static
101
+CK_RV
102
+_pkcs11h_getObjectById (
103
+	IN const pkcs11h_session_t pkcs11h_session,
104
+	IN const CK_OBJECT_CLASS class,
105
+	IN const unsigned char * const id,
106
+	IN const size_t id_size,
107
+	OUT CK_OBJECT_HANDLE * const handle
108
+);
109
+static
110
+CK_RV
111
+_pkcs11h_setSessionTokenInfo (
112
+	IN const pkcs11h_session_t pkcs11h_session
113
+);
114
+static
115
+CK_RV
116
+_pkcs11h_resetSlot (
117
+	IN const pkcs11h_session_t pkcs11h_session
118
+);
119
+static
120
+CK_RV
121
+_pkcs11h_loadCertificate (
122
+	IN const pkcs11h_session_t pkcs11h_session,
123
+	IN const char * const szIdType,
124
+	IN const char * const szId
125
+);
126
+static
127
+CK_RV
128
+_pkcs11h_loadKeyProperties (
129
+	IN const pkcs11h_session_t pkcs11h_session
130
+);
131
+static
132
+bool
133
+_isBetterCertificate (
134
+	IN const unsigned char * const pCurrent,
135
+	IN const size_t nCurrentSize,
136
+	IN const unsigned char * const pNew,
137
+	IN const size_t nNewSize
138
+);
139
+static
140
+CK_RV
141
+_pkcs11h_validateSession (
142
+	IN const pkcs11h_session_t pkcs11h_session
143
+);
144
+static
145
+CK_RV
146
+_pkcs11h_login (
147
+	IN const pkcs11h_session_t pkcs11h_session
148
+);
149
+static
150
+CK_RV
151
+_pkcs11h_logout (
152
+	IN const pkcs11h_session_t pkcs11h_session
153
+);
154
+static
155
+int
156
+_pkcs11h_openssl_sign (
157
+	IN int type,
158
+	IN const unsigned char *m,
159
+	IN unsigned int m_len,
160
+	OUT unsigned char *sigret,
161
+	OUT unsigned int *siglen,
162
+	IN OUT const RSA *rsa
163
+);
164
+
165
+/*==========================================
166
+ * openssl interface
167
+ */
168
+
169
+static
170
+int
171
+_pkcs11h_openssl_finish (
172
+	IN OUT RSA *rsa
173
+);
174
+static
175
+int
176
+_pkcs11h_openssl_priv_dec (
177
+	IN int flen,
178
+	IN const unsigned char *from,
179
+	OUT unsigned char *to,
180
+	IN OUT RSA *rsa,
181
+	IN int padding
182
+);
183
+static
184
+int
185
+_pkcs11h_openssl_priv_enc (
186
+	IN int flen,
187
+	IN const unsigned char *from,
188
+	OUT unsigned char *to,
189
+	IN OUT RSA *rsa,
190
+	IN int padding
191
+);
192
+static
193
+pkcs11h_openssl_session_t
194
+_pkcs11h_openssl_get_pkcs11h_openssl_session (
195
+	IN OUT const RSA *rsa
196
+);  
197
+static
198
+pkcs11h_session_t
199
+_pkcs11h_openssl_get_pkcs11h_session (
200
+	IN OUT const RSA *rsa
201
+);  
202
+
203
+/*==========================================
204
+ * Static data
205
+ */
206
+
207
+pkcs11h_data_t pkcs11h_data = NULL;
208
+
209
+/*==========================================
210
+ * Internal utility functions
211
+ */
212
+
213
+static
214
+void
215
+_pkcs11h_fixupFixedString (
216
+	IN const char * const szSource,
217
+	OUT char * const szTarget,			/* MUST BE >= nLength+1 */
218
+	IN const size_t nLength				/* FIXED STRING LENGTH */
219
+) {
220
+	char *p;
221
+
222
+	PKCS11ASSERT (szSource!=NULL);
223
+	PKCS11ASSERT (szTarget!=NULL);
224
+	
225
+	p = szTarget+nLength;
226
+	memmove (szTarget, szSource, nLength);
227
+	*p = '\0';
228
+	p--;
229
+	while (p >= szTarget && *p == ' ') {
230
+		*p = '\0';
231
+		p--;
232
+	}
233
+}
234
+
235
+static
236
+void
237
+_hexToBinary (
238
+	IN const char * const szSource,
239
+	OUT unsigned char * const target,
240
+	IN OUT size_t * const target_size
241
+) {
242
+	size_t target_max_size;
243
+	const char *p;
244
+	char buf[3] = {'\0', '\0', '\0'};
245
+	int i = 0;
246
+
247
+	PKCS11ASSERT (szSource!=NULL);
248
+	PKCS11ASSERT (target!=NULL);
249
+	PKCS11ASSERT (target_size!=NULL);
250
+
251
+	target_max_size = *target_size;
252
+	p = szSource;
253
+	*target_size = 0;
254
+
255
+	while (*p != '\0' && *target_size < target_max_size) {
256
+		if (isxdigit (*p)) {
257
+			buf[i%2] = *p;
258
+
259
+			if ((i%2) == 1) {
260
+				unsigned v;
261
+				sscanf (buf, "%x", &v);
262
+				target[*target_size] = v & 0xff;
263
+				(*target_size)++;
264
+			}
265
+
266
+			i++;
267
+		}
268
+		p++;
269
+	}
270
+}
271
+
272
+static
273
+bool
274
+_isBetterCertificate (
275
+	IN const unsigned char * const pCurrent,
276
+	IN const size_t nCurrentSize,
277
+	IN const unsigned char * const pNew,
278
+	IN const size_t nNewSize
279
+) {
280
+	/*
281
+	 * This function compare the notBefore
282
+	 * and select the most recent certificate
283
+	 * it does not deal with timezones...
284
+	 * When openssl will have ASN1_TIME compare function
285
+	 * it should be used.
286
+	 */
287
+
288
+	X509 *x509Current = NULL, *x509New = NULL;
289
+	char szNotBeforeCurrent[1024], szNotBeforeNew[1024];
290
+	bool fBetter = false;
291
+
292
+	PKCS11LOG (
293
+		PKCS11_LOG_DEBUG2,
294
+		"PKCS#11: _isBetterCertificate entry pCurrent=%p, nCurrentSize=%u, pNew=%p, nNewSize=%u",
295
+		pCurrent,
296
+		nCurrentSize,
297
+		pNew,
298
+		nNewSize
299
+	);
300
+
301
+	/*
302
+	 * First certificae
303
+	 * always select
304
+	 */
305
+	if (nCurrentSize == 0) {
306
+		fBetter = true;
307
+	}
308
+	else {
309
+		PKCS11ASSERT (pCurrent!=NULL);
310
+		PKCS11ASSERT (pNew!=NULL);
311
+
312
+		szNotBeforeCurrent[0] = '\0';
313
+		szNotBeforeNew[0] = '\0';
314
+
315
+		x509Current = X509_new ();
316
+		x509New = X509_new ();
317
+
318
+		if (x509Current != NULL && x509New != NULL) {
319
+			const unsigned char *p1, *p2;
320
+
321
+			p1 = pCurrent;
322
+			p2 = pNew;
323
+			if (
324
+				d2i_X509 (&x509Current, (unsigned char **)&p1, nCurrentSize) &&
325
+				d2i_X509 (&x509New, (unsigned char **)&p2, nNewSize)
326
+			) {
327
+				ASN1_TIME *notBeforeCurrent = X509_get_notBefore (x509Current);
328
+				ASN1_TIME *notBeforeNew = X509_get_notBefore (x509New);
329
+
330
+				if (
331
+					notBeforeCurrent != NULL &&
332
+					notBeforeNew != NULL &&
333
+					notBeforeCurrent->length < (int) sizeof (szNotBeforeCurrent) - 1 &&
334
+					notBeforeNew->length < (int) sizeof (szNotBeforeNew) - 1
335
+				) {
336
+					memmove (szNotBeforeCurrent, notBeforeCurrent->data, notBeforeCurrent->length);
337
+					szNotBeforeCurrent[notBeforeCurrent->length] = '\0';
338
+					memmove (szNotBeforeNew, notBeforeNew->data, notBeforeNew->length);
339
+					szNotBeforeNew[notBeforeNew->length] = '\0';
340
+				}
341
+			}
342
+		}
343
+
344
+		if (x509Current != NULL) {
345
+			X509_free (x509Current);
346
+			x509Current = NULL;
347
+		}
348
+		if (x509New != NULL) {
349
+			X509_free (x509New);
350
+			x509New = NULL;
351
+		}
352
+
353
+		fBetter = strcmp (szNotBeforeCurrent, szNotBeforeNew) < 0;
354
+	}
355
+
356
+	PKCS11LOG (
357
+		PKCS11_LOG_DEBUG2,
358
+		"PKCS#11: _isBetterCertificate return fBetter=%d",
359
+		fBetter ? 1 : 0
360
+	);
361
+	
362
+	return fBetter;
363
+}
364
+
365
+/*========================================
366
+ * Low level PKCS#11 functions
367
+ */
368
+
369
+static
370
+CK_RV
371
+_pkcs11h_getSlotById (
372
+	IN const pkcs11h_session_t pkcs11h_session,
373
+	IN const char * const szSlot
374
+) {
375
+	pkcs11h_provider_t provider;
376
+	CK_RV rv = CKR_OK;
377
+	int provider_number;
378
+	int slot_number;
379
+	int i;
380
+
381
+	PKCS11ASSERT (pkcs11h_session!=NULL);
382
+	PKCS11ASSERT (szSlot!=NULL);
383
+
384
+	PKCS11LOG (
385
+		PKCS11_LOG_DEBUG2,
386
+		"PKCS#11: _pkcs11h_getSlotById entry pkcs11h_session=%p, szSlot=%s",
387
+		(void *)pkcs11h_session,
388
+		szSlot
389
+	);
390
+
391
+	if (rv == CKR_OK) {
392
+		if (strchr (szSlot, ':') == NULL) {
393
+			provider_number = 0;
394
+			slot_number = atoi (szSlot);
395
+		}
396
+		else {
397
+			sscanf (szSlot, "%d:%d", &provider_number, &slot_number);
398
+		}
399
+	}
400
+	
401
+	if (rv == CKR_OK) {
402
+		for (
403
+			i=0, provider=pkcs11h_data->providers;
404
+			(
405
+				i < provider_number &&
406
+				provider != NULL &&
407
+				rv == CKR_OK
408
+			);
409
+			i++, provider = provider->next
410
+		);
411
+	
412
+		if (
413
+			provider == NULL ||
414
+			(
415
+				provider != NULL &&
416
+				!provider->fEnabled
417
+			)
418
+		) {
419
+			rv = CKR_SLOT_ID_INVALID;
420
+		}
421
+	}
422
+	
423
+	if (rv == CKR_OK) {
424
+		pkcs11h_session->provider = provider;
425
+		pkcs11h_session->slot = slot_number;
426
+	
427
+		PKCS11LOG (
428
+			PKCS11_LOG_DEBUG1,
429
+			"PKCS#11: slot selected %s-%ld",
430
+			pkcs11h_session->provider->szName,
431
+			pkcs11h_session->slot
432
+		);
433
+	}
434
+
435
+	PKCS11LOG (
436
+		PKCS11_LOG_DEBUG2,
437
+		"PKCS#11: _pkcs11h_getSlotById return rv=%ld-'%s'",
438
+		rv,
439
+		pkcs11h_getMessage (rv)
440
+	);
441
+
442
+	return rv;
443
+}
444
+
445
+static
446
+CK_RV
447
+_pkcs11h_getSlotByName (
448
+	IN const pkcs11h_session_t pkcs11h_session,
449
+	IN const char * const szName
450
+) {
451
+	CK_RV rv = CKR_OK;
452
+
453
+	pkcs11h_provider_t provider;
454
+	bool fFound = false;
455
+
456
+	PKCS11ASSERT (pkcs11h_session!=NULL);
457
+	PKCS11ASSERT (szName!=NULL);
458
+
459
+	PKCS11LOG (
460
+		PKCS11_LOG_DEBUG2,
461
+		"PKCS#11: _pkcs11h_getSlotByName entry pkcs11h_session=%p, szName=%s",
462
+		(void *)pkcs11h_session,
463
+		szName
464
+	);
465
+
466
+	for (
467
+		provider = pkcs11h_data->providers;
468
+		(
469
+			provider != NULL &&
470
+			!fFound
471
+		);
472
+		provider = provider->next
473
+	) {
474
+		CK_SLOT_ID slots[1024];
475
+		CK_ULONG slotnum;
476
+
477
+		if (!provider->fEnabled) {
478
+			continue;
479
+		}
480
+
481
+		slotnum = sizeof (slots) / sizeof (CK_SLOT_ID);
482
+		if (
483
+			(rv = provider->f->C_GetSlotList (
484
+				TRUE,
485
+				slots,
486
+				&slotnum
487
+			)) == CKR_OK
488
+		) {
489
+			CK_SLOT_ID s;
490
+
491
+			for (s=0;!fFound && s<slotnum;s++) {
492
+				CK_SLOT_INFO info;
493
+
494
+				if (
495
+					(rv = provider->f->C_GetSlotInfo (
496
+						slots[s],
497
+						&info
498
+					)) == CKR_OK
499
+				) {
500
+					char szCurrentName[sizeof (info.slotDescription)+1];
501
+	
502
+					_pkcs11h_fixupFixedString (
503
+						(char *)info.slotDescription,
504
+						szCurrentName,
505
+						sizeof (info.slotDescription)
506
+					);
507
+
508
+					if (!strcmp (szCurrentName, szName)) {
509
+						fFound = true;
510
+						pkcs11h_session->provider = provider;
511
+						pkcs11h_session->slot = slots[s];
512
+					
513
+						PKCS11LOG (
514
+							PKCS11_LOG_DEBUG1,
515
+							"PKCS#11: slot selected %s-%ld",
516
+							pkcs11h_session->provider->szName,
517
+							pkcs11h_session->slot
518
+						);
519
+					}
520
+				}
521
+			}
522
+		}
523
+	}
524
+
525
+	PKCS11LOG (
526
+		PKCS11_LOG_DEBUG2,
527
+		"PKCS#11: _pkcs11h_getSlotByName return fFound=%d-'%s'",
528
+		fFound ? 1 : 0,
529
+		pkcs11h_getMessage (rv)
530
+	);
531
+
532
+	return fFound ? CKR_OK : CKR_SLOT_ID_INVALID;
533
+}
534
+
535
+static
536
+CK_RV
537
+_pkcs11h_getSlotByLabel (
538
+	IN const pkcs11h_session_t pkcs11h_session,
539
+	IN const char * const szLabel
540
+) {
541
+	CK_RV rv;
542
+
543
+	pkcs11h_provider_t provider;
544
+	bool fFound = false;
545
+
546
+	PKCS11ASSERT (pkcs11h_session!=NULL);
547
+	PKCS11ASSERT (szLabel!=NULL);
548
+
549
+	PKCS11LOG (
550
+		PKCS11_LOG_DEBUG2,
551
+		"_PKCS#11: pkcs11h_getSlotByLabel entry pkcs11h_session=%p, szName=%s",
552
+		(void *)pkcs11h_session,
553
+		szLabel
554
+	);
555
+
556
+	for (
557
+		provider = pkcs11h_data->providers;
558
+		(
559
+			provider != NULL &&
560
+			!fFound
561
+		);
562
+		provider = provider->next
563
+	) {
564
+		CK_SLOT_ID slots[1024];
565
+		CK_ULONG slotnum;
566
+
567
+		if (!provider->fEnabled) {
568
+			continue;
569
+		}
570
+
571
+		slotnum = sizeof (slots) / sizeof (CK_SLOT_ID);
572
+		if (
573
+			(rv = provider->f->C_GetSlotList (
574
+				TRUE,
575
+				slots,
576
+				&slotnum
577
+			)) == CKR_OK
578
+		) {
579
+			CK_SLOT_ID s;
580
+
581
+			for (s=0;!fFound && s<slotnum;s++) {
582
+				CK_TOKEN_INFO info;
583
+
584
+				if (
585
+					(rv = provider->f->C_GetTokenInfo (
586
+						slots[s],
587
+						&info
588
+					)) == CKR_OK
589
+				) {
590
+					char szCurrentLabel[sizeof (info.label)+1];
591
+			
592
+					_pkcs11h_fixupFixedString (
593
+						(char *)info.label,
594
+						szCurrentLabel,
595
+						sizeof (info.label)
596
+					);
597
+
598
+					if (!strcmp (szCurrentLabel, szLabel)) {
599
+						fFound = true;
600
+						pkcs11h_session->provider = provider;
601
+						pkcs11h_session->slot = slots[s];
602
+					
603
+						PKCS11LOG (
604
+							PKCS11_LOG_DEBUG1,
605
+							"PKCS#11: slot selected %s-%ld",
606
+							pkcs11h_session->provider->szName,
607
+							pkcs11h_session->slot
608
+						);
609
+					}
610
+				}
611
+			}
612
+		}
613
+	}
614
+
615
+	PKCS11LOG (
616
+		PKCS11_LOG_DEBUG2,
617
+		"PKCS#11: _pkcs11h_getSlotByLabel return fFound=%d",
618
+		fFound ? 1 : 0
619
+	);
620
+
621
+	return fFound ? CKR_OK : CKR_SLOT_ID_INVALID;
622
+}
623
+
624
+static
625
+CK_RV
626
+_pkcs11h_setSessionTokenInfo (
627
+	IN const pkcs11h_session_t pkcs11h_session
628
+) {
629
+	CK_TOKEN_INFO info;
630
+	CK_RV rv;
631
+
632
+	PKCS11ASSERT (pkcs11h_session!=NULL);
633
+
634
+	PKCS11LOG (
635
+		PKCS11_LOG_DEBUG2,
636
+		"PKCS#11: _pkcs11h_setSessionTokenInfo entry pkcs11h_session=%p",
637
+		(void *)pkcs11h_session
638
+	);
639
+
640
+	if (
641
+		(rv = pkcs11h_session->provider->f->C_GetTokenInfo (
642
+			pkcs11h_session->slot,
643
+			&info
644
+		)) == CKR_OK
645
+	) {
646
+		_pkcs11h_fixupFixedString (
647
+			(char *)info.label,
648
+			pkcs11h_session->szLabel,
649
+			sizeof (info.label)
650
+		);
651
+		
652
+		memmove (
653
+			pkcs11h_session->serialNumber,
654
+			info.serialNumber,
655
+			sizeof (pkcs11h_session->serialNumber)
656
+		);
657
+	}
658
+
659
+	PKCS11LOG (
660
+		PKCS11_LOG_DEBUG2,
661
+		"PKCS#11: _pkcs11h_setSessionTokenInfo return rv=%ld-'%s'",
662
+		rv,
663
+		pkcs11h_getMessage (rv)
664
+	);
665
+
666
+	return rv;
667
+}
668
+
669
+static
670
+CK_RV
671
+_pkcs11h_resetSlot (
672
+	IN const pkcs11h_session_t pkcs11h_session
673
+) {
674
+	CK_SLOT_ID slots[1024];
675
+	CK_ULONG slotnum;
676
+	CK_RV rv;
677
+	bool fFound = false;
678
+	bool fCancel = false;
679
+
680
+	PKCS11ASSERT (pkcs11h_session!=NULL);
681
+
682
+	PKCS11LOG (
683
+		PKCS11_LOG_DEBUG2,
684
+		"PKCS#11: _pkcs11h_resetSlot entry pkcs11h_session=%p",
685
+		(void *)pkcs11h_session
686
+	);
687
+
688
+	do {
689
+		slotnum = sizeof (slots) / sizeof (CK_SLOT_ID);
690
+		if (
691
+			(rv = pkcs11h_session->provider->f->C_GetSlotList (
692
+				TRUE,
693
+				slots,
694
+				&slotnum
695
+			)) == CKR_OK
696
+		) {
697
+			CK_SLOT_ID s;
698
+
699
+			for (s=0;!fFound && s<slotnum;s++) {
700
+				CK_TOKEN_INFO info;
701
+
702
+				if (
703
+					(rv = pkcs11h_session->provider->f->C_GetTokenInfo (
704
+						slots[s],
705
+						&info
706
+					)) == CKR_OK
707
+				) {
708
+					if (
709
+						!memcmp (
710
+							pkcs11h_session->serialNumber,
711
+							info.serialNumber,
712
+							sizeof (pkcs11h_session->serialNumber)
713
+						)
714
+					) {
715
+						pkcs11h_session->slot = slots[s];
716
+						fFound = true;
717
+					}
718
+				}
719
+			}
720
+		}
721
+
722
+		if (!fFound) {
723
+			fCancel = !pkcs11h_data->hooks->card_prompt (
724
+				pkcs11h_data->hooks->card_prompt_data,
725
+				pkcs11h_session->szLabel
726
+			);
727
+		}
728
+	} while (!fFound && !fCancel);
729
+
730
+	PKCS11LOG (
731
+		PKCS11_LOG_DEBUG2,
732
+		"PKCS#11: _pkcs11h_resetSlot return fFound=%d",
733
+		fFound ? 1 : 0
734
+	);
735
+
736
+	return fFound ? CKR_OK : CKR_SLOT_ID_INVALID;
737
+}
738
+
739
+static
740
+CK_RV
741
+_pkcs11h_getObjectById (
742
+	IN const pkcs11h_session_t pkcs11h_session,
743
+	IN const CK_OBJECT_CLASS class,
744
+	IN const unsigned char * const id,
745
+	IN const size_t id_size,
746
+	OUT CK_OBJECT_HANDLE * const handle
747
+) {
748
+	CK_ULONG count;
749
+	CK_RV rv = CKR_OK;
750
+
751
+	CK_ATTRIBUTE filter[] = {
752
+		{CKA_CLASS, (void *)&class, sizeof (class)},
753
+		{CKA_ID, (void *)id, id_size}
754
+	};
755
+	
756
+	PKCS11ASSERT (pkcs11h_session!=NULL);
757
+	PKCS11ASSERT (id!=NULL);
758
+	PKCS11ASSERT (handle!=NULL);
759
+
760
+	PKCS11LOG (
761
+		PKCS11_LOG_DEBUG2,
762
+		"PKCS#11: _pkcs11h_getObjectById entry pkcs11h_session=%p, class=%ld, id=%p, id_size=%u, handle=%p",
763
+		(void *)pkcs11h_session,
764
+		class,
765
+		id,
766
+		id_size,
767
+		(void *)handle
768
+	);
769
+
770
+	if (rv == CKR_OK) {
771
+		rv = pkcs11h_session->provider->f->C_FindObjectsInit (
772
+			pkcs11h_session->session,
773
+			filter,
774
+			sizeof (filter) / sizeof (CK_ATTRIBUTE)
775
+		);
776
+	}
777
+
778
+	if (rv == CKR_OK) {
779
+		rv = pkcs11h_session->provider->f->C_FindObjects (
780
+			pkcs11h_session->session,
781
+			handle,
782
+			1,
783
+			&count
784
+		);
785
+	}
786
+
787
+	if (
788
+		rv == CKR_OK &&
789
+		count == 0
790
+	) {
791
+		rv = CKR_FUNCTION_REJECTED;
792
+	}
793
+
794
+	pkcs11h_session->provider->f->C_FindObjectsFinal (
795
+		pkcs11h_session->session
796
+	);
797
+
798
+	PKCS11LOG (
799
+		PKCS11_LOG_DEBUG2,
800
+		"PKCS#11: _pkcs11h_getObjectById return rv=%ld-'%s'",
801
+		rv,
802
+		pkcs11h_getMessage (rv)
803
+	);
804
+
805
+	return rv;
806
+}
807
+
808
+static
809
+CK_RV
810
+_pkcs11h_loadCertificate (
811
+	IN const pkcs11h_session_t pkcs11h_session,
812
+	IN const char * const szIdType,
813
+	IN const char * const szId
814
+) {
815
+	CK_OBJECT_HANDLE objects[10];
816
+	CK_ULONG objects_found;
817
+	CK_RV rv = CKR_OK;
818
+
819
+	unsigned char selected_id[PKCS11H_MAX_ATTRIBUTE_SIZE];
820
+	int selected_id_size = 0;
821
+	unsigned char selected_certificate[PKCS11H_MAX_ATTRIBUTE_SIZE];
822
+	int selected_certificate_size = 0;
823
+
824
+	CK_OBJECT_CLASS cert_filter_class = CKO_CERTIFICATE;
825
+	unsigned char cert_filter_by[PKCS11H_MAX_ATTRIBUTE_SIZE];
826
+	CK_ATTRIBUTE cert_filter[] = {
827
+		{CKA_CLASS, &cert_filter_class, sizeof (cert_filter_class)},
828
+		{0, cert_filter_by, 0}
829
+	};
830
+
831
+	PKCS11ASSERT (pkcs11h_session!=NULL);
832
+	PKCS11ASSERT (szIdType!=NULL);
833
+	PKCS11ASSERT (szId!=NULL);
834
+
835
+	PKCS11LOG (
836
+		PKCS11_LOG_DEBUG2,
837
+		"PKCS#11: _pkcs11h_loadCertificate entry pkcs11h_session=%p, szIdType=%s, szId=%s",
838
+		(void *)pkcs11h_session,
839
+		szIdType,
840
+		szId
841
+	);
842
+
843
+	if (rv == CKR_OK) {
844
+		if (!strcmp (szIdType, "label")) {
845
+			cert_filter[1].type = CKA_LABEL;
846
+			cert_filter[1].ulValueLen = (CK_ULONG)(
847
+				strlen (szId) < sizeof (cert_filter_by)  ?
848
+				strlen (szId) :
849
+				sizeof (cert_filter_by)
850
+			);
851
+			memmove (
852
+				cert_filter_by,
853
+				szId,
854
+				cert_filter[1].ulValueLen
855
+			);
856
+		}
857
+		else if (!strcmp (szIdType, "id")) {
858
+			size_t s = sizeof (cert_filter_by);
859
+	
860
+			cert_filter[1].type = CKA_ID;
861
+			_hexToBinary (
862
+				szId,
863
+				cert_filter_by,
864
+				&s
865
+			);
866
+			cert_filter[1].ulValueLen = s;
867
+		}
868
+		else if (!strcmp (szIdType, "subject")) {
869
+			memmove (&cert_filter[1], &cert_filter[0], sizeof (CK_ATTRIBUTE));
870
+		}
871
+		else {
872
+			rv = CKR_ARGUMENTS_BAD;
873
+		}
874
+	}
875
+	
876
+	if (rv == CKR_OK) {
877
+		rv = pkcs11h_session->provider->f->C_FindObjectsInit (
878
+			pkcs11h_session->session,
879
+			cert_filter,
880
+			sizeof (cert_filter) / sizeof (CK_ATTRIBUTE)
881
+		);
882
+	}
883
+
884
+	if (rv == CKR_OK) {
885
+		while (
886
+			(rv = pkcs11h_session->provider->f->C_FindObjects (
887
+				pkcs11h_session->session,
888
+				objects,
889
+				sizeof (objects) / sizeof (CK_OBJECT_HANDLE),
890
+				&objects_found
891
+			)) == CKR_OK &&
892
+			objects_found > 0
893
+		) { 
894
+			CK_ULONG i;
895
+			
896
+			for (i=0;i<objects_found;i++) {
897
+				unsigned char attrs_id[PKCS11H_MAX_ATTRIBUTE_SIZE];
898
+				unsigned char attrs_value[PKCS11H_MAX_ATTRIBUTE_SIZE];
899
+				CK_ATTRIBUTE attrs[] = {
900
+					{CKA_ID, attrs_id, sizeof (attrs_id)},
901
+					{CKA_VALUE, attrs_value, sizeof (attrs_value)}
902
+				};
903
+		
904
+				if (
905
+					pkcs11h_session->provider->f->C_GetAttributeValue (
906
+						pkcs11h_session->session,
907
+						objects[i],
908
+						attrs,
909
+						sizeof (attrs) / sizeof (CK_ATTRIBUTE)
910
+					) == CKR_OK
911
+				) {
912
+					bool fSelected = false;
913
+	
914
+					if (!strcmp (szIdType, "subject")) {
915
+						X509 *x509 = NULL;
916
+						char szSubject[1024];
917
+						unsigned char *p;
918
+	
919
+						x509 = X509_new ();
920
+	
921
+						p = attrs_value;
922
+						if (d2i_X509 (&x509, &p, attrs[1].ulValueLen)) {
923
+							X509_NAME_oneline (
924
+								X509_get_subject_name (x509),
925
+								szSubject,
926
+								sizeof (szSubject)
927
+							);
928
+							szSubject[sizeof (szSubject) - 1] = '\0';
929
+						}
930
+	
931
+						if (x509 != NULL) {
932
+							X509_free (x509);
933
+							x509 = NULL;
934
+						}
935
+	
936
+						if (!strcmp (szId, szSubject)) {
937
+							fSelected = true;
938
+						}
939
+					}
940
+					else {
941
+						fSelected = true;
942
+					}
943
+	
944
+					if (
945
+						fSelected &&
946
+						_isBetterCertificate (
947
+							selected_certificate,
948
+							selected_certificate_size,
949
+							attrs_value,
950
+							attrs[1].ulValueLen
951
+						)
952
+					) {
953
+						selected_certificate_size = attrs[1].ulValueLen;
954
+						memmove (
955
+							selected_certificate,
956
+							attrs_value,
957
+							selected_certificate_size
958
+						);
959
+						selected_id_size = attrs[0].ulValueLen;
960
+						memmove (
961
+							selected_id,
962
+							attrs_id,
963
+							selected_id_size
964
+						);
965
+					}
966
+				}
967
+			}
968
+		}
969
+	
970
+		pkcs11h_session->provider->f->C_FindObjectsFinal (
971
+			pkcs11h_session->session
972
+		);
973
+		rv = CKR_OK;
974
+	}
975
+
976
+	if (
977
+		rv == CKR_OK &&
978
+		selected_certificate_size == 0
979
+	) {
980
+		rv = CKR_ATTRIBUTE_VALUE_INVALID;
981
+	}
982
+
983
+	if (
984
+		rv == CKR_OK &&
985
+		(pkcs11h_session->certificate = (unsigned char *)malloc (selected_certificate_size)) == NULL
986
+	) {
987
+		rv = CKR_HOST_MEMORY;
988
+	}
989
+	
990
+	if (rv == CKR_OK) {
991
+		pkcs11h_session->certificate_size = selected_certificate_size;
992
+		memmove (
993
+			pkcs11h_session->certificate,
994
+			selected_certificate,
995
+			selected_certificate_size
996
+		);
997
+	}
998
+	
999
+	if (
1000
+		rv == CKR_OK &&
1001
+		(pkcs11h_session->certificate_id = (unsigned char *)malloc (selected_id_size)) == NULL
1002
+	) {
1003
+		rv = CKR_HOST_MEMORY;
1004
+	}
1005
+	
1006
+	if (rv == CKR_OK) {
1007
+		pkcs11h_session->certificate_id_size = selected_id_size;
1008
+		memmove (
1009
+			pkcs11h_session->certificate_id,
1010
+			selected_id,
1011
+			selected_id_size
1012
+		);
1013
+	}
1014
+	
1015
+	PKCS11LOG (
1016
+		PKCS11_LOG_DEBUG2,
1017
+		"PKCS#11: _pkcs11h_loadCertificate return rv=%ld-'%s'",
1018
+		rv,
1019
+		pkcs11h_getMessage (rv)
1020
+	);
1021
+
1022
+	return rv;
1023
+}
1024
+
1025
+static
1026
+CK_RV
1027
+_pkcs11h_loadKeyProperties (
1028
+	IN const pkcs11h_session_t pkcs11h_session
1029
+) {
1030
+	CK_OBJECT_HANDLE key;
1031
+	CK_RV rv = CKR_OK;
1032
+
1033
+	CK_BBOOL key_attrs_sign_recover;
1034
+	CK_BBOOL key_attrs_sign;
1035
+	CK_ATTRIBUTE key_attrs[] = {
1036
+		{CKA_SIGN, &key_attrs_sign_recover, sizeof (key_attrs_sign_recover)},
1037
+		{CKA_SIGN_RECOVER, &key_attrs_sign, sizeof (key_attrs_sign)}
1038
+	};
1039
+
1040
+	PKCS11ASSERT (pkcs11h_session!=NULL);
1041
+
1042
+	PKCS11LOG (
1043
+		PKCS11_LOG_DEBUG2,
1044
+		"PKCS#11: _pkcs11h_loadKeyProperties entry pkcs11h_session=%p",
1045
+		(void *)pkcs11h_session
1046
+	);
1047
+
1048
+	if (!strcmp (pkcs11h_session->provider->szSignMode, "recover")) {
1049
+		pkcs11h_session->fKeySignRecover = true;
1050
+	}
1051
+	else if (!strcmp (pkcs11h_session->provider->szSignMode, "sign")) {
1052
+		pkcs11h_session->fKeySignRecover = false;
1053
+	}
1054
+	else {
1055
+		if (rv == CKR_OK) {
1056
+			rv = _pkcs11h_getObjectById (
1057
+				pkcs11h_session,
1058
+				CKO_PRIVATE_KEY,
1059
+				pkcs11h_session->certificate_id,
1060
+				pkcs11h_session->certificate_id_size,
1061
+				&key
1062
+			);
1063
+		}
1064
+
1065
+		if (rv == CKR_OK) {
1066
+			rv = pkcs11h_session->provider->f->C_GetAttributeValue (
1067
+				pkcs11h_session->session,
1068
+				key,
1069
+				key_attrs,
1070
+				sizeof (key_attrs) / sizeof (CK_ATTRIBUTE)
1071
+			);
1072
+		}
1073
+		
1074
+		if (rv == CKR_OK) {
1075
+			if (key_attrs_sign_recover != CK_FALSE) {
1076
+				pkcs11h_session->fKeySignRecover = true;
1077
+			}
1078
+			else if (key_attrs_sign != CK_FALSE) {
1079
+				pkcs11h_session->fKeySignRecover = false;
1080
+			}
1081
+			else {
1082
+				rv = CKR_KEY_TYPE_INCONSISTENT;
1083
+			}
1084
+		}
1085
+	}
1086
+	
1087
+	PKCS11LOG (
1088
+		PKCS11_LOG_DEBUG2,
1089
+		"PKCS#11: _pkcs11h_loadKeyProperties return rv=%ld-'%s'",
1090
+		rv,
1091
+		pkcs11h_getMessage (rv)
1092
+	);
1093
+
1094
+	return rv;
1095
+}
1096
+
1097
+static
1098
+CK_RV
1099
+_pkcs11h_validateSession (
1100
+	IN const pkcs11h_session_t pkcs11h_session
1101
+) {
1102
+	PKCS11LOG (
1103
+		PKCS11_LOG_DEBUG2,
1104
+		"PKCS#11: _pkcs11h_validateSession entry pkcs11h_session=%p",
1105
+		(void *)pkcs11h_session
1106
+	);
1107
+
1108
+	if (
1109
+		pkcs11h_session->timePINExpire != (time_t)0 &&
1110
+		pkcs11h_session->timePINExpire < time (NULL)
1111
+	) {
1112
+		_pkcs11h_logout (pkcs11h_session);
1113
+	}
1114
+
1115
+	PKCS11LOG (
1116
+		PKCS11_LOG_DEBUG2,
1117
+		"PKCS#11: _pkcs11h_validateSession return"
1118
+	);
1119
+
1120
+	return CKR_OK;
1121
+}
1122
+
1123
+static
1124
+CK_RV
1125
+_pkcs11h_login (
1126
+	IN const pkcs11h_session_t pkcs11h_session
1127
+) {
1128
+	CK_RV rv = CKR_OK;
1129
+
1130
+
1131
+	PKCS11ASSERT (pkcs11h_session!=NULL);
1132
+
1133
+	PKCS11LOG (
1134
+		PKCS11_LOG_DEBUG2,
1135
+		"PKCS#11: _pkcs11h_login entry pkcs11h_session=%p",
1136
+		(void *)pkcs11h_session
1137
+	);
1138
+
1139
+	_pkcs11h_logout (pkcs11h_session);
1140
+
1141
+	if (rv == CKR_OK) {
1142
+		rv = _pkcs11h_resetSlot (pkcs11h_session);
1143
+	}
1144
+
1145
+	if (rv == CKR_OK) {
1146
+		rv = pkcs11h_session->provider->f->C_OpenSession (
1147
+			pkcs11h_session->slot,
1148
+			CKF_SERIAL_SESSION,
1149
+			NULL_PTR,
1150
+			NULL_PTR,
1151
+			&pkcs11h_session->session
1152
+		);
1153
+	}
1154
+
1155
+	if (rv == CKR_OK) {
1156
+		int nRetryCount = 0;
1157
+		do {
1158
+			CK_UTF8CHAR_PTR utfPIN = NULL;
1159
+			CK_ULONG lPINLength = 0;
1160
+			char szPIN[1024];
1161
+
1162
+			/*
1163
+			 * Assume OK for next iteration
1164
+			 */
1165
+			rv = CKR_OK;
1166
+
1167
+			if (
1168
+				rv == CKR_OK &&
1169
+				!pkcs11h_session->fProtectedAuthentication
1170
+			) {
1171
+				if (
1172
+					!pkcs11h_data->hooks->pin_prompt (
1173
+						pkcs11h_data->hooks->pin_prompt_data,
1174
+						pkcs11h_session->szLabel,
1175
+						szPIN,
1176
+						sizeof (szPIN)
1177
+					)
1178
+				) {
1179
+					rv = CKR_FUNCTION_FAILED;
1180
+				}
1181
+				else {
1182
+					utfPIN = (CK_UTF8CHAR_PTR)szPIN;
1183
+					lPINLength = strlen (szPIN);
1184
+				}
1185
+			}
1186
+
1187
+			if (pkcs11h_data->nPINCachePeriod == -1) {
1188
+				pkcs11h_session->timePINExpire = 0;
1189
+			}
1190
+			else {
1191
+				pkcs11h_session->timePINExpire = (
1192
+					time (NULL) +
1193
+					(time_t)pkcs11h_data->nPINCachePeriod
1194
+				);
1195
+			}
1196
+			if (
1197
+				rv == CKR_OK &&
1198
+				(rv = pkcs11h_session->provider->f->C_Login (
1199
+					pkcs11h_session->session,
1200
+					CKU_USER,
1201
+					utfPIN,
1202
+					lPINLength
1203
+				)) != CKR_OK
1204
+			) {
1205
+				if (rv == CKR_USER_ALREADY_LOGGED_IN) {
1206
+					rv = CKR_OK;
1207
+				}
1208
+			}
1209
+
1210
+			/*
1211
+			 * Clean PIN buffer
1212
+			 */
1213
+			memset (szPIN, 0, sizeof (szPIN));
1214
+		} while (
1215
+			++nRetryCount < 3 &&
1216
+			(
1217
+				rv == CKR_PIN_INCORRECT ||
1218
+				rv == CKR_PIN_INVALID
1219
+			)
1220
+		);
1221
+	}
1222
+
1223
+	if (
1224
+		rv == CKR_OK &&
1225
+		pkcs11h_session->certificate_id != NULL
1226
+	) {
1227
+		rv = _pkcs11h_getObjectById (
1228
+			pkcs11h_session,
1229
+			CKO_PRIVATE_KEY,
1230
+			pkcs11h_session->certificate_id,
1231
+			pkcs11h_session->certificate_id_size,
1232
+			&pkcs11h_session->key
1233
+		);
1234
+	}
1235
+
1236
+	PKCS11LOG (
1237
+		PKCS11_LOG_DEBUG2,
1238
+		"PKCS#11: _pkcs11h_login return rv=%ld-'%s'",
1239
+		rv,
1240
+		pkcs11h_getMessage (rv)
1241
+	);
1242
+
1243
+	return rv;
1244
+}
1245
+
1246
+static
1247
+CK_RV
1248
+_pkcs11h_logout (
1249
+	IN const pkcs11h_session_t pkcs11h_session
1250
+) {
1251
+	PKCS11ASSERT (pkcs11h_session!=NULL);
1252
+
1253
+	PKCS11LOG (
1254
+		PKCS11_LOG_DEBUG2,
1255
+		"PKCS#11: _pkcs11h_logout entry pkcs11h_session=%p",
1256
+		(void *)pkcs11h_session
1257
+	);
1258
+
1259
+	if (pkcs11h_session->session != (CK_SESSION_HANDLE)-1) {
1260
+		pkcs11h_session->provider->f->C_Logout (pkcs11h_session->session);
1261
+		pkcs11h_session->provider->f->C_CloseSession (pkcs11h_session->session);
1262
+		pkcs11h_session->key = (CK_OBJECT_HANDLE)-1;
1263
+		pkcs11h_session->session = (CK_SESSION_HANDLE)-1;
1264
+	}
1265
+
1266
+	PKCS11LOG (
1267
+		PKCS11_LOG_DEBUG2,
1268
+		"PKCS#11: _pkcs11h_logout return"
1269
+	);
1270
+
1271
+	return CKR_OK;
1272
+}
1273
+
1274
+
1275
+/*=======================================
1276
+ * Simplified PKCS#11 functions
1277
+ */
1278
+
1279
+static
1280
+bool
1281
+_pkcs11h_hooks_card_prompt_default (
1282
+	IN const void * pData,
1283
+	IN const char * const szLabel
1284
+) {
1285
+	PKCS11LOG (
1286
+		PKCS11_LOG_DEBUG2,
1287
+		"PKCS#11: _pkcs11h_hooks_card_prompt_default pData=%p, szLabel=%s",
1288
+		pData,
1289
+		szLabel
1290
+	);
1291
+
1292
+	return false;
1293
+}
1294
+
1295
+static
1296
+bool
1297
+_pkcs11h_hooks_pin_prompt_default (
1298
+	IN const void * pData,
1299
+	IN const char * const szLabel,
1300
+	OUT char * const szPIN,
1301
+	IN const size_t nMaxPIN
1302
+) {
1303
+	PKCS11LOG (
1304
+		PKCS11_LOG_DEBUG2,
1305
+		"PKCS#11: _pkcs11h_hooks_pin_prompt_default pData=%p, szLabel=%s",
1306
+		pData,
1307
+		szLabel
1308
+	);
1309
+	
1310
+	return false;
1311
+}
1312
+
1313
+CK_RV
1314
+pkcs11h_initialize () {
1315
+
1316
+	CK_RV rv = CKR_OK;
1317
+
1318
+	PKCS11LOG (
1319
+		PKCS11_LOG_DEBUG2,
1320
+		"PKCS#11: pkcs11h_initialize entry"
1321
+	);
1322
+
1323
+	pkcs11h_terminate ();
1324
+
1325
+	if (
1326
+		rv == CKR_OK &&
1327
+		(pkcs11h_data = (pkcs11h_data_t)malloc (sizeof (struct pkcs11h_data_s))) == NULL
1328
+	) {
1329
+		rv = CKR_HOST_MEMORY;
1330
+	}
1331
+
1332
+	if (rv == CKR_OK) {
1333
+		memset (pkcs11h_data, 0, sizeof (struct pkcs11h_data_s));
1334
+	}
1335
+	
1336
+	if (
1337
+		rv == CKR_OK &&
1338
+		(pkcs11h_data->hooks = (pkcs11h_hooks_t)malloc (sizeof (struct pkcs11h_hooks_s))) == NULL
1339
+	) {
1340
+		rv = CKR_HOST_MEMORY;
1341
+	}
1342
+
1343
+	if (rv == CKR_OK) {
1344
+		memset (pkcs11h_data->hooks, 0, sizeof (struct pkcs11h_hooks_s));
1345
+	
1346
+		pkcs11h_data->fInitialized = true;
1347
+		pkcs11h_data->nPINCachePeriod = -1;
1348
+	
1349
+		pkcs11h_setCardPromptHook (_pkcs11h_hooks_card_prompt_default, NULL);
1350
+		pkcs11h_setPINPromptHook (_pkcs11h_hooks_pin_prompt_default, NULL);
1351
+	}
1352
+	
1353
+	PKCS11LOG (
1354
+		PKCS11_LOG_DEBUG2,
1355
+		"PKCS#11: pkcs11h_initialize return rv=%ld-'%s'",
1356
+		rv,
1357
+		pkcs11h_getMessage (rv)
1358
+	);
1359
+
1360
+	return rv;
1361
+}
1362
+
1363
+CK_RV
1364
+pkcs11h_terminate () {
1365
+
1366
+	PKCS11LOG (
1367
+		PKCS11_LOG_DEBUG2,
1368
+		"PKCS#11: pkcs11h_terminate entry"
1369
+	);
1370
+
1371
+	if (pkcs11h_data != NULL) {
1372
+		pkcs11h_provider_t last = NULL;
1373
+
1374
+		for (
1375
+			;
1376
+			pkcs11h_data->providers != NULL;
1377
+			pkcs11h_data->providers = pkcs11h_data->providers->next
1378
+		) {
1379
+			if (last != NULL) {
1380
+				free (last);
1381
+			}
1382
+			last = pkcs11h_data->providers;
1383
+		
1384
+			if (pkcs11h_data->providers->szSignMode != NULL) {
1385
+				free (pkcs11h_data->providers->szSignMode);
1386
+				pkcs11h_data->providers->szSignMode = NULL;
1387
+			}
1388
+	
1389
+			if (pkcs11h_data->providers->fShouldFinalize) {
1390
+				pkcs11h_data->providers->f->C_Finalize (NULL);
1391
+				pkcs11h_data->providers->fShouldFinalize = false;
1392
+			}
1393
+
1394
+			if (pkcs11h_data->providers->f != NULL) {
1395
+				pkcs11h_data->providers->f = NULL;
1396
+			}
1397
+	
1398
+			if (pkcs11h_data->providers->hLibrary != NULL) {
1399
+#if defined(WIN32)
1400
+				FreeLibrary (pkcs11h_data->providers->hLibrary);
1401
+#else
1402
+				dlclose (pkcs11h_data->providers->hLibrary);
1403
+#endif
1404
+				pkcs11h_data->providers->hLibrary = NULL;
1405
+			}
1406
+		}
1407
+
1408
+		if (last != NULL) {
1409
+			free (last);
1410
+		}
1411
+
1412
+		if (pkcs11h_data->hooks != NULL) {
1413
+			free (pkcs11h_data->hooks);
1414
+			pkcs11h_data->hooks = NULL;
1415
+		}
1416
+
1417
+		free (pkcs11h_data);
1418
+		pkcs11h_data = NULL;
1419
+	}
1420
+
1421
+	PKCS11LOG (
1422
+		PKCS11_LOG_DEBUG2,
1423
+		"PKCS#11: pkcs11h_terminate return"
1424
+	);
1425
+
1426
+	return CKR_OK;
1427
+}
1428
+
1429
+CK_RV
1430
+pkcs11h_setPINPromptHook (
1431
+	IN const pkcs11h_hook_pin_prompt_t hook,
1432
+	IN void * const pData
1433
+) {
1434
+	PKCS11ASSERT (pkcs11h_data!=NULL);
1435
+	PKCS11ASSERT (pkcs11h_data->fInitialized);
1436
+
1437
+	pkcs11h_data->hooks->pin_prompt = hook;
1438
+	pkcs11h_data->hooks->pin_prompt_data = pData;
1439
+
1440
+	return CKR_OK;
1441
+}
1442
+
1443
+CK_RV
1444
+pkcs11h_setCardPromptHook (
1445
+	IN const pkcs11h_hook_card_prompt_t hook,
1446
+	IN void * const pData
1447
+) {
1448
+	PKCS11ASSERT (pkcs11h_data!=NULL);
1449
+	PKCS11ASSERT (pkcs11h_data->fInitialized);
1450
+
1451
+	pkcs11h_data->hooks->card_prompt = hook;
1452
+	pkcs11h_data->hooks->card_prompt_data = pData;
1453
+
1454
+	return CKR_OK;
1455
+}
1456
+
1457
+CK_RV
1458
+pkcs11h_setPINCachePeriod (
1459
+	IN const int nPINCachePeriod
1460
+) {
1461
+	PKCS11ASSERT (pkcs11h_data!=NULL);
1462
+	PKCS11ASSERT (pkcs11h_data->fInitialized);
1463
+
1464
+	pkcs11h_data->nPINCachePeriod = nPINCachePeriod;
1465
+
1466
+	return CKR_OK;
1467
+}
1468
+
1469
+CK_RV
1470
+pkcs11h_addProvider (
1471
+	IN const char * const szProvider,
1472
+	IN const char * const szSignMode
1473
+) {
1474
+	pkcs11h_provider_t provider = NULL;
1475
+	CK_C_GetFunctionList gfl = NULL;
1476
+	CK_RV rv = CKR_OK;
1477
+
1478
+	PKCS11ASSERT (pkcs11h_data!=NULL);
1479
+	PKCS11ASSERT (pkcs11h_data->fInitialized);
1480
+	PKCS11ASSERT (szProvider!=NULL);
1481
+
1482
+	PKCS11LOG (
1483
+		PKCS11_LOG_DEBUG2,
1484
+		"PKCS#11: pkcs11h_addProvider entry pid=%d, szProvider=%s, szSignMode=%s",
1485
+#if defined(WIN32)
1486
+		0,
1487
+#else
1488
+		getpid (),
1489
+#endif		
1490
+		szProvider,
1491
+		szSignMode
1492
+	);
1493
+
1494
+	if (
1495
+		rv == CKR_OK &&
1496
+		(provider = (pkcs11h_provider_t)malloc (sizeof (struct pkcs11h_provider_s))) == NULL
1497
+	) {
1498
+		rv = CKR_HOST_MEMORY;
1499
+	}
1500
+
1501
+	if (rv == CKR_OK) {
1502
+		memset (provider, 0, sizeof (struct pkcs11h_provider_s));
1503
+		provider->szName = strdup (szProvider);
1504
+		
1505
+		if (szSignMode == NULL) {
1506
+			provider->szSignMode = strdup ("auto");
1507
+		}
1508
+		else {
1509
+			provider->szSignMode = strdup (szSignMode);
1510
+		}
1511
+		if (provider->szSignMode == NULL) {
1512
+			rv = CKR_HOST_MEMORY;
1513
+		}
1514
+	}
1515
+		
1516
+	if (rv == CKR_OK) {
1517
+#if defined(WIN32)
1518
+		provider->hLibrary = LoadLibrary (szProvider);
1519
+#else
1520
+		provider->hLibrary = dlopen (szProvider, RTLD_NOW);
1521
+#endif
1522
+		if (provider->hLibrary == NULL) {
1523
+			rv = CKR_FUNCTION_FAILED;
1524
+		}
1525
+	}
1526
+
1527
+	if (rv == CKR_OK) {
1528
+#if defined(WIN32)
1529
+		gfl = (CK_C_GetFunctionList)GetProcAddress (
1530
+			provider->hLibrary,
1531
+			"C_GetFunctionList"
1532
+		);
1533
+#else
1534
+		/*
1535
+		 * Make compiler happy!
1536
+		 */
1537
+		void *p = dlsym (
1538
+			provider->hLibrary,
1539
+			"C_GetFunctionList"
1540
+		);
1541
+		memmove (
1542
+			&gfl, 
1543
+			&p,
1544
+			sizeof (void *)
1545
+		);
1546
+#endif
1547
+		if (gfl == NULL) {
1548
+			rv = CKR_FUNCTION_FAILED;
1549
+		}
1550
+	}
1551
+
1552
+	if (rv == CKR_OK) {
1553
+		rv = gfl (&provider->f);
1554
+	}
1555
+
1556
+	if (rv == CKR_OK) {
1557
+		if ((rv = provider->f->C_Initialize (NULL)) != CKR_OK) {
1558
+			if (rv == CKR_CRYPTOKI_ALREADY_INITIALIZED) {
1559
+				rv = CKR_OK;
1560
+			}
1561
+		}
1562
+		else {
1563
+			provider->fShouldFinalize = true;
1564
+		}
1565
+	}
1566
+
1567
+	if (rv == CKR_OK) {
1568
+		provider->fEnabled = true;
1569
+	}
1570
+
1571
+	if (provider != NULL) {
1572
+		if (pkcs11h_data->providers == NULL) {
1573
+			pkcs11h_data->providers = provider;
1574
+		}
1575
+		else {
1576
+			pkcs11h_provider_t last = NULL;
1577
+	
1578
+			for (
1579
+				last = pkcs11h_data->providers;
1580
+				last->next != NULL;
1581
+				last = last->next
1582
+			);
1583
+			last->next = provider;
1584
+		}
1585
+	}
1586
+
1587
+	PKCS11LOG (
1588
+		PKCS11_LOG_DEBUG2,
1589
+		"PKCS#11: pkcs11h_addProvider return rv=%ld-'%s'",
1590
+		rv,
1591
+		pkcs11h_getMessage (rv)
1592
+	);
1593
+
1594
+	return rv;
1595
+}
1596
+
1597
+CK_RV
1598
+pkcs11h_forkFixup () {
1599
+
1600
+	PKCS11LOG (
1601
+		PKCS11_LOG_DEBUG2,
1602
+		"PKCS#11: pkcs11h_forkFixup entry pid=%d",
1603
+#if defined(WIN32)
1604
+		0
1605
+#else
1606
+		getpid ()
1607
+#endif		
1608
+	);
1609
+
1610
+	if (pkcs11h_data != NULL && pkcs11h_data->fInitialized) {
1611
+
1612
+		pkcs11h_provider_t current;
1613
+
1614
+		for (
1615
+			current = pkcs11h_data->providers;
1616
+			current != NULL;
1617
+			current = current->next
1618
+		) {
1619
+			if (current->fEnabled) {
1620
+				current->f->C_Initialize (NULL);
1621
+			}
1622
+		}
1623
+	}
1624
+
1625
+	PKCS11LOG (
1626
+		PKCS11_LOG_DEBUG2,
1627
+		"PKCS#11: pkcs11h_forkFixup return"
1628
+	);
1629
+
1630
+	return CKR_OK;
1631
+}
1632
+	
1633
+CK_RV
1634
+pkcs11h_createSession (
1635
+	IN const char * const szSlotType,
1636
+	IN const char * const szSlot,
1637
+	IN const char * const szIdType,
1638
+	IN const char * const szId,
1639
+	IN const bool fProtectedAuthentication,
1640
+	OUT pkcs11h_session_t * const p_pkcs11h_session
1641
+) {
1642
+	pkcs11h_session_t pkcs11h_session;
1643
+	CK_RV rv = CKR_OK;
1644
+
1645
+	PKCS11ASSERT (pkcs11h_data!=NULL);
1646
+	PKCS11ASSERT (pkcs11h_data->fInitialized);
1647
+	PKCS11ASSERT (szSlotType!=NULL);
1648
+	PKCS11ASSERT (szSlot!=NULL);
1649
+	PKCS11ASSERT (szIdType!=NULL);
1650
+	PKCS11ASSERT (szId!=NULL);
1651
+	PKCS11ASSERT (p_pkcs11h_session!=NULL);
1652
+
1653
+	PKCS11LOG (
1654
+		PKCS11_LOG_DEBUG2,
1655
+		"PKCS#11: pkcs11h_createSession entry szSlotType=%s, szSlot=%s, szIdType=%s, szId=%s, fProtectedAuthentication=%d, p_pkcs11h_session=%p",
1656
+		szSlotType,
1657
+		szSlot,
1658
+		szIdType,
1659
+		szId,
1660
+		fProtectedAuthentication ? 1 : 0,
1661
+		(void *)p_pkcs11h_session
1662
+	);
1663
+
1664
+	if (
1665
+		rv == CKR_OK &&
1666
+		(pkcs11h_session = (pkcs11h_session_t)malloc (sizeof (struct pkcs11h_session_s))) == NULL
1667
+	) {
1668
+		rv = CKR_HOST_MEMORY;
1669
+	}
1670
+
1671
+	if (rv == CKR_OK) {
1672
+		*p_pkcs11h_session = pkcs11h_session;
1673
+		memset (pkcs11h_session, 0, sizeof (struct pkcs11h_session_s));
1674
+	}
1675
+	
1676
+	if (rv == CKR_OK) {
1677
+		pkcs11h_session->key = (CK_OBJECT_HANDLE)-1;
1678
+		pkcs11h_session->session = (CK_SESSION_HANDLE)-1;
1679
+		pkcs11h_session->fProtectedAuthentication = fProtectedAuthentication;
1680
+	}
1681
+
1682
+	if (rv == CKR_OK) {
1683
+		bool fCancel = false;
1684
+
1685
+		do {
1686
+			if (!strcmp (szSlotType, "id")) {
1687
+				rv = _pkcs11h_getSlotById (pkcs11h_session, szSlot);
1688
+			}
1689
+			else if (!strcmp (szSlotType, "name")) {
1690
+				rv = _pkcs11h_getSlotByName (pkcs11h_session, szSlot);
1691
+			}
1692
+			else if (!strcmp (szSlotType, "label")) {
1693
+				rv = _pkcs11h_getSlotByLabel (pkcs11h_session, szSlot);
1694
+			}
1695
+			else {
1696
+				rv = CKR_ARGUMENTS_BAD;
1697
+			}
1698
+
1699
+			if (rv == CKR_SLOT_ID_INVALID) {
1700
+				char szLabel[1024];
1701
+				strcpy (szLabel, "SLOT(");
1702
+				strncat (szLabel, szSlotType, sizeof (szLabel)-1);
1703
+				strncat (szLabel, "=", sizeof (szLabel)-1);
1704
+				strncat (szLabel, szSlot, sizeof (szLabel)-1);
1705
+				strncat (szLabel, ")", sizeof (szLabel)-1);
1706
+				szLabel[sizeof (szLabel)-1] = 0;
1707
+				fCancel = !pkcs11h_data->hooks->card_prompt (
1708
+					pkcs11h_data->hooks->card_prompt_data,
1709
+					szLabel
1710
+				);
1711
+			}
1712
+		} while (rv == CKR_SLOT_ID_INVALID && !fCancel);
1713
+	}
1714
+
1715
+	if (rv == CKR_OK) {
1716
+		rv = _pkcs11h_setSessionTokenInfo (pkcs11h_session);
1717
+	}
1718
+
1719
+	if (rv == CKR_OK) {
1720
+		rv = _pkcs11h_login (
1721
+			pkcs11h_session
1722
+		);
1723
+	}
1724
+
1725
+	if (rv == CKR_OK) {
1726
+		rv = _pkcs11h_loadCertificate (
1727
+			pkcs11h_session,
1728
+			szIdType,
1729
+			szId
1730
+		);
1731
+	}
1732
+
1733
+	if (rv == CKR_OK) {
1734
+		rv = _pkcs11h_loadKeyProperties (
1735
+			pkcs11h_session
1736
+		);
1737
+	}
1738
+	
1739
+	/*
1740
+	 * Complete missing login process
1741
+	 */
1742
+	if (rv == CKR_OK) {
1743
+		rv = _pkcs11h_getObjectById (
1744
+			pkcs11h_session,
1745
+			CKO_PRIVATE_KEY,
1746
+			pkcs11h_session->certificate_id,
1747
+			pkcs11h_session->certificate_id_size,
1748
+			&pkcs11h_session->key
1749
+		);
1750
+	}
1751
+
1752
+	PKCS11LOG (
1753
+		PKCS11_LOG_DEBUG2,
1754
+		"PKCS#11: pkcs11h_createSession return rv=%ld-'%s'",
1755
+		rv,
1756
+		pkcs11h_getMessage (rv)
1757
+	);
1758
+	
1759
+	return rv;
1760
+}
1761
+
1762
+CK_RV
1763
+pkcs11h_freeSession (
1764
+	IN const pkcs11h_session_t pkcs11h_session
1765
+) {
1766
+	PKCS11ASSERT (pkcs11h_data!=NULL);
1767
+	PKCS11ASSERT (pkcs11h_data->fInitialized);
1768
+
1769
+	PKCS11LOG (
1770
+		PKCS11_LOG_DEBUG2,
1771
+		"PKCS#11: pkcs11h_freeSession entry pkcs11h_session=%p",
1772
+		(void *)pkcs11h_session
1773
+	);
1774
+
1775
+	if (pkcs11h_session != NULL) {
1776
+		_pkcs11h_logout (pkcs11h_session);
1777
+
1778
+		if (pkcs11h_session->certificate != NULL) {
1779
+			free (pkcs11h_session->certificate);
1780
+		}
1781
+		if (pkcs11h_session->certificate_id != NULL) {
1782
+			free (pkcs11h_session->certificate_id);
1783
+		}
1784
+
1785
+		free (pkcs11h_session);
1786
+	}
1787
+
1788
+	PKCS11LOG (
1789
+		PKCS11_LOG_DEBUG2,
1790
+		"PKCS#11: pkcs11h_freeSession return"
1791
+	);
1792
+
1793
+	return CKR_OK;
1794
+}
1795
+
1796
+CK_RV
1797
+pkcs11h_sign (
1798
+	IN const pkcs11h_session_t pkcs11h_session,
1799
+	IN const CK_MECHANISM_TYPE mech_type,
1800
+	IN const unsigned char * const source,
1801
+	IN const size_t source_size,
1802
+	OUT unsigned char * const target,
1803
+	IN OUT size_t * const target_size
1804
+) {
1805
+	CK_MECHANISM mech = {
1806
+		mech_type, NULL, 0
1807
+	};
1808
+	
1809
+	CK_RV rv = CKR_OK;
1810
+	bool fLogonRetry = false;
1811
+	bool fOpSuccess = false;
1812
+
1813
+	PKCS11ASSERT (pkcs11h_data!=NULL);
1814
+	PKCS11ASSERT (pkcs11h_data->fInitialized);
1815
+	PKCS11ASSERT (pkcs11h_session!=NULL);
1816
+	PKCS11ASSERT (source!=NULL);
1817
+	PKCS11ASSERT (target_size!=NULL);
1818
+
1819
+	PKCS11LOG (
1820
+		PKCS11_LOG_DEBUG2,
1821
+		"PKCS#11: pkcs11h_sign entry pkcs11h_session=%p, mech_type=%ld, source=%p, source_size=%u, target=%p, target_size=%p",
1822
+		(void *)pkcs11h_session,
1823
+		mech_type,
1824
+		source,
1825
+		source_size,
1826
+		target,
1827
+		(void *)target_size
1828
+	);
1829
+
1830
+	if (rv == CKR_OK) {
1831
+		rv = _pkcs11h_validateSession (pkcs11h_session);
1832
+	}
1833
+
1834
+	while (rv == CKR_OK && !fOpSuccess) {
1835
+		rv = pkcs11h_session->provider->f->C_SignInit (
1836
+			pkcs11h_session->session,
1837
+			&mech,
1838
+			pkcs11h_session->key
1839
+		);
1840
+
1841
+		if (rv == CKR_OK) {
1842
+			fOpSuccess = true;
1843
+		}
1844
+		else {
1845
+			if (!fLogonRetry) {
1846
+				fLogonRetry = true;
1847
+				rv = _pkcs11h_login (pkcs11h_session);
1848
+			}
1849
+		}
1850
+	}
1851
+
1852
+	if (rv == CKR_OK) {
1853
+		CK_ULONG size = *target_size;
1854
+		rv = pkcs11h_session->provider->f->C_Sign (
1855
+			pkcs11h_session->session,
1856
+			(CK_BYTE_PTR)source,
1857
+			source_size,
1858
+			(CK_BYTE_PTR)target,
1859
+			&size
1860
+		);
1861
+
1862
+		*target_size = (int)size;
1863
+	}
1864
+
1865
+	PKCS11LOG (
1866
+		PKCS11_LOG_DEBUG2,
1867
+		"PKCS#11: pkcs11h_sign return rv=%ld-'%s'",
1868
+		rv,
1869
+		pkcs11h_getMessage (rv)
1870
+	);
1871
+	
1872
+	return rv;
1873
+}
1874
+
1875
+CK_RV
1876
+pkcs11h_signRecover (
1877
+	IN const pkcs11h_session_t pkcs11h_session,
1878
+	IN const CK_MECHANISM_TYPE mech_type,
1879
+	IN const unsigned char * const source,
1880
+	IN const size_t source_size,
1881
+	OUT unsigned char * const target,
1882
+	IN OUT size_t * const target_size
1883
+) {
1884
+	CK_MECHANISM mech = {
1885
+		mech_type, NULL, 0
1886
+	};
1887
+	CK_RV rv = CKR_OK;
1888
+	bool fLogonRetry = false;
1889
+	bool fOpSuccess = false;
1890
+
1891
+	PKCS11ASSERT (pkcs11h_data!=NULL);
1892
+	PKCS11ASSERT (pkcs11h_data->fInitialized);
1893
+	PKCS11ASSERT (pkcs11h_session!=NULL);
1894
+	PKCS11ASSERT (source!=NULL);
1895
+	PKCS11ASSERT (target_size!=NULL);
1896
+
1897
+	PKCS11LOG (
1898
+		PKCS11_LOG_DEBUG2,
1899
+		"PKCS#11: pkcs11h_signRecover entry pkcs11h_session=%p, mech_type=%ld, source=%p, source_size=%u, target=%p, target_size=%p",
1900
+		(void *)pkcs11h_session,
1901
+		mech_type,
1902
+		source,
1903
+		source_size,
1904
+		target,
1905
+		(void *)target_size
1906
+	);
1907
+
1908
+	if (rv == CKR_OK) {
1909
+		rv = _pkcs11h_validateSession (pkcs11h_session);
1910
+	}
1911
+
1912
+	while (rv == CKR_OK && !fOpSuccess) {
1913
+		rv = pkcs11h_session->provider->f->C_SignRecoverInit (
1914
+			pkcs11h_session->session,
1915
+			&mech,
1916
+			pkcs11h_session->key
1917
+		);
1918
+
1919
+		if (rv == CKR_OK) {
1920
+			fOpSuccess = true;
1921
+		}
1922
+		else {
1923
+			if (!fLogonRetry) {
1924
+				fLogonRetry = true;
1925
+				rv = _pkcs11h_login (pkcs11h_session);
1926
+			}
1927
+		}
1928
+	}
1929
+
1930
+	if (rv == CKR_OK) {
1931
+		CK_ULONG size = *target_size;
1932
+		rv = pkcs11h_session->provider->f->C_SignRecover (
1933
+			pkcs11h_session->session,
1934
+			(CK_BYTE_PTR)source,
1935
+			source_size,
1936
+			(CK_BYTE_PTR)target,
1937
+			&size
1938
+		);
1939
+
1940
+		*target_size = (int)size;
1941
+	}
1942
+
1943
+	PKCS11LOG (
1944
+		PKCS11_LOG_DEBUG2,
1945
+		"PKCS#11: pkcs11h_signRecover return rv=%ld-'%s'",
1946
+		rv,
1947
+		pkcs11h_getMessage (rv)
1948
+	);
1949
+
1950
+	return rv;
1951
+}
1952
+
1953
+CK_RV
1954
+pkcs11h_decrypt (
1955
+	IN const pkcs11h_session_t pkcs11h_session,
1956
+	IN const CK_MECHANISM_TYPE mech_type,
1957
+	IN const unsigned char * const source,
1958
+	IN const size_t source_size,
1959
+	OUT unsigned char * const target,
1960
+	IN OUT size_t * const target_size
1961
+) {
1962
+	CK_MECHANISM mech = {
1963
+		mech_type, NULL, 0
1964
+	};
1965
+	CK_ULONG size;
1966
+	CK_RV rv = CKR_OK;
1967
+	bool fLogonRetry = false;
1968
+	bool fOpSuccess = false;
1969
+
1970
+	PKCS11ASSERT (pkcs11h_data!=NULL);
1971
+	PKCS11ASSERT (pkcs11h_data->fInitialized);
1972
+	PKCS11ASSERT (pkcs11h_session!=NULL);
1973
+	PKCS11ASSERT (source!=NULL);
1974
+	PKCS11ASSERT (target_size!=NULL);
1975
+
1976
+	PKCS11LOG (
1977
+		PKCS11_LOG_DEBUG2,
1978
+		"PKCS#11: pkcs11h_decrypt entry pkcs11h_session=%p, mech_type=%ld, source=%p, source_size=%u, target=%p, target_size=%p",
1979
+		(void *)pkcs11h_session,
1980
+		mech_type,
1981
+		source,
1982
+		source_size,
1983
+		target,
1984
+		(void *)target_size
1985
+	);
1986
+
1987
+	if (rv != CKR_OK) {
1988
+		rv = _pkcs11h_validateSession (pkcs11h_session);
1989
+	}
1990
+
1991
+	while (rv == CKR_OK && !fOpSuccess) {
1992
+		rv = pkcs11h_session->provider->f->C_DecryptInit (
1993
+			pkcs11h_session->session,
1994
+			&mech,
1995
+			pkcs11h_session->key
1996
+		);
1997
+
1998
+		if (rv == CKR_OK) {
1999
+			fOpSuccess = true;
2000
+		}
2001
+		else {
2002
+			if (!fLogonRetry) {
2003
+				fLogonRetry = true;
2004
+				rv = _pkcs11h_login (pkcs11h_session);
2005
+			}
2006
+		}
2007
+	}
2008
+
2009
+	if (rv == CKR_OK) {
2010
+		size = *target_size;
2011
+		rv = pkcs11h_session->provider->f->C_Decrypt (
2012
+			pkcs11h_session->session,
2013
+			(CK_BYTE_PTR)source,
2014
+			source_size,
2015
+			(CK_BYTE_PTR)target,
2016
+			&size
2017
+		);
2018
+
2019
+		*target_size = (int)size;
2020
+	}
2021
+
2022
+	PKCS11LOG (
2023
+		PKCS11_LOG_DEBUG2,
2024
+		"PKCS#11: pkcs11h_decrypt return rv=%ld-'%s'",
2025
+		rv,
2026
+		pkcs11h_getMessage (rv)
2027
+	);
2028
+
2029
+	return rv;
2030
+}
2031
+
2032
+CK_RV
2033
+pkcs11h_getCertificate (
2034
+	IN const pkcs11h_session_t pkcs11h_session,
2035
+	OUT unsigned char * const certificate,
2036
+	IN OUT size_t * const certificate_size
2037
+) {
2038
+	CK_RV rv = CKR_OK;
2039
+	
2040
+	PKCS11ASSERT (pkcs11h_data!=NULL);
2041
+	PKCS11ASSERT (pkcs11h_data->fInitialized);
2042
+	PKCS11ASSERT (certificate_size!=NULL);
2043
+
2044
+	PKCS11LOG (
2045
+		PKCS11_LOG_DEBUG2,
2046
+		"PKCS#11: pkcs11h_getCertificate entry pkcs11h_session=%p, certificate=%p, certificate_size=%p",
2047
+		(void *)pkcs11h_session,
2048
+		certificate,
2049
+		(void *)certificate_size
2050
+	);
2051
+
2052
+	*certificate_size = pkcs11h_session->certificate_size;
2053
+
2054
+	if (certificate != NULL) {
2055
+		if (
2056
+			rv == CKR_OK &&
2057
+			*certificate_size > pkcs11h_session->certificate_size
2058
+		) {
2059
+			rv = CKR_BUFFER_TOO_SMALL;
2060
+		}
2061
+	
2062
+		if (rv == CKR_OK) {
2063
+			memmove (certificate, pkcs11h_session->certificate, *certificate_size);	
2064
+		}
2065
+	}
2066
+
2067
+	PKCS11LOG (
2068
+		PKCS11_LOG_DEBUG2,
2069
+		"PKCS#11: pkcs11h_getCertificate return rv=%ld-'%s'",
2070
+		rv,
2071
+		pkcs11h_getMessage (rv)
2072
+	);
2073
+
2074
+	return CKR_OK;
2075
+}
2076
+
2077
+char *
2078
+pkcs11h_getMessage (
2079
+	IN const int rv
2080
+) {
2081
+	switch (rv) {
2082
+		case CKR_OK: return "CKR_OK";
2083
+		case CKR_CANCEL: return "CKR_CANCEL";
2084
+		case CKR_HOST_MEMORY: return "CKR_HOST_MEMORY";
2085
+		case CKR_SLOT_ID_INVALID: return "CKR_SLOT_ID_INVALID";
2086
+		case CKR_GENERAL_ERROR: return "CKR_GENERAL_ERROR";
2087
+		case CKR_FUNCTION_FAILED: return "CKR_FUNCTION_FAILED";
2088
+		case CKR_ARGUMENTS_BAD: return "CKR_ARGUMENTS_BAD";
2089
+		case CKR_NO_EVENT: return "CKR_NO_EVENT";
2090
+		case CKR_NEED_TO_CREATE_THREADS: return "CKR_NEED_TO_CREATE_THREADS";
2091
+		case CKR_CANT_LOCK: return "CKR_CANT_LOCK";
2092
+		case CKR_ATTRIBUTE_READ_ONLY: return "CKR_ATTRIBUTE_READ_ONLY";
2093
+		case CKR_ATTRIBUTE_SENSITIVE: return "CKR_ATTRIBUTE_SENSITIVE";
2094
+		case CKR_ATTRIBUTE_TYPE_INVALID: return "CKR_ATTRIBUTE_TYPE_INVALID";
2095
+		case CKR_ATTRIBUTE_VALUE_INVALID: return "CKR_ATTRIBUTE_VALUE_INVALID";
2096
+		case CKR_DATA_INVALID: return "CKR_DATA_INVALID";
2097
+		case CKR_DATA_LEN_RANGE: return "CKR_DATA_LEN_RANGE";
2098
+		case CKR_DEVICE_ERROR: return "CKR_DEVICE_ERROR";
2099
+		case CKR_DEVICE_MEMORY: return "CKR_DEVICE_MEMORY";
2100
+		case CKR_DEVICE_REMOVED: return "CKR_DEVICE_REMOVED";
2101
+		case CKR_ENCRYPTED_DATA_INVALID: return "CKR_ENCRYPTED_DATA_INVALID";
2102
+		case CKR_ENCRYPTED_DATA_LEN_RANGE: return "CKR_ENCRYPTED_DATA_LEN_RANGE";
2103
+		case CKR_FUNCTION_CANCELED: return "CKR_FUNCTION_CANCELED";
2104
+		case CKR_FUNCTION_NOT_PARALLEL: return "CKR_FUNCTION_NOT_PARALLEL";
2105
+		case CKR_FUNCTION_NOT_SUPPORTED: return "CKR_FUNCTION_NOT_SUPPORTED";
2106
+		case CKR_KEY_HANDLE_INVALID: return "CKR_KEY_HANDLE_INVALID";
2107
+		case CKR_KEY_SIZE_RANGE: return "CKR_KEY_SIZE_RANGE";
2108
+		case CKR_KEY_TYPE_INCONSISTENT: return "CKR_KEY_TYPE_INCONSISTENT";
2109
+		case CKR_KEY_NOT_NEEDED: return "CKR_KEY_NOT_NEEDED";
2110
+		case CKR_KEY_CHANGED: return "CKR_KEY_CHANGED";
2111
+		case CKR_KEY_NEEDED: return "CKR_KEY_NEEDED";
2112
+		case CKR_KEY_INDIGESTIBLE: return "CKR_KEY_INDIGESTIBLE";
2113
+		case CKR_KEY_FUNCTION_NOT_PERMITTED: return "CKR_KEY_FUNCTION_NOT_PERMITTED";
2114
+		case CKR_KEY_NOT_WRAPPABLE: return "CKR_KEY_NOT_WRAPPABLE";
2115
+		case CKR_KEY_UNEXTRACTABLE: return "CKR_KEY_UNEXTRACTABLE";
2116
+		case CKR_MECHANISM_INVALID: return "CKR_MECHANISM_INVALID";
2117
+		case CKR_MECHANISM_PARAM_INVALID: return "CKR_MECHANISM_PARAM_INVALID";
2118
+		case CKR_OBJECT_HANDLE_INVALID: return "CKR_OBJECT_HANDLE_INVALID";
2119
+		case CKR_OPERATION_ACTIVE: return "CKR_OPERATION_ACTIVE";
2120
+		case CKR_OPERATION_NOT_INITIALIZED: return "CKR_OPERATION_NOT_INITIALIZED";
2121
+		case CKR_PIN_INCORRECT: return "CKR_PIN_INCORRECT";
2122
+		case CKR_PIN_INVALID: return "CKR_PIN_INVALID";
2123
+		case CKR_PIN_LEN_RANGE: return "CKR_PIN_LEN_RANGE";
2124
+		case CKR_PIN_EXPIRED: return "CKR_PIN_EXPIRED";
2125
+		case CKR_PIN_LOCKED: return "CKR_PIN_LOCKED";
2126
+		case CKR_SESSION_CLOSED: return "CKR_SESSION_CLOSED";
2127
+		case CKR_SESSION_COUNT: return "CKR_SESSION_COUNT";
2128
+		case CKR_SESSION_HANDLE_INVALID: return "CKR_SESSION_HANDLE_INVALID";
2129
+		case CKR_SESSION_PARALLEL_NOT_SUPPORTED: return "CKR_SESSION_PARALLEL_NOT_SUPPORTED";
2130
+		case CKR_SESSION_READ_ONLY: return "CKR_SESSION_READ_ONLY";
2131
+		case CKR_SESSION_EXISTS: return "CKR_SESSION_EXISTS";
2132
+		case CKR_SESSION_READ_ONLY_EXISTS: return "CKR_SESSION_READ_ONLY_EXISTS";
2133
+		case CKR_SESSION_READ_WRITE_SO_EXISTS: return "CKR_SESSION_READ_WRITE_SO_EXISTS";
2134
+		case CKR_SIGNATURE_INVALID: return "CKR_SIGNATURE_INVALID";
2135
+		case CKR_SIGNATURE_LEN_RANGE: return "CKR_SIGNATURE_LEN_RANGE";
2136
+		case CKR_TEMPLATE_INCOMPLETE: return "CKR_TEMPLATE_INCOMPLETE";
2137
+		case CKR_TEMPLATE_INCONSISTENT: return "CKR_TEMPLATE_INCONSISTENT";
2138
+		case CKR_TOKEN_NOT_PRESENT: return "CKR_TOKEN_NOT_PRESENT";
2139
+		case CKR_TOKEN_NOT_RECOGNIZED: return "CKR_TOKEN_NOT_RECOGNIZED";
2140
+		case CKR_TOKEN_WRITE_PROTECTED: return "CKR_TOKEN_WRITE_PROTECTED";
2141
+		case CKR_UNWRAPPING_KEY_HANDLE_INVALID: return "CKR_UNWRAPPING_KEY_HANDLE_INVALID";
2142
+		case CKR_UNWRAPPING_KEY_SIZE_RANGE: return "CKR_UNWRAPPING_KEY_SIZE_RANGE";
2143
+		case CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT: return "CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT";
2144
+		case CKR_USER_ALREADY_LOGGED_IN: return "CKR_USER_ALREADY_LOGGED_IN";
2145
+		case CKR_USER_NOT_LOGGED_IN: return "CKR_USER_NOT_LOGGED_IN";
2146
+		case CKR_USER_PIN_NOT_INITIALIZED: return "CKR_USER_PIN_NOT_INITIALIZED";
2147
+		case CKR_USER_TYPE_INVALID: return "CKR_USER_TYPE_INVALID";
2148
+		case CKR_USER_ANOTHER_ALREADY_LOGGED_IN: return "CKR_USER_ANOTHER_ALREADY_LOGGED_IN";
2149
+		case CKR_USER_TOO_MANY_TYPES: return "CKR_USER_TOO_MANY_TYPES";
2150
+		case CKR_WRAPPED_KEY_INVALID: return "CKR_WRAPPED_KEY_INVALID";
2151
+		case CKR_WRAPPED_KEY_LEN_RANGE: return "CKR_WRAPPED_KEY_LEN_RANGE";
2152
+		case CKR_WRAPPING_KEY_HANDLE_INVALID: return "CKR_WRAPPING_KEY_HANDLE_INVALID";
2153
+		case CKR_WRAPPING_KEY_SIZE_RANGE: return "CKR_WRAPPING_KEY_SIZE_RANGE";
2154
+		case CKR_WRAPPING_KEY_TYPE_INCONSISTENT: return "CKR_WRAPPING_KEY_TYPE_INCONSISTENT";
2155
+		case CKR_RANDOM_SEED_NOT_SUPPORTED: return "CKR_RANDOM_SEED_NOT_SUPPORTED";
2156
+		case CKR_RANDOM_NO_RNG: return "CKR_RANDOM_NO_RNG";
2157
+		case CKR_DOMAIN_PARAMS_INVALID: return "CKR_DOMAIN_PARAMS_INVALID";
2158
+		case CKR_BUFFER_TOO_SMALL: return "CKR_BUFFER_TOO_SMALL";
2159
+		case CKR_SAVED_STATE_INVALID: return "CKR_SAVED_STATE_INVALID";
2160
+		case CKR_INFORMATION_SENSITIVE: return "CKR_INFORMATION_SENSITIVE";
2161
+		case CKR_STATE_UNSAVEABLE: return "CKR_STATE_UNSAVEABLE";
2162
+		case CKR_CRYPTOKI_NOT_INITIALIZED: return "CKR_CRYPTOKI_NOT_INITIALIZED";
2163
+		case CKR_CRYPTOKI_ALREADY_INITIALIZED: return "CKR_CRYPTOKI_ALREADY_INITIALIZED";
2164
+		case CKR_MUTEX_BAD: return "CKR_MUTEX_BAD";
2165
+		case CKR_MUTEX_NOT_LOCKED: return "CKR_MUTEX_NOT_LOCKED";
2166
+		case CKR_FUNCTION_REJECTED: return "CKR_FUNCTION_REJECTED";
2167
+		case CKR_VENDOR_DEFINED: return "CKR_VENDOR_DEFINED";
2168
+		default: return "Unknown PKCS#11 error";
2169
+	}
2170
+}
2171
+
2172
+/*==========================================
2173
+ * openssl interface
2174
+ */
2175
+
2176
+static
2177
+pkcs11h_openssl_session_t
2178
+_pkcs11h_openssl_get_pkcs11h_openssl_session (
2179
+	IN OUT const RSA *rsa
2180
+) {
2181
+	pkcs11h_openssl_session_t session;
2182
+		
2183
+	PKCS11ASSERT (rsa!=NULL);
2184
+	session = (pkcs11h_openssl_session_t)RSA_get_app_data (rsa);
2185
+	PKCS11ASSERT (session!=NULL);
2186
+
2187
+	return session;
2188
+}
2189
+
2190
+static
2191
+pkcs11h_session_t
2192
+_pkcs11h_openssl_get_pkcs11h_session (
2193
+	IN OUT const RSA *rsa
2194
+) {
2195
+	pkcs11h_openssl_session_t session;
2196
+	
2197
+	PKCS11ASSERT (rsa!=NULL);
2198
+	session = (pkcs11h_openssl_session_t)RSA_get_app_data (rsa);
2199
+	PKCS11ASSERT (session!=NULL);
2200
+	PKCS11ASSERT (session->pkcs11h_session!=NULL);
2201
+
2202
+	return session->pkcs11h_session;
2203
+}
2204
+
2205
+static
2206
+int
2207
+_pkcs11h_openssl_priv_enc (
2208
+	IN int flen,
2209
+	IN const unsigned char *from,
2210
+	OUT unsigned char *to,
2211
+	IN OUT RSA *rsa,
2212
+	IN int padding
2213
+) {
2214
+	PKCS11LOG (PKCS11_LOG_WARN, "PKCS#11: Private key encryption not supported");
2215
+	return -1;
2216
+}
2217
+
2218
+static
2219
+int
2220
+_pkcs11h_openssl_priv_dec (
2221
+	IN int flen,
2222
+	IN const unsigned char *from,
2223
+	OUT unsigned char *to,
2224
+	IN OUT RSA *rsa,
2225
+	IN int padding
2226
+) {
2227
+	pkcs11h_session_t pkcs11h_session = _pkcs11h_openssl_get_pkcs11h_session (rsa);
2228
+	CK_RV rv = CKR_OK;
2229
+
2230
+	PKCS11LOG (
2231
+		PKCS11_LOG_DEBUG2,
2232
+		"PKCS#11: _pkcs11h_openssl_priv_dec entered - flen=%d, from=%p, to=%p, rsa=%p, padding=%d",
2233
+		flen,
2234
+		from,
2235
+		to,
2236
+		(void *)rsa,
2237
+		padding
2238
+	);
2239
+
2240
+	PKCS11ASSERT (from!=NULL);
2241
+	PKCS11ASSERT (to!=NULL);
2242
+
2243
+	PKCS11LOG (
2244
+		PKCS11_LOG_DEBUG1,	
2245
+		"PKCS#11: Performing decryption using private key"
2246
+	);
2247
+
2248
+	if (padding != RSA_PKCS1_PADDING) {
2249
+		rv = CKR_ARGUMENTS_BAD;
2250
+	}
2251
+
2252
+	if (
2253
+		rv == CKR_OK &&
2254
+		(rv = pkcs11h_decrypt (
2255
+			pkcs11h_session,
2256
+			CKM_RSA_PKCS,
2257
+			from,
2258
+			flen,
2259
+			to,
2260
+			(size_t *)&flen
2261
+		)) != CKR_OK
2262
+	) {
2263
+		PKCS11LOG (PKCS11_LOG_WARN, "PKCS#11: Cannot decrypt using private key %ld:'%s'", rv, pkcs11h_getMessage (rv));
2264
+	}
2265
+
2266
+	PKCS11LOG (
2267
+		PKCS11_LOG_DEBUG2,
2268
+		"PKCS#11: _pkcs11h_openssl_priv_dec - return rv=%ld-'%s'",
2269
+		rv,
2270
+		pkcs11h_getMessage (rv)
2271
+	);
2272
+	
2273
+	return rv == CKR_OK ? 1 : -1; 
2274
+}
2275
+
2276
+static
2277
+int
2278
+_pkcs11h_openssl_sign (
2279
+	IN int type,
2280
+	IN const unsigned char *m,
2281
+	IN unsigned int m_len,
2282
+	OUT unsigned char *sigret,
2283
+	OUT unsigned int *siglen,
2284
+	IN OUT const RSA *rsa
2285
+) {
2286
+	pkcs11h_openssl_session_t pkcs11h_openssl_session = _pkcs11h_openssl_get_pkcs11h_openssl_session (rsa);
2287
+	pkcs11h_session_t pkcs11h_session = _pkcs11h_openssl_get_pkcs11h_session (rsa);
2288
+	CK_RV rv = CKR_OK;
2289
+
2290
+	int myrsa_size = 0;
2291
+	
2292
+	unsigned char *enc_alloc = NULL;
2293
+	unsigned char *enc;
2294
+	int enc_len = 0;
2295
+	
2296
+	PKCS11LOG (
2297
+		PKCS11_LOG_DEBUG2,
2298
+		"PKCS#11: _pkcs11h_openssl_sign entered - type=%d, m=%p, m_len=%u, signret=%p, signlen=%p, rsa=%p",
2299
+		type,
2300
+		m,
2301
+		m_len,
2302
+		sigret,
2303
+		(void *)siglen,
2304
+		(void *)rsa
2305
+	);
2306
+
2307
+	PKCS11ASSERT (m!=NULL);
2308
+	PKCS11ASSERT (sigret!=NULL);
2309
+	PKCS11ASSERT (siglen!=NULL);
2310
+
2311
+	if (rv == CKR_OK) {
2312
+		myrsa_size=RSA_size(rsa);
2313
+	}
2314
+
2315
+	if (pkcs11h_openssl_session->fShouldPadSign) {
2316
+		X509_SIG sig;
2317
+		ASN1_TYPE parameter;
2318
+		X509_ALGOR algor;
2319
+		ASN1_OCTET_STRING digest;
2320
+
2321
+		if (
2322
+			rv == CKR_OK &&
2323
+			(enc=enc_alloc=(unsigned char *)malloc ((unsigned int)myrsa_size+1)) == NULL
2324
+		) {
2325
+			rv = CKR_HOST_MEMORY;
2326
+		}
2327
+		
2328
+		if (rv == CKR_OK) {
2329
+			sig.algor= &algor;
2330
+		}
2331
+
2332
+		if (
2333
+			rv == CKR_OK &&
2334
+			(sig.algor->algorithm=OBJ_nid2obj(type)) == NULL
2335
+		) {
2336
+			rv = CKR_FUNCTION_FAILED;
2337
+		}
2338
+	
2339
+		if (
2340
+			rv == CKR_OK &&
2341
+			sig.algor->algorithm->length == 0
2342
+		) {
2343
+			rv = CKR_KEY_SIZE_RANGE;
2344
+		}
2345
+	
2346
+		if (rv == CKR_OK) {
2347
+			parameter.type=V_ASN1_NULL;
2348
+			parameter.value.ptr=NULL;
2349
+	
2350
+			sig.algor->parameter= &parameter;
2351
+
2352
+			sig.digest=&digest;
2353
+			sig.digest->data=(unsigned char *)m;
2354
+			sig.digest->length=m_len;
2355
+		}
2356
+	
2357
+		if (
2358
+			rv == CKR_OK &&
2359
+			(enc_len=i2d_X509_SIG(&sig,NULL)) < 0
2360
+		) {
2361
+			rv = CKR_FUNCTION_FAILED;
2362
+		}
2363
+	
2364
+		if (
2365
+			rv == CKR_OK &&
2366
+			enc_len > (myrsa_size-RSA_PKCS1_PADDING_SIZE)
2367
+		) {
2368
+			rv = CKR_KEY_SIZE_RANGE;
2369
+		}
2370
+	
2371
+		if (rv == CKR_OK) {
2372
+			unsigned char *p=enc;
2373
+			i2d_X509_SIG(&sig,&p);
2374
+		}
2375
+	}
2376
+	else {
2377
+		if (rv == CKR_OK) {
2378
+			enc = (unsigned char *)m;
2379
+			enc_len = m_len;
2380
+		}
2381
+	}
2382
+
2383
+	PKCS11LOG (
2384
+		PKCS11_LOG_DEBUG1,
2385
+		"PKCS#11: Performing signature"
2386
+	);
2387
+
2388
+	*siglen = myrsa_size;
2389
+
2390
+	if (pkcs11h_session->fKeySignRecover) {
2391
+		if (
2392
+			(rv = pkcs11h_signRecover (
2393
+				pkcs11h_session,
2394
+				CKM_RSA_PKCS,
2395
+				enc,
2396
+				enc_len,
2397
+				sigret,
2398
+				siglen
2399
+			)) != CKR_OK
2400
+		) {
2401
+			PKCS11LOG (PKCS11_LOG_WARN, "PKCS#11: Cannot perform signature-recover %ld:'%s'", rv, pkcs11h_getMessage (rv));
2402
+		}
2403
+	}
2404
+	else {
2405
+		if (
2406
+			(rv = pkcs11h_sign (
2407
+				pkcs11h_session,
2408
+				CKM_RSA_PKCS,
2409
+				enc,
2410
+				enc_len,
2411
+				sigret,
2412
+				siglen
2413
+			)) != CKR_OK
2414
+		) {
2415
+			PKCS11LOG (PKCS11_LOG_WARN, "PKCS#11: Cannot perform signature %ld:'%s'", rv, pkcs11h_getMessage (rv));
2416
+		}
2417
+	}
2418
+	
2419
+	PKCS11LOG (
2420
+		PKCS11_LOG_DEBUG2,
2421
+		"PKCS#11: _pkcs11h_openssl_sign - return rv=%ld-'%s'",
2422
+		rv,
2423
+		pkcs11h_getMessage (rv)
2424
+	);
2425
+
2426
+	if (enc_alloc != NULL) {
2427
+		free (enc_alloc);
2428
+	}
2429
+	
2430
+	return rv == CKR_OK ? 1 : -1; 
2431
+}
2432
+
2433
+static
2434
+int
2435
+_pkcs11h_openssl_finish (
2436
+	IN OUT RSA *rsa
2437
+) {
2438
+	pkcs11h_openssl_session_t pkcs11h_openssl_session = _pkcs11h_openssl_get_pkcs11h_openssl_session (rsa);
2439
+
2440
+	PKCS11LOG (
2441
+		PKCS11_LOG_DEBUG2,
2442
+		"PKCS#11: _pkcs11h_openssl_finish - entered rsa=%p",
2443
+		(void *)rsa
2444
+	);
2445
+
2446
+	RSA_set_app_data (rsa, NULL);
2447
+	
2448
+	if (pkcs11h_openssl_session->orig_finish != NULL) {
2449
+		pkcs11h_openssl_session->orig_finish (rsa);
2450
+
2451
+#ifdef BROKEN_OPENSSL_ENGINE
2452
+		{
2453
+			/* We get called TWICE here, once for
2454
+			 * releasing the key and also for
2455
+			 * releasing the engine.
2456
+			 * To prevent endless recursion, FIRST
2457
+			 * clear rsa->engine, THEN call engine->finish
2458
+			 */
2459
+			ENGINE *e = rsa->engine;
2460
+			rsa->engine = NULL;
2461
+			if (e) {
2462
+				ENGINE_finish(e);
2463
+			}
2464
+		}
2465
+#endif
2466
+	}
2467
+
2468
+	pkcs11h_openssl_freeSession (pkcs11h_openssl_session);
2469
+
2470
+	PKCS11LOG (
2471
+		PKCS11_LOG_DEBUG2,
2472
+		"PKCS#11: _pkcs11h_openssl_finish - return"
2473
+	);
2474
+	
2475
+	return 1;
2476
+}
2477
+
2478
+pkcs11h_openssl_session_t
2479
+pkcs11h_openssl_createSession (
2480
+	IN const bool fShouldPadSign
2481
+) {
2482
+	pkcs11h_openssl_session_t pkcs11h_openssl_session = NULL;
2483
+	bool fOK = true;
2484
+
2485
+	PKCS11LOG (
2486
+		PKCS11_LOG_DEBUG2,
2487
+		"PKCS#11: pkcs11h_openssl_createSession - entry fShouldPadSign=%d",
2488
+		fShouldPadSign ? 1 : 0
2489
+	);
2490
+
2491
+	if (
2492
+		fOK &&
2493
+		(pkcs11h_openssl_session = (pkcs11h_openssl_session_t)malloc (sizeof (struct pkcs11h_openssl_session_s))) == NULL
2494
+	) {
2495
+		fOK = false;
2496
+		PKCS11LOG (PKCS11_LOG_WARN, "PKCS#11: Cannot allocate memory");
2497
+	}
2498
+
2499
+	if (fOK) {
2500
+		memset (pkcs11h_openssl_session, 0, sizeof (struct pkcs11h_openssl_session_s));
2501
+	}
2502
+
2503
+	if (fOK) {
2504
+		pkcs11h_openssl_session->fShouldPadSign = fShouldPadSign;
2505
+		pkcs11h_openssl_session->nReferenceCount = 1;
2506
+	}
2507
+
2508
+	if (!fOK) {
2509
+		free (pkcs11h_openssl_session);
2510
+		pkcs11h_openssl_session = NULL;
2511
+	}
2512
+	
2513
+	PKCS11LOG (
2514
+		PKCS11_LOG_DEBUG2,
2515
+		"PKCS#11: pkcs11h_openssl_createSession - return pkcs11h_openssl_session=%p",
2516
+		(void *)pkcs11h_openssl_session
2517
+	);
2518
+
2519
+	return pkcs11h_openssl_session;
2520
+}
2521
+
2522
+void
2523
+pkcs11h_openssl_freeSession (
2524
+	IN const pkcs11h_openssl_session_t pkcs11h_openssl_session
2525
+) {
2526
+	PKCS11ASSERT (pkcs11h_openssl_session!=NULL);
2527
+	PKCS11ASSERT (pkcs11h_openssl_session->nReferenceCount>0);
2528
+	
2529
+	PKCS11LOG (
2530
+		PKCS11_LOG_DEBUG2,
2531
+		"PKCS#11: pkcs11h_openssl_freeSession - entry pkcs11h_openssl_session=%p, count=%d",
2532
+		(void *)pkcs11h_openssl_session,
2533
+		pkcs11h_openssl_session->nReferenceCount
2534
+	);
2535
+
2536
+	pkcs11h_openssl_session->nReferenceCount--;
2537
+	
2538
+	if (pkcs11h_openssl_session->nReferenceCount == 0) {
2539
+		if (pkcs11h_openssl_session->x509) {
2540
+			X509_free (pkcs11h_openssl_session->x509);
2541
+			pkcs11h_openssl_session->x509 = NULL;
2542
+		}
2543
+		if (pkcs11h_openssl_session->pkcs11h_session != NULL) {
2544
+			pkcs11h_freeSession (pkcs11h_openssl_session->pkcs11h_session);
2545
+			pkcs11h_openssl_session->pkcs11h_session = NULL;
2546
+		}
2547
+		
2548
+		free (pkcs11h_openssl_session);
2549
+	}
2550
+
2551
+	PKCS11LOG (
2552
+		PKCS11_LOG_DEBUG2,
2553
+		"PKCS#11: pkcs11h_openssl_freeSession - return"
2554
+	);
2555
+}
2556
+
2557
+RSA *
2558
+pkcs11h_openssl_getRSA (
2559
+	IN const pkcs11h_openssl_session_t pkcs11h_openssl_session
2560
+) {
2561
+	X509 *x509 = NULL;
2562
+	RSA *rsa = NULL;
2563
+	EVP_PKEY *pubkey = NULL;
2564
+	CK_RV rv = CKR_OK;
2565
+
2566
+	unsigned char certificate[10*1024];
2567
+	size_t certificate_size;
2568
+	unsigned char *p;
2569
+	bool fOK = true;
2570
+
2571
+	PKCS11ASSERT (pkcs11h_openssl_session!=NULL);
2572
+	PKCS11ASSERT (!pkcs11h_openssl_session->fInitialized);
2573
+
2574
+	PKCS11LOG (
2575
+		PKCS11_LOG_DEBUG2,
2576
+		"PKCS#11: pkcs11h_openssl_getRSA - entry pkcs11h_openssl_session=%p",
2577
+		(void *)pkcs11h_openssl_session
2578
+	);
2579
+
2580
+	if (
2581
+		fOK &&
2582
+		(x509 = X509_new ()) == NULL
2583
+	) {
2584
+		fOK = false;
2585
+		PKCS11LOG (PKCS11_LOG_WARN, "PKCS#11: Unable to allocate certificate object");
2586
+	}
2587
+
2588
+	certificate_size = sizeof (certificate);
2589
+	if (
2590
+		fOK &&
2591
+		(rv = pkcs11h_getCertificate (
2592
+			pkcs11h_openssl_session->pkcs11h_session,
2593
+			certificate,
2594
+			&certificate_size
2595
+		)) != CKR_OK
2596
+	) { 
2597
+		fOK = false;
2598
+		PKCS11LOG (PKCS11_LOG_WARN, "PKCS#11: Cannot read X.509 certificate from token %ld-'%s'", rv, pkcs11h_getMessage (rv));
2599
+	}
2600
+
2601
+	p = certificate;
2602
+	if (
2603
+		fOK &&
2604
+		!d2i_X509 (&x509, &p, certificate_size)
2605
+	) {
2606
+		fOK = false;
2607
+		PKCS11LOG (PKCS11_LOG_WARN, "PKCS#11: Unable to parse X.509 certificate");
2608
+	}
2609
+
2610
+	if (
2611
+		fOK &&
2612
+		(pubkey = X509_get_pubkey (x509)) == NULL
2613
+	) {
2614
+		fOK = false;
2615
+		PKCS11LOG (PKCS11_LOG_WARN, "PKCS#11: Cannot get public key");
2616
+	}
2617
+	
2618
+	if (
2619
+		fOK &&
2620
+		pubkey->type != EVP_PKEY_RSA
2621
+	) {
2622
+		fOK = false;
2623
+		PKCS11LOG (PKCS11_LOG_WARN, "PKCS#11: Invalid public key algorithm");
2624
+	}
2625
+
2626
+	if (
2627
+		fOK &&
2628
+		(rsa = EVP_PKEY_get1_RSA (pubkey)) == NULL
2629
+	) {
2630
+		fOK = false;
2631
+		PKCS11LOG (PKCS11_LOG_WARN, "PKCS#11: Cannot get RSA key");
2632
+	}
2633
+
2634
+ 	if (fOK) {
2635
+		const RSA_METHOD *def = RSA_get_default_method();
2636
+
2637
+		memmove (&pkcs11h_openssl_session->smart_rsa, def, sizeof(RSA_METHOD));
2638
+
2639
+		pkcs11h_openssl_session->orig_finish = def->finish;
2640
+
2641
+		pkcs11h_openssl_session->smart_rsa.name = "pkcs11";
2642
+		pkcs11h_openssl_session->smart_rsa.rsa_priv_enc = _pkcs11h_openssl_priv_enc;
2643
+		pkcs11h_openssl_session->smart_rsa.rsa_priv_dec = _pkcs11h_openssl_priv_dec;
2644
+		pkcs11h_openssl_session->smart_rsa.rsa_sign = _pkcs11h_openssl_sign;
2645
+		pkcs11h_openssl_session->smart_rsa.finish = _pkcs11h_openssl_finish;
2646
+		pkcs11h_openssl_session->smart_rsa.flags  = RSA_METHOD_FLAG_NO_CHECK | RSA_FLAG_EXT_PKEY;
2647
+
2648
+		RSA_set_method (rsa, &pkcs11h_openssl_session->smart_rsa);
2649
+		RSA_set_app_data (rsa, pkcs11h_openssl_session);
2650
+		pkcs11h_openssl_session->nReferenceCount++;
2651
+	}
2652
+	
2653
+#ifdef BROKEN_OPENSSL_ENGINE
2654
+	if (fOK) {
2655
+		if (!rsa->engine)
2656
+			rsa->engine = ENGINE_get_default_RSA();
2657
+
2658
+		ENGINE_set_RSA(ENGINE_get_default_RSA(), &pkcs11h_openssl_session->smart_rsa);
2659
+		PKCS11LOG (PKCS11_LOG_WARN, "PKCS#11: OpenSSL engine support is broken! Workaround enabled");
2660
+	}
2661
+#endif
2662
+		
2663
+	if (fOK) {
2664
+		/*
2665
+			So that it won't hold RSA
2666
+		*/
2667
+		pkcs11h_openssl_session->x509 = X509_dup (x509);
2668
+		rsa->flags |= RSA_FLAG_SIGN_VER;
2669
+		pkcs11h_openssl_session->fInitialized = true;
2670
+	}
2671
+	else {
2672
+		if (rsa != NULL) {
2673
+			RSA_free (rsa);
2674
+			rsa = NULL;
2675
+		}
2676
+	}
2677
+
2678
+	/*
2679
+	 * openssl objects have reference
2680
+	 * count, so release them
2681
+	 */
2682
+	if (pubkey != NULL) {
2683
+		EVP_PKEY_free (pubkey);
2684
+		pubkey = NULL;
2685
+	}
2686
+
2687
+	if (x509 != NULL) {
2688
+		X509_free (x509);
2689
+		x509 = NULL;
2690
+	}
2691
+	
2692
+	PKCS11LOG (
2693
+		PKCS11_LOG_DEBUG2,
2694
+		"PKCS#11: pkcs11h_openssl_getRSA - return rsa=%p",
2695
+		(void *)rsa
2696
+	);
2697
+
2698
+	return rsa;
2699
+}
2700
+
2701
+X509 *
2702
+pkcs11h_openssl_getX509 (
2703
+	IN const pkcs11h_openssl_session_t pkcs11h_openssl_session
2704
+) {
2705
+	X509 *x509 = NULL;
2706
+	
2707
+	PKCS11ASSERT (pkcs11h_openssl_session!=NULL);
2708
+
2709
+	PKCS11LOG (
2710
+		PKCS11_LOG_DEBUG2,
2711
+		"PKCS#11: pkcs11h_openssl_getX509 - entry pkcs11h_openssl_session=%p",
2712
+		(void *)pkcs11h_openssl_session
2713
+	);
2714
+
2715
+	if (pkcs11h_openssl_session->x509 != NULL) {
2716
+		x509 = X509_dup (pkcs11h_openssl_session->x509);
2717
+	}
2718
+	
2719
+	PKCS11LOG (
2720
+		PKCS11_LOG_DEBUG2,
2721
+		"PKCS#11: pkcs11h_openssl_getX509 - return x509=%p",
2722
+		(void *)x509
2723
+	);
2724
+
2725
+	return x509;
2726
+}
2727
+
2728
+
2729
+void
2730
+pkcs11h_standalone_dump_slots (
2731
+	IN const pkcs11h_output_print_t my_output,
2732
+	IN const void *pData,
2733
+	IN const char * const provider
2734
+) {
2735
+	CK_RV rv = CKR_OK;
2736
+
2737
+	pkcs11h_provider_t pkcs11h_provider;
2738
+
2739
+	PKCS11ASSERT (provider!=NULL);
2740
+
2741
+	if (
2742
+		rv == CKR_OK &&
2743
+		(rv = pkcs11h_initialize ()) != CKR_OK
2744
+	) {
2745
+		my_output (pData, "PKCS#11: Cannot initialize interface %ld-'%s'\n", rv, pkcs11h_getMessage (rv));
2746
+	}
2747
+
2748
+	if (
2749
+		rv == CKR_OK &&
2750
+		(rv = pkcs11h_addProvider (provider, NULL)) != CKR_OK
2751
+	) {
2752
+		my_output (pData, "PKCS#11: Cannot initialize provider %ld-'%s'\n", rv, pkcs11h_getMessage (rv));
2753
+	}
2754
+
2755
+	/*
2756
+	 * our provider is head
2757
+	 */
2758
+	if (rv == CKR_OK) {
2759
+		pkcs11h_provider = pkcs11h_data->providers;
2760
+		if (pkcs11h_provider == NULL || !pkcs11h_provider->fEnabled) {
2761
+			my_output (pData, "PKCS#11: Cannot get provider %ld-'%s'\n", rv, pkcs11h_getMessage (rv));
2762
+			rv = CKR_GENERAL_ERROR;
2763
+		}
2764
+	}
2765
+
2766
+	if (rv == CKR_OK) {
2767
+		CK_INFO info;
2768
+		
2769
+		if ((rv = pkcs11h_provider->f->C_GetInfo (&info)) != CKR_OK) {
2770
+			my_output (pData, "PKCS#11: Cannot get PKCS#11 provider information %ld-'%s'\n", rv, pkcs11h_getMessage (rv));
2771
+			rv = CKR_OK;
2772
+		}
2773
+		else {
2774
+			char szManufacturerID[sizeof (info.manufacturerID)+1];
2775
+	
2776
+			_pkcs11h_fixupFixedString (
2777
+				(char *)info.manufacturerID,
2778
+				szManufacturerID,
2779
+				sizeof (info.manufacturerID)
2780
+			);
2781
+	
2782
+			my_output (
2783
+				pData,
2784
+				(
2785
+					"Provider Information:\n"
2786
+					"\tcryptokiVersion:\t%u.%u\n"
2787
+					"\tmanufacturerID:\t\t%s\n"
2788
+					"\tflags:\t\t\t%d\n"
2789
+					"\n"
2790
+				),
2791
+				info.cryptokiVersion.major,
2792
+				info.cryptokiVersion.minor,
2793
+				szManufacturerID,
2794
+				(unsigned)info.flags
2795
+			);
2796
+		}
2797
+	}
2798
+	
2799
+	if (rv == CKR_OK) {
2800
+		CK_SLOT_ID slots[1024];
2801
+		CK_ULONG slotnum;
2802
+		CK_SLOT_ID s;
2803
+		
2804
+		slotnum = sizeof (slots) / sizeof (CK_SLOT_ID);
2805
+		if (
2806
+			(rv = pkcs11h_provider->f->C_GetSlotList (
2807
+				FALSE,
2808
+				slots,
2809
+				&slotnum
2810
+			)) != CKR_OK
2811
+		) {
2812
+			my_output (pData, "PKCS#11: Cannot get slot list %ld-'%s'\n", rv, pkcs11h_getMessage (rv));
2813
+		}
2814
+		else {
2815
+			my_output (
2816
+				pData,
2817
+				(
2818
+					"The following slots are available for use with this provider.\n"
2819
+					"Each slot shown below may be used as a parameter to a\n"
2820
+					"%s and %s options.\n"
2821
+					"\n"
2822
+					"Slots: (id - name)\n"
2823
+				),
2824
+				PKCS11_PRM_SLOT_TYPE,
2825
+				PKCS11_PRM_SLOT_ID
2826
+			);
2827
+			for (s=0;s<slotnum;s++) {
2828
+				CK_SLOT_INFO info;
2829
+	
2830
+				if (
2831
+					(rv = pkcs11h_provider->f->C_GetSlotInfo (
2832
+						slots[s],
2833
+						&info
2834
+					)) == CKR_OK
2835
+				) {
2836
+					char szCurrentName[sizeof (info.slotDescription)+1];
2837
+				
2838
+					_pkcs11h_fixupFixedString (
2839
+						(char *)info.slotDescription,
2840
+						szCurrentName,
2841
+						sizeof (info.slotDescription)
2842
+					);
2843
+	
2844
+					my_output (pData, "\t%lu - %s\n", slots[s], szCurrentName);
2845
+				}
2846
+			}
2847
+		}
2848
+	}
2849
+	
2850
+	pkcs11h_terminate ();
2851
+}
2852
+
2853
+static
2854
+bool
2855
+_pkcs11h_standalone_dump_objects_pin_prompt (
2856
+	IN const void *pData,
2857
+	IN const char * const szLabel,
2858
+	OUT char * const szPIN,
2859
+	IN const size_t nMaxPIN
2860
+) {
2861
+	strncpy (szPIN, (char *)pData, nMaxPIN);
2862
+	return true;
2863
+}
2864
+
2865
+void
2866
+pkcs11h_standalone_dump_objects (
2867
+	IN const pkcs11h_output_print_t my_output,
2868
+	IN const void *pData,
2869
+	IN const char * const provider,
2870
+	IN const char * const slot,
2871
+	IN const char * const pin
2872
+) {
2873
+	CK_SLOT_ID s;
2874
+	CK_RV rv = CKR_OK;
2875
+
2876
+	pkcs11h_provider_t pkcs11h_provider;
2877
+
2878
+	PKCS11ASSERT (provider!=NULL);
2879
+	PKCS11ASSERT (slot!=NULL);
2880
+	PKCS11ASSERT (pin!=NULL);
2881
+
2882
+	s = atoi (slot);
2883
+
2884
+	if (
2885
+		rv == CKR_OK &&
2886
+		(rv = pkcs11h_initialize ()) != CKR_OK
2887
+	) {
2888
+		my_output (pData, "PKCS#11: Cannot initialize interface %ld-'%s'\n", rv, pkcs11h_getMessage (rv));
2889
+	}
2890
+
2891
+	if (
2892
+		rv == CKR_OK &&
2893
+		(rv = pkcs11h_setPINPromptHook (_pkcs11h_standalone_dump_objects_pin_prompt, (void *)pin)) != CKR_OK
2894
+	) {
2895
+		my_output (pData, "PKCS#11: Cannot set hooks %ld-'%s'\n", rv, pkcs11h_getMessage (rv));
2896
+	}
2897
+
2898
+	if (
2899
+		rv == CKR_OK &&
2900
+		(rv = pkcs11h_addProvider (provider, NULL)) != CKR_OK
2901
+	) {
2902
+		my_output (pData, "PKCS#11: Cannot initialize provider %ld-'%s'\n", rv, pkcs11h_getMessage (rv));
2903
+	}
2904
+
2905
+  	/*
2906
+	 * our provider is head
2907
+	 */
2908
+	if (rv == CKR_OK) {
2909
+		pkcs11h_provider = pkcs11h_data->providers;
2910
+		if (pkcs11h_provider == NULL || !pkcs11h_provider->fEnabled) {
2911
+			my_output (pData, "PKCS#11: Cannot get provider %ld-'%s'\n", rv, pkcs11h_getMessage (rv));
2912
+			rv = CKR_GENERAL_ERROR;
2913
+		}
2914
+	}
2915
+
2916
+	if (rv == CKR_OK) {
2917
+		CK_TOKEN_INFO info;
2918
+		
2919
+		if (
2920
+			(rv = pkcs11h_provider->f->C_GetTokenInfo (
2921
+				s,
2922
+				&info
2923
+			)) != CKR_OK
2924
+		) {
2925
+			my_output (pData, "PKCS#11: Cannot get token information for slot %ld %ld-'%s'\n", s, rv, pkcs11h_getMessage (rv));
2926
+			rv = CKR_OK;
2927
+		}
2928
+		else {
2929
+			char szLabel[sizeof (info.label)+1];
2930
+			char szManufacturerID[sizeof (info.manufacturerID)+1];
2931
+			char szModel[sizeof (info.model)+1];
2932
+			char szSerialNumber[sizeof (info.serialNumber)+1];
2933
+			
2934
+			_pkcs11h_fixupFixedString (
2935
+				(char *)info.label,
2936
+				szLabel,
2937
+				sizeof (info.label)
2938
+			);
2939
+			_pkcs11h_fixupFixedString (
2940
+				(char *)info.manufacturerID,
2941
+				szManufacturerID,
2942
+				sizeof (info.manufacturerID)
2943
+			);
2944
+			_pkcs11h_fixupFixedString (
2945
+				(char *)info.model,
2946
+				szModel,
2947
+				sizeof (info.model)
2948
+			);
2949
+			_pkcs11h_fixupFixedString (
2950
+				(char *)info.serialNumber,
2951
+				szSerialNumber,
2952
+				sizeof (info.serialNumber)
2953
+			);
2954
+	
2955
+			my_output (
2956
+				pData,
2957
+				(
2958
+					"Token Information:\n"
2959
+					"\tlabel:\t\t%s\n"
2960
+					"\tmanufacturerID:\t%s\n"
2961
+					"\tmodel:\t\t%s\n"
2962
+					"\tserialNumber:\t%s\n"
2963
+					"\tflags:\t\t%08x\n"
2964
+					"\n"
2965
+					"You can access this token using\n"
2966
+					"%s \"label\" %s \"%s\" options.\n"
2967
+					"\n"
2968
+				),
2969
+				szLabel,
2970
+				szManufacturerID,
2971
+				szModel,
2972
+				szSerialNumber,
2973
+				(unsigned)info.flags,
2974
+				PKCS11_PRM_SLOT_TYPE,
2975
+				PKCS11_PRM_SLOT_ID,
2976
+				szLabel
2977
+			);
2978
+		}
2979
+	}
2980
+
2981
+	if (rv == CKR_OK) {
2982
+		CK_SESSION_HANDLE session;
2983
+		
2984
+		if (
2985
+			(rv = pkcs11h_provider->f->C_OpenSession (
2986
+				s,
2987
+				CKF_SERIAL_SESSION,
2988
+				NULL_PTR,
2989
+				NULL_PTR,
2990
+				&session
2991
+			)) != CKR_OK
2992
+		) {
2993
+			my_output (pData, "PKCS#11: Cannot open session to slot %ld %ld-'%s'\n", s, rv, pkcs11h_getMessage (rv));
2994
+			rv = CKR_OK;
2995
+		}
2996
+		else {
2997
+			CK_OBJECT_HANDLE objects[10];
2998
+			CK_ULONG objects_found;
2999
+	
3000
+			if (
3001
+				(rv = pkcs11h_provider->f->C_Login (
3002
+					session,
3003
+					CKU_USER,
3004
+					(CK_CHAR_PTR)pin,
3005
+					(CK_ULONG)strlen (pin)
3006
+				)) != CKR_OK &&
3007
+				rv != CKR_USER_ALREADY_LOGGED_IN
3008
+			) {
3009
+				my_output (pData, "PKCS#11: Cannot login to token on slot %ld %ld-'%s'\n", s, rv, pkcs11h_getMessage (rv));
3010
+			}
3011
+		
3012
+			if (
3013
+				(rv = pkcs11h_provider->f->C_FindObjectsInit (
3014
+					session,
3015
+					NULL,
3016
+					0
3017
+				)) != CKR_OK
3018
+			) {
3019
+				my_output (pData, "PKCS#11: Cannot query objects for token on slot %ld %ld-'%s'\n", s, rv, pkcs11h_getMessage (rv));
3020
+			}
3021
+		
3022
+			my_output (
3023
+				pData,
3024
+				(
3025
+					"The following objects are available for use with this token.\n"
3026
+					"Each object shown below may be used as a parameter to\n"
3027
+					"%s and %s options.\n"
3028
+					"\n"
3029
+				),
3030
+				PKCS11_PRM_OBJ_TYPE,
3031
+				PKCS11_PRM_OBJ_ID
3032
+			);
3033
+		
3034
+			while (
3035
+				(rv = pkcs11h_provider->f->C_FindObjects (
3036
+					session,
3037
+					objects,
3038
+					sizeof (objects) / sizeof (CK_OBJECT_HANDLE),
3039
+					&objects_found
3040
+				)) == CKR_OK &&
3041
+				objects_found > 0
3042
+			) { 
3043
+				CK_ULONG i;
3044
+				
3045
+				for (i=0;i<objects_found;i++) {
3046
+					CK_OBJECT_CLASS attrs_class;
3047
+					unsigned char attrs_id[PKCS11H_MAX_ATTRIBUTE_SIZE];
3048
+					unsigned char attrs_label[PKCS11H_MAX_ATTRIBUTE_SIZE];
3049
+					CK_ATTRIBUTE attrs[] = {
3050
+						{CKA_CLASS, &attrs_class, sizeof (attrs_class)},
3051
+						{CKA_ID, attrs_id, sizeof (attrs_id)},
3052
+						{CKA_LABEL, attrs_label, sizeof (attrs_label)-1}
3053
+					};
3054
+			
3055
+					if (
3056
+						pkcs11h_provider->f->C_GetAttributeValue (
3057
+							session,
3058
+							objects[i],
3059
+							attrs,
3060
+							sizeof (attrs) / sizeof (CK_ATTRIBUTE)
3061
+						) == CKR_OK
3062
+					) {
3063
+						int id_len = attrs[1].ulValueLen;
3064
+						int j;
3065
+							
3066
+						attrs_label[attrs[2].ulValueLen] = 0;
3067
+		
3068
+						my_output (
3069
+							pData,
3070
+							(
3071
+								"Object\n"
3072
+								"\tLabel:\t\t%s\n"
3073
+								"\tId:\n"
3074
+							),
3075
+							attrs_label
3076
+						);
3077
+		
3078
+							
3079
+						for (j=0;j<id_len;j+=16) {
3080
+							char szLine[3*16+1];
3081
+							int k;
3082
+		
3083
+							szLine[0] = '\0';
3084
+							for (k=0;k<16 && j+k<id_len;k++) {
3085
+								sprintf (szLine+strlen (szLine), "%02x ", attrs_id[j+k]);
3086
+							}
3087
+		
3088
+							my_output (pData, "\t\t%s\n", szLine);
3089
+						}
3090
+		
3091
+						if (attrs_class == CKO_CERTIFICATE) {
3092
+							unsigned char certificate[PKCS11H_MAX_ATTRIBUTE_SIZE];
3093
+							CK_ATTRIBUTE attrs_cert[] = {
3094
+								{CKA_VALUE, certificate, sizeof (certificate)}
3095
+							};
3096
+		
3097
+							my_output (pData, "\tType:\t\tCertificate\n");
3098
+		
3099
+							if (
3100
+								pkcs11h_provider->f->C_GetAttributeValue (
3101
+									session,
3102
+									objects[i],
3103
+									attrs_cert,
3104
+									sizeof (attrs_cert) / sizeof (CK_ATTRIBUTE)
3105
+								) == CKR_OK
3106
+							) {
3107
+								X509 *x509 = NULL;
3108
+								BIO *bioSerial = NULL;
3109
+		
3110
+								char szSubject[1024];
3111
+								char szSerial[1024];
3112
+								char szNotBefore[1024];
3113
+		
3114
+								szSubject[0] = '\0';
3115
+								szSerial[0] = '\0';
3116
+								szNotBefore[0] = '\0';
3117
+		
3118
+								if ((x509 = X509_new ()) == NULL) {
3119
+									my_output (pData, "Cannot create x509 context\n");
3120
+								}
3121
+								else {
3122
+									unsigned char *p;
3123
+		
3124
+									p = certificate;
3125
+									if (d2i_X509 (&x509, &p, attrs_cert[0].ulValueLen)) {
3126
+		
3127
+										ASN1_TIME *notBefore = X509_get_notBefore (x509);
3128
+										if (notBefore != NULL && notBefore->length < (int) sizeof (szNotBefore) - 1) {
3129
+											memmove (szNotBefore, notBefore->data, notBefore->length);
3130
+											szNotBefore[notBefore->length] = '\0';
3131
+										}
3132
+		
3133
+										X509_NAME_oneline (
3134
+											X509_get_subject_name (x509),
3135
+											szSubject,
3136
+											sizeof (szSubject)
3137
+										);
3138
+										szSubject[sizeof (szSubject) - 1] = '\0';
3139
+									}
3140
+								}
3141
+		
3142
+								if ((bioSerial = BIO_new (BIO_s_mem ())) == NULL) {
3143
+									my_output (pData, "Cannot create BIO context\n");
3144
+								}
3145
+								else {
3146
+									int n;
3147
+		
3148
+									i2a_ASN1_INTEGER(bioSerial, X509_get_serialNumber (x509));
3149
+									n = BIO_read (bioSerial, szSerial, sizeof (szSerial)-1);
3150
+									if (n<0) {
3151
+										szSerial[0] = '\0';
3152
+									}
3153
+									else {
3154
+										szSerial[n] = '\0';
3155
+									}
3156
+								}
3157
+		
3158
+		
3159
+								if (x509 != NULL) {
3160
+									X509_free (x509);
3161
+									x509 = NULL;
3162
+								}
3163
+								if (bioSerial != NULL) {
3164
+									BIO_free_all (bioSerial);
3165
+									bioSerial = NULL;
3166
+								}
3167
+		
3168
+								my_output (
3169
+									pData,
3170
+									(
3171
+										"\tsubject:\t%s\n"
3172
+										"\tserialNumber:\t%s\n"
3173
+										"\tnotBefore:\t%s\n"
3174
+									),
3175
+									szSubject,
3176
+									szSerial,
3177
+									szNotBefore
3178
+								);
3179
+							}
3180
+						}
3181
+						else if (attrs_class == CKO_PRIVATE_KEY) {
3182
+							CK_BBOOL sign_recover;
3183
+							CK_BBOOL sign;
3184
+							CK_ATTRIBUTE attrs_key[] = {
3185
+								{CKA_SIGN, &sign_recover, sizeof (sign_recover)},
3186
+								{CKA_SIGN_RECOVER, &sign, sizeof (sign)}
3187
+							};
3188
+		
3189
+							my_output (pData, "\tType:\t\tPrivate Key\n");
3190
+		
3191
+							if (
3192
+								pkcs11h_provider->f->C_GetAttributeValue (
3193
+									session,
3194
+									objects[i],
3195
+									attrs_key,
3196
+									sizeof (attrs_key) / sizeof (CK_ATTRIBUTE)
3197
+								) == CKR_OK
3198
+							) {
3199
+								my_output (
3200
+									pData,
3201
+									(
3202
+										"\tSign:\t\t%s\n"
3203
+										"\tSign Recover:\t%s\n"
3204
+									),
3205
+									sign ? "TRUE" : "FALSE",
3206
+									sign_recover ? "TRUE" : "FALSE"
3207
+								);
3208
+							}
3209
+						}
3210
+						else {
3211
+							my_output (pData, "\tType:\t\tUnsupported\n");
3212
+						}
3213
+					}
3214
+				}
3215
+			
3216
+				pkcs11h_provider->f->C_FindObjectsFinal (session);
3217
+				pkcs11h_provider->f->C_Logout (session);
3218
+				pkcs11h_provider->f->C_CloseSession (session);
3219
+			}
3220
+		}
3221
+	}
3222
+	
3223
+	pkcs11h_terminate ();
3224
+}
3225
+
3226
+#ifdef BROKEN_OPENSSL_ENGINE
3227
+static void broken_openssl_init() __attribute__ ((constructor));
3228
+static void  broken_openssl_init()
3229
+{
3230
+	SSL_library_init();
3231
+	ENGINE_load_openssl();
3232
+	ENGINE_register_all_RSA();
3233
+}
3234
+#endif
3235
+
3236
+#else
3237
+static void dummy (void) {}
3238
+#endif /* PKCS11_HELPER_ENABLE */
0 3239
new file mode 100644
... ...
@@ -0,0 +1,252 @@
0
+/*
1
+ * Copyright (c) 2005 Alon Bar-Lev <alon.barlev@gmail.com>
2
+ * All rights reserved.
3
+ *
4
+ * Redistribution and use in source and binary forms, with or without modifi-
5
+ * cation, are permitted provided that the following conditions are met:
6
+ *
7
+ *   o  Redistributions of source code must retain the above copyright notice,
8
+ *      this list of conditions and the following disclaimer.
9
+ *
10
+ *   o  Redistributions in binary form must reproduce the above copyright no-
11
+ *      tice, this list of conditions and the following disclaimer in the do-
12
+ *      cumentation and/or other materials provided with the distribution.
13
+ *
14
+ *   o  The names of the contributors may not be used to endorse or promote
15
+ *      products derived from this software without specific prior written
16
+ *      permission.
17
+ *
18
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
20
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
21
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LI-
22
+ * ABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUEN-
23
+ * TIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEV-
25
+ * ER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABI-
26
+ * LITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
27
+ * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
+ */
29
+
30
+/*
31
+ * The routines in this file deal with providing private key cryptography
32
+ * using RSA Security Inc. PKCS #11 Cryptographic Token Interface (Cryptoki).
33
+ *
34
+ */
35
+
36
+#ifndef __PKCS11_HELPER_H
37
+#define __PKCS11_HELPER_H
38
+
39
+#include "pkcs11-helper-config.h"
40
+
41
+#define PKCS11H_MAX_ATTRIBUTE_SIZE (10*1024)
42
+
43
+typedef void (*pkcs11h_output_print_t)(
44
+	IN const void *pData,
45
+	IN const char * const szFormat,
46
+	IN ...
47
+);
48
+
49
+typedef bool (*pkcs11h_hook_card_prompt_t)(
50
+	IN const void *pData,
51
+	IN const char * const szLabel
52
+);
53
+
54
+typedef bool (*pkcs11h_hook_pin_prompt_t)(
55
+	IN const void *pData,
56
+	IN const char * const szLabel,
57
+	OUT char * const szPIN,
58
+	IN const size_t nMaxPIN
59
+);
60
+
61
+
62
+typedef struct pkcs11h_hooks_s {
63
+	void *card_prompt_data;
64
+	void *pin_prompt_data;
65
+	pkcs11h_hook_card_prompt_t card_prompt;
66
+	pkcs11h_hook_pin_prompt_t pin_prompt;
67
+} *pkcs11h_hooks_t;
68
+
69
+typedef struct pkcs11h_provider_s {
70
+	struct pkcs11h_provider_s *next;
71
+
72
+	bool fEnabled;
73
+	char *szName;
74
+	
75
+#if defined(WIN32)
76
+	HANDLE hLibrary;
77
+#else
78
+	void *hLibrary;
79
+#endif
80
+	CK_FUNCTION_LIST_PTR f;
81
+	bool fShouldFinalize;
82
+	char *szSignMode;
83
+
84
+} *pkcs11h_provider_t;
85
+
86
+typedef struct pkcs11h_session_s {
87
+
88
+	pkcs11h_provider_t provider;
89
+
90
+	bool fProtectedAuthentication;
91
+
92
+	char szLabel[sizeof (((CK_TOKEN_INFO *)NULL)->label)+1];
93
+	CK_CHAR serialNumber[sizeof (((CK_TOKEN_INFO *)NULL)->serialNumber)];
94
+	
95
+	unsigned char *certificate;
96
+	size_t certificate_size;
97
+	unsigned char *certificate_id;
98
+	size_t certificate_id_size;
99
+
100
+	CK_SLOT_ID slot;
101
+	bool fKeySignRecover;
102
+
103
+	CK_SESSION_HANDLE session;
104
+	CK_OBJECT_HANDLE key;
105
+
106
+	time_t timePINExpire;
107
+} *pkcs11h_session_t;
108
+
109
+typedef struct pkcs11h_data_s {
110
+	bool fInitialized;
111
+	int nPINCachePeriod;
112
+	pkcs11h_provider_t providers;
113
+	pkcs11h_hooks_t hooks;
114
+} *pkcs11h_data_t;
115
+
116
+typedef struct pkcs11h_openssl_session_s {
117
+	int nReferenceCount;
118
+	bool fInitialized;
119
+	bool fShouldPadSign;
120
+	X509 *x509;
121
+	RSA_METHOD smart_rsa;
122
+	int (*orig_finish)(RSA *rsa);
123
+	pkcs11h_session_t pkcs11h_session;
124
+} *pkcs11h_openssl_session_t;
125
+
126
+CK_RV
127
+pkcs11h_initialize ();
128
+
129
+CK_RV
130
+pkcs11h_terminate ();
131
+
132
+CK_RV
133
+pkcs11h_setCardPromptHook (
134
+	IN const pkcs11h_hook_card_prompt_t hook,
135
+	IN void * const pData
136
+);
137
+
138
+CK_RV
139
+pkcs11h_setPINPromptHook (
140
+	IN const pkcs11h_hook_pin_prompt_t hook,
141
+	IN void * const pData
142
+);
143
+
144
+CK_RV
145
+pkcs11h_setPINCachePeriod (
146
+	IN const int nPINCachePeriod
147
+);
148
+
149
+CK_RV
150
+pkcs11h_addProvider (
151
+	IN const char * const szProvider,
152
+	IN const char * const szSignMode
153
+);
154
+
155
+CK_RV
156
+pkcs11h_forkFixup ();
157
+
158
+CK_RV
159
+pkcs11h_createSession (
160
+	IN const char * const szSlotType,
161
+	IN const char * const szSlot,
162
+	IN const char * const szIdType,
163
+	IN const char * const szId,
164
+	IN const bool fProtectedAuthentication,
165
+	OUT pkcs11h_session_t * const pkcs11h_session
166
+);
167
+
168
+CK_RV
169
+pkcs11h_freeSession (
170
+	IN const pkcs11h_session_t pkcs11h_session
171
+);
172
+
173
+CK_RV
174
+pkcs11h_sign (
175
+	IN const pkcs11h_session_t pkcs11h_session,
176
+	IN const CK_MECHANISM_TYPE mech_type,
177
+	IN const unsigned char * const source,
178
+	IN const size_t source_size,
179
+	OUT unsigned char * const target,
180
+	IN OUT size_t * const target_size
181
+);
182
+
183
+CK_RV
184
+pkcs11h_signRecover (
185
+	IN const pkcs11h_session_t pkcs11h_session,
186
+	IN const CK_MECHANISM_TYPE mech_type,
187
+	IN const unsigned char * const source,
188
+	IN const size_t source_size,
189
+	OUT unsigned char * const target,
190
+	IN OUT size_t * const target_size
191
+);
192
+
193
+CK_RV
194
+pkcs11h_decrypt (
195
+	IN const pkcs11h_session_t pkcs11h_session,
196
+	IN const CK_MECHANISM_TYPE mech_type,
197
+	IN const unsigned char * const source,
198
+	IN const size_t source_size,
199
+	OUT unsigned char * const target,
200
+	IN OUT size_t * const target_size
201
+);
202
+
203
+CK_RV
204
+pkcs11h_getCertificate (
205
+	IN const pkcs11h_session_t pkcs11h_session,
206
+	OUT unsigned char * const certificate,
207
+	IN OUT size_t * const certificate_size
208
+);
209
+
210
+char *
211
+pkcs11h_getMessage (
212
+	IN const int rv
213
+);
214
+
215
+pkcs11h_openssl_session_t
216
+pkcs11h_openssl_createSession (
217
+	IN const bool fShouldPadSign
218
+);
219
+
220
+void
221
+pkcs11h_openssl_freeSession (
222
+	IN const pkcs11h_openssl_session_t pkcs11h_openssl_session
223
+);
224
+
225
+RSA *
226
+pkcs11h_openssl_getRSA (
227
+	IN const pkcs11h_openssl_session_t pkcs11h_openssl_session
228
+);
229
+
230
+X509 *
231
+pkcs11h_openssl_getX509 (
232
+	IN const pkcs11h_openssl_session_t pkcs11h_openssl_session
233
+);
234
+
235
+void
236
+pkcs11h_standalone_dump_slots (
237
+	IN const pkcs11h_output_print_t my_output,
238
+	IN const void *pData,
239
+	IN const char * const provider
240
+);
241
+
242
+void
243
+pkcs11h_standalone_dump_objects (
244
+	IN const pkcs11h_output_print_t my_output,
245
+	IN const void *pData,
246
+	IN const char * const provider,
247
+	IN const char * const slot,
248
+	IN const char * const pin
249
+);
250
+
251
+#endif
... ...
@@ -38,2143 +38,34 @@
38 38
 
39 39
 #if defined(ENABLE_PKCS11)
40 40
 
41
-#include "error.h"
42
-#include "misc.h"
43
-#include "ssl.h"
44
-
45
-#if !defined(IN)
46
-#define IN
47
-#endif
48
-#if !defined(OUT)
49
-#define OUT
50
-#endif
51
-
52
-#if defined(WIN32)
53
-#include "cryptoki-win32.h"
54
-#else
55
-#include "cryptoki.h"
56
-#endif
41
+#define PKCS11H_NO_NEED_INCLUDE_CONFIG
57 42
 
43
+#include "pkcs11-helper.h"
58 44
 #include "pkcs11.h"
59 45
 
60
-/*===========================================
61
- * MACROS
62
- */
63
-
64 46
 #define snprintf openvpn_snprintf
65 47
 
66
-/*===========================================
67
- * Constants
68
- */
69
-
70
-#if OPENSSL_VERSION_NUMBER < 0x00907000L && defined(CRYPTO_LOCK_ENGINE)
71
-# define RSA_get_default_method RSA_get_default_openssl_method
72
-#else
73
-# ifdef HAVE_ENGINE_GET_DEFAULT_RSA
74
-#  include <openssl/engine.h>
75
-#  if OPENSSL_VERSION_NUMBER < 0x0090704fL
76
-#   define BROKEN_OPENSSL_ENGINE
77
-#  endif
78
-# endif
79
-#endif
80
-
81
-#define PKCS11_MAX_ATTRIBUTE_SIZE (10*1024)
82
-
83
-/*===========================================
84
- * Types
85
- */
86
-
87
-typedef bool (*pkcs11_hook_card_prompt_t)(
88
-	IN const void *pData,
89
-	IN const char * const szLabel
90
-);
91
-
92
-typedef bool (*pkcs11_hook_pin_prompt_t)(
93
-	IN const void *pData,
94
-	IN const char * const szLabel,
95
-	OUT char * const szPIN,
96
-	IN const size_t nMaxPIN
97
-);
98
-	
99
-typedef struct pkcs11_hooks_s {
100
-	void *card_prompt_data;
101
-	void *pin_prompt_data;
102
-	pkcs11_hook_card_prompt_t card_prompt;
103
-	pkcs11_hook_pin_prompt_t pin_prompt;
104
-} *pkcs11_hooks_t;
105
-
106
-typedef struct pkcs11_provider_s {
107
-	struct pkcs11_provider_s *next;
108
-
109
-	bool fEnabled;
110
-	
111
-#if defined(WIN32)
112
-	HANDLE hLibrary;
113
-#else
114
-	void *hLibrary;
115
-#endif
116
-	CK_FUNCTION_LIST_PTR f;
117
-	bool fShouldFinalize;
118
-	char *szSignMode;
119
-
120
-} *pkcs11_provider_t;
121
-
122
-typedef struct pkcs11_session_s {
123
-
124
-	pkcs11_provider_t provider;
125
-
126
-	bool fProtectedAuthentication;
127
-
128
-	char szLabel[sizeof (((CK_TOKEN_INFO *)NULL)->label)+1];
129
-	CK_CHAR serialNumber[sizeof (((CK_TOKEN_INFO *)NULL)->serialNumber)];
130
-	
131
-	unsigned char *certificate;
132
-	size_t certificate_size;
133
-	unsigned char *certificate_id;
134
-	size_t certificate_id_size;
135
-
136
-	CK_SLOT_ID slot;
137
-	bool fKeySignRecover;
138
-
139
-	CK_SESSION_HANDLE session;
140
-	CK_OBJECT_HANDLE key;
141
-
142
-	time_t timePINExpire;
143
-} *pkcs11_session_t;
144
-
145
-typedef struct pkcs11_data_s {
146
-	bool fInitialized;
147
-	int nPINCachePeriod;
148
-	pkcs11_provider_t providers;
149
-	pkcs11_hooks_t hooks;
150
-} *pkcs11_data_t;
151
-
152
-/*===========================================
153
- * Low level prototypes
154
- */
155
-
156
-static
157
-void
158
-_fixupFixedString (
159
-	IN const char * const szSource,
160
-	OUT char * const szTarget,			/* MUST BE >= nLength+1 */
161
-	IN const size_t nLength				/* FIXED STRING LENGTH */
162
-);
163 48
 static
164 49
 void
165
-_hexToBinary (
166
-	IN const char * const szSource,
167
-	OUT unsigned char * const target,
168
-	IN OUT size_t * const target_size
169
-);
170
-static
171
-CK_RV
172
-_pkcs11_getSlotById (
173
-	IN const pkcs11_session_t pkcs11_session,
174
-	IN const char * const szSlot
175
-);
176
-static
177
-CK_RV
178
-_pkcs11_getSlotByName (
179
-	IN const pkcs11_session_t pkcs11_session,
180
-	IN const char * const szName
181
-);
182
-static
183
-CK_RV
184
-_pkcs11_getSlotByLabel (
185
-	IN const pkcs11_session_t pkcs11_session,
186
-	IN const char * const szLabel
187
-);
188
-static
189
-CK_RV
190
-_pkcs11_getObjectById (
191
-	IN const pkcs11_session_t pkcs11_session,
192
-	IN const CK_OBJECT_CLASS class,
193
-	IN const unsigned char * const id,
194
-	IN const size_t id_size,
195
-	OUT CK_OBJECT_HANDLE * const handle
196
-);
197
-static
198
-CK_RV
199
-_pkcs11_setSessionTokenInfo (
200
-	IN const pkcs11_session_t pkcs11_session
201
-);
202
-static
203
-CK_RV
204
-_pkcs11_resetSlot (
205
-	IN const pkcs11_session_t pkcs11_session
206
-);
207
-static
208
-CK_RV
209
-_pkcs11_loadCertificate (
210
-	IN const pkcs11_session_t pkcs11_session,
211
-	IN const char * const szIdType,
212
-	IN const char * const szId
213
-);
214
-static
215
-CK_RV
216
-_pkcs11_loadKeyProperties (
217
-	IN const pkcs11_session_t pkcs11_session
218
-);
219
-static
220
-bool
221
-_isBetterCertificate (
222
-	IN const unsigned char * const pCurrent,
223
-	IN const size_t nCurrentSize,
224
-	IN const unsigned char * const pNew,
225
-	IN const size_t nNewSize
226
-);
227
-static
228
-CK_RV
229
-_pkcs11_validateSession (
230
-	IN const pkcs11_session_t pkcs11_session
231
-);
232
-static
233
-CK_RV
234
-_pkcs11_login (
235
-	IN const pkcs11_session_t pkcs11_session
236
-);
237
-static
238
-CK_RV
239
-_pkcs11_logout (
240
-	IN const pkcs11_session_t pkcs11_session
241
-);
242
-
243
-/*=========================================
244
- * Simplified functions prototypes
245
- */
246
-static
247
-bool
248
-_pkcs11_hooks_card_prompt_default (
249
-	IN const void *pData,
250
-	IN const char * const szLabel
251
-);
252
-static
253
-bool
254
-_pkcs11_hooks_pin_prompt_default (
50
+_pkcs11_openvpn_print (
255 51
 	IN const void *pData,
256
-	IN const char * const szLabel,
257
-	OUT char * const szPIN,
258
-	IN const size_t nMaxPIN
259
-);
260
-static
261
-CK_RV
262
-pkcs11_initialize ();
263
-static
264
-CK_RV
265
-pkcs11_terminate ();
266
-static
267
-CK_RV
268
-pkcs11_setCardPromptHook (
269
-	IN const pkcs11_hook_card_prompt_t hook,
270
-	IN void * const pData
271
-);
272
-static
273
-CK_RV
274
-pkcs11_setPINPromptHook (
275
-	IN const pkcs11_hook_pin_prompt_t hook,
276
-	IN void * const pData
277
-);
278
-static
279
-CK_RV
280
-pkcs11_setPINCachePeriod (
281
-	IN const int nPINCachePeriod
282
-);
283
-static
284
-CK_RV
285
-pkcs11_addProvider (
286
-	IN const char * const szProvider,
287
-	IN const char * const szSignMode
288
-);
289
-static
290
-CK_RV
291
-pkcs11_forkFixup ();
292
-static
293
-CK_RV
294
-pkcs11_createSession (
295
-	IN const char * const szSlotType,
296
-	IN const char * const szSlot,
297
-	IN const char * const szIdType,
298
-	IN const char * const szId,
299
-	IN const bool fProtectedAuthentication,
300
-	OUT pkcs11_session_t * const pkcs11_session
301
-);
302
-static
303
-CK_RV
304
-pkcs11_freeSession (
305
-	IN const pkcs11_session_t pkcs11_session
306
-);
307
-static
308
-CK_RV
309
-pkcs11_sign (
310
-	IN const pkcs11_session_t pkcs11_session,
311
-	IN const CK_MECHANISM_TYPE mech_type,
312
-	IN const unsigned char * const source,
313
-	IN const size_t source_size,
314
-	OUT unsigned char * const target,
315
-	IN OUT size_t * const target_size
316
-);
317
-static
318
-CK_RV
319
-pkcs11_signRecover (
320
-	IN const pkcs11_session_t pkcs11_session,
321
-	IN const CK_MECHANISM_TYPE mech_type,
322
-	IN const unsigned char * const source,
323
-	IN const size_t source_size,
324
-	OUT unsigned char * const target,
325
-	IN OUT size_t * const target_size
326
-);
327
-static
328
-CK_RV
329
-pkcs11_decrypt (
330
-	IN const pkcs11_session_t pkcs11_session,
331
-	IN const CK_MECHANISM_TYPE mech_type,
332
-	IN const unsigned char * const source,
333
-	IN const size_t source_size,
334
-	OUT unsigned char * const target,
335
-	IN OUT size_t * const target_size
336
-);
337
-static
338
-CK_RV
339
-pkcs11_getCertificate (
340
-	IN const pkcs11_session_t pkcs11_session,
341
-	OUT unsigned char * const certificate,
342
-	IN OUT size_t * const certificate_size
343
-);
344
-static
345
-char *
346
-pkcs11_getMessage (
347
-	IN const int rv
348
-);
349
-
350
-/*==========================================
351
- * Static data
352
- */
353
-
354
-static pkcs11_data_t pkcs11_data = NULL;
355
-
356
-/*==========================================
357
- * Internal utility functions
358
- */
359
-
360
-static
361
-void
362
-_fixupFixedString (
363
-	IN const char * const szSource,
364
-	OUT char * const szTarget,			/* MUST BE >= nLength+1 */
365
-	IN const size_t nLength				/* FIXED STRING LENGTH */
366
-) {
367
-	char *p;
368
-
369
-	ASSERT (szSource!=NULL);
370
-	ASSERT (szTarget!=NULL);
371
-	
372
-	p = szTarget+nLength;
373
-	memmove (szTarget, szSource, nLength);
374
-	*p = '\0';
375
-	p--;
376
-	while (p >= szTarget && *p == ' ') {
377
-		*p = '\0';
378
-		p--;
379
-	}
380
-}
381
-
382
-static
383
-void
384
-_hexToBinary (
385
-	IN const char * const szSource,
386
-	OUT unsigned char * const target,
387
-	IN OUT size_t * const target_size
388
-) {
389
-	size_t target_max_size;
390
-	const char *p;
391
-	char buf[3] = {'\0', '\0', '\0'};
392
-	int i = 0;
393
-
394
-	ASSERT (szSource!=NULL);
395
-	ASSERT (target!=NULL);
396
-	ASSERT (target_size!=NULL);
397
-
398
-	target_max_size = *target_size;
399
-	p = szSource;
400
-	*target_size = 0;
401
-
402
-	while (*p != '\0' && *target_size < target_max_size) {
403
-		if (isxdigit (*p)) {
404
-			buf[i%2] = *p;
405
-
406
-			if ((i%2) == 1) {
407
-				unsigned v;
408
-				sscanf (buf, "%x", &v);
409
-				target[*target_size] = v & 0xff;
410
-				(*target_size)++;
411
-			}
412
-
413
-			i++;
414
-		}
415
-		p++;
416
-	}
417
-}
418
-
419
-static
420
-bool
421
-_isBetterCertificate (
422
-	IN const unsigned char * const pCurrent,
423
-	IN const size_t nCurrentSize,
424
-	IN const unsigned char * const pNew,
425
-	IN const size_t nNewSize
426
-) {
427
-	/*
428
-	 * This function compare the notBefore
429
-	 * and select the most recent certificate
430
-	 * it does not deal with timezones...
431
-	 * When openssl will have ASN1_TIME compare function
432
-	 * it should be used.
433
-	 */
434
-
435
-	X509 *x509Current = NULL, *x509New = NULL;
436
-	char szNotBeforeCurrent[1024], szNotBeforeNew[1024];
437
-
438
-	/*
439
-	 * First certificae
440
-	 * always select
441
-	 */
442
-	if (nCurrentSize == 0) {
443
-		return true;
444
-	}
445
-
446
-	szNotBeforeCurrent[0] = '\0';
447
-	szNotBeforeNew[0] = '\0';
448
-
449
-	x509Current = X509_new ();
450
-	x509New = X509_new ();
451
-
452
-	if (x509Current != NULL && x509New != NULL) {
453
-		const unsigned char *p1, *p2;
454
-
455
-		p1 = pCurrent;
456
-		p2 = pNew;
457
-		if (
458
-			d2i_X509 (&x509Current, (unsigned char **)&p1, nCurrentSize) &&
459
-			d2i_X509 (&x509New, (unsigned char **)&p2, nNewSize)
460
-		) {
461
-			ASN1_TIME *notBeforeCurrent = X509_get_notBefore (x509Current);
462
-			ASN1_TIME *notBeforeNew = X509_get_notBefore (x509New);
463
-
464
-			if (
465
-				notBeforeCurrent != NULL &&
466
-				notBeforeNew != NULL &&
467
-				notBeforeCurrent->length < (int) sizeof (szNotBeforeCurrent) - 1 &&
468
-				notBeforeNew->length < (int) sizeof (szNotBeforeNew) - 1
469
-			) {
470
-				memmove (szNotBeforeCurrent, notBeforeCurrent->data, notBeforeCurrent->length);
471
-				szNotBeforeCurrent[notBeforeCurrent->length] = '\0';
472
-				memmove (szNotBeforeNew, notBeforeNew->data, notBeforeNew->length);
473
-				szNotBeforeNew[notBeforeNew->length] = '\0';
474
-			}
475
-		}
476
-	}
477
-
478
-	if (x509Current != NULL) {
479
-		X509_free (x509Current);
480
-		x509Current = NULL;
481
-	}
482
-	if (x509New != NULL) {
483
-		X509_free (x509New);
484
-		x509New = NULL;
485
-	}
486
-
487
-	return strcmp (szNotBeforeCurrent, szNotBeforeNew) < 0;
488
-}
489
-
490
-/*========================================
491
- * Low level PKCS#11 functions
492
- */
493
-
494
-static
495
-CK_RV
496
-_pkcs11_getSlotById (
497
-	IN const pkcs11_session_t pkcs11_session,
498
-	IN const char * const szSlot
499
-) {
500
-	pkcs11_provider_t provider;
501
-	int provider_number;
502
-	int slot_number;
503
-	int i;
504
-
505
-	ASSERT (pkcs11_session!=NULL);
506
-	ASSERT (szSlot!=NULL);
507
-
508
-	if (strchr (szSlot, ':') == NULL) {
509
-		provider_number = 0;
510
-		slot_number = atoi (szSlot);
511
-	}
512
-	else {
513
-		sscanf (szSlot, "%d:%d", &provider_number, &slot_number);
514
-	}
515
-
516
-	for (
517
-		i=0, provider=pkcs11_data->providers;
518
-		i < provider_number && provider != NULL;
519
-		i++, provider = provider->next
520
-	);
521
-
522
-	if (
523
-		provider == NULL ||
524
-		(
525
-			provider != NULL &&
526
-			!provider->fEnabled
527
-		)
528
-	) {
529
-		return CKR_SLOT_ID_INVALID;
530
-	}
531
-
532
-	pkcs11_session->provider = provider;
533
-	pkcs11_session->slot = slot_number;
534
-	return CKR_OK;
535
-}
536
-
537
-static
538
-CK_RV
539
-_pkcs11_getSlotByName (
540
-	IN const pkcs11_session_t pkcs11_session,
541
-	IN const char * const szName
542
-) {
543
-	CK_RV rv;
544
-
545
-	pkcs11_provider_t provider;
546
-	bool fFound = false;
547
-
548
-	ASSERT (pkcs11_session!=NULL);
549
-	ASSERT (szName!=NULL);
550
-
551
-	for (
552
-		provider = pkcs11_data->providers;
553
-		(
554
-			provider != NULL &&
555
-			!fFound
556
-		);
557
-		provider = provider->next
558
-	) {
559
-		CK_SLOT_ID slots[1024];
560
-		CK_ULONG slotnum;
561
-
562
-		if (!provider->fEnabled) {
563
-			continue;
564
-		}
565
-
566
-		slotnum = sizeof (slots) / sizeof (CK_SLOT_ID);
567
-		if (
568
-			(rv = provider->f->C_GetSlotList (
569
-				TRUE,
570
-				slots,
571
-				&slotnum
572
-			)) == CKR_OK
573
-		) {
574
-			CK_SLOT_ID s;
575
-
576
-			for (s=0;!fFound && s<slotnum;s++) {
577
-				CK_SLOT_INFO info;
578
-
579
-				if (
580
-					(rv = provider->f->C_GetSlotInfo (
581
-						slots[s],
582
-						&info
583
-					)) == CKR_OK
584
-				) {
585
-					char szCurrentName[sizeof (info.slotDescription)+1];
586
-	
587
-					_fixupFixedString (
588
-						(char *)info.slotDescription,
589
-						szCurrentName,
590
-						sizeof (info.slotDescription)
591
-					);
592
-
593
-					if (!strcmp (szCurrentName, szName)) {
594
-						fFound = true;
595
-						pkcs11_session->provider = provider;
596
-						pkcs11_session->slot = slots[s];
597
-					}
598
-				}
599
-			}
600
-		}
601
-	}
602
-
603
-	return fFound ? CKR_OK : CKR_SLOT_ID_INVALID;
604
-}
605
-
606
-static
607
-CK_RV
608
-_pkcs11_getSlotByLabel (
609
-	IN const pkcs11_session_t pkcs11_session,
610
-	IN const char * const szLabel
611
-) {
612
-	CK_RV rv;
613
-
614
-	pkcs11_provider_t provider;
615
-	bool fFound = false;
616
-
617
-	ASSERT (pkcs11_session!=NULL);
618
-	ASSERT (szLabel!=NULL);
619
-
620
-	for (
621
-		provider = pkcs11_data->providers;
622
-		(
623
-			provider != NULL &&
624
-			!fFound
625
-		);
626
-		provider = provider->next
627
-	) {
628
-		CK_SLOT_ID slots[1024];
629
-		CK_ULONG slotnum;
630
-
631
-		if (!provider->fEnabled) {
632
-			continue;
633
-		}
634
-
635
-		slotnum = sizeof (slots) / sizeof (CK_SLOT_ID);
636
-		if (
637
-			(rv = provider->f->C_GetSlotList (
638
-				TRUE,
639
-				slots,
640
-				&slotnum
641
-			)) == CKR_OK
642
-		) {
643
-			CK_SLOT_ID s;
644
-
645
-			for (s=0;!fFound && s<slotnum;s++) {
646
-				CK_TOKEN_INFO info;
647
-
648
-				if (
649
-					(rv = provider->f->C_GetTokenInfo (
650
-						slots[s],
651
-						&info
652
-					)) == CKR_OK
653
-				) {
654
-					char szCurrentLabel[sizeof (info.label)+1];
655
-			
656
-					_fixupFixedString (
657
-						(char *)info.label,
658
-						szCurrentLabel,
659
-						sizeof (info.label)
660
-					);
661
-
662
-					if (!strcmp (szCurrentLabel, szLabel)) {
663
-						fFound = true;
664
-						pkcs11_session->provider = provider;
665
-						pkcs11_session->slot = slots[s];
666
-					}
667
-				}
668
-			}
669
-		}
670
-	}
671
-
672
-	return fFound ? CKR_OK : CKR_SLOT_ID_INVALID;
673
-}
674
-
675
-static
676
-CK_RV
677
-_pkcs11_setSessionTokenInfo (
678
-	IN const pkcs11_session_t pkcs11_session
679
-) {
680
-	CK_TOKEN_INFO info;
681
-	CK_RV rv;
682
-
683
-	ASSERT (pkcs11_session!=NULL);
684
-
685
-	if (
686
-		(rv = pkcs11_session->provider->f->C_GetTokenInfo (
687
-			pkcs11_session->slot,
688
-			&info
689
-		)) == CKR_OK
690
-	) {
691
-		_fixupFixedString (
692
-			(char *)info.label,
693
-			pkcs11_session->szLabel,
694
-			sizeof (info.label)
695
-		);
696
-		
697
-		memmove (
698
-			pkcs11_session->serialNumber,
699
-			info.serialNumber,
700
-			sizeof (pkcs11_session->serialNumber)
701
-		);
702
-	}
703
-
704
-	return rv;
705
-}
706
-
707
-static
708
-CK_RV
709
-_pkcs11_resetSlot (
710
-	IN const pkcs11_session_t pkcs11_session
711
-) {
712
-	CK_SLOT_ID slots[1024];
713
-	CK_ULONG slotnum;
714
-	CK_RV rv;
715
-	bool fFound = false;
716
-	bool fCancel = false;
717
-
718
-	ASSERT (pkcs11_session!=NULL);
719
-
720
-	do {
721
-		slotnum = sizeof (slots) / sizeof (CK_SLOT_ID);
722
-		if (
723
-			(rv = pkcs11_session->provider->f->C_GetSlotList (
724
-				TRUE,
725
-				slots,
726
-				&slotnum
727
-			)) == CKR_OK
728
-		) {
729
-			CK_SLOT_ID s;
730
-
731
-			for (s=0;!fFound && s<slotnum;s++) {
732
-				CK_TOKEN_INFO info;
733
-
734
-				if (
735
-					(rv = pkcs11_session->provider->f->C_GetTokenInfo (
736
-						slots[s],
737
-						&info
738
-					)) == CKR_OK
739
-				) {
740
-					if (
741
-						!memcmp (
742
-							pkcs11_session->serialNumber,
743
-							info.serialNumber,
744
-							sizeof (pkcs11_session->serialNumber)
745
-						)
746
-					) {
747
-						pkcs11_session->slot = slots[s];
748
-						fFound = true;
749
-					}
750
-				}
751
-			}
752
-		}
753
-
754
-		if (!fFound) {
755
-			fCancel = !pkcs11_data->hooks->card_prompt (
756
-				pkcs11_data->hooks->card_prompt_data,
757
-				pkcs11_session->szLabel
758
-			);
759
-		}
760
-	} while (!fFound && !fCancel);
761
-
762
-	return fFound ? CKR_OK : CKR_SLOT_ID_INVALID;
763
-}
764
-
765
-static
766
-CK_RV
767
-_pkcs11_getObjectById (
768
-	IN const pkcs11_session_t pkcs11_session,
769
-	IN const CK_OBJECT_CLASS class,
770
-	IN const unsigned char * const id,
771
-	IN const size_t id_size,
772
-	OUT CK_OBJECT_HANDLE * const handle
773
-) {
774
-	CK_ULONG count;
775
-	CK_RV rv = CKR_OK;
776
-
777
-	CK_ATTRIBUTE filter[] = {
778
-		{CKA_CLASS, (void *)&class, sizeof (class)},
779
-		{CKA_ID, (void *)id, id_size}
780
-	};
781
-	
782
-	ASSERT (pkcs11_session!=NULL);
783
-	ASSERT (id!=NULL);
784
-	ASSERT (handle!=NULL);
785
-
786
-	if (rv == CKR_OK) {
787
-		rv = pkcs11_session->provider->f->C_FindObjectsInit (
788
-			pkcs11_session->session,
789
-			filter,
790
-			sizeof (filter) / sizeof (CK_ATTRIBUTE)
791
-		);
792
-	}
793
-
794
-	if (rv == CKR_OK) {
795
-		rv = pkcs11_session->provider->f->C_FindObjects (
796
-			pkcs11_session->session,
797
-			handle,
798
-			1,
799
-			&count
800
-		);
801
-	}
802
-
803
-	if (
804
-		rv == CKR_OK &&
805
-		count == 0
806
-	) {
807
-		rv = CKR_FUNCTION_REJECTED;
808
-	}
809
-
810
-	pkcs11_session->provider->f->C_FindObjectsFinal (
811
-		pkcs11_session->session
812
-	);
813
-
814
-	return rv;
815
-}
816
-
817
-static
818
-CK_RV
819
-_pkcs11_loadCertificate (
820
-	IN const pkcs11_session_t pkcs11_session,
821
-	IN const char * const szIdType,
822
-	IN const char * const szId
823
-) {
824
-	CK_OBJECT_HANDLE objects[10];
825
-	CK_ULONG objects_found;
826
-	CK_RV rv;
827
-
828
-	unsigned char selected_id[PKCS11_MAX_ATTRIBUTE_SIZE];
829
-	int selected_id_size = 0;
830
-	unsigned char selected_certificate[PKCS11_MAX_ATTRIBUTE_SIZE];
831
-	int selected_certificate_size = 0;
832
-
833
-	CK_OBJECT_CLASS cert_filter_class = CKO_CERTIFICATE;
834
-	unsigned char cert_filter_by[PKCS11_MAX_ATTRIBUTE_SIZE];
835
-	CK_ATTRIBUTE cert_filter[] = {
836
-		{CKA_CLASS, &cert_filter_class, sizeof (cert_filter_class)},
837
-		{0, cert_filter_by, 0}
838
-	};
839
-
840
-	ASSERT (pkcs11_session!=NULL);
841
-	ASSERT (szIdType!=NULL);
842
-	ASSERT (szId!=NULL);
843
-
844
-	if (!strcmp (szIdType, "label")) {
845
-		cert_filter[1].type = CKA_LABEL;
846
-		cert_filter[1].ulValueLen = (CK_ULONG)(
847
-			strlen (szId) < sizeof (cert_filter_by)  ?
848
-			strlen (szId) :
849
-			sizeof (cert_filter_by)
850
-		);
851
-		memmove (
852
-			cert_filter_by,
853
-			szId,
854
-			cert_filter[1].ulValueLen
855
-		);
856
-	}
857
-	else if (!strcmp (szIdType, "id")) {
858
-		size_t s = sizeof (cert_filter_by);
859
-
860
-		cert_filter[1].type = CKA_ID;
861
-		_hexToBinary (
862
-			szId,
863
-			cert_filter_by,
864
-			&s
865
-		);
866
-		cert_filter[1].ulValueLen = s;
867
-	}
868
-	else if (!strcmp (szIdType, "subject")) {
869
-		memmove (&cert_filter[1], &cert_filter[0], sizeof (CK_ATTRIBUTE));
870
-	}
871
-	else {
872
-		return CKR_ARGUMENTS_BAD;
873
-	}
874
-
875
-	if (
876
-		(rv = pkcs11_session->provider->f->C_FindObjectsInit (
877
-			pkcs11_session->session,
878
-			cert_filter,
879
-			sizeof (cert_filter) / sizeof (CK_ATTRIBUTE)
880
-		)) != CKR_OK
881
-	) {
882
-		return rv;
883
-	}
884
-
885
-	while (
886
-		(rv = pkcs11_session->provider->f->C_FindObjects (
887
-			pkcs11_session->session,
888
-			objects,
889
-			sizeof (objects) / sizeof (CK_OBJECT_HANDLE),
890
-			&objects_found
891
-		)) == CKR_OK &&
892
-		objects_found > 0
893
-	) { 
894
-		CK_ULONG i;
895
-		
896
-		for (i=0;i<objects_found;i++) {
897
-			unsigned char attrs_id[PKCS11_MAX_ATTRIBUTE_SIZE];
898
-			unsigned char attrs_value[PKCS11_MAX_ATTRIBUTE_SIZE];
899
-			CK_ATTRIBUTE attrs[] = {
900
-				{CKA_ID, attrs_id, sizeof (attrs_id)},
901
-				{CKA_VALUE, attrs_value, sizeof (attrs_value)}
902
-			};
903
-	
904
-			if (
905
-				pkcs11_session->provider->f->C_GetAttributeValue (
906
-					pkcs11_session->session,
907
-					objects[i],
908
-					attrs,
909
-					sizeof (attrs) / sizeof (CK_ATTRIBUTE)
910
-				) == CKR_OK
911
-			) {
912
-				bool fSelected = false;
913
-
914
-				if (!strcmp (szIdType, "subject")) {
915
-					X509 *x509 = NULL;
916
-					char szSubject[1024];
917
-					unsigned char *p;
918
-
919
-					x509 = X509_new ();
920
-
921
-					p = attrs_value;
922
-					if (d2i_X509 (&x509, &p, attrs[1].ulValueLen)) {
923
-  						X509_NAME_oneline (
924
-							X509_get_subject_name (x509),
925
-							szSubject,
926
-							sizeof (szSubject)
927
-						);
928
-						szSubject[sizeof (szSubject) - 1] = '\0';
929
-					}
930
-
931
-					if (x509 != NULL) {
932
-						X509_free (x509);
933
-						x509 = NULL;
934
-					}
935
-
936
-					if (!strcmp (szId, szSubject)) {
937
-						fSelected = true;
938
-					}
939
-				}
940
-				else {
941
-					fSelected = true;
942
-				}
943
-
944
-				if (
945
-					fSelected &&
946
-					_isBetterCertificate (
947
-						selected_certificate,
948
-						selected_certificate_size,
949
-						attrs_value,
950
-						attrs[1].ulValueLen
951
-					)
952
-				) {
953
-					selected_certificate_size = attrs[1].ulValueLen;
954
-					memmove (
955
-						selected_certificate,
956
-						attrs_value,
957
-						selected_certificate_size
958
-					);
959
-					selected_id_size = attrs[0].ulValueLen;
960
-					memmove (
961
-						selected_id,
962
-						attrs_id,
963
-						selected_id_size
964
-					);
965
-				}
966
-			}
967
-		}
968
-	}
969
-
970
-	pkcs11_session->provider->f->C_FindObjectsFinal (
971
-		pkcs11_session->session
972
-	);
973
-
974
-	if (selected_certificate_size == 0) {
975
-		return CKR_ATTRIBUTE_VALUE_INVALID;
976
-	}
977
-
978
-	if ((pkcs11_session->certificate = (unsigned char *)malloc (selected_certificate_size)) == NULL) {
979
-		return CKR_HOST_MEMORY;
980
-	}
981
-	pkcs11_session->certificate_size = selected_certificate_size;
982
-	memmove (
983
-		pkcs11_session->certificate,
984
-		selected_certificate,
985
-		selected_certificate_size
986
-	);
987
-	if ((pkcs11_session->certificate_id = (unsigned char *)malloc (selected_id_size)) == NULL) {
988
-		return CKR_HOST_MEMORY;
989
-	}
990
-	pkcs11_session->certificate_id_size = selected_id_size;
991
-	memmove (
992
-		pkcs11_session->certificate_id,
993
-		selected_id,
994
-		selected_id_size
995
-	);
996
-
997
-	return CKR_OK;
998
-}
999
-
1000
-static
1001
-CK_RV
1002
-_pkcs11_loadKeyProperties (
1003
-	IN const pkcs11_session_t pkcs11_session
1004
-) {
1005
-	CK_OBJECT_HANDLE key;
1006
-	CK_RV rv;
1007
-
1008
-	CK_BBOOL key_attrs_sign_recover;
1009
-	CK_BBOOL key_attrs_sign;
1010
-	CK_ATTRIBUTE key_attrs[] = {
1011
-		{CKA_SIGN, &key_attrs_sign_recover, sizeof (key_attrs_sign_recover)},
1012
-		{CKA_SIGN_RECOVER, &key_attrs_sign, sizeof (key_attrs_sign)}
1013
-	};
1014
-
1015
-	ASSERT (pkcs11_session!=NULL);
1016
-
1017
-	if (!strcmp (pkcs11_session->provider->szSignMode, "recover")) {
1018
-		pkcs11_session->fKeySignRecover = true;
1019
-	}
1020
-	else if (!strcmp (pkcs11_session->provider->szSignMode, "sign")) {
1021
-		pkcs11_session->fKeySignRecover = false;
1022
-	}
1023
-	else {
1024
-		if (
1025
-			(rv = _pkcs11_getObjectById (
1026
-				pkcs11_session,
1027
-				CKO_PRIVATE_KEY,
1028
-				pkcs11_session->certificate_id,
1029
-				pkcs11_session->certificate_id_size,
1030
-				&key
1031
-			)) != CKR_OK
1032
-		) {
1033
-			return rv;
1034
-		}
1035
-
1036
-		if (
1037
-			pkcs11_session->provider->f->C_GetAttributeValue (
1038
-				pkcs11_session->session,
1039
-				key,
1040
-				key_attrs,
1041
-				sizeof (key_attrs) / sizeof (CK_ATTRIBUTE)
1042
-			) == CKR_OK
1043
-		) {
1044
-			if (key_attrs_sign_recover != CK_FALSE) {
1045
-				pkcs11_session->fKeySignRecover = true;
1046
-			}
1047
-			else if (key_attrs_sign != CK_FALSE) {
1048
-				pkcs11_session->fKeySignRecover = false;
1049
-			}
1050
-			else {
1051
-				return CKR_KEY_TYPE_INCONSISTENT;
1052
-			}
1053
-		}
1054
-
1055
-	}
1056
-
1057
-	return CKR_OK;
1058
-}
1059
-
1060
-static
1061
-CK_RV
1062
-_pkcs11_validateSession (
1063
-	IN const pkcs11_session_t pkcs11_session
1064
-) {
1065
-	if (
1066
-		pkcs11_session->timePINExpire != (time_t)0 &&
1067
-		pkcs11_session->timePINExpire < time (NULL)
1068
-	) {
1069
-		_pkcs11_logout (pkcs11_session);
1070
-	}
1071
-	return CKR_OK;
1072
-}
1073
-
1074
-static
1075
-CK_RV
1076
-_pkcs11_login (
1077
-	IN const pkcs11_session_t pkcs11_session
1078
-) {
1079
-	CK_RV rv = CKR_OK;
1080
-
1081
-
1082
-	ASSERT (pkcs11_session!=NULL);
1083
-
1084
-	_pkcs11_logout (pkcs11_session);
1085
-
1086
-	if (rv == CKR_OK) {
1087
-		rv = _pkcs11_resetSlot (pkcs11_session);
1088
-	}
1089
-
1090
-	if (rv == CKR_OK) {
1091
-		rv = pkcs11_session->provider->f->C_OpenSession (
1092
-			pkcs11_session->slot,
1093
-			CKF_SERIAL_SESSION,
1094
-			NULL_PTR,
1095
-			NULL_PTR,
1096
-			&pkcs11_session->session
1097
-		);
1098
-	}
1099
-
1100
-	if (rv == CKR_OK) {
1101
-		int nRetryCount = 0;
1102
-		do {
1103
-			CK_UTF8CHAR_PTR utfPIN = NULL;
1104
-			CK_ULONG lPINLength = 0;
1105
-			char szPIN[1024];
1106
-
1107
-			/*
1108
-			 * Assume OK for next iteration
1109
-			 */
1110
-			rv = CKR_OK;
1111
-
1112
-			if (
1113
-				rv == CKR_OK &&
1114
-				!pkcs11_session->fProtectedAuthentication
1115
-			) {
1116
-				if (
1117
-					!pkcs11_data->hooks->pin_prompt (
1118
-						pkcs11_data->hooks->pin_prompt_data,
1119
-						pkcs11_session->szLabel,
1120
-						szPIN,
1121
-						sizeof (szPIN)
1122
-					)
1123
-				) {
1124
-					rv = CKR_FUNCTION_FAILED;
1125
-				}
1126
-				else {
1127
-					utfPIN = (CK_UTF8CHAR_PTR)szPIN;
1128
-					lPINLength = strlen (szPIN);
1129
-				}
1130
-			}
1131
-
1132
-			if (pkcs11_data->nPINCachePeriod == -1) {
1133
-				pkcs11_session->timePINExpire = 0;
1134
-			}
1135
-			else {
1136
-				pkcs11_session->timePINExpire = (
1137
-					time (NULL) +
1138
-					(time_t)pkcs11_data->nPINCachePeriod
1139
-				);
1140
-			}
1141
-			if (
1142
-				rv == CKR_OK &&
1143
-				(rv = pkcs11_session->provider->f->C_Login (
1144
-					pkcs11_session->session,
1145
-					CKU_USER,
1146
-					utfPIN,
1147
-					lPINLength
1148
-				)) != CKR_OK
1149
-			) {
1150
-				if (rv == CKR_USER_ALREADY_LOGGED_IN) {
1151
-					rv = CKR_OK;
1152
-				}
1153
-			}
1154
-
1155
-			/*
1156
-			 * Clean PIN buffer
1157
-			 */
1158
-			memset (szPIN, 0, sizeof (szPIN));
1159
-		} while (
1160
-			++nRetryCount < 3 &&
1161
-			(
1162
-				rv == CKR_PIN_INCORRECT ||
1163
-				rv == CKR_PIN_INVALID
1164
-			)
1165
-		);
1166
-	}
1167
-
1168
-	if (
1169
-		rv == CKR_OK &&
1170
-		pkcs11_session->certificate_id != NULL
1171
-	) {
1172
-		rv = _pkcs11_getObjectById (
1173
-			pkcs11_session,
1174
-			CKO_PRIVATE_KEY,
1175
-			pkcs11_session->certificate_id,
1176
-			pkcs11_session->certificate_id_size,
1177
-			&pkcs11_session->key
1178
-		);
1179
-	}
1180
-
1181
-	return rv;
1182
-}
1183
-
1184
-static
1185
-CK_RV
1186
-_pkcs11_logout (
1187
-	IN const pkcs11_session_t pkcs11_session
1188
-) {
1189
-	ASSERT (pkcs11_session!=NULL);
1190
-
1191
-	if (pkcs11_session->session != (CK_SESSION_HANDLE)-1) {
1192
-		pkcs11_session->provider->f->C_Logout (pkcs11_session->session);
1193
-		pkcs11_session->provider->f->C_CloseSession (pkcs11_session->session);
1194
-		pkcs11_session->key = (CK_OBJECT_HANDLE)-1;
1195
-		pkcs11_session->session = (CK_SESSION_HANDLE)-1;
1196
-	}
1197
-
1198
-	return CKR_OK;
1199
-}
1200
-
1201
-
1202
-/*=======================================
1203
- * Simplified PKCS#11 functions
1204
- */
1205
-
1206
-static
1207
-bool
1208
-_pkcs11_hooks_card_prompt_default (
1209
-	IN const void * pData,
1210
-	IN const char * const szLabel
1211
-) {
1212
-	return false;
1213
-}
1214
-
1215
-static
1216
-bool
1217
-_pkcs11_hooks_pin_prompt_default (
1218
-	IN const void * pData,
1219
-	IN const char * const szLabel,
1220
-	OUT char * const szPIN,
1221
-	IN const size_t nMaxPIN
1222
-) {
1223
-	return false;
1224
-}
1225
-
1226
-static
1227
-CK_RV
1228
-pkcs11_initialize () {
1229
-
1230
-	pkcs11_terminate ();
1231
-
1232
-	pkcs11_data = (pkcs11_data_t)malloc (sizeof (struct pkcs11_data_s));
1233
-	if (pkcs11_data == NULL) {
1234
-		return CKR_HOST_MEMORY;
1235
-	}
1236
-
1237
-	memset (pkcs11_data, 0, sizeof (struct pkcs11_data_s));
1238
-
1239
-	pkcs11_data->nPINCachePeriod = -1;
1240
-
1241
-	pkcs11_data->hooks = (pkcs11_hooks_t)malloc (sizeof (struct pkcs11_hooks_s));
1242
-	if (pkcs11_data->hooks == NULL) {
1243
-		return CKR_HOST_MEMORY;
1244
-	}
1245
-
1246
-	memset (pkcs11_data->hooks, 0, sizeof (struct pkcs11_hooks_s));
1247
-
1248
-	pkcs11_data->fInitialized = true;
1249
-
1250
-	pkcs11_setCardPromptHook (_pkcs11_hooks_card_prompt_default, NULL);
1251
-	pkcs11_setPINPromptHook (_pkcs11_hooks_pin_prompt_default, NULL);
1252
-
1253
-	return CKR_OK;
1254
-}
1255
-
1256
-static
1257
-CK_RV
1258
-pkcs11_terminate () {
1259
-
1260
-	if (pkcs11_data != NULL) {
1261
-		pkcs11_provider_t last = NULL;
1262
-
1263
-		for (
1264
-			;
1265
-			pkcs11_data->providers != NULL;
1266
-			pkcs11_data->providers = pkcs11_data->providers->next
1267
-		) {
1268
-			if (last != NULL) {
1269
-				free (last);
1270
-			}
1271
-			last = pkcs11_data->providers;
1272
-		
1273
-			if (pkcs11_data->providers->szSignMode != NULL) {
1274
-				free (pkcs11_data->providers->szSignMode);
1275
-				pkcs11_data->providers->szSignMode = NULL;
1276
-			}
1277
-	
1278
-			if (pkcs11_data->providers->fShouldFinalize) {
1279
-				pkcs11_data->providers->f->C_Finalize (NULL);
1280
-				pkcs11_data->providers->fShouldFinalize = false;
1281
-			}
1282
-
1283
-			if (pkcs11_data->providers->f != NULL) {
1284
-				pkcs11_data->providers->f = NULL;
1285
-			}
1286
-	
1287
-			if (pkcs11_data->providers->hLibrary != NULL) {
1288
-#if defined(WIN32)
1289
-				FreeLibrary (pkcs11_data->providers->hLibrary);
1290
-#else
1291
-				dlclose (pkcs11_data->providers->hLibrary);
1292
-#endif
1293
-				pkcs11_data->providers->hLibrary = NULL;
1294
-			}
1295
-		}
1296
-
1297
-		if (last != NULL) {
1298
-			free (last);
1299
-		}
1300
-
1301
-		if (pkcs11_data->hooks != NULL) {
1302
-			free (pkcs11_data->hooks);
1303
-			pkcs11_data->hooks = NULL;
1304
-		}
1305
-
1306
-		free (pkcs11_data);
1307
-		pkcs11_data = NULL;
1308
-	}
1309
-
1310
-	return CKR_OK;
1311
-}
1312
-
1313
-static
1314
-CK_RV
1315
-pkcs11_setPINPromptHook (
1316
-	IN const pkcs11_hook_pin_prompt_t hook,
1317
-	IN void * const pData
1318
-) {
1319
-	ASSERT (pkcs11_data!=NULL);
1320
-	ASSERT (pkcs11_data->fInitialized);
1321
-
1322
-	pkcs11_data->hooks->pin_prompt = hook;
1323
-	pkcs11_data->hooks->pin_prompt_data = pData;
1324
-
1325
-	return CKR_OK;
1326
-}
1327
-
1328
-static
1329
-CK_RV
1330
-pkcs11_setCardPromptHook (
1331
-	IN const pkcs11_hook_card_prompt_t hook,
1332
-	IN void * const pData
1333
-) {
1334
-	ASSERT (pkcs11_data!=NULL);
1335
-	ASSERT (pkcs11_data->fInitialized);
1336
-
1337
-	pkcs11_data->hooks->card_prompt = hook;
1338
-	pkcs11_data->hooks->card_prompt_data = pData;
1339
-
1340
-	return CKR_OK;
1341
-}
1342
-
1343
-static
1344
-CK_RV
1345
-pkcs11_setPINCachePeriod (
1346
-	IN const int nPINCachePeriod
1347
-) {
1348
-	ASSERT (pkcs11_data!=NULL);
1349
-	ASSERT (pkcs11_data->fInitialized);
1350
-
1351
-	pkcs11_data->nPINCachePeriod = nPINCachePeriod;
1352
-
1353
-	return CKR_OK;
1354
-}
1355
-
1356
-static
1357
-CK_RV
1358
-pkcs11_addProvider (
1359
-	IN const char * const szProvider,
1360
-	IN const char * const szSignMode
1361
-) {
1362
-	pkcs11_provider_t provider = NULL;
1363
-	CK_C_GetFunctionList gfl = NULL;
1364
-	CK_RV rv = CKR_OK;
1365
-
1366
-	ASSERT (pkcs11_data!=NULL);
1367
-	ASSERT (pkcs11_data->fInitialized);
1368
-	ASSERT (szProvider!=NULL);
1369
-
1370
-	if (
1371
-		rv == CKR_OK &&
1372
-		(provider = (pkcs11_provider_t)malloc (sizeof (struct pkcs11_provider_s))) == NULL
1373
-	) {
1374
-		rv = CKR_HOST_MEMORY;
1375
-	}
1376
-
1377
-	if (rv == CKR_OK) {
1378
-		memset (provider, 0, sizeof (struct pkcs11_provider_s));
1379
-		if (szSignMode == NULL) {
1380
-			provider->szSignMode = strdup ("auto");
1381
-		}
1382
-		else {
1383
-			provider->szSignMode = strdup (szSignMode);
1384
-		}
1385
-		if (provider->szSignMode == NULL) {
1386
-			rv = CKR_HOST_MEMORY;
1387
-		}
1388
-	}
1389
-		
1390
-	if (rv == CKR_OK) {
1391
-#if defined(WIN32)
1392
-		provider->hLibrary = LoadLibrary (szProvider);
1393
-#else
1394
-		provider->hLibrary = dlopen (szProvider, RTLD_NOW);
1395
-#endif
1396
-		if (provider->hLibrary == NULL) {
1397
-			rv = CKR_FUNCTION_FAILED;
1398
-		}
1399
-	}
1400
-
1401
-	if (rv == CKR_OK) {
1402
-#if defined(WIN32)
1403
-		gfl = (CK_C_GetFunctionList)GetProcAddress (
1404
-			provider->hLibrary,
1405
-			"C_GetFunctionList"
1406
-		);
1407
-#else
1408
-		/*
1409
-		 * Make compiler happy!
1410
-		 */
1411
-		void *p = dlsym (
1412
-			provider->hLibrary,
1413
-			"C_GetFunctionList"
1414
-		);
1415
-		memmove (
1416
-			&gfl, 
1417
-			&p,
1418
-			sizeof (void *)
1419
-		);
1420
-#endif
1421
-		if (gfl == NULL) {
1422
-			rv = CKR_FUNCTION_FAILED;
1423
-		}
1424
-	}
1425
-
1426
-	if (rv == CKR_OK) {
1427
-		rv = gfl (&provider->f);
1428
-	}
1429
-
1430
-	if (rv == CKR_OK) {
1431
-		if ((rv = provider->f->C_Initialize (NULL)) != CKR_OK) {
1432
-			if (rv == CKR_CRYPTOKI_ALREADY_INITIALIZED) {
1433
-				rv = CKR_OK;
1434
-			}
1435
-		}
1436
-		else {
1437
-			provider->fShouldFinalize = true;
1438
-		}
1439
-	}
1440
-
1441
-	if (rv == CKR_OK) {
1442
-		provider->fEnabled = true;
1443
-	}
1444
-
1445
-	if (provider != NULL) {
1446
-		if (pkcs11_data->providers == NULL) {
1447
-			pkcs11_data->providers = provider;
1448
-		}
1449
-		else {
1450
-			pkcs11_provider_t last = NULL;
1451
-	
1452
-			for (
1453
-				last = pkcs11_data->providers;
1454
-				last->next != NULL;
1455
-				last = last->next
1456
-			);
1457
-			last->next = provider;
1458
-		}
1459
-	}
1460
-
1461
-	return rv;
1462
-}
1463
-
1464
-static
1465
-CK_RV
1466
-pkcs11_forkFixup () {
1467
-
1468
-	if (pkcs11_data != NULL && pkcs11_data->fInitialized) {
1469
-
1470
-		pkcs11_provider_t current;
1471
-
1472
-		for (
1473
-			current = pkcs11_data->providers;
1474
-			current != NULL;
1475
-			current = current->next
1476
-		) {
1477
-			if (current->fEnabled) {
1478
-				current->f->C_Initialize (NULL);
1479
-			}
1480
-		}
1481
-	}
1482
-
1483
-	return CKR_OK;
1484
-}
1485
-	
1486
-static
1487
-CK_RV
1488
-pkcs11_createSession (
1489
-	IN const char * const szSlotType,
1490
-	IN const char * const szSlot,
1491
-	IN const char * const szIdType,
1492
-	IN const char * const szId,
1493
-	IN const bool fProtectedAuthentication,
1494
-	OUT pkcs11_session_t * const p_pkcs11_session
52
+	IN const char * const szFormat,
53
+	IN ...
1495 54
 ) {
1496
-	pkcs11_session_t pkcs11_session;
1497
-	CK_RV rv = CKR_OK;
1498
-
1499
-	ASSERT (pkcs11_data!=NULL);
1500
-	ASSERT (pkcs11_data->fInitialized);
1501
-	ASSERT (szSlotType!=NULL);
1502
-	ASSERT (szSlot!=NULL);
1503
-	ASSERT (szIdType!=NULL);
1504
-	ASSERT (szId!=NULL);
1505
-	ASSERT (p_pkcs11_session!=NULL);
1506
-	
1507
-	if (
1508
-		rv == CKR_OK &&
1509
-		(pkcs11_session = (pkcs11_session_t)malloc (sizeof (struct pkcs11_session_s))) == NULL
1510
-	) {
1511
-		rv = CKR_HOST_MEMORY;
1512
-	}
1513
-
1514
-	if (rv == CKR_OK) {
1515
-		*p_pkcs11_session = pkcs11_session;
1516
-		memset (pkcs11_session, 0, sizeof (struct pkcs11_session_s));
1517
-	}
1518
-	
1519
-	if (rv == CKR_OK) {
1520
-		pkcs11_session->key = (CK_OBJECT_HANDLE)-1;
1521
-		pkcs11_session->session = (CK_SESSION_HANDLE)-1;
1522
-		pkcs11_session->fProtectedAuthentication = fProtectedAuthentication;
1523
-	}
1524
-
1525
-	if (rv == CKR_OK) {
1526
-		bool fCancel = false;
1527
-
1528
-		do {
1529
-			if (!strcmp (szSlotType, "id")) {
1530
-				rv = _pkcs11_getSlotById (pkcs11_session, szSlot);
1531
-			}
1532
-			else if (!strcmp (szSlotType, "name")) {
1533
-				rv = _pkcs11_getSlotByName (pkcs11_session, szSlot);
1534
-			}
1535
-			else if (!strcmp (szSlotType, "label")) {
1536
-				rv = _pkcs11_getSlotByLabel (pkcs11_session, szSlot);
1537
-			}
1538
-			else {
1539
-				rv = CKR_ARGUMENTS_BAD;
1540
-			}
1541
-
1542
-			if (rv == CKR_SLOT_ID_INVALID) {
1543
-				char szLabel[1024];
1544
-				snprintf (szLabel, sizeof (szLabel), "SLOT(%s=%s)", szSlotType, szSlot);
1545
-				fCancel = !pkcs11_data->hooks->card_prompt (
1546
-					pkcs11_data->hooks->card_prompt_data,
1547
-					szLabel
1548
-				);
1549
-			}
1550
-		} while (rv == CKR_SLOT_ID_INVALID && !fCancel);
1551
-	}
1552
-
1553
-	if (rv == CKR_OK) {
1554
-		rv = _pkcs11_setSessionTokenInfo (pkcs11_session);
1555
-	}
1556
-
1557
-	if (rv == CKR_OK) {
1558
-		rv = _pkcs11_login (
1559
-			pkcs11_session
1560
-		);
1561
-	}
1562
-
1563
-	if (rv == CKR_OK) {
1564
-		rv = _pkcs11_loadCertificate (
1565
-			pkcs11_session,
1566
-			szIdType,
1567
-			szId
1568
-		);
1569
-	}
1570
-
1571
-	if (rv == CKR_OK) {
1572
-		rv = _pkcs11_loadKeyProperties (
1573
-			pkcs11_session
1574
-		);
1575
-	}
1576
-	
1577
-	/*
1578
-	 * Complete missing login process
1579
-	 */
1580
-	if (rv == CKR_OK) {
1581
-		rv = _pkcs11_getObjectById (
1582
-			pkcs11_session,
1583
-			CKO_PRIVATE_KEY,
1584
-			pkcs11_session->certificate_id,
1585
-			pkcs11_session->certificate_id_size,
1586
-			&pkcs11_session->key
1587
-		);
1588
-	}
1589
-
1590
-	return rv;
1591
-}
1592
-
1593
-CK_RV
1594
-pkcs11_freeSession (
1595
-	IN const pkcs11_session_t pkcs11_session
1596
-) {
1597
-	ASSERT (pkcs11_data!=NULL);
1598
-	ASSERT (pkcs11_data->fInitialized);
1599
-
1600
-	if (pkcs11_session != NULL) {
1601
-		_pkcs11_logout (pkcs11_session);
1602
-
1603
-		if (pkcs11_session->certificate != NULL) {
1604
-			free (pkcs11_session->certificate);
1605
-		}
1606
-		if (pkcs11_session->certificate_id != NULL) {
1607
-			free (pkcs11_session->certificate_id);
1608
-		}
1609
-
1610
-		free (pkcs11_session);
1611
-	}
1612
-
1613
-	return CKR_OK;
1614
-}
1615
-
1616
-static
1617
-CK_RV
1618
-pkcs11_sign (
1619
-	IN const pkcs11_session_t pkcs11_session,
1620
-	IN const CK_MECHANISM_TYPE mech_type,
1621
-	IN const unsigned char * const source,
1622
-	IN const size_t source_size,
1623
-	OUT unsigned char * const target,
1624
-	IN OUT size_t * const target_size
1625
-) {
1626
-	CK_MECHANISM mech = {
1627
-		mech_type, NULL, 0
1628
-	};
1629
-	CK_RV rv = CKR_OK;
1630
-	bool fLogonRetry = false;
1631
-	bool fOpSuccess = false;
1632
-
1633
-	ASSERT (pkcs11_data!=NULL);
1634
-	ASSERT (pkcs11_data->fInitialized);
1635
-	ASSERT (pkcs11_session!=NULL);
1636
-	ASSERT (source!=NULL);
1637
-	ASSERT (target_size!=NULL);
1638
-
1639
-	rv = _pkcs11_validateSession (pkcs11_session);
1640
-
1641
-	while (rv == CKR_OK && !fOpSuccess) {
1642
-		rv = pkcs11_session->provider->f->C_SignInit (
1643
-			pkcs11_session->session,
1644
-			&mech,
1645
-			pkcs11_session->key
1646
-		);
1647
-
1648
-		if (rv == CKR_OK) {
1649
-			fOpSuccess = true;
1650
-		}
1651
-		else {
1652
-			if (!fLogonRetry) {
1653
-				fLogonRetry = true;
1654
-				rv = _pkcs11_login (pkcs11_session);
1655
-			}
1656
-		}
1657
-	}
1658
-
1659
-	if (rv == CKR_OK) {
1660
-		CK_ULONG size = *target_size;
1661
-		rv = pkcs11_session->provider->f->C_Sign (
1662
-			pkcs11_session->session,
1663
-			(CK_BYTE_PTR)source,
1664
-			source_size,
1665
-			(CK_BYTE_PTR)target,
1666
-			&size
1667
-		);
1668
-
1669
-		*target_size = (int)size;
1670
-	}
1671
-
1672
-	return rv;
1673
-}
1674
-
1675
-static
1676
-CK_RV
1677
-pkcs11_signRecover (
1678
-	IN const pkcs11_session_t pkcs11_session,
1679
-	IN const CK_MECHANISM_TYPE mech_type,
1680
-	IN const unsigned char * const source,
1681
-	IN const size_t source_size,
1682
-	OUT unsigned char * const target,
1683
-	IN OUT size_t * const target_size
1684
-) {
1685
-	CK_MECHANISM mech = {
1686
-		mech_type, NULL, 0
1687
-	};
1688
-	CK_RV rv = CKR_OK;
1689
-	bool fLogonRetry = false;
1690
-	bool fOpSuccess = false;
1691
-
1692
-	ASSERT (pkcs11_data!=NULL);
1693
-	ASSERT (pkcs11_data->fInitialized);
1694
-	ASSERT (pkcs11_session!=NULL);
1695
-	ASSERT (source!=NULL);
1696
-	ASSERT (target_size!=NULL);
1697
-
1698
-	rv = _pkcs11_validateSession (pkcs11_session);
1699
-
1700
-	while (rv == CKR_OK && !fOpSuccess) {
1701
-		rv = pkcs11_session->provider->f->C_SignRecoverInit (
1702
-			pkcs11_session->session,
1703
-			&mech,
1704
-			pkcs11_session->key
1705
-		);
1706
-
1707
-		if (rv == CKR_OK) {
1708
-			fOpSuccess = true;
1709
-		}
1710
-		else {
1711
-			if (!fLogonRetry) {
1712
-				fLogonRetry = true;
1713
-				rv = _pkcs11_login (pkcs11_session);
1714
-			}
1715
-		}
1716
-	}
1717
-
1718
-	if (rv == CKR_OK) {
1719
-		CK_ULONG size = *target_size;
1720
-		rv = pkcs11_session->provider->f->C_SignRecover (
1721
-			pkcs11_session->session,
1722
-			(CK_BYTE_PTR)source,
1723
-			source_size,
1724
-			(CK_BYTE_PTR)target,
1725
-			&size
1726
-		);
1727
-
1728
-		*target_size = (int)size;
1729
-	}
1730
-
1731
-	return rv;
1732
-}
1733
-
1734
-static
1735
-CK_RV
1736
-pkcs11_decrypt (
1737
-	IN const pkcs11_session_t pkcs11_session,
1738
-	IN const CK_MECHANISM_TYPE mech_type,
1739
-	IN const unsigned char * const source,
1740
-	IN const size_t source_size,
1741
-	OUT unsigned char * const target,
1742
-	IN OUT size_t * const target_size
1743
-) {
1744
-	CK_MECHANISM mech = {
1745
-		mech_type, NULL, 0
1746
-	};
1747
-	CK_ULONG size;
1748
-	CK_RV rv = CKR_OK;
1749
-	bool fLogonRetry = false;
1750
-	bool fOpSuccess = false;
1751
-
1752
-	ASSERT (pkcs11_data!=NULL);
1753
-	ASSERT (pkcs11_data->fInitialized);
1754
-	ASSERT (pkcs11_session!=NULL);
1755
-	ASSERT (source!=NULL);
1756
-	ASSERT (target_size!=NULL);
1757
-
1758
-	rv = _pkcs11_validateSession (pkcs11_session);
1759
-
1760
-	while (rv == CKR_OK && !fOpSuccess) {
1761
-		rv = pkcs11_session->provider->f->C_DecryptInit (
1762
-			pkcs11_session->session,
1763
-			&mech,
1764
-			pkcs11_session->key
1765
-		);
1766
-
1767
-		if (rv == CKR_OK) {
1768
-			fOpSuccess = true;
1769
-		}
1770
-		else {
1771
-			if (!fLogonRetry) {
1772
-				fLogonRetry = true;
1773
-				rv = _pkcs11_login (pkcs11_session);
1774
-			}
1775
-		}
1776
-	}
1777
-
1778
-	if (rv == CKR_OK) {
1779
-		size = *target_size;
1780
-		rv = pkcs11_session->provider->f->C_Decrypt (
1781
-			pkcs11_session->session,
1782
-			(CK_BYTE_PTR)source,
1783
-			source_size,
1784
-			(CK_BYTE_PTR)target,
1785
-			&size
1786
-		);
1787
-
1788
-		*target_size = (int)size;
1789
-	}
1790
-
1791
-	return rv;
1792
-}
1793
-
1794
-static
1795
-CK_RV
1796
-pkcs11_getCertificate (
1797
-	IN const pkcs11_session_t pkcs11_session,
1798
-	OUT unsigned char * const certificate,
1799
-	IN OUT size_t * const certificate_size
1800
-) {
1801
-	ASSERT (pkcs11_data!=NULL);
1802
-	ASSERT (pkcs11_data->fInitialized);
1803
-	ASSERT (certificate_size!=NULL);
1804
-
1805
-	*certificate_size = pkcs11_session->certificate_size;
1806
-
1807
-	if (certificate == NULL) {
1808
-		return CKR_OK;
1809
-	}
1810
-
1811
-	if (*certificate_size > pkcs11_session->certificate_size) {
1812
-		return CKR_BUFFER_TOO_SMALL;
1813
-	}
1814
-
1815
-	memmove (certificate, pkcs11_session->certificate, *certificate_size);	
1816
-
1817
-	return CKR_OK;
1818
-}
1819
-
1820
-static
1821
-char *
1822
-pkcs11_getMessage (
1823
-	IN const int rv
1824
-) {
1825
-	switch (rv) {
1826
-		case CKR_OK: return "CKR_OK";
1827
-		case CKR_CANCEL: return "CKR_CANCEL";
1828
-		case CKR_HOST_MEMORY: return "CKR_HOST_MEMORY";
1829
-		case CKR_SLOT_ID_INVALID: return "CKR_SLOT_ID_INVALID";
1830
-		case CKR_GENERAL_ERROR: return "CKR_GENERAL_ERROR";
1831
-		case CKR_FUNCTION_FAILED: return "CKR_FUNCTION_FAILED";
1832
-		case CKR_ARGUMENTS_BAD: return "CKR_ARGUMENTS_BAD";
1833
-		case CKR_NO_EVENT: return "CKR_NO_EVENT";
1834
-		case CKR_NEED_TO_CREATE_THREADS: return "CKR_NEED_TO_CREATE_THREADS";
1835
-		case CKR_CANT_LOCK: return "CKR_CANT_LOCK";
1836
-		case CKR_ATTRIBUTE_READ_ONLY: return "CKR_ATTRIBUTE_READ_ONLY";
1837
-		case CKR_ATTRIBUTE_SENSITIVE: return "CKR_ATTRIBUTE_SENSITIVE";
1838
-		case CKR_ATTRIBUTE_TYPE_INVALID: return "CKR_ATTRIBUTE_TYPE_INVALID";
1839
-		case CKR_ATTRIBUTE_VALUE_INVALID: return "CKR_ATTRIBUTE_VALUE_INVALID";
1840
-		case CKR_DATA_INVALID: return "CKR_DATA_INVALID";
1841
-		case CKR_DATA_LEN_RANGE: return "CKR_DATA_LEN_RANGE";
1842
-		case CKR_DEVICE_ERROR: return "CKR_DEVICE_ERROR";
1843
-		case CKR_DEVICE_MEMORY: return "CKR_DEVICE_MEMORY";
1844
-		case CKR_DEVICE_REMOVED: return "CKR_DEVICE_REMOVED";
1845
-		case CKR_ENCRYPTED_DATA_INVALID: return "CKR_ENCRYPTED_DATA_INVALID";
1846
-		case CKR_ENCRYPTED_DATA_LEN_RANGE: return "CKR_ENCRYPTED_DATA_LEN_RANGE";
1847
-		case CKR_FUNCTION_CANCELED: return "CKR_FUNCTION_CANCELED";
1848
-		case CKR_FUNCTION_NOT_PARALLEL: return "CKR_FUNCTION_NOT_PARALLEL";
1849
-		case CKR_FUNCTION_NOT_SUPPORTED: return "CKR_FUNCTION_NOT_SUPPORTED";
1850
-		case CKR_KEY_HANDLE_INVALID: return "CKR_KEY_HANDLE_INVALID";
1851
-		case CKR_KEY_SIZE_RANGE: return "CKR_KEY_SIZE_RANGE";
1852
-		case CKR_KEY_TYPE_INCONSISTENT: return "CKR_KEY_TYPE_INCONSISTENT";
1853
-		case CKR_KEY_NOT_NEEDED: return "CKR_KEY_NOT_NEEDED";
1854
-		case CKR_KEY_CHANGED: return "CKR_KEY_CHANGED";
1855
-		case CKR_KEY_NEEDED: return "CKR_KEY_NEEDED";
1856
-		case CKR_KEY_INDIGESTIBLE: return "CKR_KEY_INDIGESTIBLE";
1857
-		case CKR_KEY_FUNCTION_NOT_PERMITTED: return "CKR_KEY_FUNCTION_NOT_PERMITTED";
1858
-		case CKR_KEY_NOT_WRAPPABLE: return "CKR_KEY_NOT_WRAPPABLE";
1859
-		case CKR_KEY_UNEXTRACTABLE: return "CKR_KEY_UNEXTRACTABLE";
1860
-		case CKR_MECHANISM_INVALID: return "CKR_MECHANISM_INVALID";
1861
-		case CKR_MECHANISM_PARAM_INVALID: return "CKR_MECHANISM_PARAM_INVALID";
1862
-		case CKR_OBJECT_HANDLE_INVALID: return "CKR_OBJECT_HANDLE_INVALID";
1863
-		case CKR_OPERATION_ACTIVE: return "CKR_OPERATION_ACTIVE";
1864
-		case CKR_OPERATION_NOT_INITIALIZED: return "CKR_OPERATION_NOT_INITIALIZED";
1865
-		case CKR_PIN_INCORRECT: return "CKR_PIN_INCORRECT";
1866
-		case CKR_PIN_INVALID: return "CKR_PIN_INVALID";
1867
-		case CKR_PIN_LEN_RANGE: return "CKR_PIN_LEN_RANGE";
1868
-		case CKR_PIN_EXPIRED: return "CKR_PIN_EXPIRED";
1869
-		case CKR_PIN_LOCKED: return "CKR_PIN_LOCKED";
1870
-		case CKR_SESSION_CLOSED: return "CKR_SESSION_CLOSED";
1871
-		case CKR_SESSION_COUNT: return "CKR_SESSION_COUNT";
1872
-		case CKR_SESSION_HANDLE_INVALID: return "CKR_SESSION_HANDLE_INVALID";
1873
-		case CKR_SESSION_PARALLEL_NOT_SUPPORTED: return "CKR_SESSION_PARALLEL_NOT_SUPPORTED";
1874
-		case CKR_SESSION_READ_ONLY: return "CKR_SESSION_READ_ONLY";
1875
-		case CKR_SESSION_EXISTS: return "CKR_SESSION_EXISTS";
1876
-		case CKR_SESSION_READ_ONLY_EXISTS: return "CKR_SESSION_READ_ONLY_EXISTS";
1877
-		case CKR_SESSION_READ_WRITE_SO_EXISTS: return "CKR_SESSION_READ_WRITE_SO_EXISTS";
1878
-		case CKR_SIGNATURE_INVALID: return "CKR_SIGNATURE_INVALID";
1879
-		case CKR_SIGNATURE_LEN_RANGE: return "CKR_SIGNATURE_LEN_RANGE";
1880
-		case CKR_TEMPLATE_INCOMPLETE: return "CKR_TEMPLATE_INCOMPLETE";
1881
-		case CKR_TEMPLATE_INCONSISTENT: return "CKR_TEMPLATE_INCONSISTENT";
1882
-		case CKR_TOKEN_NOT_PRESENT: return "CKR_TOKEN_NOT_PRESENT";
1883
-		case CKR_TOKEN_NOT_RECOGNIZED: return "CKR_TOKEN_NOT_RECOGNIZED";
1884
-		case CKR_TOKEN_WRITE_PROTECTED: return "CKR_TOKEN_WRITE_PROTECTED";
1885
-		case CKR_UNWRAPPING_KEY_HANDLE_INVALID: return "CKR_UNWRAPPING_KEY_HANDLE_INVALID";
1886
-		case CKR_UNWRAPPING_KEY_SIZE_RANGE: return "CKR_UNWRAPPING_KEY_SIZE_RANGE";
1887
-		case CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT: return "CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT";
1888
-		case CKR_USER_ALREADY_LOGGED_IN: return "CKR_USER_ALREADY_LOGGED_IN";
1889
-		case CKR_USER_NOT_LOGGED_IN: return "CKR_USER_NOT_LOGGED_IN";
1890
-		case CKR_USER_PIN_NOT_INITIALIZED: return "CKR_USER_PIN_NOT_INITIALIZED";
1891
-		case CKR_USER_TYPE_INVALID: return "CKR_USER_TYPE_INVALID";
1892
-		case CKR_USER_ANOTHER_ALREADY_LOGGED_IN: return "CKR_USER_ANOTHER_ALREADY_LOGGED_IN";
1893
-		case CKR_USER_TOO_MANY_TYPES: return "CKR_USER_TOO_MANY_TYPES";
1894
-		case CKR_WRAPPED_KEY_INVALID: return "CKR_WRAPPED_KEY_INVALID";
1895
-		case CKR_WRAPPED_KEY_LEN_RANGE: return "CKR_WRAPPED_KEY_LEN_RANGE";
1896
-		case CKR_WRAPPING_KEY_HANDLE_INVALID: return "CKR_WRAPPING_KEY_HANDLE_INVALID";
1897
-		case CKR_WRAPPING_KEY_SIZE_RANGE: return "CKR_WRAPPING_KEY_SIZE_RANGE";
1898
-		case CKR_WRAPPING_KEY_TYPE_INCONSISTENT: return "CKR_WRAPPING_KEY_TYPE_INCONSISTENT";
1899
-		case CKR_RANDOM_SEED_NOT_SUPPORTED: return "CKR_RANDOM_SEED_NOT_SUPPORTED";
1900
-		case CKR_RANDOM_NO_RNG: return "CKR_RANDOM_NO_RNG";
1901
-		case CKR_DOMAIN_PARAMS_INVALID: return "CKR_DOMAIN_PARAMS_INVALID";
1902
-		case CKR_BUFFER_TOO_SMALL: return "CKR_BUFFER_TOO_SMALL";
1903
-		case CKR_SAVED_STATE_INVALID: return "CKR_SAVED_STATE_INVALID";
1904
-		case CKR_INFORMATION_SENSITIVE: return "CKR_INFORMATION_SENSITIVE";
1905
-		case CKR_STATE_UNSAVEABLE: return "CKR_STATE_UNSAVEABLE";
1906
-		case CKR_CRYPTOKI_NOT_INITIALIZED: return "CKR_CRYPTOKI_NOT_INITIALIZED";
1907
-		case CKR_CRYPTOKI_ALREADY_INITIALIZED: return "CKR_CRYPTOKI_ALREADY_INITIALIZED";
1908
-		case CKR_MUTEX_BAD: return "CKR_MUTEX_BAD";
1909
-		case CKR_MUTEX_NOT_LOCKED: return "CKR_MUTEX_NOT_LOCKED";
1910
-		case CKR_FUNCTION_REJECTED: return "CKR_FUNCTION_REJECTED";
1911
-		case CKR_VENDOR_DEFINED: return "CKR_VENDOR_DEFINED";
1912
-		default: return "Unknown PKCS#11 error";
1913
-	}
1914
-}
1915
-
1916
-/*==========================================
1917
- * openssl interface
1918
- */
1919
-
1920
-typedef struct openssl_session_s {
1921
-	RSA_METHOD smart_rsa;
1922
-	int (*orig_finish)(RSA *rsa);
1923
-	pkcs11_session_t pkcs11_session;
1924
-} *openssl_session_t;
1925
-
1926
-static
1927
-pkcs11_session_t
1928
-_openssl_get_pkcs11_session (const RSA *rsa) {
1929
-	openssl_session_t session;
1930
-	
1931
-	ASSERT (rsa!=NULL);
1932
-	session = (openssl_session_t)RSA_get_app_data (rsa);
1933
-	ASSERT (session!=NULL);
1934
-	ASSERT (session->pkcs11_session!=NULL);
1935
-
1936
-	return session->pkcs11_session;
1937
-}
1938
-
1939
-static
1940
-int
1941
-openssl_pkcs11_priv_enc (
1942
-	int flen,
1943
-	const unsigned char *from,
1944
-	unsigned char *to,
1945
-	RSA *rsa,
1946
-	int padding
1947
-) {
1948
-	msg(M_WARN, "PKCS#11: Private key encryption not supported");
1949
-	return -1;
1950
-}
1951
-
1952
-static
1953
-int
1954
-openssl_pkcs11_priv_dec (
1955
-	int flen, const unsigned char *from,
1956
-	unsigned char *to,
1957
-	RSA *rsa,
1958
-	int padding
1959
-) {
1960
-	pkcs11_session_t pkcs11_session = _openssl_get_pkcs11_session (rsa);
1961
-	CK_RV rv = CKR_OK;
1962
-
1963
-	msg (
1964
-		D_PKCS11_DEBUG,
1965
-		"PKCS#11: openssl_pkcs11_priv_dec entered - flen=%d, from=%p, to=%p, rsa=%p, padding=%d",
1966
-		flen,
1967
-		from,
1968
-		to,
1969
-		(void *)rsa,
1970
-		padding
1971
-	);
1972
-
1973
-	ASSERT (from!=NULL);
1974
-	ASSERT (to!=NULL);
1975
-
1976
-	msg (
1977
-		D_SHOW_PKCS11,
1978
-		"PKCS#11: Performing decryption using private key"
1979
-	);
1980
-
1981
-	if (padding != RSA_PKCS1_PADDING) {
1982
-		rv = CKR_ARGUMENTS_BAD;
1983
-	}
1984
-
1985
-	if (
1986
-		rv == CKR_OK &&
1987
-		(rv = pkcs11_decrypt (
1988
-			pkcs11_session,
1989
-			CKM_RSA_PKCS,
1990
-			from,
1991
-			flen,
1992
-			to,
1993
-			(size_t *)&flen
1994
-		)) != CKR_OK
1995
-	) {
1996
-		msg (M_WARN, "PKCS#11: Cannot decrypt using private key %ld:'%s'", rv, pkcs11_getMessage (rv));
1997
-	}
1998
-
1999
-	msg (
2000
-		D_PKCS11_DEBUG,
2001
-		"PKCS#11: openssl_pkcs11_priv_dec - return rv=%ld",
2002
-		rv
2003
-	);
2004
-	
2005
-	return rv == CKR_OK ? 1 : -1; 
2006
-}
2007
-
2008
-static
2009
-int
2010
-openssl_pkcs11_sign (
2011
-	int type,
2012
-	const unsigned char *m,
2013
-	unsigned int m_len,
2014
-	unsigned char *sigret,
2015
-	unsigned int *siglen,
2016
-	const RSA *rsa
2017
-) {
2018
-	pkcs11_session_t pkcs11_session = _openssl_get_pkcs11_session (rsa);
2019
-	CK_RV rv = CKR_OK;
2020
-
2021
-	msg (
2022
-		D_PKCS11_DEBUG,
2023
-		"PKCS#11: openssl_pkcs11_priv_sign entered - type=%d, m=%p, m_len=%u, signret=%p, signlen=%p, rsa=%p",
2024
-		type,
2025
-		m,
2026
-		m_len,
2027
-		sigret,
2028
-		(void *)siglen,
2029
-		(void *)rsa
2030
-	);
2031
-
2032
-	ASSERT (m!=NULL);
2033
-	ASSERT (siglen!=NULL);
2034
-
2035
-	msg (
2036
-		D_SHOW_PKCS11,
2037
-		"PKCS#11: Performing signature"
2038
-	);
2039
-
2040
-	*siglen = RSA_size(rsa);
2041
-
2042
-	if (pkcs11_session->fKeySignRecover) {
2043
-		if (
2044
-			(rv = pkcs11_signRecover (
2045
-				pkcs11_session,
2046
-				CKM_RSA_PKCS,
2047
-				m,
2048
-				m_len,
2049
-				sigret,
2050
-				siglen
2051
-			)) != CKR_OK
2052
-		) {
2053
-			msg (M_WARN, "PKCS#11: Cannot perform signature-recover %ld:'%s'", rv, pkcs11_getMessage (rv));
2054
-		}
2055
-	}
2056
-	else {
2057
-		if (
2058
-			(rv = pkcs11_sign (
2059
-				pkcs11_session,
2060
-				CKM_RSA_PKCS,
2061
-				m,
2062
-				m_len,
2063
-				sigret,
2064
-				siglen
2065
-			)) != CKR_OK
2066
-		) {
2067
-			msg (M_WARN, "PKCS#11: Cannot perform signature %ld:'%s'", rv, pkcs11_getMessage (rv));
2068
-		}
2069
-	}
2070
-
2071
-	msg (
2072
-		D_PKCS11_DEBUG,
2073
-		"PKCS#11: openssl_pkcs11_priv_sign - return rv=%ld",
2074
-		rv
2075
-	);
2076
-	
2077
-	return rv == CKR_OK ? 1 : -1; 
2078
-}
2079
-
2080
-static
2081
-int
2082
-openssl_pkcs11_finish(RSA *rsa) {
2083
-	pkcs11_session_t pkcs11_session = _openssl_get_pkcs11_session (rsa);
2084
-	openssl_session_t openssl_session;
2085
-
2086
-	msg (
2087
-		D_PKCS11_DEBUG,
2088
-		"PKCS#11: openssl_pkcs11_finish - entered rsa=%p",
2089
-		(void *)rsa
2090
-	);
2091
-
2092
-	openssl_session = (openssl_session_t)RSA_get_app_data (rsa);
2093
-
2094
-	RSA_set_app_data (rsa, NULL);
2095
-	pkcs11_freeSession (pkcs11_session);
2096
-	
2097
-	if (openssl_session->orig_finish != NULL) {
2098
-		openssl_session->orig_finish (rsa);
2099
-
2100
-#ifdef BROKEN_OPENSSL_ENGINE
2101
-		{
2102
-			/* We get called TWICE here, once for
2103
-			 * releasing the key and also for
2104
-			 * releasing the engine.
2105
-			 * To prevent endless recursion, FIRST
2106
-			 * clear rsa->engine, THEN call engine->finish
2107
-			 */
2108
-			ENGINE *e = rsa->engine;
2109
-			rsa->engine = NULL;
2110
-			if (e) {
2111
-				ENGINE_finish(e);
2112
-			}
2113
-		}
2114
-#endif
2115
-	}
2116
-
2117
-	free  (openssl_session);
2118
-
2119
-	msg (
2120
-		D_PKCS11_DEBUG,
2121
-		"PKCS#11: openssl_pkcs11_finish - return"
2122
-	);
55
+	char Buffer[10*1024];
56
+	va_list args;
2123 57
 	
2124
-	return 1;
2125
-}
2126
-
2127
-void
2128
-openssl_pkcs11_set_rsa(const openssl_session_t openssl_session, RSA *rsa)
2129
-{
2130
-	const RSA_METHOD *def = RSA_get_default_method();
2131
-
2132
-	ASSERT (openssl_session!=NULL);
2133
-	ASSERT (rsa!=NULL);
2134
-
2135
-	memmove (&openssl_session->smart_rsa, def, sizeof(RSA_METHOD));
2136
-
2137
-	openssl_session->orig_finish = def->finish;
2138
-
2139
-	openssl_session->smart_rsa.name = "pkcs11";
2140
-	openssl_session->smart_rsa.rsa_priv_enc = openssl_pkcs11_priv_enc;
2141
-	openssl_session->smart_rsa.rsa_priv_dec = openssl_pkcs11_priv_dec;
2142
-	openssl_session->smart_rsa.rsa_sign = openssl_pkcs11_sign;
2143
-	openssl_session->smart_rsa.finish = openssl_pkcs11_finish;
2144
-	openssl_session->smart_rsa.flags  = RSA_METHOD_FLAG_NO_CHECK | RSA_FLAG_EXT_PKEY;
2145
-
2146
-	RSA_set_method (rsa, &openssl_session->smart_rsa);
2147
-	RSA_set_app_data (rsa, openssl_session);
58
+	va_start (args, szFormat);
59
+	vsnprintf (Buffer, sizeof (Buffer), szFormat, args);
60
+	va_end (args);
61
+	Buffer[sizeof (Buffer)-1] = 0;
2148 62
 	
2149
-#ifdef BROKEN_OPENSSL_ENGINE
2150
-	if (fOK) {
2151
-		if (!rsa->engine)
2152
-			rsa->engine = ENGINE_get_default_RSA();
2153
-
2154
-		ENGINE_set_RSA(ENGINE_get_default_RSA(), openssl_session->smart_rsa);
2155
-		msg(M_WARN, "PKCS#11: OpenSSL engine support is broken! Workaround enabled");
2156
-	}
2157
-#endif
2158
-}
2159
-
2160
-
2161
-#ifdef BROKEN_OPENSSL_ENGINE
2162
-static void broken_openssl_init() __attribute__ ((constructor));
2163
-static void  broken_openssl_init()
2164
-{
2165
-	SSL_library_init();
2166
-	ENGINE_load_openssl();
2167
-	ENGINE_register_all_RSA();
63
+	msg (M_INFO|M_NOPREFIX|M_NOLF, "%s", Buffer);
2168 64
 }
2169
-#endif
2170
-
2171
-/*==========================================
2172
- * openvpn interface
2173
- */
2174 65
 
2175 66
 static
2176 67
 bool
2177
-_openvpn_pkcs11_card_prompt (
68
+_pkcs11_openvpn_card_prompt (
2178 69
 	IN const void *pData,
2179 70
 	IN const char * const szLabel
2180 71
 ) {
... ...
@@ -2184,11 +75,11 @@ _openvpn_pkcs11_card_prompt (
2184 2184
 
2185 2185
 	ASSERT (szLabel!=NULL);
2186 2186
 
2187
-	openvpn_snprintf (szPrompt, sizeof (szPrompt), "INSERT");
2187
+	openvpn_snprintf (szPrompt, sizeof (szPrompt), "Please insert %s token", szLabel);
2188 2188
 
2189 2189
 	token_pass.defined = false;
2190 2190
 	token_pass.nocache = true;
2191
-	get_user_pass (&token_pass, NULL, true, szPrompt, GET_USER_PASS_MANAGEMENT|GET_USER_PASS_SENSITIVE);
2191
+	get_user_pass (&token_pass, NULL, szPrompt, GET_USER_PASS_MANAGEMENT|GET_USER_PASS_NEED_OK);
2192 2192
 	strncpynt (szTemp, token_pass.password, sizeof (szTemp));
2193 2193
 	purge_user_pass (&token_pass, true);
2194 2194
 
... ...
@@ -2202,7 +93,7 @@ _openvpn_pkcs11_card_prompt (
2202 2202
 
2203 2203
 static
2204 2204
 bool
2205
-_openvpn_pkcs11_pin_prompt (
2205
+_pkcs11_openvpn_pin_prompt (
2206 2206
 	IN const void *pData,
2207 2207
 	IN const char * const szLabel,
2208 2208
 	OUT char * const szPIN,
... ...
@@ -2217,7 +108,7 @@ _openvpn_pkcs11_pin_prompt (
2217 2217
 
2218 2218
 	token_pass.defined = false;
2219 2219
 	token_pass.nocache = true;
2220
-	get_user_pass (&token_pass, NULL, true, szPrompt, GET_USER_PASS_MANAGEMENT|GET_USER_PASS_SENSITIVE);
2220
+	get_user_pass (&token_pass, NULL, szPrompt, GET_USER_PASS_MANAGEMENT|GET_USER_PASS_PASSWORD_ONLY);
2221 2221
 	strncpynt (szPIN, token_pass.password, nMaxPIN);
2222 2222
 	purge_user_pass (&token_pass, true);
2223 2223
 
... ...
@@ -2230,213 +121,166 @@ _openvpn_pkcs11_pin_prompt (
2230 2230
 }
2231 2231
 
2232 2232
 void
2233
-init_pkcs11 (
2233
+pkcs11_initialize (
2234 2234
 	const int nPINCachePeriod
2235 2235
 ) {
2236 2236
 	CK_RV rv;
2237 2237
 
2238
-	msg (
2239
-		D_PKCS11_DEBUG,
2240
-		"PKCS#11: init_pkcs11 - entered"
2238
+	PKCS11LOG (
2239
+		PKCS11_LOG_DEBUG2,
2240
+		"PKCS#11: pkcs11_initialize - entered"
2241 2241
 	);
2242 2242
 
2243
-	if ((rv = pkcs11_initialize ()) != CKR_OK) {
2244
-		msg (M_FATAL, "PKCS#11: Cannot initialize %ld-'%s'", rv, pkcs11_getMessage (rv));
2243
+	if ((rv = pkcs11h_initialize ()) != CKR_OK) {
2244
+		PKCS11LOG (PKCS11_LOG_ERROR, "PKCS#11: Cannot initialize %ld-'%s'", rv, pkcs11h_getMessage (rv));
2245 2245
 	}
2246
-/*Until REQUEST/REPLY interface.
2247
-	if ((rv = pkcs11_setCardPromptHook (_openvpn_pkcs11_card_prompt, NULL)) != CKR_OK) {
2248
-		msg (M_FATAL, "PKCS#11: Cannot set hooks %ld-'%s'", rv, pkcs11_getMessage (rv));
2246
+
2247
+	if ((rv = pkcs11h_setCardPromptHook (_pkcs11_openvpn_card_prompt, NULL)) != CKR_OK) {
2248
+		PKCS11LOG (PKCS11_LOG_ERROR, "PKCS#11: Cannot set hooks %ld-'%s'", rv, pkcs11h_getMessage (rv));
2249 2249
 	}
2250
-*/
2251
-	if ((rv = pkcs11_setPINPromptHook (_openvpn_pkcs11_pin_prompt, NULL)) != CKR_OK) {
2252
-		msg (M_FATAL, "PKCS#11: Cannot set hooks %ld-'%s'", rv, pkcs11_getMessage (rv));
2250
+
2251
+	if ((rv = pkcs11h_setPINPromptHook (_pkcs11_openvpn_pin_prompt, NULL)) != CKR_OK) {
2252
+		PKCS11LOG (PKCS11_LOG_ERROR, "PKCS#11: Cannot set hooks %ld-'%s'", rv, pkcs11h_getMessage (rv));
2253 2253
 	}
2254 2254
 
2255
-	if ((rv = pkcs11_setPINCachePeriod (nPINCachePeriod)) != CKR_OK) {
2256
-		msg (M_FATAL, "PKCS#11: Cannot set PIN cache period %ld-'%s'", rv, pkcs11_getMessage (rv));
2255
+	if ((rv = pkcs11h_setPINCachePeriod (nPINCachePeriod)) != CKR_OK) {
2256
+		PKCS11LOG (PKCS11_LOG_ERROR, "PKCS#11: Cannot set PIN cache period %ld-'%s'", rv, pkcs11h_getMessage (rv));
2257 2257
 	}
2258 2258
 
2259
-	msg (
2260
-		D_PKCS11_DEBUG,
2261
-		"PKCS#11: init_pkcs11 - return"
2259
+	PKCS11LOG (
2260
+		PKCS11_LOG_DEBUG2,
2261
+		"PKCS#11: pkcs11_initialize - return"
2262 2262
 	);
2263 2263
 }
2264 2264
 
2265 2265
 void
2266
-free_pkcs11 () {
2267
-	msg (
2268
-		D_PKCS11_DEBUG,
2269
-		"PKCS#11: free_pkcs11 - entered"
2266
+pkcs11_terminate () {
2267
+	PKCS11LOG (
2268
+		PKCS11_LOG_DEBUG2,
2269
+		"PKCS#11: pkcs11_terminate - entered"
2270 2270
 	);
2271 2271
 
2272
-	pkcs11_terminate ();
2272
+	pkcs11h_terminate ();
2273 2273
 
2274
-	msg (
2275
-		D_PKCS11_DEBUG,
2276
-		"PKCS#11: free_pkcs11 - return"
2274
+	PKCS11LOG (
2275
+		PKCS11_LOG_DEBUG2,
2276
+		"PKCS#11: pkcs11_terminate - return"
2277 2277
 	);
2278 2278
 }
2279 2279
 
2280 2280
 void
2281
-fork_fix_pkcs11 () {
2282
-	pkcs11_forkFixup ();
2281
+pkcs11_forkFixup () {
2282
+	pkcs11h_forkFixup ();
2283 2283
 }
2284 2284
 
2285 2285
 void
2286
-add_pkcs11 (
2286
+pkcs11_addProvider (
2287 2287
 	IN const char * const provider,
2288 2288
 	IN const char * const sign_mode
2289 2289
 ) {
2290 2290
 	CK_RV rv;
2291 2291
 
2292
-	msg (
2293
-		D_PKCS11_DEBUG,
2294
-		"PKCS#11: add_pkcs11 - entered - provider='%s', sign_mode='%s'",
2292
+	PKCS11LOG (
2293
+		PKCS11_LOG_DEBUG2,
2294
+		"PKCS#11: pkcs11_addProvider - entered - provider='%s', sign_mode='%s'",
2295 2295
 		provider,
2296 2296
 		sign_mode == NULL ? "default" : sign_mode
2297 2297
 	);
2298 2298
 
2299
-	msg (
2300
-		M_INFO,
2299
+	PKCS11LOG (
2300
+		PKCS11_LOG_INFO,
2301 2301
 		"PKCS#11: Adding PKCS#11 provider '%s'",
2302 2302
 		provider
2303 2303
 	);
2304 2304
 
2305
-	if ((rv = pkcs11_addProvider (provider, sign_mode)) != CKR_OK) {
2306
-		msg (M_WARN, "PKCS#11: Cannot initialize provider '%s' %ld-'%s'", provider, rv, pkcs11_getMessage (rv));
2305
+	if ((rv = pkcs11h_addProvider (provider, sign_mode)) != CKR_OK) {
2306
+		PKCS11LOG (PKCS11_LOG_WARN, "PKCS#11: Cannot initialize provider '%s' %ld-'%s'", provider, rv, pkcs11h_getMessage (rv));
2307 2307
 	}
2308 2308
 
2309
-	msg (
2310
-		D_PKCS11_DEBUG,
2311
-		"PKCS#11: add_pkcs11 - return"
2309
+	PKCS11LOG (
2310
+		PKCS11_LOG_DEBUG2,
2311
+		"PKCS#11: pkcs11_addProvider - return"
2312 2312
 	);
2313 2313
 }
2314 2314
 
2315 2315
 int
2316 2316
 SSL_CTX_use_pkcs11 (
2317 2317
 	IN OUT SSL_CTX * const ssl_ctx,
2318
-	IN const char * const pkcs11_slot_type,
2319
-	IN const char * const pkcs11_slot,
2320
-	IN const char * const pkcs11_id_type,
2321
-	IN const char * const pkcs11_id,
2322
-	IN const bool pkcs11_protected_authentication
2318
+	IN const char * const pkcs11h_slot_type,
2319
+	IN const char * const pkcs11h_slot,
2320
+	IN const char * const pkcs11h_id_type,
2321
+	IN const char * const pkcs11h_id,
2322
+	IN const bool pkcs11h_protected_authentication
2323 2323
 ) {
2324 2324
 	X509 *x509 = NULL;
2325 2325
 	RSA *rsa = NULL;
2326
-	EVP_PKEY *pubkey = NULL;
2327
-	openssl_session_t openssl_session = NULL;
2328
-	bool fShouldFreeOpenSSLSession = true;
2326
+	pkcs11h_openssl_session_t pkcs11h_openssl_session = NULL;
2329 2327
 	CK_RV rv = CKR_OK;
2330 2328
 
2331
-	unsigned char certificate[10*1024];
2332
-	size_t certificate_size;
2333
-	unsigned char *p;
2334 2329
 	bool fOK = true;
2335 2330
 
2336
-	msg (
2337
-		D_PKCS11_DEBUG,
2338
-		"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",
2331
+	PKCS11LOG (
2332
+		PKCS11_LOG_DEBUG2,
2333
+		"PKCS#11: SSL_CTX_use_pkcs11 - entered - ssl_ctx=%p, pkcs11h_slot_type='%s', pkcs11h_slot='%s', pkcs11h_id_type='%s', pkcs11h_id='%s', pkcs11h_protected_authentication=%d",
2339 2334
 		(void *)ssl_ctx,
2340
-		pkcs11_slot_type,
2341
-		pkcs11_slot,
2342
-		pkcs11_id_type,
2343
-		pkcs11_id,
2344
-		pkcs11_protected_authentication ? 1 : 0
2335
+		pkcs11h_slot_type,
2336
+		pkcs11h_slot,
2337
+		pkcs11h_id_type,
2338
+		pkcs11h_id,
2339
+		pkcs11h_protected_authentication ? 1 : 0
2345 2340
 	);
2346 2341
 
2347
-	ASSERT (ssl_ctx!=NULL);
2348
-	ASSERT (pkcs11_slot_type!=NULL);
2349
-	ASSERT (pkcs11_slot!=NULL);
2350
-	ASSERT (pkcs11_id_type!=NULL);
2351
-	ASSERT (pkcs11_id!=NULL);
2342
+	PKCS11ASSERT (ssl_ctx!=NULL);
2343
+	PKCS11ASSERT (pkcs11h_slot_type!=NULL);
2344
+	PKCS11ASSERT (pkcs11h_slot!=NULL);
2345
+	PKCS11ASSERT (pkcs11h_id_type!=NULL);
2346
+	PKCS11ASSERT (pkcs11h_id!=NULL);
2352 2347
 
2353 2348
 	if (
2354 2349
 		fOK &&
2355
-		(openssl_session = (openssl_session_t)malloc (sizeof (struct openssl_session_s))) == NULL
2350
+		(pkcs11h_openssl_session = pkcs11h_openssl_createSession (false)) == NULL
2356 2351
 	) {
2357 2352
 		fOK = false;
2358
-		msg (M_WARN, "PKCS#11: Cannot allocate memory");
2353
+		PKCS11LOG (PKCS11_LOG_WARN, "PKCS#11: Cannot initialize openssh session");
2359 2354
 	}
2360 2355
 
2361
-	if (fOK) {
2362
-		memset (openssl_session, 0, sizeof (struct openssl_session_s));
2363
-	}
2364
-	
2365 2356
 	if (
2366 2357
 		fOK &&
2367
-		(rv = pkcs11_createSession (
2368
-			pkcs11_slot_type,
2369
-			pkcs11_slot,
2370
-			pkcs11_id_type,
2371
-			pkcs11_id,
2372
-			pkcs11_protected_authentication,
2373
-			&openssl_session->pkcs11_session
2358
+		(rv = pkcs11h_createSession (
2359
+			pkcs11h_slot_type,
2360
+			pkcs11h_slot,
2361
+			pkcs11h_id_type,
2362
+			pkcs11h_id,
2363
+			pkcs11h_protected_authentication,
2364
+			&pkcs11h_openssl_session->pkcs11h_session
2374 2365
 		)) != CKR_OK
2375 2366
 	) {
2376 2367
 		fOK = false;
2377
-		msg (M_WARN, "PKCS#11: Cannot set parameters %ld-'%s'", rv, pkcs11_getMessage (rv));
2368
+		PKCS11LOG (PKCS11_LOG_WARN, "PKCS#11: Cannot set parameters %ld-'%s'", rv, pkcs11h_getMessage (rv));
2378 2369
 	}
2379 2370
 
2380 2371
 	if (
2381 2372
 		fOK &&
2382
-		(x509 = X509_new ()) == NULL
2373
+		(rsa = pkcs11h_openssl_getRSA (pkcs11h_openssl_session)) == NULL
2383 2374
 	) {
2384 2375
 		fOK = false;
2385
-		msg (M_WARN, "PKCS#11: Unable to allocate certificate object");
2376
+		PKCS11LOG (PKCS11_LOG_WARN, "PKCS#11: Unable get rsa object");
2386 2377
 	}
2387 2378
 
2388
-	certificate_size = sizeof (certificate);
2389 2379
 	if (
2390 2380
 		fOK &&
2391
-		(rv = pkcs11_getCertificate (
2392
-			openssl_session->pkcs11_session,
2393
-			certificate,
2394
-			&certificate_size
2395
-		)) != CKR_OK
2396
-	) { 
2397
-		fOK = false;
2398
-		msg (M_WARN, "PKCS#11: Cannot read X.509 certificate from token %ld-'%s'", rv, pkcs11_getMessage (rv));
2399
-	}
2400
-
2401
-	p = certificate;
2402
-	if (
2403
-		fOK &&
2404
-		!d2i_X509 (&x509, &p, certificate_size)
2405
-	) {
2406
-		fOK = false;
2407
-		msg (M_WARN, "PKCS#11: Unable to parse X.509 certificate");
2408
-	}
2409
-
2410
-	if (
2411
-		fOK &&
2412
-		(pubkey = X509_get_pubkey (x509)) == NULL
2413
-	) {
2414
-		fOK = false;
2415
-		msg (M_WARN, "PKCS#11: Cannot get public key");
2416
-	}
2417
-	
2418
-	if (
2419
-		fOK &&
2420
-		pubkey->type != EVP_PKEY_RSA
2381
+		(x509 = pkcs11h_openssl_getX509 (pkcs11h_openssl_session)) == NULL
2421 2382
 	) {
2422 2383
 		fOK = false;
2423
-		msg (M_WARN, "PKCS#11: Invalid public key algorithm");
2384
+		PKCS11LOG (PKCS11_LOG_WARN, "PKCS#11: Unable get certificate object");
2424 2385
 	}
2425 2386
 
2426 2387
 	if (
2427 2388
 		fOK &&
2428
-		(rsa = EVP_PKEY_get1_RSA (pubkey)) == NULL
2389
+		!SSL_CTX_use_RSAPrivateKey (ssl_ctx, rsa)
2429 2390
 	) {
2430 2391
 		fOK = false;
2431
-		msg (M_WARN, "PKCS#11: Cannot get RSA key");
2432
-	}
2433
-
2434
-	if (fOK) {
2435
-		openssl_pkcs11_set_rsa (openssl_session, rsa);
2436
-		rsa->flags |= RSA_FLAG_SIGN_VER;
2437
-
2438
-		/* it will be freed when rsa usage count will be zero */
2439
-		fShouldFreeOpenSSLSession = false;
2392
+		PKCS11LOG (PKCS11_LOG_WARN, "PKCS#11: Cannot set private key for openssl");
2440 2393
 	}
2441 2394
 
2442 2395
 	if (
... ...
@@ -2444,25 +288,13 @@ SSL_CTX_use_pkcs11 (
2444 2444
 		!SSL_CTX_use_certificate (ssl_ctx, x509)
2445 2445
 	) {
2446 2446
 		fOK = false;
2447
-		msg (M_WARN, "PKCS#11: Cannot set certificate for openssl");
2448
-	}
2449
-
2450
-	if (
2451
-		fOK &&
2452
-		!SSL_CTX_use_RSAPrivateKey (ssl_ctx, rsa)
2453
-	) {
2454
-		fOK = false;
2455
-		msg (M_WARN, "PKCS#11: Cannot set private key for openssl");
2447
+		PKCS11LOG (PKCS11_LOG_WARN, "PKCS#11: Cannot set certificate for openssl");
2456 2448
 	}
2457 2449
 
2458 2450
 	/*
2459 2451
 	 * openssl objects have reference
2460 2452
 	 * count, so release them
2461 2453
 	 */
2462
-	if (pubkey != NULL) {
2463
-		EVP_PKEY_free (pubkey);
2464
-		pubkey = NULL;
2465
-	}
2466 2454
 
2467 2455
 	if (x509 != NULL) {
2468 2456
 		X509_free (x509);
... ...
@@ -2473,19 +305,14 @@ SSL_CTX_use_pkcs11 (
2473 2473
 		RSA_free (rsa);
2474 2474
 		rsa = NULL;
2475 2475
 	}
2476
-
2477
-	if (fShouldFreeOpenSSLSession) {
2478
-		if (openssl_session != NULL) {
2479
-			if (openssl_session->pkcs11_session != NULL) {
2480
-				pkcs11_freeSession (openssl_session->pkcs11_session);
2481
-			}
2482
-			free (openssl_session);
2483
-			openssl_session = NULL;
2484
-		}
2476
+	
2477
+	if (pkcs11h_openssl_session != NULL) {
2478
+		pkcs11h_openssl_freeSession (pkcs11h_openssl_session);
2479
+		pkcs11h_openssl_session = NULL;
2485 2480
 	}
2486 2481
 
2487
-	msg (
2488
-		D_PKCS11_DEBUG,
2482
+	PKCS11LOG (
2483
+		PKCS11_LOG_DEBUG2,
2489 2484
 		"PKCS#11: SSL_CTX_use_pkcs11 - return fOK=%d, rv=%ld",
2490 2485
 		fOK ? 1 : 0,
2491 2486
 		rv
... ...
@@ -2496,460 +323,28 @@ SSL_CTX_use_pkcs11 (
2496 2496
 
2497 2497
 void
2498 2498
 show_pkcs11_slots (
2499
-	IN const int msglev,
2500
-	IN const int warnlev,
2501
-	IN const char * const provider
2499
+	const char * const provider
2502 2500
 ) {
2503
-	CK_INFO info;
2504
-	CK_SLOT_ID slots[1024];
2505
-	CK_ULONG slotnum;
2506
-	CK_SLOT_ID s;
2507
-	CK_RV rv;
2508
-
2509
-	pkcs11_provider_t pkcs11_provider;
2510
-
2511
-	ASSERT (provider!=NULL);
2512
-
2513
-	if (
2514
-		(rv = pkcs11_initialize ()) != CKR_OK
2515
-	) {
2516
-		msg (M_FATAL, "PKCS#11: Cannot initialize interface %ld-'%s'", rv, pkcs11_getMessage (rv));
2517
-	}
2518
-
2519
-	if (
2520
-		(rv = pkcs11_addProvider (provider, NULL)) != CKR_OK
2521
-	) {
2522
-		msg (M_FATAL, "PKCS#11: Cannot initialize provider %ld-'%s'", rv, pkcs11_getMessage (rv));
2523
-	}
2524
-
2525
-	/*
2526
-	 * our provider is head
2527
-	 */
2528
-	pkcs11_provider = pkcs11_data->providers;
2529
-	if (pkcs11_provider == NULL || !pkcs11_provider->fEnabled) {
2530
-		msg (M_FATAL, "PKCS#11: Cannot get provider %ld-'%s'", rv, pkcs11_getMessage (rv));
2531
-	}
2532
-
2533
-	if (
2534
-		(rv = pkcs11_provider->f->C_GetInfo (&info)) != CKR_OK
2535
-	) {
2536
-		msg (warnlev, "PKCS#11: Cannot get PKCS#11 provider information %ld-'%s'", rv, pkcs11_getMessage (rv));
2537
-	}
2538
-	else {
2539
-		char szManufacturerID[sizeof (info.manufacturerID)+1];
2540
-
2541
-		_fixupFixedString (
2542
-			(char *)info.manufacturerID,
2543
-			szManufacturerID,
2544
-			sizeof (info.manufacturerID)
2545
-		);
2546
-
2547
-		msg (
2548
-			msglev,
2549
-			(
2550
-			 	"Provider Information:\n"
2551
-				"\tcryptokiVersion: %u.%u\n"
2552
-				"\tmanufacturerID: %s\n"
2553
-				"\tflags: %d\n"
2554
-			),
2555
-			info.cryptokiVersion.major,
2556
-			info.cryptokiVersion.minor,
2557
-			szManufacturerID,
2558
-			(unsigned)info.flags
2559
-		);
2560
-	}
2561
-	
2562
-	slotnum = sizeof (slots) / sizeof (CK_SLOT_ID);
2563
-	if (
2564
-		(rv = pkcs11_provider->f->C_GetSlotList (
2565
-			FALSE,
2566
-			slots,
2567
-			&slotnum
2568
-		)) != CKR_OK
2569
-	) {
2570
-		msg (warnlev, "PKCS#11: Cannot get slot list %ld-'%s'", rv, pkcs11_getMessage (rv));
2571
-	}
2572
-	else {
2573
-		msg (
2574
-			msglev,
2575
-			(
2576
-			 	"The following slots are available for use with this provider.\n"
2577
-				"Each slot shown below may be used as a parameter to a\n"
2578
-				"--pkcs11-slot-type and --pkcs11-slot options.\n"
2579
-				"\n"
2580
-				"Slots: (id - name)"
2581
-			)
2582
-		);
2583
-		for (s=0;s<slotnum;s++) {
2584
-			CK_SLOT_INFO info;
2585
-
2586
-			if (
2587
-				(rv = pkcs11_provider->f->C_GetSlotInfo (
2588
-					slots[s],
2589
-					&info
2590
-				)) == CKR_OK
2591
-			) {
2592
-				char szCurrentName[sizeof (info.slotDescription)+1];
2593
-			
2594
-				_fixupFixedString (
2595
-					(char *)info.slotDescription,
2596
-					szCurrentName,
2597
-					sizeof (info.slotDescription)
2598
-				);
2599
-
2600
-				msg (msglev, "\t%lu - %s", slots[s], szCurrentName);
2601
-			}
2602
-		}
2603
-	}
2604
-
2605
-	pkcs11_terminate ();
2606
-}
2607
-
2608
-static
2609
-bool
2610
-_show_pkcs11_objects_pin_prompt (
2611
-	IN const void *pData,
2612
-	IN const char * const szLabel,
2613
-	OUT char * const szPIN,
2614
-	IN const size_t nMaxPIN
2615
-) {
2616
-	strncpy (szPIN, (char *)pData, nMaxPIN);
2617
-	return true;
2501
+	pkcs11h_standalone_dump_slots (
2502
+		_pkcs11_openvpn_print,
2503
+		NULL,
2504
+		provider
2505
+	);
2618 2506
 }
2619 2507
 
2620 2508
 void
2621 2509
 show_pkcs11_objects (
2622
-	IN const int msglev,
2623
-	IN const int warnlev,
2624
-	IN const char * const provider,
2625
-	IN const char * const slot,
2626
-	IN const char * const pin
2510
+	const char * const provider,
2511
+	const char * const slot,
2512
+	const char * const pin
2627 2513
 ) {
2628
-	CK_OBJECT_HANDLE objects[10];
2629
-	CK_SESSION_HANDLE session;
2630
-	CK_ULONG objects_found;
2631
-	CK_TOKEN_INFO info;
2632
-	CK_SLOT_ID s;
2633
-	CK_RV rv;
2634
-
2635
-	pkcs11_provider_t pkcs11_provider;
2636
-
2637
-	ASSERT (provider!=NULL);
2638
-	ASSERT (slot!=NULL);
2639
-	ASSERT (pin!=NULL);
2640
-
2641
-	s = atoi (slot);
2642
-
2643
-	if (
2644
-		(rv = pkcs11_initialize ()) != CKR_OK
2645
-	) {
2646
-		msg (M_FATAL, "PKCS#11: Cannot initialize interface %ld-'%s'", rv, pkcs11_getMessage (rv));
2647
-	}
2648
-
2649
-	if (
2650
-		(rv = pkcs11_setPINPromptHook (_show_pkcs11_objects_pin_prompt, (void *)pin)) != CKR_OK
2651
-	) {
2652
-		msg (M_FATAL, "PKCS#11: Cannot set hooks %ld-'%s'", rv, pkcs11_getMessage (rv));
2653
-	}
2654
-
2655
-	if (
2656
-		(rv = pkcs11_addProvider (provider, NULL)) != CKR_OK
2657
-	) {
2658
-		msg (M_FATAL, "PKCS#11: Cannot initialize provider %ld-'%s'", rv, pkcs11_getMessage (rv));
2659
-	}
2660
-
2661
-  	/*
2662
-	 * our provider is head
2663
-	 */
2664
-	pkcs11_provider = pkcs11_data->providers;
2665
-	if (pkcs11_provider == NULL || !pkcs11_provider->fEnabled) {
2666
-		msg (M_FATAL, "PKCS#11: Cannot get provider %ld-'%s'", rv, pkcs11_getMessage (rv));
2667
-	}
2668
-
2669
-	if (
2670
-		(rv = pkcs11_provider->f->C_GetTokenInfo (
2671
-			s,
2672
-			&info
2673
-		)) != CKR_OK
2674
-	) {
2675
-		msg (warnlev, "PKCS#11: Cannot get token information for slot %ld %ld-'%s'", s, rv, pkcs11_getMessage (rv));
2676
-	}
2677
-	else {
2678
-		char szLabel[sizeof (info.label)+1];
2679
-		char szManufacturerID[sizeof (info.manufacturerID)+1];
2680
-		char szModel[sizeof (info.model)+1];
2681
-		char szSerialNumber[sizeof (info.serialNumber)+1];
2682
-		
2683
-		_fixupFixedString (
2684
-			(char *)info.label,
2685
-			szLabel,
2686
-			sizeof (info.label)
2687
-		);
2688
-		_fixupFixedString (
2689
-			(char *)info.manufacturerID,
2690
-			szManufacturerID,
2691
-			sizeof (info.manufacturerID)
2692
-		);
2693
-		_fixupFixedString (
2694
-			(char *)info.model,
2695
-			szModel,
2696
-			sizeof (info.model)
2697
-		);
2698
-		_fixupFixedString (
2699
-			(char *)info.serialNumber,
2700
-			szSerialNumber,
2701
-			sizeof (info.serialNumber)
2702
-		);
2703
-
2704
-		msg (
2705
-			msglev,
2706
-			(
2707
-			 	"Token Information:\n"
2708
-				"\tlabel:\t\t%s\n"
2709
-				"\tmanufacturerID:\t%s\n"
2710
-				"\tmodel:\t\t%s\n"
2711
-				"\tserialNumber:\t%s\n"
2712
-				"\tflags:\t\t%08x\n"
2713
-				"\n"
2714
-				"You can access this token using\n"
2715
-				"--pkcs11-slot-type \"label\" --pkcs11-slot \"%s\" options.\n"
2716
-			),
2717
-			szLabel,
2718
-			szManufacturerID,
2719
-			szModel,
2720
-			szSerialNumber,
2721
-			(unsigned)info.flags,
2722
-			szLabel
2723
-		);
2724
-	}
2725
-
2726
-	if (
2727
-		(rv = pkcs11_provider->f->C_OpenSession (
2728
-			s,
2729
-			CKF_SERIAL_SESSION,
2730
-			NULL_PTR,
2731
-			NULL_PTR,
2732
-			&session
2733
-		)) != CKR_OK
2734
-	) {
2735
-		msg (M_FATAL, "PKCS#11: Cannot open session to slot %ld %ld-'%s'", s, rv, pkcs11_getMessage (rv));
2736
-	}
2737
-
2738
-	if (
2739
-		(rv = pkcs11_provider->f->C_Login (
2740
-			session,
2741
-			CKU_USER,
2742
-			(CK_CHAR_PTR)pin,
2743
-			(CK_ULONG)strlen (pin)
2744
-		)) != CKR_OK &&
2745
-		rv != CKR_USER_ALREADY_LOGGED_IN
2746
-	) {
2747
-		msg (M_FATAL, "PKCS#11: Cannot login to token on slot %ld %ld-'%s'", s, rv, pkcs11_getMessage (rv));
2748
-	}
2749
-
2750
-	if (
2751
-		(rv = pkcs11_provider->f->C_FindObjectsInit (
2752
-			session,
2753
-			NULL,
2754
-			0
2755
-		)) != CKR_OK
2756
-	) {
2757
-		msg (M_FATAL, "PKCS#11: Cannot query objects for token on slot %ld %ld-'%s'", s, rv, pkcs11_getMessage (rv));
2758
-	}
2759
-
2760
-	msg (
2761
-		msglev,
2762
-		"The following objects are available for use with this token.\n"
2763
-		"Each object shown below may be used as a parameter to\n"
2764
-		"--pkcs11-id-type and --pkcs11-id options.\n"
2514
+	pkcs11h_standalone_dump_objects (
2515
+		_pkcs11_openvpn_print,
2516
+		NULL,
2517
+		provider,
2518
+		slot,
2519
+		pin
2765 2520
 	);
2766
-
2767
-	while (
2768
-		(rv = pkcs11_provider->f->C_FindObjects (
2769
-			session,
2770
-			objects,
2771
-			sizeof (objects) / sizeof (CK_OBJECT_HANDLE),
2772
-			&objects_found
2773
-		)) == CKR_OK &&
2774
-		objects_found > 0
2775
-	) { 
2776
-		CK_ULONG i;
2777
-		
2778
-		for (i=0;i<objects_found;i++) {
2779
-			CK_OBJECT_CLASS attrs_class;
2780
-			unsigned char attrs_id[PKCS11_MAX_ATTRIBUTE_SIZE];
2781
-			unsigned char attrs_label[PKCS11_MAX_ATTRIBUTE_SIZE];
2782
-			CK_ATTRIBUTE attrs[] = {
2783
-				{CKA_CLASS, &attrs_class, sizeof (attrs_class)},
2784
-				{CKA_ID, attrs_id, sizeof (attrs_id)},
2785
-				{CKA_LABEL, attrs_label, sizeof (attrs_label)-1}
2786
-			};
2787
-	
2788
-			if (
2789
-				pkcs11_provider->f->C_GetAttributeValue (
2790
-					session,
2791
-					objects[i],
2792
-					attrs,
2793
-					sizeof (attrs) / sizeof (CK_ATTRIBUTE)
2794
-				) == CKR_OK
2795
-			) {
2796
-				int id_len = attrs[1].ulValueLen;
2797
-				int j;
2798
-					
2799
-				attrs_label[attrs[2].ulValueLen] = 0;
2800
-
2801
-				msg (
2802
-					msglev,
2803
-					(
2804
-					 	"Object\n"
2805
-						"\tLabel:\t\t%s\n"
2806
-						"\tId:"
2807
-					),
2808
-					attrs_label
2809
-				);
2810
-
2811
-					
2812
-				for (j=0;j<id_len;j+=16) {
2813
-					char szLine[3*16+1];
2814
-					int k;
2815
-
2816
-					szLine[0] = '\0';
2817
-					for (k=0;k<16 && j+k<id_len;k++) {
2818
-						sprintf (szLine+strlen (szLine), "%02x ", attrs_id[j+k]);
2819
-					}
2820
-
2821
-					msg (msglev, "\t\t%s", szLine);
2822
-				}
2823
-
2824
-				if (attrs_class == CKO_CERTIFICATE) {
2825
-					unsigned char certificate[PKCS11_MAX_ATTRIBUTE_SIZE];
2826
-					CK_ATTRIBUTE attrs_cert[] = {
2827
-						{CKA_VALUE, certificate, sizeof (certificate)}
2828
-					};
2829
-
2830
-					msg (msglev, "\tType:\t\tCertificate");
2831
-
2832
-					if (
2833
-						pkcs11_provider->f->C_GetAttributeValue (
2834
-							session,
2835
-							objects[i],
2836
-							attrs_cert,
2837
-							sizeof (attrs_cert) / sizeof (CK_ATTRIBUTE)
2838
-						) == CKR_OK
2839
-					) {
2840
-						X509 *x509 = NULL;
2841
-						BIO *bioSerial = NULL;
2842
-
2843
-						char szSubject[1024];
2844
-						char szSerial[1024];
2845
-						char szNotBefore[1024];
2846
-
2847
-						szSubject[0] = '\0';
2848
-						szSerial[0] = '\0';
2849
-						szNotBefore[0] = '\0';
2850
-
2851
-						if ((x509 = X509_new ()) == NULL) {
2852
-							msg (warnlev, "Cannot create x509 context");
2853
-						}
2854
-						else {
2855
-							unsigned char *p;
2856
-
2857
-							p = certificate;
2858
-							if (d2i_X509 (&x509, &p, attrs_cert[0].ulValueLen)) {
2859
-
2860
-								ASN1_TIME *notBefore = X509_get_notBefore (x509);
2861
-								if (notBefore != NULL && notBefore->length < (int) sizeof (szNotBefore) - 1) {
2862
-									memmove (szNotBefore, notBefore->data, notBefore->length);
2863
-									szNotBefore[notBefore->length] = '\0';
2864
-								}
2865
-
2866
-  								X509_NAME_oneline (
2867
-									X509_get_subject_name (x509),
2868
-									szSubject,
2869
-									sizeof (szSubject)
2870
-								);
2871
-								szSubject[sizeof (szSubject) - 1] = '\0';
2872
-							}
2873
-						}
2874
-
2875
-						if ((bioSerial = BIO_new (BIO_s_mem ())) == NULL) {
2876
-							msg (warnlev, "Cannot create BIO context");
2877
-						}
2878
-						else {
2879
-							int n;
2880
-
2881
-							i2a_ASN1_INTEGER(bioSerial, X509_get_serialNumber (x509));
2882
-							n = BIO_read (bioSerial, szSerial, sizeof (szSerial)-1);
2883
-							if (n<0) {
2884
-								szSerial[0] = '\0';
2885
-							}
2886
-							else {
2887
-								szSerial[n] = '\0';
2888
-							}
2889
-						}
2890
-
2891
-
2892
-						if (x509 != NULL) {
2893
-							X509_free (x509);
2894
-							x509 = NULL;
2895
-						}
2896
-						if (bioSerial != NULL) {
2897
-							BIO_free_all (bioSerial);
2898
-							bioSerial = NULL;
2899
-						}
2900
-
2901
-						msg (
2902
-							msglev,
2903
-							(
2904
-							 	"\tsubject:\t%s\n"
2905
-								"\tserialNumber:\t%s\n"
2906
-								"\tnotBefore:\t%s"
2907
-							),
2908
-							szSubject,
2909
-							szSerial,
2910
-							szNotBefore
2911
-						);
2912
-					}
2913
-				}
2914
-				else if (attrs_class == CKO_PRIVATE_KEY) {
2915
-					CK_BBOOL sign_recover;
2916
-					CK_BBOOL sign;
2917
-					CK_ATTRIBUTE attrs_key[] = {
2918
-						{CKA_SIGN, &sign_recover, sizeof (sign_recover)},
2919
-						{CKA_SIGN_RECOVER, &sign, sizeof (sign)}
2920
-					};
2921
-
2922
-					msg (msglev, "\tType:\t\tPrivate Key");
2923
-
2924
-					if (
2925
-						pkcs11_provider->f->C_GetAttributeValue (
2926
-							session,
2927
-							objects[i],
2928
-							attrs_key,
2929
-							sizeof (attrs_key) / sizeof (CK_ATTRIBUTE)
2930
-						) == CKR_OK
2931
-					) {
2932
-						msg (
2933
-							msglev,
2934
-							(
2935
-								"\tSign:\t\t%s\n"
2936
-								"\tSign Recover:\t%s"
2937
-							),
2938
-							sign ? "TRUE" : "FALSE",
2939
-							sign_recover ? "TRUE" : "FALSE"
2940
-						);
2941
-					}
2942
-				}
2943
-				else {
2944
-					msg (msglev, "\tType:\t\tUnsupported");
2945
-				}
2946
-			}
2947
-		}
2948
-	}
2949
-	pkcs11_provider->f->C_FindObjectsFinal (session);
2950
-	pkcs11_provider->f->C_Logout (session);
2951
-	pkcs11_provider->f->C_CloseSession (session);
2952
-	pkcs11_terminate ();
2953 2521
 }
2954 2522
 
2955 2523
 #else
... ...
@@ -30,18 +30,18 @@
30 30
 #include <openssl/ssl.h>
31 31
 
32 32
 void
33
-init_pkcs11 (
33
+pkcs11_initialize (
34 34
 	const int nPINCachePeriod
35 35
 );
36 36
 
37 37
 void
38
-free_pkcs11 ();
38
+pkcs11_terminate ();
39 39
 
40 40
 void
41
-fork_fix_pkcs11 ();
41
+pkcs11_forkFixup ();
42 42
 
43 43
 void
44
-add_pkcs11 (
44
+pkcs11_addProvider (
45 45
 	const char * const provider,
46 46
 	const char * const sign_mode
47 47
 );
... ...
@@ -58,15 +58,11 @@ SSL_CTX_use_pkcs11 (
58 58
 
59 59
 void
60 60
 show_pkcs11_slots (
61
-	const int msglev,
62
-	const int warnlev,
63 61
 	const char * const provider
64 62
 );
65 63
 
66 64
 void
67 65
 show_pkcs11_objects (
68
-	const int msglev,
69
-	const int warnlev,
70 66
 	const char * const provider,
71 67
 	const char * const slot,
72 68
 	const char * const pin
... ...
@@ -280,7 +280,6 @@ new_http_proxy (const struct http_proxy_options *o,
280 280
     {
281 281
       get_user_pass (&static_proxy_user_pass,
282 282
 		     o->auth_file,
283
-		     false,
284 283
 		     "HTTP Proxy",
285 284
 		     GET_USER_PASS_MANAGEMENT);
286 285
       p->up = static_proxy_user_pass;
... ...
@@ -266,7 +266,7 @@ void
266 266
 pem_password_setup (const char *auth_file)
267 267
 {
268 268
   if (!strlen (passbuf.password))
269
-    get_user_pass (&passbuf, auth_file, true, UP_TYPE_PRIVATE_KEY, GET_USER_PASS_MANAGEMENT|GET_USER_PASS_SENSITIVE);
269
+    get_user_pass (&passbuf, auth_file, UP_TYPE_PRIVATE_KEY, GET_USER_PASS_MANAGEMENT|GET_USER_PASS_SENSITIVE|GET_USER_PASS_PASSWORD_ONLY);
270 270
 }
271 271
 
272 272
 int
... ...
@@ -296,7 +296,7 @@ auth_user_pass_setup (const char *auth_file)
296 296
 {
297 297
   auth_user_pass_enabled = true;
298 298
   if (!auth_user_pass.defined)
299
-    get_user_pass (&auth_user_pass, auth_file, false, UP_TYPE_AUTH, GET_USER_PASS_MANAGEMENT|GET_USER_PASS_SENSITIVE);
299
+    get_user_pass (&auth_user_pass, auth_file, UP_TYPE_AUTH, GET_USER_PASS_MANAGEMENT|GET_USER_PASS_SENSITIVE);
300 300
 }
301 301
 
302 302
 /*